diff --git a/app/src/main/java/com/nextcloud/talk/chat/MessageInputFragment.kt b/app/src/main/java/com/nextcloud/talk/chat/MessageInputFragment.kt index 20fd708d6c..761670250a 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/MessageInputFragment.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/MessageInputFragment.kt @@ -889,6 +889,7 @@ class MessageInputFragment : Fragment() { emojiPopup = EmojiPopup( rootView = binding.root, editText = inputEditText, + theming = viewThemeUtils.talk.getEmojiTheming(requireContext()), onEmojiPopupShownListener = { isEmojiPopupOpen = true updateSmileyButtonIcon() diff --git a/app/src/main/java/com/nextcloud/talk/chat/ScheduledMessagesActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ScheduledMessagesActivity.kt index 8c2ac490ab..2970e3782b 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ScheduledMessagesActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ScheduledMessagesActivity.kt @@ -107,6 +107,7 @@ import com.nextcloud.talk.ui.chat.LocalShowThreadButton import com.nextcloud.talk.ui.chat.formatTime import com.nextcloud.talk.ui.theme.LocalMessageUtils import com.nextcloud.talk.ui.theme.LocalViewThemeUtils +import com.nextcloud.talk.ui.theme.emojiTheming import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.DateConstants import com.nextcloud.talk.utils.DateUtils @@ -809,6 +810,7 @@ class ScheduledMessagesActivity : BaseActivity() { ) { val rootView = LocalView.current val keyboardController = LocalSoftwareKeyboardController.current + val theming = emojiTheming() val emojiEditTextRef = remember { mutableStateOf(null) } var emojiPopup by remember { mutableStateOf(null) } @@ -872,6 +874,7 @@ class ScheduledMessagesActivity : BaseActivity() { emojiPopup = EmojiPopup( rootView = rootView, editText = editText, + theming = theming, onEmojiPopupShownListener = { isEmojiOpen = true }, diff --git a/app/src/main/java/com/nextcloud/talk/chat/ui/MessageActionsBottomSheet.kt b/app/src/main/java/com/nextcloud/talk/chat/ui/MessageActionsBottomSheet.kt index e2d1e34871..3a93ed1887 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ui/MessageActionsBottomSheet.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ui/MessageActionsBottomSheet.kt @@ -68,6 +68,7 @@ import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.models.domain.ConversationModel import com.nextcloud.talk.models.json.capabilities.SpreedCapability import com.nextcloud.talk.models.json.conversations.ConversationEnums +import com.nextcloud.talk.ui.theme.emojiTheming import com.nextcloud.talk.utils.CapabilitiesUtil import com.nextcloud.talk.utils.CapabilitiesUtil.hasSpreedFeatureCapability import com.nextcloud.talk.utils.ConversationUtils @@ -648,6 +649,7 @@ private fun MoreEmojiButton( ) { val context = LocalContext.current val rootView = LocalView.current + val theming = emojiTheming() val popupRef = remember { mutableStateOf(null) } DisposableEffect(Unit) { @@ -665,6 +667,7 @@ private fun MoreEmojiButton( val emojiPopup = EmojiPopup( rootView = rootView, editText = this, + theming = theming, onEmojiPopupShownListener = { clearFocus() onPickerShown() diff --git a/app/src/main/java/com/nextcloud/talk/chooseaccount/ui/StatusMessageInputComponents.kt b/app/src/main/java/com/nextcloud/talk/chooseaccount/ui/StatusMessageInputComponents.kt index 7f5baa2125..3b7e69f0ab 100644 --- a/app/src/main/java/com/nextcloud/talk/chooseaccount/ui/StatusMessageInputComponents.kt +++ b/app/src/main/java/com/nextcloud/talk/chooseaccount/ui/StatusMessageInputComponents.kt @@ -50,6 +50,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.viewinterop.AndroidView import androidx.core.content.getSystemService import com.nextcloud.talk.R +import com.nextcloud.talk.ui.theme.emojiTheming import com.vanniktech.emoji.EmojiEditText import com.vanniktech.emoji.EmojiPopup import com.vanniktech.emoji.installDisableKeyboardInput @@ -83,6 +84,7 @@ internal fun EmojiAndMessageRow( private fun EmojiButton(emoji: String, onEmojiSelected: (String) -> Unit) { val isPreview = LocalInspectionMode.current val rootView = LocalView.current + val theming = emojiTheming() var emojiPopup by remember { mutableStateOf(null) } val displayEmoji = emoji.ifEmpty { stringResource(R.string.default_emoji) } @@ -115,6 +117,7 @@ private fun EmojiButton(emoji: String, onEmojiSelected: (String) -> Unit) { val popup = EmojiPopup( rootView = rootView, editText = this, + theming = theming, onEmojiClickListener = { onEmojiSelected(text.toString()) emojiPopup?.dismiss() diff --git a/app/src/main/java/com/nextcloud/talk/conversation/RenameConversationDialogFragment.kt b/app/src/main/java/com/nextcloud/talk/conversation/RenameConversationDialogFragment.kt index 7fb0c978b4..229c745055 100644 --- a/app/src/main/java/com/nextcloud/talk/conversation/RenameConversationDialogFragment.kt +++ b/app/src/main/java/com/nextcloud/talk/conversation/RenameConversationDialogFragment.kt @@ -123,6 +123,7 @@ class RenameConversationDialogFragment : DialogFragment() { EmojiPopup( rootView = requireView(), editText = it.textEdit, + theming = viewThemeUtils.talk.getEmojiTheming(requireContext()), onEmojiPopupShownListener = { viewThemeUtils.platform.colorImageView(it.smileyButton, ColorRole.PRIMARY) }, diff --git a/app/src/main/java/com/nextcloud/talk/ui/theme/EmojiThemings.kt b/app/src/main/java/com/nextcloud/talk/ui/theme/EmojiThemings.kt new file mode 100644 index 0000000000..f5bcbd6981 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/EmojiThemings.kt @@ -0,0 +1,33 @@ +/* + * Nextcloud Talk - Android Client + * + * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package com.nextcloud.talk.ui.theme + +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.runtime.ReadOnlyComposable +import androidx.compose.ui.graphics.toArgb +import com.vanniktech.emoji.EmojiTheming + +/** + * Themes the vanniktech emoji popup from the current [MaterialTheme.colorScheme] so its category, + * search and backspace icons stay visible in dark mode. + * Keep in sync with the view variant [TalkSpecificViewThemeUtils.getEmojiTheming]. + */ +@Composable +@ReadOnlyComposable +fun emojiTheming(): EmojiTheming = + with(MaterialTheme.colorScheme) { + EmojiTheming( + backgroundColor = surface.toArgb(), + primaryColor = onSurfaceVariant.toArgb(), + secondaryColor = primary.toArgb(), + dividerColor = outlineVariant.toArgb(), + textColor = onSurface.toArgb(), + textSecondaryColor = onSurfaceVariant.toArgb() + ) + } diff --git a/app/src/main/java/com/nextcloud/talk/ui/theme/TalkSpecificViewThemeUtils.kt b/app/src/main/java/com/nextcloud/talk/ui/theme/TalkSpecificViewThemeUtils.kt index f518539739..4bce1f1a71 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/theme/TalkSpecificViewThemeUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/TalkSpecificViewThemeUtils.kt @@ -53,6 +53,7 @@ import com.nextcloud.talk.utils.DisplayUtils import com.nextcloud.talk.utils.DrawableUtils import com.nextcloud.talk.utils.message.MessageUtils import com.vanniktech.emoji.EmojiTextView +import com.vanniktech.emoji.EmojiTheming import dynamiccolor.DynamicScheme import dynamiccolor.MaterialDynamicColors import eu.davidea.flexibleadapter.utils.FlexibleUtils @@ -182,6 +183,22 @@ class TalkSpecificViewThemeUtils @Inject constructor( } } + /** + * Themes the vanniktech emoji popup so its category, search and backspace icons stay visible in dark mode. + * Keep in sync with the Compose variant [emojiTheming]. + */ + fun getEmojiTheming(context: Context): EmojiTheming = + withScheme(context) { scheme -> + EmojiTheming( + backgroundColor = dynamicColor.surface().getArgb(scheme), + primaryColor = dynamicColor.onSurfaceVariant().getArgb(scheme), + secondaryColor = dynamicColor.primary().getArgb(scheme), + dividerColor = dynamicColor.outlineVariant().getArgb(scheme), + textColor = dynamicColor.onSurface().getArgb(scheme), + textSecondaryColor = dynamicColor.onSurfaceVariant().getArgb(scheme) + ) + } + fun setReactionsBackground(linearLayout: LinearLayout, outgoing: Boolean, isBubbled: Boolean) { withScheme(linearLayout) { scheme -> val drawable = AppCompatResources