Browse Source

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>
pull/2926/head
Marco Antonio Alvarez 4 months ago committed by GitHub
parent
commit
a9835e0dd1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      changelog.d/2917.bugfix
  2. 1
      libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt
  3. 39
      libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/markdown/MarkdownTextInput.kt
  4. 1
      libraries/textcomposer/impl/src/test/kotlin/io/element/android/libraries/textcomposer/impl/components/markdown/MarkdownTextInputTest.kt

1
changelog.d/2917.bugfix

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

1
libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt

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

39
libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/markdown/MarkdownTextInput.kt

@ -16,10 +16,13 @@
package io.element.android.libraries.textcomposer.components.markdown package io.element.android.libraries.textcomposer.components.markdown
import android.content.ClipData
import android.graphics.Color import android.graphics.Color
import android.net.Uri
import android.text.Editable import android.text.Editable
import android.text.InputType import android.text.InputType
import android.text.Selection import android.text.Selection
import android.view.View
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@ -27,6 +30,9 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.text.getSpans 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.view.setPadding
import androidx.core.widget.addTextChangedListener import androidx.core.widget.addTextChangedListener
import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.ElementPreview
@ -48,8 +54,33 @@ fun MarkdownTextInput(
onTyping: (Boolean) -> Unit, onTyping: (Boolean) -> Unit,
onSuggestionReceived: (Suggestion?) -> Unit, onSuggestionReceived: (Suggestion?) -> Unit,
richTextEditorStyle: RichTextEditorStyle, richTextEditorStyle: RichTextEditorStyle,
onRichContentSelected: ((Uri) -> Unit)?,
) { ) {
val canUpdateState = !subcomposing 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( AndroidView(
modifier = Modifier modifier = Modifier
.padding(top = 6.dp, bottom = 6.dp) .padding(top = 6.dp, bottom = 6.dp)
@ -82,6 +113,13 @@ fun MarkdownTextInput(
state.currentMentionSuggestion = editableText.checkSuggestionNeeded() state.currentMentionSuggestion = editableText.checkSuggestionNeeded()
onSuggestionReceived(state.currentMentionSuggestion) onSuggestionReceived(state.currentMentionSuggestion)
} }
if (onRichContentSelected != null) {
ViewCompat.setOnReceiveContentListener(
this,
arrayOf("image/*"),
ReceiveUriContentListener { onRichContentSelected(it) }
)
}
state.requestFocusAction = { this.requestFocus() } state.requestFocusAction = { this.requestFocus() }
} }
} }
@ -152,6 +190,7 @@ internal fun MarkdownTextInputPreview() {
onTyping = {}, onTyping = {},
onSuggestionReceived = {}, onSuggestionReceived = {},
richTextEditorStyle = style, richTextEditorStyle = style,
onRichContentSelected = {},
) )
} }
} }

1
libraries/textcomposer/impl/src/test/kotlin/io/element/android/libraries/textcomposer/impl/components/markdown/MarkdownTextInputTest.kt

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

Loading…
Cancel
Save