Add rich content listener to markdown text input (#2918)

* add rich content listener to markdown text input

Signed-off-by: Marco Antonio Alvarez <surakin@gmail.com>
This commit is contained in:
Marco Antonio Alvarez 2024-05-27 16:36:32 +02:00 committed by GitHub
parent 3a39e2a3ec
commit a9835e0dd1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 42 additions and 0 deletions

1
changelog.d/2917.bugfix Normal file
View file

@ -0,0 +1 @@
Fixed sending rich content from android keyboards on the markdown text input

View file

@ -190,6 +190,7 @@ fun TextComposer(
onTyping = onTyping,
onSuggestionReceived = onSuggestionReceived,
richTextEditorStyle = style,
onRichContentSelected = onRichContentSelected,
)
}
}

View file

@ -16,10 +16,13 @@
package io.element.android.libraries.textcomposer.components.markdown
import android.content.ClipData
import android.graphics.Color
import android.net.Uri
import android.text.Editable
import android.text.InputType
import android.text.Selection
import android.view.View
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
@ -27,6 +30,9 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.text.getSpans
import androidx.core.view.ContentInfoCompat
import androidx.core.view.OnReceiveContentListener
import androidx.core.view.ViewCompat
import androidx.core.view.setPadding
import androidx.core.widget.addTextChangedListener
import io.element.android.libraries.designsystem.preview.ElementPreview
@ -48,8 +54,33 @@ fun MarkdownTextInput(
onTyping: (Boolean) -> Unit,
onSuggestionReceived: (Suggestion?) -> Unit,
richTextEditorStyle: RichTextEditorStyle,
onRichContentSelected: ((Uri) -> Unit)?,
) {
val canUpdateState = !subcomposing
// Copied from io.element.android.wysiwyg.internal.utils.UriContentListener
class ReceiveUriContentListener(
private val onContent: (uri: Uri) -> Unit,
) : OnReceiveContentListener {
override fun onReceiveContent(view: View, payload: ContentInfoCompat): ContentInfoCompat? {
val split = payload.partition { item -> item.uri != null }
val uriContent = split.first
val remaining = split.second
if (uriContent != null) {
val clip: ClipData = uriContent.clip
for (i in 0 until clip.itemCount) {
val uri = clip.getItemAt(i).uri
// ... app-specific logic to handle the URI ...
onContent(uri)
}
}
// Return anything that we didn't handle ourselves. This preserves the default platform
// behavior for text and anything else for which we are not implementing custom handling.
return remaining
}
}
AndroidView(
modifier = Modifier
.padding(top = 6.dp, bottom = 6.dp)
@ -82,6 +113,13 @@ fun MarkdownTextInput(
state.currentMentionSuggestion = editableText.checkSuggestionNeeded()
onSuggestionReceived(state.currentMentionSuggestion)
}
if (onRichContentSelected != null) {
ViewCompat.setOnReceiveContentListener(
this,
arrayOf("image/*"),
ReceiveUriContentListener { onRichContentSelected(it) }
)
}
state.requestFocusAction = { this.requestFocus() }
}
}
@ -152,6 +190,7 @@ internal fun MarkdownTextInputPreview() {
onTyping = {},
onSuggestionReceived = {},
richTextEditorStyle = style,
onRichContentSelected = {},
)
}
}

View file

@ -191,6 +191,7 @@ class MarkdownTextInputTest {
onTyping = onTyping,
onSuggestionReceived = onSuggestionReceived,
richTextEditorStyle = style,
onRichContentSelected = null,
)
}
}