mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-15 01:35:07 +08:00
[Rich text editor] Add ability to insert GIFs from keyboard (#8185)
Closes vector-im/verticals-internal#21
This commit is contained in:
parent
bcdd92c22a
commit
7dd15af6d3
1
changelog.d/8185.feature
Normal file
1
changelog.d/8185.feature
Normal file
@ -0,0 +1 @@
|
||||
[Rich text editor] Add ability to insert GIFs from keyboard
|
@ -17,7 +17,6 @@
|
||||
|
||||
package im.vector.app.features.home.room.detail.composer
|
||||
|
||||
import android.content.ClipData
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
@ -27,12 +26,12 @@ import android.view.inputmethod.EditorInfo
|
||||
import android.view.inputmethod.InputConnection
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.appcompat.widget.AppCompatEditText
|
||||
import androidx.core.view.OnReceiveContentListener
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.inputmethod.EditorInfoCompat
|
||||
import androidx.core.view.inputmethod.InputConnectionCompat
|
||||
import im.vector.app.core.extensions.ooi
|
||||
import im.vector.app.core.platform.SimpleTextWatcher
|
||||
import im.vector.app.features.home.room.detail.composer.images.UriContentListener
|
||||
import im.vector.app.features.html.PillImageSpan
|
||||
import timber.log.Timber
|
||||
|
||||
@ -56,27 +55,11 @@ class ComposerEditText @JvmOverloads constructor(
|
||||
EditorInfoCompat.setContentMimeTypes(editorInfo, mimeTypes)
|
||||
ic = InputConnectionCompat.createWrapper(this, ic, editorInfo)
|
||||
|
||||
val onReceiveContentListener = OnReceiveContentListener { _, payload ->
|
||||
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 ...
|
||||
callback?.onRichContentSelected(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 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.
|
||||
remaining
|
||||
}
|
||||
|
||||
ViewCompat.setOnReceiveContentListener(this, mimeTypes, onReceiveContentListener)
|
||||
ViewCompat.setOnReceiveContentListener(
|
||||
this,
|
||||
mimeTypes,
|
||||
UriContentListener { callback?.onRichContentSelected(it) }
|
||||
)
|
||||
|
||||
return ic
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.constraintlayout.widget.ConstraintSet
|
||||
import androidx.core.text.toSpannable
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.isGone
|
||||
import androidx.core.view.isInvisible
|
||||
import androidx.core.view.isVisible
|
||||
@ -47,6 +48,7 @@ import im.vector.app.core.extensions.showKeyboard
|
||||
import im.vector.app.core.utils.DimensionConverter
|
||||
import im.vector.app.databinding.ComposerRichTextLayoutBinding
|
||||
import im.vector.app.databinding.ViewRichTextMenuButtonBinding
|
||||
import im.vector.app.features.home.room.detail.composer.images.UriContentListener
|
||||
import io.element.android.wysiwyg.EditorEditText
|
||||
import io.element.android.wysiwyg.inputhandlers.models.InlineFormat
|
||||
import io.element.android.wysiwyg.inputhandlers.models.LinkAction
|
||||
@ -188,6 +190,16 @@ internal class RichTextComposerLayout @JvmOverloads constructor(
|
||||
views.plainTextComposerEditText.addTextChangedListener(
|
||||
TextChangeListener({ callback?.onTextChanged(it) }, { updateTextFieldBorder(isFullScreen) })
|
||||
)
|
||||
ViewCompat.setOnReceiveContentListener(
|
||||
views.richTextComposerEditText,
|
||||
arrayOf("image/*"),
|
||||
UriContentListener { callback?.onRichContentSelected(it) }
|
||||
)
|
||||
ViewCompat.setOnReceiveContentListener(
|
||||
views.plainTextComposerEditText,
|
||||
arrayOf("image/*"),
|
||||
UriContentListener { callback?.onRichContentSelected(it) }
|
||||
)
|
||||
|
||||
disallowParentInterceptTouchEvent(views.richTextComposerEditText)
|
||||
disallowParentInterceptTouchEvent(views.plainTextComposerEditText)
|
||||
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2023 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.app.features.home.room.detail.composer.images
|
||||
|
||||
import android.content.ClipData
|
||||
import android.net.Uri
|
||||
import android.view.View
|
||||
import androidx.core.view.ContentInfoCompat
|
||||
import androidx.core.view.OnReceiveContentListener
|
||||
|
||||
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
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user