Upgrade code to latest API changes for Emojis

Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
This commit is contained in:
Andy Scherzinger 2022-05-20 14:52:58 +02:00
parent 133b058774
commit b33a4d1265
No known key found for this signature in database
GPG Key ID: 6CADC7E3523C308B
6 changed files with 149 additions and 123 deletions

View File

@ -2,6 +2,8 @@
* Nextcloud Talk application * Nextcloud Talk application
* *
* @author Mario Danic * @author Mario Danic
* @author Andy Scherzinger
* Copyright (C) 2022 Andy Scherzinger <info@andy-scherzinger.de>
* Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com> * Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -34,7 +36,7 @@ import com.nextcloud.talk.utils.MagicCharPolicy;
import com.nextcloud.talk.utils.text.Spans; import com.nextcloud.talk.utils.text.Spans;
import com.otaliastudios.autocomplete.AutocompleteCallback; import com.otaliastudios.autocomplete.AutocompleteCallback;
import com.vanniktech.emoji.EmojiRange; import com.vanniktech.emoji.EmojiRange;
import com.vanniktech.emoji.EmojiUtils; import com.vanniktech.emoji.Emojis;
public class MentionAutocompleteCallback implements AutocompleteCallback<Mention> { public class MentionAutocompleteCallback implements AutocompleteCallback<Mention> {
private Context context; private Context context;
@ -57,8 +59,8 @@ public class MentionAutocompleteCallback implements AutocompleteCallback<Mention
String replacement = item.getLabel(); String replacement = item.getLabel();
StringBuilder replacementStringBuilder = new StringBuilder(item.getLabel()); StringBuilder replacementStringBuilder = new StringBuilder(item.getLabel());
for(EmojiRange emojiRange : EmojiUtils.emojis(replacement)) { for(EmojiRange emojiRange : Emojis.emojis(replacement)) {
replacementStringBuilder.delete(emojiRange.start, emojiRange.end); replacementStringBuilder.delete(emojiRange.range.getStart(), emojiRange.range.getEndInclusive());
} }
editable.replace(start, end, replacementStringBuilder.toString() + " "); editable.replace(start, end, replacementStringBuilder.toString() + " ");

View File

@ -1637,20 +1637,25 @@ class ChatController(args: Bundle) :
val smileyButton = binding.messageInputView.findViewById<ImageButton>(R.id.smileyButton) val smileyButton = binding.messageInputView.findViewById<ImageButton>(R.id.smileyButton)
emojiPopup = binding.messageInputView.inputEditText?.let { emojiPopup = binding.messageInputView.inputEditText?.let {
EmojiPopup.Builder.fromRootView(view).setOnEmojiPopupShownListener { EmojiPopup(
rootView = view,
editText = it,
onEmojiPopupShownListener = {
if (resources != null) { if (resources != null) {
smileyButton?.setImageDrawable( smileyButton?.setImageDrawable(
ContextCompat.getDrawable(context!!, R.drawable.ic_baseline_keyboard_24) ContextCompat.getDrawable(context!!, R.drawable.ic_baseline_keyboard_24)
) )
} }
}.setOnEmojiPopupDismissListener { },
onEmojiPopupDismissListener = {
smileyButton?.setImageDrawable( smileyButton?.setImageDrawable(
ContextCompat.getDrawable(context!!, R.drawable.ic_insert_emoticon_black_24dp) ContextCompat.getDrawable(context!!, R.drawable.ic_insert_emoticon_black_24dp)
) )
}.setOnEmojiClickListener { emoji, },
imageView -> onEmojiClickListener = {
binding.messageInputView.inputEditText?.editableText?.append(" ") binding.messageInputView.inputEditText?.editableText?.append(" ")
}.build(it) }
)
} }
smileyButton?.setOnClickListener { smileyButton?.setOnClickListener {

View File

@ -115,6 +115,72 @@ class EntryMenuController(args: Bundle) :
false false
} }
textEditAddChangedListener()
var labelText = ""
when (operation) {
ConversationOperationEnum.OPS_CODE_INVITE_USERS, ConversationOperationEnum.OPS_CODE_RENAME_ROOM -> {
labelText = resources!!.getString(R.string.nc_call_name)
binding.textEdit.inputType = InputType.TYPE_CLASS_TEXT
binding.smileyButton.visibility = View.VISIBLE
emojiPopup = EmojiPopup(
rootView = view,
editText = binding.textEdit,
onEmojiPopupShownListener = {
if (resources != null) {
binding.smileyButton.setColorFilter(
resources!!.getColor(R.color.colorPrimary),
PorterDuff.Mode.SRC_IN
)
}
},
onEmojiPopupDismissListener = {
binding.smileyButton.setColorFilter(
resources!!.getColor(R.color.emoji_icons),
PorterDuff.Mode.SRC_IN
)
},
onEmojiClickListener = {
binding.textEdit.editableText.append(" ")
}
)
}
ConversationOperationEnum.OPS_CODE_CHANGE_PASSWORD -> {
labelText = resources!!.getString(R.string.nc_new_password)
binding.textEdit.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
}
ConversationOperationEnum.OPS_CODE_SET_PASSWORD,
ConversationOperationEnum.OPS_CODE_SHARE_LINK,
ConversationOperationEnum.OPS_CODE_JOIN_ROOM -> {
// 99 is joining a conversation via password
labelText = resources!!.getString(R.string.nc_password)
binding.textEdit.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
}
ConversationOperationEnum.OPS_CODE_GET_AND_JOIN_ROOM -> {
labelText = resources!!.getString(R.string.nc_conversation_link)
binding.textEdit.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_URI
}
else -> {
}
}
if (PASSWORD_ENTRY_OPERATIONS.contains(operation)) {
binding.textInputLayout.endIconMode = TextInputLayout.END_ICON_PASSWORD_TOGGLE
} else {
binding.textInputLayout.endIconMode = TextInputLayout.END_ICON_NONE
}
binding.textInputLayout.hint = labelText
binding.textInputLayout.requestFocus()
binding.smileyButton.setOnClickListener { onSmileyClick() }
binding.okButton.setOnClickListener { onOkButtonClick() }
}
private fun textEditAddChangedListener() {
binding.textEdit.addTextChangedListener(object : TextWatcher { binding.textEdit.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) { override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
// unused atm // unused atm
@ -171,62 +237,6 @@ class EntryMenuController(args: Bundle) :
} }
} }
}) })
var labelText = ""
when (operation) {
ConversationOperationEnum.OPS_CODE_INVITE_USERS, ConversationOperationEnum.OPS_CODE_RENAME_ROOM -> {
labelText = resources!!.getString(R.string.nc_call_name)
binding.textEdit.inputType = InputType.TYPE_CLASS_TEXT
binding.smileyButton.visibility = View.VISIBLE
emojiPopup = EmojiPopup.Builder.fromRootView(view)
.setOnEmojiPopupShownListener {
if (resources != null) {
binding.smileyButton.setColorFilter(
resources!!.getColor(R.color.colorPrimary),
PorterDuff.Mode.SRC_IN
)
}
}.setOnEmojiPopupDismissListener {
binding.smileyButton.setColorFilter(
resources!!.getColor(R.color.emoji_icons),
PorterDuff.Mode.SRC_IN
)
}.setOnEmojiClickListener { emoji, imageView -> binding.textEdit.editableText.append(" ") }
.build(binding.textEdit)
}
ConversationOperationEnum.OPS_CODE_CHANGE_PASSWORD -> {
labelText = resources!!.getString(R.string.nc_new_password)
binding.textEdit.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
}
ConversationOperationEnum.OPS_CODE_SET_PASSWORD,
ConversationOperationEnum.OPS_CODE_SHARE_LINK,
ConversationOperationEnum.OPS_CODE_JOIN_ROOM -> {
// 99 is joining a conversation via password
labelText = resources!!.getString(R.string.nc_password)
binding.textEdit.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
}
ConversationOperationEnum.OPS_CODE_GET_AND_JOIN_ROOM -> {
labelText = resources!!.getString(R.string.nc_conversation_link)
binding.textEdit.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_URI
}
else -> {
}
}
if (PASSWORD_ENTRY_OPERATIONS.contains(operation)) {
binding.textInputLayout.endIconMode = TextInputLayout.END_ICON_PASSWORD_TOGGLE
} else {
binding.textInputLayout.endIconMode = TextInputLayout.END_ICON_NONE
}
binding.textInputLayout.hint = labelText
binding.textInputLayout.requestFocus()
binding.smileyButton.setOnClickListener { onSmileyClick() }
binding.okButton.setOnClickListener { onOkButtonClick() }
} }
private fun onSmileyClick() { private fun onSmileyClick() {
@ -234,29 +244,13 @@ class EntryMenuController(args: Bundle) :
} }
private fun onOkButtonClick() { private fun onOkButtonClick() {
val bundle: Bundle
if (operation === ConversationOperationEnum.OPS_CODE_JOIN_ROOM) { if (operation === ConversationOperationEnum.OPS_CODE_JOIN_ROOM) {
bundle = Bundle() joinRoom()
bundle.putParcelable(BundleKeys.KEY_ROOM, Parcels.wrap<Any>(conversation))
bundle.putString(BundleKeys.KEY_CALL_URL, callUrl)
bundle.putString(BundleKeys.KEY_CONVERSATION_PASSWORD, binding.textEdit.text.toString())
bundle.putSerializable(BundleKeys.KEY_OPERATION_CODE, operation)
if (originalBundle.containsKey(BundleKeys.KEY_SERVER_CAPABILITIES)) {
bundle.putParcelable(
BundleKeys.KEY_SERVER_CAPABILITIES,
originalBundle.getParcelable<Parcelable>(BundleKeys.KEY_SERVER_CAPABILITIES)
)
}
router.pushController(
RouterTransaction.with(OperationsMenuController(bundle))
.pushChangeHandler(HorizontalChangeHandler())
.popChangeHandler(HorizontalChangeHandler())
)
} else if (operation !== ConversationOperationEnum.OPS_CODE_SHARE_LINK && } else if (operation !== ConversationOperationEnum.OPS_CODE_SHARE_LINK &&
operation !== ConversationOperationEnum.OPS_CODE_GET_AND_JOIN_ROOM && operation !== ConversationOperationEnum.OPS_CODE_GET_AND_JOIN_ROOM &&
operation !== ConversationOperationEnum.OPS_CODE_INVITE_USERS operation !== ConversationOperationEnum.OPS_CODE_INVITE_USERS
) { ) {
bundle = Bundle() val bundle = Bundle()
if (operation === ConversationOperationEnum.OPS_CODE_CHANGE_PASSWORD || if (operation === ConversationOperationEnum.OPS_CODE_CHANGE_PASSWORD ||
operation === ConversationOperationEnum.OPS_CODE_SET_PASSWORD operation === ConversationOperationEnum.OPS_CODE_SET_PASSWORD
) { ) {
@ -271,8 +265,7 @@ class EntryMenuController(args: Bundle) :
.pushChangeHandler(HorizontalChangeHandler()) .pushChangeHandler(HorizontalChangeHandler())
.popChangeHandler(HorizontalChangeHandler()) .popChangeHandler(HorizontalChangeHandler())
) )
} else if (operation === ConversationOperationEnum.OPS_CODE_SHARE_LINK) { } else if (operation === ConversationOperationEnum.OPS_CODE_SHARE_LINK && activity != null) {
if (activity != null) {
shareIntent?.putExtra( shareIntent?.putExtra(
Intent.EXTRA_TEXT, Intent.EXTRA_TEXT,
ShareUtils.getStringForIntent( ShareUtils.getStringForIntent(
@ -286,9 +279,8 @@ class EntryMenuController(args: Bundle) :
intent.component = ComponentName(packageName, name) intent.component = ComponentName(packageName, name)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
activity?.startActivity(intent) activity?.startActivity(intent)
}
} else if (operation !== ConversationOperationEnum.OPS_CODE_INVITE_USERS) { } else if (operation !== ConversationOperationEnum.OPS_CODE_INVITE_USERS) {
bundle = Bundle() val bundle = Bundle()
bundle.putSerializable(BundleKeys.KEY_OPERATION_CODE, operation) bundle.putSerializable(BundleKeys.KEY_OPERATION_CODE, operation)
bundle.putString(BundleKeys.KEY_CALL_URL, binding.textEdit.text.toString()) bundle.putString(BundleKeys.KEY_CALL_URL, binding.textEdit.text.toString())
router.pushController( router.pushController(
@ -310,6 +302,25 @@ class EntryMenuController(args: Bundle) :
} }
} }
private fun joinRoom() {
val bundle = Bundle()
bundle.putParcelable(BundleKeys.KEY_ROOM, Parcels.wrap<Any>(conversation))
bundle.putString(BundleKeys.KEY_CALL_URL, callUrl)
bundle.putString(BundleKeys.KEY_CONVERSATION_PASSWORD, binding.textEdit.text.toString())
bundle.putSerializable(BundleKeys.KEY_OPERATION_CODE, operation)
if (originalBundle.containsKey(BundleKeys.KEY_SERVER_CAPABILITIES)) {
bundle.putParcelable(
BundleKeys.KEY_SERVER_CAPABILITIES,
originalBundle.getParcelable<Parcelable>(BundleKeys.KEY_SERVER_CAPABILITIES)
)
}
router.pushController(
RouterTransaction.with(OperationsMenuController(bundle))
.pushChangeHandler(HorizontalChangeHandler())
.popChangeHandler(HorizontalChangeHandler())
)
}
init { init {
sharedApplication!!.componentApplication.inject(this) sharedApplication!!.componentApplication.inject(this)

View File

@ -47,6 +47,8 @@ import com.nextcloud.talk.models.json.generic.GenericOverall
import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.ApiUtils
import com.vanniktech.emoji.EmojiPopup import com.vanniktech.emoji.EmojiPopup
import com.vanniktech.emoji.EmojiTextView import com.vanniktech.emoji.EmojiTextView
import com.vanniktech.emoji.installDisableKeyboardInput
import com.vanniktech.emoji.installForceSingleEmoji
import io.reactivex.Observer import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable import io.reactivex.disposables.Disposable
@ -118,17 +120,18 @@ class MessageActionsDialog(
true true
} }
popup = EmojiPopup.Builder popup = EmojiPopup(
.fromRootView(dialogMessageActionsBinding.root) rootView = dialogMessageActionsBinding.root,
.setOnEmojiPopupShownListener { editText = dialogMessageActionsBinding.emojiMore,
onEmojiPopupShownListener = {
dialogMessageActionsBinding.emojiMore.clearFocus() dialogMessageActionsBinding.emojiMore.clearFocus()
dialogMessageActionsBinding.messageActions.visibility = View.GONE dialogMessageActionsBinding.messageActions.visibility = View.GONE
} },
.setOnEmojiClickListener { _, imageView -> onEmojiClickListener = {
popup.dismiss() popup.dismiss()
sendReaction(message, imageView.unicode) sendReaction(message, it.unicode)
} },
.setOnEmojiPopupDismissListener { onEmojiPopupDismissListener = {
dialogMessageActionsBinding.emojiMore.clearFocus() dialogMessageActionsBinding.emojiMore.clearFocus()
dialogMessageActionsBinding.messageActions.visibility = View.VISIBLE dialogMessageActionsBinding.messageActions.visibility = View.VISIBLE
@ -136,9 +139,9 @@ class MessageActionsDialog(
InputMethodManager InputMethodManager
imm.hideSoftInputFromWindow(dialogMessageActionsBinding.emojiMore.windowToken, 0) imm.hideSoftInputFromWindow(dialogMessageActionsBinding.emojiMore.windowToken, 0)
} }
.build(dialogMessageActionsBinding.emojiMore) )
dialogMessageActionsBinding.emojiMore.disableKeyboardInput(popup) dialogMessageActionsBinding.emojiMore.installDisableKeyboardInput(popup)
dialogMessageActionsBinding.emojiMore.forceSingleEmoji() dialogMessageActionsBinding.emojiMore.installForceSingleEmoji()
} }
/* /*

View File

@ -56,6 +56,8 @@ import com.nextcloud.talk.models.json.status.predefined.PredefinedStatusOverall
import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.DisplayUtils import com.nextcloud.talk.utils.DisplayUtils
import com.vanniktech.emoji.EmojiPopup import com.vanniktech.emoji.EmojiPopup
import com.vanniktech.emoji.installDisableKeyboardInput
import com.vanniktech.emoji.installForceSingleEmoji
import io.reactivex.Observer import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable import io.reactivex.disposables.Disposable
@ -206,18 +208,19 @@ class SetStatusDialogFragment :
binding.setStatus.setOnClickListener { setStatusMessage() } binding.setStatus.setOnClickListener { setStatusMessage() }
binding.emoji.setOnClickListener { openEmojiPopup() } binding.emoji.setOnClickListener { openEmojiPopup() }
popup = EmojiPopup.Builder popup = EmojiPopup(
.fromRootView(view) rootView = view,
.setOnEmojiClickListener { _, _ -> editText = binding.emoji,
onEmojiClickListener = {
popup.dismiss() popup.dismiss()
binding.emoji.clearFocus() binding.emoji.clearFocus()
val imm: InputMethodManager = context?.getSystemService(Context.INPUT_METHOD_SERVICE) as val imm: InputMethodManager = context?.getSystemService(Context.INPUT_METHOD_SERVICE) as
InputMethodManager InputMethodManager
imm.hideSoftInputFromWindow(binding.emoji.windowToken, 0) imm.hideSoftInputFromWindow(binding.emoji.windowToken, 0)
} }
.build(binding.emoji) )
binding.emoji.disableKeyboardInput(popup) binding.emoji.installDisableKeyboardInput(popup)
binding.emoji.forceSingleEmoji() binding.emoji.installForceSingleEmoji()
binding.clearStatusAfterSpinner.apply { binding.clearStatusAfterSpinner.apply {
this.adapter = createClearTimesArrayAdapter() this.adapter = createClearTimesArrayAdapter()

View File

@ -3,6 +3,8 @@
* *
* @author Mario Danic * @author Mario Danic
* @author Tim Krüger * @author Tim Krüger
* @author Andy Scherzinger
* Copyright (C) 2022 Andy Scherzinger <info@andy-scherzinger.de>
* Copyright (C) 2021 Tim Krüger <t@timkrueger.me> * Copyright (C) 2021 Tim Krüger <t@timkrueger.me>
* Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com> * Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
* *
@ -25,14 +27,14 @@
package com.nextcloud.talk.utils; package com.nextcloud.talk.utils;
import com.vanniktech.emoji.EmojiInformation; import com.vanniktech.emoji.EmojiInformation;
import com.vanniktech.emoji.EmojiUtils; import com.vanniktech.emoji.Emojis;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
public final class TextMatchers { public final class TextMatchers {
public static boolean isMessageWithSingleEmoticonOnly(@Nullable final String text) { public static boolean isMessageWithSingleEmoticonOnly(@Nullable final String text) {
final EmojiInformation emojiInformation = EmojiUtils.emojiInformation(text); final EmojiInformation emojiInformation = Emojis.emojiInformation(text);
return (emojiInformation.isOnlyEmojis && emojiInformation.emojis.size() == 1); return (emojiInformation.isOnlyEmojis && emojiInformation.emojis.size() == 1);
} }
} }