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
*
* @author Mario Danic
* @author Andy Scherzinger
* Copyright (C) 2022 Andy Scherzinger <info@andy-scherzinger.de>
* Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
*
* 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.otaliastudios.autocomplete.AutocompleteCallback;
import com.vanniktech.emoji.EmojiRange;
import com.vanniktech.emoji.EmojiUtils;
import com.vanniktech.emoji.Emojis;
public class MentionAutocompleteCallback implements AutocompleteCallback<Mention> {
private Context context;
@ -57,8 +59,8 @@ public class MentionAutocompleteCallback implements AutocompleteCallback<Mention
String replacement = item.getLabel();
StringBuilder replacementStringBuilder = new StringBuilder(item.getLabel());
for(EmojiRange emojiRange : EmojiUtils.emojis(replacement)) {
replacementStringBuilder.delete(emojiRange.start, emojiRange.end);
for(EmojiRange emojiRange : Emojis.emojis(replacement)) {
replacementStringBuilder.delete(emojiRange.range.getStart(), emojiRange.range.getEndInclusive());
}
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)
emojiPopup = binding.messageInputView.inputEditText?.let {
EmojiPopup.Builder.fromRootView(view).setOnEmojiPopupShownListener {
if (resources != null) {
EmojiPopup(
rootView = view,
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_baseline_keyboard_24)
ContextCompat.getDrawable(context!!, R.drawable.ic_insert_emoticon_black_24dp)
)
},
onEmojiClickListener = {
binding.messageInputView.inputEditText?.editableText?.append(" ")
}
}.setOnEmojiPopupDismissListener {
smileyButton?.setImageDrawable(
ContextCompat.getDrawable(context!!, R.drawable.ic_insert_emoticon_black_24dp)
)
}.setOnEmojiClickListener { emoji,
imageView ->
binding.messageInputView.inputEditText?.editableText?.append(" ")
}.build(it)
)
}
smileyButton?.setOnClickListener {

View file

@ -115,6 +115,72 @@ class EntryMenuController(args: Bundle) :
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 {
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
// 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() {
@ -234,29 +244,13 @@ class EntryMenuController(args: Bundle) :
}
private fun onOkButtonClick() {
val bundle: Bundle
if (operation === ConversationOperationEnum.OPS_CODE_JOIN_ROOM) {
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())
)
joinRoom()
} else if (operation !== ConversationOperationEnum.OPS_CODE_SHARE_LINK &&
operation !== ConversationOperationEnum.OPS_CODE_GET_AND_JOIN_ROOM &&
operation !== ConversationOperationEnum.OPS_CODE_INVITE_USERS
) {
bundle = Bundle()
val bundle = Bundle()
if (operation === ConversationOperationEnum.OPS_CODE_CHANGE_PASSWORD ||
operation === ConversationOperationEnum.OPS_CODE_SET_PASSWORD
) {
@ -271,24 +265,22 @@ class EntryMenuController(args: Bundle) :
.pushChangeHandler(HorizontalChangeHandler())
.popChangeHandler(HorizontalChangeHandler())
)
} else if (operation === ConversationOperationEnum.OPS_CODE_SHARE_LINK) {
if (activity != null) {
shareIntent?.putExtra(
Intent.EXTRA_TEXT,
ShareUtils.getStringForIntent(
activity,
binding.textEdit.text.toString(),
userUtils,
conversation
)
} else if (operation === ConversationOperationEnum.OPS_CODE_SHARE_LINK && activity != null) {
shareIntent?.putExtra(
Intent.EXTRA_TEXT,
ShareUtils.getStringForIntent(
activity,
binding.textEdit.text.toString(),
userUtils,
conversation
)
val intent = Intent(shareIntent)
intent.component = ComponentName(packageName, name)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
activity?.startActivity(intent)
}
)
val intent = Intent(shareIntent)
intent.component = ComponentName(packageName, name)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
activity?.startActivity(intent)
} else if (operation !== ConversationOperationEnum.OPS_CODE_INVITE_USERS) {
bundle = Bundle()
val bundle = Bundle()
bundle.putSerializable(BundleKeys.KEY_OPERATION_CODE, operation)
bundle.putString(BundleKeys.KEY_CALL_URL, binding.textEdit.text.toString())
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 {
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.vanniktech.emoji.EmojiPopup
import com.vanniktech.emoji.EmojiTextView
import com.vanniktech.emoji.installDisableKeyboardInput
import com.vanniktech.emoji.installForceSingleEmoji
import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
@ -118,17 +120,18 @@ class MessageActionsDialog(
true
}
popup = EmojiPopup.Builder
.fromRootView(dialogMessageActionsBinding.root)
.setOnEmojiPopupShownListener {
popup = EmojiPopup(
rootView = dialogMessageActionsBinding.root,
editText = dialogMessageActionsBinding.emojiMore,
onEmojiPopupShownListener = {
dialogMessageActionsBinding.emojiMore.clearFocus()
dialogMessageActionsBinding.messageActions.visibility = View.GONE
}
.setOnEmojiClickListener { _, imageView ->
},
onEmojiClickListener = {
popup.dismiss()
sendReaction(message, imageView.unicode)
}
.setOnEmojiPopupDismissListener {
sendReaction(message, it.unicode)
},
onEmojiPopupDismissListener = {
dialogMessageActionsBinding.emojiMore.clearFocus()
dialogMessageActionsBinding.messageActions.visibility = View.VISIBLE
@ -136,9 +139,9 @@ class MessageActionsDialog(
InputMethodManager
imm.hideSoftInputFromWindow(dialogMessageActionsBinding.emojiMore.windowToken, 0)
}
.build(dialogMessageActionsBinding.emojiMore)
dialogMessageActionsBinding.emojiMore.disableKeyboardInput(popup)
dialogMessageActionsBinding.emojiMore.forceSingleEmoji()
)
dialogMessageActionsBinding.emojiMore.installDisableKeyboardInput(popup)
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.DisplayUtils
import com.vanniktech.emoji.EmojiPopup
import com.vanniktech.emoji.installDisableKeyboardInput
import com.vanniktech.emoji.installForceSingleEmoji
import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
@ -206,18 +208,19 @@ class SetStatusDialogFragment :
binding.setStatus.setOnClickListener { setStatusMessage() }
binding.emoji.setOnClickListener { openEmojiPopup() }
popup = EmojiPopup.Builder
.fromRootView(view)
.setOnEmojiClickListener { _, _ ->
popup = EmojiPopup(
rootView = view,
editText = binding.emoji,
onEmojiClickListener = {
popup.dismiss()
binding.emoji.clearFocus()
val imm: InputMethodManager = context?.getSystemService(Context.INPUT_METHOD_SERVICE) as
InputMethodManager
imm.hideSoftInputFromWindow(binding.emoji.windowToken, 0)
}
.build(binding.emoji)
binding.emoji.disableKeyboardInput(popup)
binding.emoji.forceSingleEmoji()
)
binding.emoji.installDisableKeyboardInput(popup)
binding.emoji.installForceSingleEmoji()
binding.clearStatusAfterSpinner.apply {
this.adapter = createClearTimesArrayAdapter()

View file

@ -3,6 +3,8 @@
*
* @author Mario Danic
* @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) 2017-2018 Mario Danic <mario@lovelyhq.com>
*
@ -25,14 +27,14 @@
package com.nextcloud.talk.utils;
import com.vanniktech.emoji.EmojiInformation;
import com.vanniktech.emoji.EmojiUtils;
import com.vanniktech.emoji.Emojis;
import androidx.annotation.Nullable;
public final class TextMatchers {
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);
}
}