Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented Google EmojiPicker #3439

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -178,11 +178,11 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.11.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation "com.vanniktech:emoji-google:0.18.0"
implementation "androidx.emoji2:emoji2:${emojiVersion}"
implementation "androidx.emoji2:emoji2-bundled:${emojiVersion}"
implementation "androidx.emoji2:emoji2-views:${emojiVersion}"
implementation "androidx.emoji2:emoji2-views-helper:${emojiVersion}"
implementation "androidx.emoji2:emoji2-emojipicker:${emojiVersion}"
implementation 'org.michaelevans.colorart:library:0.0.3'
implementation "androidx.work:work-runtime:${workVersion}"
implementation "androidx.work:work-rxjava2:${workVersion}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.TextView
import androidx.emoji2.widget.EmojiTextView
import com.nextcloud.talk.databinding.ReactionsInsideMessageBinding
import com.nextcloud.talk.models.json.chat.ChatMessage
import com.nextcloud.talk.ui.theme.ViewThemeUtils
import com.nextcloud.talk.utils.DisplayUtils
import com.vanniktech.emoji.EmojiTextView

class Reaction {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,6 @@ import com.nextcloud.talk.utils.database.arbitrarystorage.ArbitraryStorageModule
import com.nextcloud.talk.utils.database.user.UserModule
import com.nextcloud.talk.utils.preferences.AppPreferences
import com.nextcloud.talk.webrtc.MagicWebRTCUtils
import com.vanniktech.emoji.EmojiManager
import com.vanniktech.emoji.google.GoogleEmojiProvider
import de.cotech.hw.SecurityKeyManager
import de.cotech.hw.SecurityKeyManagerConfig
import net.sqlcipher.database.SQLiteDatabase
Expand Down Expand Up @@ -181,9 +179,7 @@ class NextcloudTalkApplication : MultiDexApplication(), LifecycleObserver {

val config = BundledEmojiCompatConfig(this)
config.setReplaceAll(true)
val emojiCompat = EmojiCompat.init(config)

EmojiManager.install(GoogleEmojiProvider())
EmojiCompat.init(config)

NotificationUtils.registerNotificationChannels(applicationContext, appPreferences)
}
Expand Down
5 changes: 2 additions & 3 deletions app/src/main/java/com/nextcloud/talk/call/ReactionAnimator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ import android.widget.TextView
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.DrawableCompat
import androidx.emoji2.widget.EmojiTextView
import com.nextcloud.talk.R
import com.nextcloud.talk.ui.theme.ViewThemeUtils
import com.vanniktech.emoji.EmojiTextView

class ReactionAnimator(
val context: Context,
Expand All @@ -57,7 +57,6 @@ class ReactionAnimator(

private fun animateReaction(callReaction: CallReaction) {
val reactionWrapper = getReactionWrapperView(callReaction)

val params = RelativeLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT
Expand Down Expand Up @@ -94,7 +93,6 @@ class ReactionAnimator(

val animatorWithFullAlpha = AnimatorSet()
animatorWithFullAlpha.play(moveWithFullAlpha)

animatorWithFullAlpha.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
reactionsList.remove(callReaction)
Expand Down Expand Up @@ -177,6 +175,7 @@ class ReactionAnimator(
private const val BOTTOM_MARGIN: Int = 5
}
}

data class CallReaction(
var emoji: String,
var userName: String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import android.text.Editable;
import android.text.Spanned;
import android.widget.EditText;

import third.parties.fresco.BetterImageSpan;
import com.nextcloud.talk.R;
import com.nextcloud.talk.data.user.model.User;
Expand All @@ -36,9 +35,6 @@
import com.nextcloud.talk.utils.MagicCharPolicy;
import com.nextcloud.talk.utils.text.Spans;
import com.otaliastudios.autocomplete.AutocompleteCallback;
import com.vanniktech.emoji.EmojiRange;
import com.vanniktech.emoji.Emojis;

import kotlin.OptIn;

public class MentionAutocompleteCallback implements AutocompleteCallback<Mention> {
Expand All @@ -64,12 +60,8 @@ public boolean onPopupItemClicked(Editable editable, Mention item) {
if (range == null) {
return false;
}
String replacement = item.getLabel();

StringBuilder replacementStringBuilder = new StringBuilder(item.getLabel());
for (EmojiRange emojiRange : Emojis.emojis(replacement)) {
replacementStringBuilder.delete(emojiRange.range.getStart(), emojiRange.range.getEndInclusive());
}

editable.replace(range.getStart(), range.getEnd(), replacementStringBuilder + " ");
Spans.MentionChipSpan mentionChipSpan =
Expand Down
67 changes: 38 additions & 29 deletions app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ import android.view.animation.AccelerateInterpolator
import android.view.animation.AlphaAnimation
import android.view.animation.Animation
import android.view.animation.LinearInterpolator
import android.view.inputmethod.InputMethodManager
import android.widget.AbsListView
import android.widget.FrameLayout
import android.widget.ImageButton
Expand All @@ -92,6 +93,7 @@ import androidx.core.content.PermissionChecker.PERMISSION_GRANTED
import androidx.core.graphics.drawable.toBitmap
import androidx.core.text.bold
import androidx.core.widget.doAfterTextChanged
import androidx.emoji2.emojipicker.EmojiPickerView
import androidx.emoji2.text.EmojiCompat
import androidx.emoji2.widget.EmojiTextView
import androidx.fragment.app.DialogFragment
Expand Down Expand Up @@ -235,7 +237,6 @@ import com.stfalcon.chatkit.messages.MessageHolders
import com.stfalcon.chatkit.messages.MessageHolders.ContentChecker
import com.stfalcon.chatkit.messages.MessagesListAdapter
import com.stfalcon.chatkit.utils.DateFormatter
import com.vanniktech.emoji.EmojiPopup
import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
Expand Down Expand Up @@ -322,7 +323,6 @@ class ChatActivity :
lateinit var roomId: String
var voiceOnly: Boolean = true
var isFirstMessagesProcessing = true
private var emojiPopup: EmojiPopup? = null
private lateinit var path: String

var myFirstMessage: CharSequence? = null
Expand Down Expand Up @@ -364,6 +364,8 @@ class ChatActivity :
var mediaPlayer: MediaPlayer? = null
lateinit var mediaPlayerHandler: Handler

private var isEmojiPickerVisible = false

private var currentlyPlayedVoiceMessage: ChatMessage? = null

private lateinit var micInputAudioRecorder: AudioRecord
Expand Down Expand Up @@ -468,7 +470,6 @@ class ChatActivity :
binding.progressBar.visibility = View.VISIBLE

onBackPressedDispatcher.addCallback(this, onBackPressedCallback)

initObservers()
}

Expand Down Expand Up @@ -660,7 +661,6 @@ class ChatActivity :
logConversationInfos("onResume")

pullChatMessagesPending = false

setupWebsocket()
webSocketInstance?.getSignalingMessageReceiver()?.addListener(localParticipantMessageListener)
webSocketInstance?.getSignalingMessageReceiver()?.addListener(conversationMessageListener)
Expand All @@ -672,7 +672,7 @@ class ChatActivity :
}

initSmileyKeyboardToggler()

initMessageInputToggler()
themeMessageInputView()

cancelNotificationsForCurrentConversation()
Expand Down Expand Up @@ -1443,36 +1443,45 @@ class ChatActivity :
}
}

private fun initSmileyKeyboardToggler() {
val smileyButton = binding.messageInputView.findViewById<ImageButton>(R.id.smileyButton)

emojiPopup = binding.messageInputView.inputEditText?.let {
EmojiPopup(
rootView = binding.root,
editText = it,
onEmojiPopupShownListener = {
if (resources != null) {
smileyButton?.setImageDrawable(
ContextCompat.getDrawable(context, R.drawable.ic_baseline_keyboard_24)
)
}
},
onEmojiPopupDismissListener = {
smileyButton?.setImageDrawable(
ContextCompat.getDrawable(context, R.drawable.ic_insert_emoticon_black_24dp)
)
},
onEmojiClickListener = {
binding.messageInputView.inputEditText?.editableText?.append(" ")
}
)
private fun initMessageInputToggler() {
val messageInput = binding.messageInputView.findViewById<ImageEmojiEditText>(R.id.messageInput)
messageInput.setOnFocusChangeListener { _, hasFocus ->
if (hasFocus) {
keyboardtoggle()
}
}
messageInput.setOnClickListener {
keyboardtoggle()
}
}

private fun keyboardtoggle() {
binding.messageInputView.findViewById<FrameLayout>(R.id.emoji_picker).visibility = View.GONE
isEmojiPickerVisible = false
}

private fun initSmileyKeyboardToggler() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the keyboard toggler is somehow broken with the new solution. It's now possible to show the emoji picker and the keyboard at the same timebelow it, which is a bit confusing.

val smileyButton = binding.messageInputView.findViewById<ImageButton>(R.id.smileyButton)
smileyButton?.setOnClickListener {
emojiPopup?.toggle()
if (!isEmojiPickerVisible) {
binding.messageInputView.findViewById<FrameLayout>(R.id.emoji_picker).visibility = View.VISIBLE
isEmojiPickerVisible = true
hideKeyboard()
} else {
binding.messageInputView.findViewById<EmojiPickerView>(R.id.emoji_picker).visibility = View.GONE
isEmojiPickerVisible = false
}
binding.messageInputView.findViewById<EmojiPickerView>(R.id.emoji_picker).setOnEmojiPickedListener {
binding.messageInputView.inputEditText.editableText?.append(it.emoji)
}
}
}

private fun hideKeyboard() {
val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(currentFocus?.windowToken, 0)
}

@Suppress("MagicNumber", "LongMethod")
private fun updateTypingIndicator() {
fun ellipsize(text: String): String {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ package com.nextcloud.talk.conversation

import android.annotation.SuppressLint
import android.app.Dialog
import android.content.Context
import android.content.Intent
import android.content.res.ColorStateList
import android.os.Bundle
import android.os.Parcelable
import android.text.Editable
Expand All @@ -33,8 +33,8 @@ import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import androidx.appcompat.app.AlertDialog
import androidx.core.content.res.ResourcesCompat
import androidx.fragment.app.DialogFragment
import androidx.lifecycle.ViewModelProvider
import androidx.work.Data
Expand All @@ -44,7 +44,6 @@ import androidx.work.WorkManager
import autodagger.AutoInjector
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.snackbar.Snackbar
import com.nextcloud.android.common.ui.theme.utils.ColorRole
import com.nextcloud.talk.R
import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.chat.ChatActivity
Expand All @@ -55,7 +54,6 @@ import com.nextcloud.talk.models.json.conversations.Conversation
import com.nextcloud.talk.ui.theme.ViewThemeUtils
import com.nextcloud.talk.utils.bundle.BundleKeys
import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew
import com.vanniktech.emoji.EmojiPopup
import org.greenrobot.eventbus.EventBus
import org.parceler.Parcels
import javax.inject.Inject
Expand All @@ -77,9 +75,7 @@ class CreateConversationDialogFragment : DialogFragment() {

private lateinit var binding: DialogCreateConversationBinding
private lateinit var viewModel: ConversationViewModel

private var emojiPopup: EmojiPopup? = null

private var isEmojiPickerVisible = false
private var conversationType: Conversation.ConversationType? = null
private var usersToInvite: ArrayList<String> = ArrayList()
private var groupsToInvite: ArrayList<String> = ArrayList()
Expand Down Expand Up @@ -135,8 +131,6 @@ class CreateConversationDialogFragment : DialogFragment() {

setupListeners()
setupStateObserver()

setupEmojiPopup()
}

override fun onStart() {
Expand All @@ -161,32 +155,38 @@ class CreateConversationDialogFragment : DialogFragment() {
viewThemeUtils.material.colorTextInputLayout(binding.textInputLayout)
}

private fun hideKeyboard() {
val imm = requireContext().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(binding.textEdit.windowToken, 0)
}

private fun keyboardtoggle() {
binding.emojiPicker.visibility = View.GONE
isEmojiPickerVisible = false
}

private fun setupEmojiPopup() {
emojiPopup = binding.let {
EmojiPopup(
rootView = requireView(),
editText = it.textEdit,
onEmojiPopupShownListener = {
viewThemeUtils.platform.colorImageView(it.smileyButton, ColorRole.PRIMARY)
},
onEmojiPopupDismissListener = {
it.smileyButton.imageTintList = ColorStateList.valueOf(
ResourcesCompat.getColor(
resources,
R.color.medium_emphasis_text,
context?.theme
)
)
},
onEmojiClickListener = {
binding.textEdit.editableText?.append(" ")
}
)
if (!isEmojiPickerVisible) {
binding.emojiPicker.visibility = View.VISIBLE
isEmojiPickerVisible = true
hideKeyboard()
} else {
binding.emojiPicker.visibility = View.GONE
isEmojiPickerVisible = false
}
binding.emojiPicker.setOnEmojiPickedListener {
binding.textEdit.editableText?.append(it.emoji)
}
}

private fun setupListeners() {
binding.smileyButton.setOnClickListener { emojiPopup?.toggle() }
binding.smileyButton.setOnClickListener { setupEmojiPopup() }
binding.textEdit.setOnFocusChangeListener { _, hasFocus ->
if (hasFocus) {
keyboardtoggle()
}
}
binding.textEdit.setOnClickListener { keyboardtoggle() }
binding.textEdit.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
// unused atm
Expand Down Expand Up @@ -222,6 +222,7 @@ class CreateConversationDialogFragment : DialogFragment() {
Log.e(TAG, "Failed to create conversation")
showError()
}

else -> {}
}
}
Expand Down Expand Up @@ -286,6 +287,14 @@ class CreateConversationDialogFragment : DialogFragment() {
Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show()
}

override fun onResume() {
super.onResume()
dialog?.window?.setLayout(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
}

/**
* Fragment creator
*/
Expand Down
Loading
Loading