Add autocomplete to plain text composer

This commit is contained in:
jonnyandrew 2023-05-18 11:05:04 +01:00
parent 24614bbbae
commit 3157a35b74
No known key found for this signature in database
GPG key ID: 0D58D4EF33D27015
3 changed files with 46 additions and 14 deletions

View file

@ -87,6 +87,7 @@ class AutoCompleter @AssistedInject constructor(
}
private lateinit var glideRequests: GlideRequests
private val autocompletes: MutableSet<Autocomplete<*>> = hashSetOf()
fun setup(editText: EditText) {
this.editText = editText
@ -98,16 +99,27 @@ class AutoCompleter @AssistedInject constructor(
setupRooms(backgroundDrawable, editText)
}
fun setEnabled(isEnabled: Boolean) =
autocompletes.forEach {
if (!isEnabled) { it.dismissPopup() }
it.setEnabled(isEnabled)
}
fun clear() {
this.editText = null
autocompleteEmojiPresenter.clear()
autocompleteRoomPresenter.clear()
autocompleteCommandPresenter.clear()
autocompleteMemberPresenter.clear()
autocompletes.forEach {
it.setEnabled(false)
it.dismissPopup()
}
autocompletes.clear()
}
private fun setupCommands(backgroundDrawable: Drawable, editText: EditText) {
Autocomplete.on<Command>(editText)
autocompletes += Autocomplete.on<Command>(editText)
.with(commandAutocompletePolicy)
.with(autocompleteCommandPresenter)
.with(ELEVATION_DP)
@ -133,7 +145,7 @@ class AutoCompleter @AssistedInject constructor(
private fun setupMembers(backgroundDrawable: ColorDrawable, editText: EditText) {
autocompleteMemberPresenter = autocompleteMemberPresenterFactory.create(roomId)
Autocomplete.on<AutocompleteMemberItem>(editText)
autocompletes += Autocomplete.on<AutocompleteMemberItem>(editText)
.with(CharPolicy(TRIGGER_AUTO_COMPLETE_MEMBERS, true))
.with(autocompleteMemberPresenter)
.with(ELEVATION_DP)
@ -158,7 +170,7 @@ class AutoCompleter @AssistedInject constructor(
}
private fun setupRooms(backgroundDrawable: ColorDrawable, editText: EditText) {
Autocomplete.on<RoomSummary>(editText)
autocompletes += Autocomplete.on<RoomSummary>(editText)
.with(CharPolicy(TRIGGER_AUTO_COMPLETE_ROOMS, true))
.with(autocompleteRoomPresenter)
.with(ELEVATION_DP)
@ -179,7 +191,7 @@ class AutoCompleter @AssistedInject constructor(
// Rich text editor is not yet supported
if (editText is EditorEditText) return
Autocomplete.on<String>(editText)
autocompletes += Autocomplete.on<String>(editText)
.with(CharPolicy(TRIGGER_AUTO_COMPLETE_EMOJIS, false))
.with(autocompleteEmojiPresenter)
.with(ELEVATION_DP)

View file

@ -125,9 +125,7 @@ class MessageComposerFragment : VectorBaseFragment<FragmentComposerBinding>(), A
private val roomId: String get() = withState(timelineViewModel) { it.roomId }
private val autoCompleter: AutoCompleter by lazy {
autoCompleterFactory.create(roomId, isThreadTimeLine())
}
private val autoCompleters: MutableMap<EditText, AutoCompleter> = hashMapOf()
private val emojiPopup: EmojiPopup by lifecycleAwareLazy {
createEmojiPopup()
@ -262,9 +260,8 @@ class MessageComposerFragment : VectorBaseFragment<FragmentComposerBinding>(), A
override fun onDestroyView() {
super.onDestroyView()
if (!vectorPreferences.isRichTextEditorEnabled()) {
autoCompleter.clear()
}
autoCompleters.values.forEach(AutoCompleter::clear)
autoCompleters.clear()
messageComposerViewModel.endAllVoiceActions()
}
@ -275,7 +272,12 @@ class MessageComposerFragment : VectorBaseFragment<FragmentComposerBinding>(), A
(composer as? View)?.isVisible = messageComposerState.isComposerVisible
composer.sendButton.isInvisible = !messageComposerState.isSendButtonVisible
(composer as? RichTextComposerLayout)?.isTextFormattingEnabled = attachmentState.isTextFormattingEnabled
(composer as? RichTextComposerLayout)?.also {
val isTextFormattingEnabled = attachmentState.isTextFormattingEnabled
it.isTextFormattingEnabled = isTextFormattingEnabled
autoCompleters[it.richTextEditText]?.setEnabled(isTextFormattingEnabled)
autoCompleters[it.plainTextEditText]?.setEnabled(!isTextFormattingEnabled)
}
}
private fun setupBottomSheet() {
@ -316,7 +318,12 @@ class MessageComposerFragment : VectorBaseFragment<FragmentComposerBinding>(), A
val composerEditText = composer.editText
composerEditText.setHint(R.string.room_message_placeholder)
autoCompleter.setup(composerEditText)
(composer as? RichTextComposerLayout)?.let {
initAutoCompleter(it.richTextEditText)
initAutoCompleter(it.plainTextEditText)
} ?: run {
initAutoCompleter(composer.editText)
}
observerUserTyping()
@ -412,6 +419,14 @@ class MessageComposerFragment : VectorBaseFragment<FragmentComposerBinding>(), A
}
}
private fun initAutoCompleter(editText: EditText) {
if (autoCompleters.containsKey(editText)) return
autoCompleters[editText] =
autoCompleterFactory.create(roomId, isThreadTimeLine())
.also { it.setup(editText) }
}
private fun sendTextMessage(text: CharSequence, formattedText: String? = null) {
if (lockSendButton) {
Timber.w("Send button is locked")
@ -441,12 +456,12 @@ class MessageComposerFragment : VectorBaseFragment<FragmentComposerBinding>(), A
}
private fun renderRegularMode(content: CharSequence) {
autoCompleter.exitSpecialMode()
autoCompleters.values.forEach(AutoCompleter::exitSpecialMode)
composer.renderComposerMode(MessageComposerMode.Normal(content))
}
private fun renderSpecialMode(mode: MessageComposerMode.Special) {
autoCompleter.enterSpecialMode()
autoCompleters.values.forEach(AutoCompleter::enterSpecialMode)
composer.renderComposerMode(mode)
}

View file

@ -106,6 +106,11 @@ internal class RichTextComposerLayout @JvmOverloads constructor(
override val attachmentButton: ImageButton
get() = views.attachmentButton
val richTextEditText: EditText get() =
views.richTextComposerEditText
val plainTextEditText: EditText get() =
views.plainTextComposerEditText
var pillDisplayHandler: PillDisplayHandler? = null
// Border of the EditText