Merge pull request #2514 from vector-im/feature/ons/emoji_keyboard

Emoji Keyboard
This commit is contained in:
Benoit Marty 2020-12-10 17:13:43 +01:00 committed by GitHub
commit 43ac66feb3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 166 additions and 106 deletions

View File

@ -4,6 +4,7 @@ Changes in Element 1.0.12 (2020-XX-XX)
Features ✨:
- Add room aliases management, and room directory visibility management in a dedicated screen (#1579, #2428)
- Room setting: update join rules and guest access (#2442)
- Emoji Keyboard (#2520)
Improvements 🙌:
- Add Setting Item to Change PIN (#2462)

View File

@ -440,6 +440,10 @@ dependencies {
implementation 'com.google.zxing:core:3.3.3'
implementation 'me.dm7.barcodescanner:zxing:1.9.13'
// Emoji Keyboard
implementation 'com.vanniktech:emoji-material:0.7.0'
implementation 'com.vanniktech:emoji-google:0.7.0'
// TESTS
testImplementation 'junit:junit:4.13'
testImplementation "org.amshove.kluent:kluent-android:$kluent_version"

View File

@ -347,11 +347,6 @@ SOFTWARE.
<br/>
Copyright 2017 Gabriel Ittner.
</li>
<li>
<b>Android-multipicker-library</b>
<br/>
Copyright 2018 Kumar Bibek
</li>
<li>
<b>htmlcompressor</b>
<br/>
@ -390,6 +385,11 @@ SOFTWARE.
<br/>
Copyright 2018, Aleksandr Nikiforov
</li>
<li>
<b>Emoji</b>
<br/>
Copyright (C) 2016 - Niklas Baudy, Ruben Gees, Mario Đanić and contributors
</li>
</ul>
<pre>
Apache License

View File

@ -36,6 +36,8 @@ import com.airbnb.epoxy.EpoxyAsyncUtil
import com.airbnb.epoxy.EpoxyController
import com.facebook.stetho.Stetho
import com.gabrielittner.threetenbp.LazyThreeTen
import com.vanniktech.emoji.EmojiManager
import com.vanniktech.emoji.google.GoogleEmojiProvider
import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.di.DaggerVectorComponent
import im.vector.app.core.di.HasVectorInjector
@ -184,6 +186,8 @@ class VectorApplication :
addAction(Intent.ACTION_SCREEN_OFF)
addAction(Intent.ACTION_SCREEN_ON)
})
EmojiManager.install(GoogleEmojiProvider())
}
private fun enableStrictModeIfNeeded() {

View File

@ -53,7 +53,6 @@ import androidx.lifecycle.Observer
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import butterknife.BindView
import com.airbnb.epoxy.EpoxyModel
import com.airbnb.epoxy.OnModelBuildFinishedListener
import com.airbnb.epoxy.addGlidePreloader
@ -69,6 +68,7 @@ import com.airbnb.mvrx.withState
import com.google.android.material.snackbar.Snackbar
import com.google.android.material.textfield.TextInputEditText
import com.jakewharton.rxbinding3.widget.textChanges
import com.vanniktech.emoji.EmojiPopup
import im.vector.app.R
import im.vector.app.core.dialogs.ConfirmationDialogBuilder
import im.vector.app.core.dialogs.GalleryOrCameraDialogHelper
@ -289,8 +289,6 @@ class RoomDetailFragment @Inject constructor(
private lateinit var attachmentsHelper: AttachmentsHelper
private lateinit var keyboardStateUtils: KeyboardStateUtils
@BindView(R.id.composerLayout)
lateinit var composerLayout: TextComposerView
private lateinit var attachmentTypeSelector: AttachmentTypeSelectorView
private var lockSendButton = false
@ -311,6 +309,7 @@ class RoomDetailFragment @Inject constructor(
setupActiveCallView()
setupJumpToBottomView()
setupConfBannerView()
setupEmojiPopup()
roomToolbarContentView.debouncedClicks {
navigator.openRoomProfile(requireActivity(), roomDetailArgs.roomId)
@ -478,6 +477,20 @@ class RoomDetailFragment @Inject constructor(
}
}
private fun setupEmojiPopup() {
val emojiPopup = EmojiPopup
.Builder
.fromRootView(rootConstraintLayout)
.setKeyboardAnimationStyle(R.style.emoji_fade_animation_style)
.setOnEmojiPopupShownListener { composerLayout?.composerEmojiButton?.setImageResource(R.drawable.ic_keyboard) }
.setOnEmojiPopupDismissListener { composerLayout?.composerEmojiButton?.setImageResource(R.drawable.ic_insert_emoji) }
.build(composerLayout.composerEditText)
composerLayout.composerEmojiButton.debouncedClicks {
emojiPopup.toggle()
}
}
private fun joinJitsiRoom(jitsiWidget: Widget, enableVideo: Boolean) {
navigator.openRoomWidget(requireContext(), roomDetailArgs.roomId, jitsiWidget, mapOf(JitsiCallViewModel.ENABLE_VIDEO_OPTION to enableVideo))
}
@ -1211,9 +1224,6 @@ class RoomDetailFragment @Inject constructor(
scrollOnHighlightedEventCallback.timeline = roomDetailViewModel.timeline
timelineEventController.update(state)
inviteView.visibility = View.GONE
val uid = session.myUserId
val meMember = state.myRoomMember()
avatarRenderer.render(MatrixItem.UserItem(uid, meMember?.displayName, meMember?.avatarUrl), composerLayout.composerAvatarImageView)
if (state.tombstoneEvent == null) {
if (state.canSendMessage) {
composerLayout.visibility = View.VISIBLE

View File

@ -24,16 +24,16 @@ import android.text.Editable
import android.util.AttributeSet
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputConnection
import androidx.appcompat.widget.AppCompatEditText
import androidx.core.view.inputmethod.EditorInfoCompat
import androidx.core.view.inputmethod.InputConnectionCompat
import com.vanniktech.emoji.EmojiEditText
import im.vector.app.core.extensions.ooi
import im.vector.app.core.platform.SimpleTextWatcher
import im.vector.app.features.html.PillImageSpan
import timber.log.Timber
class ComposerEditText @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = android.R.attr.editTextStyle)
: AppCompatEditText(context, attrs, defStyleAttr) {
: EmojiEditText(context, attrs, defStyleAttr) {
interface Callback {
fun onRichContentSelected(contentUri: Uri): Boolean

View File

@ -72,8 +72,8 @@ class TextComposerView @JvmOverloads constructor(context: Context, attrs: Attrib
@BindView(R.id.composerEditText)
lateinit var composerEditText: ComposerEditText
@BindView(R.id.composer_avatar_view)
lateinit var composerAvatarImageView: ImageView
@BindView(R.id.composer_emoji)
lateinit var composerEmojiButton: ImageButton
@BindView(R.id.composer_shield)
lateinit var composerShieldImageView: ImageView

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="oval">
<solid android:color="@color/riotx_accent" />
</shape>
</item>
<item android:drawable="?attr/selectableItemBackground" />
</layer-list>

View File

@ -1,7 +1,21 @@
<vector android:autoMirrored="true" android:height="24dp"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#ffffff"
android:pathData="M21,12C21,16.9706 16.9706,21 12,21C7.0294,21 3,16.9706 3,12C3,7.0294 7.0294,3 12,3C16.9706,3 21,7.0294 21,12ZM8,10C6.8954,10 6,10.8954 6,12C6,13.1046 6.8954,14 8,14H10V16C10,17.1046 10.8954,18 12,18C13.1046,18 14,17.1046 14,16V14H16C17.1046,14 18,13.1046 18,12C18,10.8954 17.1046,10 16,10H14V8C14,6.8954 13.1046,6 12,6C10.8954,6 10,6.8954 10,8V10H8Z"
android:strokeColor="#ffffff" android:strokeWidth="2"/>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="32dp"
android:viewportWidth="32"
android:viewportHeight="32">
<path
android:pathData="M16,16m-16,0a16,16 0,1 1,32 0a16,16 0,1 1,-32 0"
android:fillColor="#E3E8F0"/>
<path
android:pathData="M10.0009,16H22.0009"
android:strokeWidth="1.5"
android:fillColor="#00000000"
android:strokeColor="#61708B"
android:strokeLineCap="round"/>
<path
android:pathData="M16.0009,10V22"
android:strokeWidth="1.5"
android:fillColor="#00000000"
android:strokeColor="#61708B"
android:strokeLineCap="round"/>
</vector>

View File

@ -0,0 +1,21 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="32dp"
android:viewportWidth="32"
android:viewportHeight="32">
<path
android:pathData="M16,16m-16,0a16,16 0,1 1,32 0a16,16 0,1 1,-32 0"
android:fillColor="#E3E8F0"/>
<path
android:pathData="M9.276,19.6667C10.7004,21.8728 13.1806,23.3333 16.0019,23.3333C18.8233,23.3333 21.3035,21.8728 22.7278,19.6667"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#61708B"
android:strokeLineCap="round"/>
<path
android:pathData="M18.6667,12.6667a2,2.6667 0,1 0,4 0a2,2.6667 0,1 0,-4 0z"
android:fillColor="#61708B"/>
<path
android:pathData="M8.6667,12.6667a2,2.6667 0,1 0,4 0a2,2.6667 0,1 0,-4 0z"
android:fillColor="#61708B"/>
</vector>

View File

@ -0,0 +1,4 @@
<vector android:height="32dp" android:viewportHeight="24"
android:viewportWidth="24" android:width="32dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#E3E8F0" android:pathData="M20,5L4,5c-1.1,0 -1.99,0.9 -1.99,2L2,17c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,7c0,-1.1 -0.9,-2 -2,-2zM11,8h2v2h-2L11,8zM11,11h2v2h-2v-2zM8,8h2v2L8,10L8,8zM8,11h2v2L8,13v-2zM7,13L5,13v-2h2v2zM7,10L5,10L5,8h2v2zM16,17L8,17v-2h8v2zM16,13h-2v-2h2v2zM16,10h-2L14,8h2v2zM19,13h-2v-2h2v2zM19,10h-2L17,8h2v2z"/>
</vector>

View File

@ -77,9 +77,9 @@
android:alpha="0"
app:layout_constraintEnd_toStartOf="parent"
app:layout_constraintTop_toBottomOf="parent"
app:tint="?riotx_text_primary"
tools:ignore="MissingConstraints,MissingPrefix"
tools:src="@drawable/ic_edit"
app:tint="?riotx_text_primary" />
tools:src="@drawable/ic_edit" />
<ImageButton
@ -88,54 +88,50 @@
android:layout_height="22dp"
android:background="?android:attr/selectableItemBackground"
android:src="@drawable/ic_close_round"
app:tint="@color/riotx_notice"
android:visibility="invisible"
app:layout_constraintBottom_toTopOf="parent"
app:layout_constraintStart_toEndOf="parent"
tools:visibility="visible"
tools:ignore="MissingPrefix" />
app:tint="@color/riotx_notice"
tools:ignore="MissingPrefix"
tools:visibility="visible" />
<ImageView
android:id="@+id/composer_avatar_view"
<ImageButton
android:id="@+id/attachmentButton"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="4dp"
app:layout_goneMarginEnd="8dp"
android:layout_marginBottom="8dp"
android:layout_margin="12dp"
android:background="?android:attr/selectableItemBackground"
android:src="@drawable/ic_attachment"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/composer_shield"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1"
app:layout_constraintEnd_toStartOf="@+id/composer_shield"
tools:src="@tools:sample/avatars" />
tools:ignore="MissingPrefix" />
<ImageView
android:id="@+id/composer_shield"
android:layout_width="16dp"
android:layout_height="16dp"
app:layout_constraintTop_toTopOf="@id/composer_avatar_view"
app:layout_constraintEnd_toStartOf="@+id/composerEditText"
app:layout_constraintBottom_toBottomOf="@id/composer_avatar_view"
app:layout_constraintStart_toEndOf="@+id/composer_avatar_view"
app:layout_constraintBottom_toBottomOf="@id/attachmentButton"
app:layout_constraintEnd_toStartOf="@+id/attachmentButton"
app:layout_constraintStart_toEndOf="@+id/attachmentButton"
app:layout_constraintTop_toTopOf="@id/attachmentButton"
tools:src="@drawable/ic_shield_black"
tools:visibility="visible"
/>
tools:visibility="visible" />
<ImageButton
android:id="@+id/attachmentButton"
android:layout_width="48dp"
android:layout_height="48dp"
android:id="@+id/composer_emoji"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:background="?android:attr/selectableItemBackground"
android:src="@drawable/ic_attachment"
app:tint="?attr/colorAccent"
app:layout_constraintBottom_toBottomOf="parent"
android:src="@drawable/ic_insert_emoji"
app:layout_constraintBottom_toBottomOf="@id/sendButton"
app:layout_constraintEnd_toStartOf="@+id/sendButton"
app:layout_constraintStart_toEndOf="@id/composerEditText"
tools:ignore="MissingPrefix" />
app:layout_constraintTop_toTopOf="@id/sendButton"
app:layout_goneMarginEnd="8dp" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/composer_preview_barrier"
@ -149,14 +145,15 @@
<ImageButton
android:id="@+id/sendButton"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="?android:attr/selectableItemBackground"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginEnd="12dp"
android:layout_marginBottom="10dp"
android:background="@drawable/bg_send"
android:src="@drawable/ic_send"
app:tint="?attr/colorAccent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/attachmentButton"
app:layout_constraintStart_toEndOf="@id/composer_emoji"
tools:ignore="MissingPrefix" />
<im.vector.app.features.home.room.detail.composer.ComposerEditText
@ -168,7 +165,7 @@
android:nextFocusLeft="@id/composerEditText"
android:nextFocusUp="@id/composerEditText"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/attachmentButton"
app:layout_constraintEnd_toStartOf="@+id/composer_emoji"
app:layout_constraintStart_toEndOf="@+id/composer_shield"
app:layout_constraintTop_toTopOf="parent"
tools:text="@tools:sample/lorem/random" />

View File

@ -83,9 +83,9 @@
app:layout_constraintEnd_toEndOf="@id/composer_related_message_avatar_view"
app:layout_constraintStart_toStartOf="@id/composer_related_message_avatar_view"
app:layout_constraintTop_toBottomOf="@id/composer_related_message_avatar_view"
tools:src="@drawable/ic_edit"
app:tint="?riotx_text_primary"
tools:ignore="MissingPrefix" />
tools:ignore="MissingPrefix"
tools:src="@drawable/ic_edit" />
<ImageButton
@ -94,51 +94,47 @@
android:layout_height="48dp"
android:background="?android:attr/selectableItemBackground"
android:src="@drawable/ic_close_round"
app:tint="@color/riotx_notice"
app:layout_constraintBottom_toBottomOf="@id/composer_related_message_preview"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/composer_related_message_preview"
app:tint="@color/riotx_notice"
tools:ignore="MissingPrefix" />
<ImageView
android:id="@+id/composer_avatar_view"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="4dp"
app:layout_goneMarginEnd="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/composer_shield"
app:layout_constraintStart_toStartOf="parent"
tools:src="@tools:sample/avatars" />
<ImageView
android:id="@+id/composer_shield"
android:layout_width="16dp"
android:layout_height="16dp"
app:layout_constraintTop_toTopOf="@id/composer_avatar_view"
app:layout_constraintEnd_toStartOf="@+id/composerEditText"
app:layout_constraintBottom_toBottomOf="@id/composer_avatar_view"
app:layout_constraintStart_toEndOf="@+id/composer_avatar_view"
tools:src="@drawable/ic_shield_black" />
<ImageButton
android:id="@+id/attachmentButton"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="?android:attr/selectableItemBackground"
android:src="@drawable/ic_attachment"
app:tint="?attr/colorAccent"
app:layout_constraintEnd_toStartOf="@+id/sendButton"
app:layout_constraintStart_toStartOf="@id/composerEditText"
app:layout_constraintTop_toBottomOf="parent"
tools:ignore="MissingPrefix" />
<ImageView
android:id="@+id/composer_shield"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_marginStart="8dp"
app:layout_constraintBottom_toBottomOf="@id/composer_emoji"
app:layout_constraintEnd_toStartOf="@+id/composerEditText"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/composer_emoji"
tools:src="@drawable/ic_shield_black" />
<ImageButton
android:id="@+id/composer_emoji"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:background="?android:attr/selectableItemBackground"
android:src="@drawable/ic_insert_emoji"
app:layout_constraintBottom_toBottomOf="@id/sendButton"
app:layout_constraintEnd_toStartOf="@+id/sendButton"
app:layout_constraintStart_toEndOf="@id/composerEditText"
app:layout_constraintTop_toTopOf="@id/sendButton"
app:layout_goneMarginEnd="8dp" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/composer_preview_barrier"
android:layout_width="0dp"
@ -151,11 +147,13 @@
<ImageButton
android:id="@+id/sendButton"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="?android:attr/selectableItemBackground"
android:layout_width="36dp"
android:layout_height="36dp"
android:background="@drawable/bg_send"
android:src="@drawable/ic_send"
app:tint="?attr/colorAccent"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:layout_marginEnd="12dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/composer_preview_barrier"
@ -170,8 +168,8 @@
android:nextFocusLeft="@id/composerEditText"
android:nextFocusUp="@id/composerEditText"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/sendButton"
app:layout_constraintStart_toEndOf="@id/composer_shield"
app:layout_constraintEnd_toStartOf="@+id/composer_emoji"
app:layout_constraintStart_toEndOf="@+id/composer_shield"
app:layout_constraintTop_toBottomOf="@id/composer_preview_barrier"
tools:text="@tools:sample/lorem/random" />

View File

@ -70,8 +70,8 @@
android:id="@+id/composer_related_message_action_image"
android:layout_width="0dp"
android:layout_height="0dp"
tools:ignore="MissingConstraints,MissingPrefix"
app:tint="?riotx_text_primary" />
app:tint="?riotx_text_primary"
tools:ignore="MissingConstraints,MissingPrefix" />
<ImageButton
android:id="@+id/composer_related_message_close"
@ -83,13 +83,13 @@
android:tint="@color/riotx_notice"
tools:ignore="MissingConstraints" />
<ImageView
android:id="@+id/composer_avatar_view"
<ImageButton
android:id="@+id/composer_emoji"
android:layout_width="0dp"
android:layout_height="0dp"
tools:ignore="MissingConstraints"
tools:src="@tools:sample/avatars" />
android:background="?android:attr/selectableItemBackground"
android:src="@drawable/ic_insert_emoji"
tools:ignore="MissingConstraints" />
<ImageButton
android:id="@+id/attachmentButton"
@ -98,7 +98,6 @@
android:background="?android:attr/selectableItemBackground"
android:contentDescription="@string/option_send_files"
android:src="@drawable/ic_attachment"
android:tint="?attr/colorAccent"
tools:ignore="MissingConstraints" />
<androidx.constraintlayout.widget.Barrier
@ -115,10 +114,9 @@
android:id="@+id/sendButton"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="?android:attr/selectableItemBackground"
android:background="@drawable/bg_send"
android:contentDescription="@string/send"
android:src="@drawable/ic_send"
android:tint="?attr/colorAccent"
tools:ignore="MissingConstraints" />
<im.vector.app.features.home.room.detail.composer.ComposerEditText