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:
parent
9065e9d2eb
commit
873f57399d
4 changed files with 42 additions and 0 deletions
1
changelog.d/2917.bugfix
Normal file
1
changelog.d/2917.bugfix
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Fixed sending rich content from android keyboards on the markdown text input
|
||||||
|
|
@ -190,6 +190,7 @@ fun TextComposer(
|
||||||
onTyping = onTyping,
|
onTyping = onTyping,
|
||||||
onSuggestionReceived = onSuggestionReceived,
|
onSuggestionReceived = onSuggestionReceived,
|
||||||
richTextEditorStyle = style,
|
richTextEditorStyle = style,
|
||||||
|
onRichContentSelected = onRichContentSelected,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 = {},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -191,6 +191,7 @@ class MarkdownTextInputTest {
|
||||||
onTyping = onTyping,
|
onTyping = onTyping,
|
||||||
onSuggestionReceived = onSuggestionReceived,
|
onSuggestionReceived = onSuggestionReceived,
|
||||||
richTextEditorStyle = style,
|
richTextEditorStyle = style,
|
||||||
|
onRichContentSelected = null,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue