Skip to content
This repository has been archived by the owner on Sep 27, 2024. It is now read-only.

Commit

Permalink
Merge pull request #915 from matrix-org/android/setOnReceiveContentLi…
Browse files Browse the repository at this point in the history
…stener

Add support for sending rich content from the keyboard.
  • Loading branch information
bmarty authored Dec 29, 2023
2 parents cf12239 + e2d6c6e commit 6dc0a78
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.element.android.wysiwyg.compose

import android.net.Uri
import android.view.View
import androidx.appcompat.widget.AppCompatEditText
import androidx.compose.runtime.Composable
Expand Down Expand Up @@ -41,6 +42,7 @@ import timber.log.Timber
* @param resolveRoomMentionDisplay A function to resolve the [TextDisplay] of an `@room` mention.
* @param onTyping Called when the user starts or stops typing in the editor.
* @param onError Called when an internal error occurs
* @param onRichContentSelected Called when user uses the keyboard to send a rich content
*/
@Composable
fun RichTextEditor(
Expand All @@ -53,6 +55,7 @@ fun RichTextEditor(
resolveRoomMentionDisplay: () -> TextDisplay = RichTextEditorDefaults.RoomMentionDisplay,
onTyping: (Boolean) -> Unit = {},
onError: (Throwable) -> Unit = {},
onRichContentSelected: ((Uri) -> Unit)? = null,
) {
val isPreview = LocalInspectionMode.current

Expand All @@ -69,6 +72,7 @@ fun RichTextEditor(
resolveMentionDisplay = resolveMentionDisplay,
resolveRoomMentionDisplay = resolveRoomMentionDisplay,
onTyping = onTyping,
onRichContentSelected = onRichContentSelected,
)
}
}
Expand All @@ -84,6 +88,7 @@ private fun RealEditor(
resolveMentionDisplay: (text: String, url: String) -> TextDisplay,
resolveRoomMentionDisplay: () -> TextDisplay,
onTyping: (Boolean) -> Unit,
onRichContentSelected: ((Uri) -> Unit)?,
) {
val context = LocalContext.current
val coroutineScope = rememberCoroutineScope()
Expand Down Expand Up @@ -154,6 +159,7 @@ private fun RealEditor(
setHtml(state.internalHtml)
setSelection(state.selection.first, state.selection.second)

setOnRichContentSelected(onRichContentSelected)
// Only start listening for text changes after the initial state has been restored
if (registerStateUpdates) {
coroutineScope.launch(context = Dispatchers.Main) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import android.content.ClipboardManager
import android.content.Context
import android.content.Context.CLIPBOARD_SERVICE
import android.graphics.Canvas
import android.net.Uri
import android.os.Build
import android.os.Parcelable
import android.text.Selection
Expand All @@ -18,10 +19,12 @@ import android.widget.EditText
import androidx.annotation.VisibleForTesting
import androidx.appcompat.widget.AppCompatEditText
import androidx.core.graphics.withTranslation
import androidx.core.view.ViewCompat
import androidx.lifecycle.*
import io.element.android.wysiwyg.display.MentionDisplayHandler
import io.element.android.wysiwyg.inputhandlers.InterceptInputConnection
import io.element.android.wysiwyg.internal.display.MemoizingMentionDisplayHandler
import io.element.android.wysiwyg.internal.utils.UriContentListener
import io.element.android.wysiwyg.internal.view.EditorEditTextAttributeReader
import io.element.android.wysiwyg.internal.view.viewModel
import io.element.android.wysiwyg.internal.viewmodel.EditorInputAction
Expand Down Expand Up @@ -276,6 +279,16 @@ class EditorEditText : AppCompatEditText {
htmlConverter = createHtmlConverter(styleConfig, mentionDisplayHandler)
}

fun setOnRichContentSelected(onRichContentSelected: ((Uri) -> Unit)?) {
if (onRichContentSelected != null) {
ViewCompat.setOnReceiveContentListener(
this,
arrayOf("image/*"),
UriContentListener { onRichContentSelected(it) }
)
}
}

private fun addHardwareKeyInterceptor() {
// This seems to be the only way to prevent EditText from automatically handling key strokes
setOnKeyListener { _, keyCode, event ->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package io.element.android.wysiwyg.internal.utils

import android.content.ClipData
import android.net.Uri
import android.view.View
import androidx.core.view.ContentInfoCompat
import androidx.core.view.OnReceiveContentListener

internal class UriContentListener(
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
}
}

0 comments on commit 6dc0a78

Please sign in to comment.