mirror of
https://github.com/nextcloud/talk-android
synced 2025-06-22 13:09:46 +01:00
ViewThemeUtils: split talk-specific and appcompat utils
Signed-off-by: Álvaro Brey <alvaro.brey@nextcloud.com>
This commit is contained in:
parent
1f32b35117
commit
892cc82ade
@ -206,7 +206,7 @@ public class ContactItem extends AbstractFlexibleItem<ContactItem.ContactItemVie
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
holder.binding.avatarDraweeView.getHierarchy().setPlaceholderImage(
|
||||
DisplayUtils.getRoundedDrawable(
|
||||
viewThemeUtils.themePlaceholderAvatar(holder.binding.avatarDraweeView,
|
||||
viewThemeUtils.talk.themePlaceholderAvatar(holder.binding.avatarDraweeView,
|
||||
roundPlaceholderDrawable)));
|
||||
} else {
|
||||
holder.binding.avatarDraweeView.setImageResource(fallbackImageResource);
|
||||
|
@ -266,7 +266,7 @@ public class ConversationItem extends AbstractFlexibleItem<ConversationItem.Conv
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
holder.binding.dialogAvatar.setImageDrawable(
|
||||
DisplayUtils.getRoundedDrawable(
|
||||
viewThemeUtils.themePlaceholderAvatar(holder.binding.dialogAvatar,
|
||||
viewThemeUtils.talk.themePlaceholderAvatar(holder.binding.dialogAvatar,
|
||||
R.drawable.ic_avatar_document)));
|
||||
} else {
|
||||
holder.binding.dialogAvatar.setImageDrawable(
|
||||
@ -316,7 +316,7 @@ public class ConversationItem extends AbstractFlexibleItem<ConversationItem.Conv
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
holder.binding.dialogAvatar.setImageDrawable(
|
||||
DisplayUtils.getRoundedDrawable(
|
||||
viewThemeUtils.themePlaceholderAvatar(holder.binding.dialogAvatar,
|
||||
viewThemeUtils.talk.themePlaceholderAvatar(holder.binding.dialogAvatar,
|
||||
R.drawable.ic_avatar_group)));
|
||||
} else {
|
||||
holder.binding.dialogAvatar.setImageDrawable(
|
||||
@ -327,7 +327,7 @@ public class ConversationItem extends AbstractFlexibleItem<ConversationItem.Conv
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
holder.binding.dialogAvatar.setImageDrawable(
|
||||
DisplayUtils.getRoundedDrawable(
|
||||
viewThemeUtils.themePlaceholderAvatar(holder.binding.dialogAvatar,
|
||||
viewThemeUtils.talk.themePlaceholderAvatar(holder.binding.dialogAvatar,
|
||||
R.drawable.ic_avatar_link)));
|
||||
} else {
|
||||
holder.binding.dialogAvatar.setImageDrawable(
|
||||
|
@ -153,7 +153,7 @@ public class MentionAutocompleteItem extends AbstractFlexibleItem<ParticipantIte
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
holder.binding.avatarDraweeView.getHierarchy().setPlaceholderImage(
|
||||
DisplayUtils.getRoundedDrawable(
|
||||
viewThemeUtils.themePlaceholderAvatar(holder.binding.avatarDraweeView,
|
||||
viewThemeUtils.talk.themePlaceholderAvatar(holder.binding.avatarDraweeView,
|
||||
R.drawable.ic_avatar_group)));
|
||||
} else {
|
||||
holder.binding.avatarDraweeView.setImageResource(R.drawable.ic_circular_group);
|
||||
|
@ -155,7 +155,7 @@ public class ParticipantItem extends AbstractFlexibleItem<ParticipantItem.Partic
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
holder.binding.avatarDraweeView.getHierarchy().setPlaceholderImage(
|
||||
DisplayUtils.getRoundedDrawable(
|
||||
viewThemeUtils.themePlaceholderAvatar(holder.binding.avatarDraweeView,
|
||||
viewThemeUtils.talk.themePlaceholderAvatar(holder.binding.avatarDraweeView,
|
||||
R.drawable.ic_avatar_group)));
|
||||
} else {
|
||||
holder.binding.avatarDraweeView.setImageResource(R.drawable.ic_circular_group);
|
||||
@ -164,7 +164,7 @@ public class ParticipantItem extends AbstractFlexibleItem<ParticipantItem.Partic
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
holder.binding.avatarDraweeView.getHierarchy().setPlaceholderImage(
|
||||
DisplayUtils.getRoundedDrawable(
|
||||
viewThemeUtils.themePlaceholderAvatar(holder.binding.avatarDraweeView,
|
||||
viewThemeUtils.talk.themePlaceholderAvatar(holder.binding.avatarDraweeView,
|
||||
R.drawable.ic_avatar_mail)));
|
||||
} else {
|
||||
holder.binding.avatarDraweeView.setImageResource(R.drawable.ic_circular_mail);
|
||||
|
@ -161,7 +161,7 @@ class IncomingLocationMessageViewHolder(incomingView: View, payload: Any) : Mess
|
||||
}
|
||||
|
||||
private fun colorizeMessageBubble(message: ChatMessage) {
|
||||
viewThemeUtils.themeIncomingMessageBubble(bubble, message.isGrouped, message.isDeleted)
|
||||
viewThemeUtils.talk.themeIncomingMessageBubble(bubble, message.isGrouped, message.isDeleted)
|
||||
}
|
||||
|
||||
private fun setParentMessageDataOnMessageItem(message: ChatMessage) {
|
||||
|
@ -191,7 +191,7 @@ class IncomingPollMessageViewHolder(incomingView: View, payload: Any) : MessageH
|
||||
}
|
||||
|
||||
private fun colorizeMessageBubble(message: ChatMessage) {
|
||||
viewThemeUtils.themeIncomingMessageBubble(bubble, message.isGrouped, message.isDeleted)
|
||||
viewThemeUtils.talk.themeIncomingMessageBubble(bubble, message.isGrouped, message.isDeleted)
|
||||
}
|
||||
|
||||
private fun setParentMessageDataOnMessageItem(message: ChatMessage) {
|
||||
|
@ -266,7 +266,7 @@ class IncomingVoiceMessageViewHolder(incomingView: View, payload: Any) : Message
|
||||
}
|
||||
|
||||
private fun colorizeMessageBubble(message: ChatMessage) {
|
||||
viewThemeUtils.themeIncomingMessageBubble(bubble, message.isGrouped, message.isDeleted)
|
||||
viewThemeUtils.talk.themeIncomingMessageBubble(bubble, message.isGrouped, message.isDeleted)
|
||||
}
|
||||
|
||||
private fun setParentMessageDataOnMessageItem(message: ChatMessage) {
|
||||
|
@ -87,7 +87,7 @@ class MagicIncomingTextMessageViewHolder(itemView: View, payload: Any) : Message
|
||||
binding.messageAuthor.visibility = View.GONE
|
||||
}
|
||||
|
||||
viewThemeUtils.themeIncomingMessageBubble(bubble, message.isGrouped, message.isDeleted)
|
||||
viewThemeUtils.talk.themeIncomingMessageBubble(bubble, message.isGrouped, message.isDeleted)
|
||||
|
||||
itemView.isSelected = false
|
||||
|
||||
|
@ -156,7 +156,7 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage
|
||||
}
|
||||
|
||||
private fun setBubbleOnChatMessage(message: ChatMessage) {
|
||||
viewThemeUtils.themeOutgoingMessageBubble(bubble, message.isGrouped, message.isDeleted)
|
||||
viewThemeUtils.talk.themeOutgoingMessageBubble(bubble, message.isGrouped, message.isDeleted)
|
||||
}
|
||||
|
||||
private fun processMessageParameters(
|
||||
|
@ -167,8 +167,8 @@ public abstract class MagicPreviewMessageViewHolder extends MessageHolders.Incom
|
||||
progressBar = getPreviewContactProgressBar();
|
||||
getMessageText().setVisibility(View.INVISIBLE);
|
||||
clickView = getPreviewContactContainer();
|
||||
viewThemeUtils.colorContactChatItemBackground(getPreviewContactContainer());
|
||||
viewThemeUtils.colorContactChatItemName(getPreviewContactName());
|
||||
viewThemeUtils.talk.colorContactChatItemBackground(getPreviewContactContainer());
|
||||
viewThemeUtils.talk.colorContactChatItemName(getPreviewContactName());
|
||||
viewThemeUtils.platform.colorCircularProgressBarOnPrimaryContainer(getPreviewContactProgressBar());
|
||||
} else {
|
||||
getPreviewContainer().setVisibility(View.VISIBLE);
|
||||
|
@ -212,9 +212,9 @@ class OutcomingLocationMessageViewHolder(incomingView: View) : MessageHolders
|
||||
binding.messageQuote.quotedMessageAuthor.text = parentChatMessage.actorDisplayName
|
||||
?: context!!.getText(R.string.nc_nick_guest)
|
||||
binding.messageQuote.quotedMessage.text = parentChatMessage.text
|
||||
viewThemeUtils.colorOutgoingQuoteText(binding.messageQuote.quotedMessage)
|
||||
viewThemeUtils.colorOutgoingQuoteAuthorText(binding.messageQuote.quotedMessageAuthor)
|
||||
viewThemeUtils.colorOutgoingQuoteBackground(binding.messageQuote.quoteColoredView)
|
||||
viewThemeUtils.talk.colorOutgoingQuoteText(binding.messageQuote.quotedMessage)
|
||||
viewThemeUtils.talk.colorOutgoingQuoteAuthorText(binding.messageQuote.quotedMessageAuthor)
|
||||
viewThemeUtils.talk.colorOutgoingQuoteBackground(binding.messageQuote.quoteColoredView)
|
||||
|
||||
binding.messageQuote.quotedChatMessageView.visibility = View.VISIBLE
|
||||
} else {
|
||||
@ -223,7 +223,7 @@ class OutcomingLocationMessageViewHolder(incomingView: View) : MessageHolders
|
||||
}
|
||||
|
||||
private fun colorizeMessageBubble(message: ChatMessage) {
|
||||
viewThemeUtils.themeOutgoingMessageBubble(bubble, message.isGrouped, message.isDeleted)
|
||||
viewThemeUtils.talk.themeOutgoingMessageBubble(bubble, message.isGrouped, message.isDeleted)
|
||||
}
|
||||
|
||||
private fun openGeoLink() {
|
||||
|
@ -176,9 +176,9 @@ class OutcomingPollMessageViewHolder(outcomingView: View, payload: Any) : Messag
|
||||
binding.messageQuote.quotedMessageAuthor.text = parentChatMessage.actorDisplayName
|
||||
?: context.getText(R.string.nc_nick_guest)
|
||||
binding.messageQuote.quotedMessage.text = parentChatMessage.text
|
||||
viewThemeUtils.colorOutgoingQuoteText(binding.messageQuote.quotedMessage)
|
||||
viewThemeUtils.colorOutgoingQuoteAuthorText(binding.messageQuote.quotedMessageAuthor)
|
||||
viewThemeUtils.colorOutgoingQuoteBackground(binding.messageQuote.quoteColoredView)
|
||||
viewThemeUtils.talk.colorOutgoingQuoteText(binding.messageQuote.quotedMessage)
|
||||
viewThemeUtils.talk.colorOutgoingQuoteAuthorText(binding.messageQuote.quotedMessageAuthor)
|
||||
viewThemeUtils.talk.colorOutgoingQuoteBackground(binding.messageQuote.quoteColoredView)
|
||||
|
||||
binding.messageQuote.quotedChatMessageView.visibility = View.VISIBLE
|
||||
} else {
|
||||
@ -187,7 +187,7 @@ class OutcomingPollMessageViewHolder(outcomingView: View, payload: Any) : Messag
|
||||
}
|
||||
|
||||
private fun colorizeMessageBubble(message: ChatMessage) {
|
||||
viewThemeUtils.themeOutgoingMessageBubble(bubble, message.isGrouped, message.isDeleted)
|
||||
viewThemeUtils.talk.themeOutgoingMessageBubble(bubble, message.isGrouped, message.isDeleted)
|
||||
}
|
||||
|
||||
fun assignReactionInterface(reactionsInterface: ReactionsInterface) {
|
||||
|
@ -263,9 +263,9 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) : MessageHolders
|
||||
binding.messageQuote.quotedMessageAuthor.text = parentChatMessage.actorDisplayName
|
||||
?: context!!.getText(R.string.nc_nick_guest)
|
||||
binding.messageQuote.quotedMessage.text = parentChatMessage.text
|
||||
viewThemeUtils.colorOutgoingQuoteText(binding.messageQuote.quotedMessage)
|
||||
viewThemeUtils.colorOutgoingQuoteAuthorText(binding.messageQuote.quotedMessageAuthor)
|
||||
viewThemeUtils.colorOutgoingQuoteBackground(binding.messageQuote.quoteColoredView)
|
||||
viewThemeUtils.talk.colorOutgoingQuoteText(binding.messageQuote.quotedMessage)
|
||||
viewThemeUtils.talk.colorOutgoingQuoteAuthorText(binding.messageQuote.quotedMessageAuthor)
|
||||
viewThemeUtils.talk.colorOutgoingQuoteBackground(binding.messageQuote.quoteColoredView)
|
||||
|
||||
binding.messageQuote.quotedChatMessageView.visibility = View.VISIBLE
|
||||
} else {
|
||||
@ -274,7 +274,7 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) : MessageHolders
|
||||
}
|
||||
|
||||
private fun colorizeMessageBubble(message: ChatMessage) {
|
||||
viewThemeUtils.themeOutgoingMessageBubble(bubble, message.isGrouped, message.isDeleted)
|
||||
viewThemeUtils.talk.themeOutgoingMessageBubble(bubble, message.isGrouped, message.isDeleted)
|
||||
}
|
||||
|
||||
fun assignVoiceMessageInterface(voiceMessageInterface: VoiceMessageInterface) {
|
||||
|
@ -112,7 +112,7 @@ class Reaction {
|
||||
} else {
|
||||
layoutInfo.viewThemeUtils.getScheme(emojiWithAmountWrapper.context).primaryContainer
|
||||
}
|
||||
layoutInfo.viewThemeUtils.setCheckedBackground(emojiWithAmountWrapper, color)
|
||||
layoutInfo.viewThemeUtils.talk.setCheckedBackground(emojiWithAmountWrapper, color)
|
||||
|
||||
emojiWithAmountWrapper.setPaddingRelative(
|
||||
layoutInfo.paddingSide,
|
||||
|
@ -334,7 +334,7 @@ class ContactsController(args: Bundle) :
|
||||
val searchManager: SearchManager? = activity?.getSystemService(Context.SEARCH_SERVICE) as SearchManager?
|
||||
if (searchItem != null) {
|
||||
searchView = MenuItemCompat.getActionView(searchItem) as SearchView
|
||||
viewThemeUtils.themeSearchView(searchView!!)
|
||||
viewThemeUtils.appcompat.themeSearchView(searchView!!)
|
||||
searchView!!.maxWidth = Int.MAX_VALUE
|
||||
searchView!!.inputType = InputType.TYPE_TEXT_VARIATION_FILTER
|
||||
var imeOptions: Int = EditorInfo.IME_ACTION_DONE or EditorInfo.IME_FLAG_NO_FULLSCREEN
|
||||
|
@ -780,7 +780,7 @@ class ConversationInfoController(args: Bundle) :
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
binding.avatarImage.hierarchy.setPlaceholderImage(
|
||||
DisplayUtils.getRoundedDrawable(
|
||||
viewThemeUtils.themePlaceholderAvatar(binding.avatarImage, R.drawable.ic_avatar_group)
|
||||
viewThemeUtils.talk.themePlaceholderAvatar(binding.avatarImage, R.drawable.ic_avatar_group)
|
||||
)
|
||||
)
|
||||
} else {
|
||||
@ -793,7 +793,7 @@ class ConversationInfoController(args: Bundle) :
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
binding.avatarImage.hierarchy.setPlaceholderImage(
|
||||
DisplayUtils.getRoundedDrawable(
|
||||
viewThemeUtils.themePlaceholderAvatar(binding.avatarImage, R.drawable.ic_avatar_link)
|
||||
viewThemeUtils.talk.themePlaceholderAvatar(binding.avatarImage, R.drawable.ic_avatar_link)
|
||||
)
|
||||
)
|
||||
} else {
|
||||
|
@ -296,7 +296,7 @@ class ConversationsListController(bundle: Bundle) :
|
||||
val searchManager = activity!!.getSystemService(Context.SEARCH_SERVICE) as SearchManager?
|
||||
if (searchItem != null) {
|
||||
searchView = MenuItemCompat.getActionView(searchItem) as SearchView
|
||||
viewThemeUtils.themeSearchView(searchView!!)
|
||||
viewThemeUtils.appcompat.themeSearchView(searchView!!)
|
||||
searchView!!.maxWidth = Int.MAX_VALUE
|
||||
searchView!!.inputType = InputType.TYPE_TEXT_VARIATION_FILTER
|
||||
var imeOptions = EditorInfo.IME_ACTION_DONE or EditorInfo.IME_FLAG_NO_FULLSCREEN
|
||||
|
@ -98,7 +98,7 @@ class RemoteFileBrowserItemsListViewHolder(
|
||||
binding.fileIcon
|
||||
.hierarchy
|
||||
.setPlaceholderImage(
|
||||
viewThemeUtils.getPlaceholderImage(binding.root.context, item.mimeType)
|
||||
viewThemeUtils.talk.getPlaceholderImage(binding.root.context, item.mimeType)
|
||||
)
|
||||
|
||||
if (item.hasPreview) {
|
||||
|
@ -70,7 +70,7 @@ abstract class SharedItemsViewHolder(
|
||||
)
|
||||
|
||||
open fun onBind(item: SharedFileItem) {
|
||||
image.hierarchy.setPlaceholderImage(viewThemeUtils.getPlaceholderImage(image.context, item.mimeType))
|
||||
image.hierarchy.setPlaceholderImage(viewThemeUtils.talk.getPlaceholderImage(image.context, item.mimeType))
|
||||
if (item.previewAvailable) {
|
||||
image.controller = configurePreview(item)
|
||||
}
|
||||
|
@ -225,7 +225,7 @@ class MessageActionsDialog(
|
||||
|
||||
private fun checkAndSetEmojiSelfReaction(emoji: EmojiTextView) {
|
||||
if (emoji.text?.toString() != null && message.reactionsSelf?.contains(emoji.text?.toString()) == true) {
|
||||
viewThemeUtils.setCheckedBackground(emoji)
|
||||
viewThemeUtils.talk.setCheckedBackground(emoji)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,48 +21,27 @@
|
||||
|
||||
package com.nextcloud.talk.ui.theme
|
||||
|
||||
import android.annotation.TargetApi
|
||||
import android.content.Context
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.graphics.drawable.LayerDrawable
|
||||
import android.os.Build
|
||||
import android.text.Spannable
|
||||
import android.text.SpannableString
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.appcompat.content.res.AppCompatResources
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.appcompat.widget.SwitchCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import androidx.core.graphics.ColorUtils
|
||||
import androidx.core.graphics.drawable.DrawableCompat
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.children
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import com.google.android.material.card.MaterialCardView
|
||||
import com.google.android.material.chip.ChipDrawable
|
||||
import com.nextcloud.android.common.ui.theme.MaterialSchemes
|
||||
import com.nextcloud.android.common.ui.theme.ViewThemeUtilsBase
|
||||
import com.nextcloud.talk.R
|
||||
import com.nextcloud.talk.ui.theme.viewthemeutils.AndroidViewThemeUtils
|
||||
import com.nextcloud.talk.ui.theme.viewthemeutils.AppCompatViewThemeUtils
|
||||
import com.nextcloud.talk.ui.theme.viewthemeutils.MaterialViewThemeUtils
|
||||
import com.nextcloud.talk.ui.theme.viewthemeutils.TalkSpecificViewThemeUtils
|
||||
import com.nextcloud.talk.utils.DisplayUtils
|
||||
import com.nextcloud.talk.utils.DrawableUtils
|
||||
import com.vanniktech.emoji.EmojiTextView
|
||||
import com.yarolegovich.mp.MaterialPreferenceCategory
|
||||
import com.yarolegovich.mp.MaterialSwitchPreference
|
||||
import eu.davidea.flexibleadapter.utils.FlexibleUtils
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
@Suppress("TooManyFunctions")
|
||||
class ViewThemeUtils @Inject constructor(
|
||||
@ -70,149 +49,13 @@ class ViewThemeUtils @Inject constructor(
|
||||
@JvmField
|
||||
val platform: AndroidViewThemeUtils,
|
||||
@JvmField
|
||||
val material: MaterialViewThemeUtils
|
||||
val material: MaterialViewThemeUtils,
|
||||
@JvmField
|
||||
val appcompat: AppCompatViewThemeUtils,
|
||||
@JvmField
|
||||
val talk: TalkSpecificViewThemeUtils
|
||||
) : ViewThemeUtilsBase(schemes) {
|
||||
|
||||
fun themeSearchView(searchView: SearchView) {
|
||||
withScheme(searchView) { scheme ->
|
||||
// hacky as no default way is provided
|
||||
val editText = searchView.findViewById<SearchView.SearchAutoComplete>(R.id.search_src_text)
|
||||
val searchPlate = searchView.findViewById<LinearLayout>(R.id.search_plate)
|
||||
editText.textSize = SEARCH_TEXT_SIZE
|
||||
editText.setHintTextColor(scheme.onSurfaceVariant)
|
||||
editText.setTextColor(scheme.onSurface)
|
||||
editText.setBackgroundColor(scheme.surface)
|
||||
searchPlate.setBackgroundColor(scheme.surface)
|
||||
}
|
||||
}
|
||||
|
||||
fun themeIncomingMessageBubble(bubble: ViewGroup, grouped: Boolean, deleted: Boolean) {
|
||||
val resources = bubble.resources
|
||||
|
||||
var bubbleResource = R.drawable.shape_incoming_message
|
||||
|
||||
if (grouped) {
|
||||
bubbleResource = R.drawable.shape_grouped_incoming_message
|
||||
}
|
||||
|
||||
val bgBubbleColor = if (deleted) {
|
||||
resources.getColor(R.color.bg_message_list_incoming_bubble_deleted)
|
||||
} else {
|
||||
resources.getColor(R.color.bg_message_list_incoming_bubble)
|
||||
}
|
||||
val bubbleDrawable = DisplayUtils.getMessageSelector(
|
||||
bgBubbleColor,
|
||||
resources.getColor(R.color.transparent),
|
||||
bgBubbleColor,
|
||||
bubbleResource
|
||||
)
|
||||
ViewCompat.setBackground(bubble, bubbleDrawable)
|
||||
}
|
||||
|
||||
fun themeOutgoingMessageBubble(bubble: ViewGroup, grouped: Boolean, deleted: Boolean) {
|
||||
withScheme(bubble) { scheme ->
|
||||
val bgBubbleColor = if (deleted) {
|
||||
ColorUtils.setAlphaComponent(scheme.surfaceVariant, HALF_ALPHA_INT)
|
||||
} else {
|
||||
scheme.surfaceVariant
|
||||
}
|
||||
|
||||
val layout = if (grouped) {
|
||||
R.drawable.shape_grouped_outcoming_message
|
||||
} else {
|
||||
R.drawable.shape_outcoming_message
|
||||
}
|
||||
val bubbleDrawable = DisplayUtils.getMessageSelector(
|
||||
bgBubbleColor,
|
||||
ResourcesCompat.getColor(bubble.resources, R.color.transparent, null),
|
||||
bgBubbleColor,
|
||||
layout
|
||||
)
|
||||
ViewCompat.setBackground(bubble, bubbleDrawable)
|
||||
}
|
||||
}
|
||||
|
||||
fun colorOutgoingQuoteText(textView: TextView) {
|
||||
withScheme(textView) { scheme ->
|
||||
textView.setTextColor(scheme.onSurfaceVariant)
|
||||
}
|
||||
}
|
||||
|
||||
fun colorOutgoingQuoteAuthorText(textView: TextView) {
|
||||
withScheme(textView) { scheme ->
|
||||
ColorUtils.setAlphaComponent(scheme.onSurfaceVariant, ALPHA_80_INT)
|
||||
}
|
||||
}
|
||||
|
||||
fun colorOutgoingQuoteBackground(view: View) {
|
||||
withScheme(view) { scheme ->
|
||||
view.setBackgroundColor(scheme.onSurfaceVariant)
|
||||
}
|
||||
}
|
||||
|
||||
fun colorContactChatItemName(contactName: androidx.emoji.widget.EmojiTextView) {
|
||||
withScheme(contactName) { scheme ->
|
||||
contactName.setTextColor(scheme.onPrimaryContainer)
|
||||
}
|
||||
}
|
||||
|
||||
fun colorContactChatItemBackground(card: MaterialCardView) {
|
||||
withScheme(card) { scheme ->
|
||||
card.setCardBackgroundColor(scheme.primaryContainer)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO split this util into classes depending on framework views vs library views
|
||||
fun colorPreferenceCategory(category: MaterialPreferenceCategory) {
|
||||
withScheme(category) { scheme ->
|
||||
category.setTitleColor(scheme.primary)
|
||||
}
|
||||
}
|
||||
|
||||
fun colorSwitchPreference(preference: MaterialSwitchPreference) {
|
||||
val children = preference.children
|
||||
val switch = children.find { it is SwitchCompat }
|
||||
if (switch != null) {
|
||||
val switchCompat = (switch as SwitchCompat)
|
||||
colorSwitchCompat(switchCompat)
|
||||
}
|
||||
}
|
||||
|
||||
fun colorSwitchCompat(switchCompat: SwitchCompat) {
|
||||
withScheme(switchCompat) { scheme ->
|
||||
|
||||
val context = switchCompat.context
|
||||
|
||||
val thumbUncheckedColor = ResourcesCompat.getColor(
|
||||
context.resources,
|
||||
R.color.switch_thumb_color_unchecked,
|
||||
context.theme
|
||||
)
|
||||
val trackUncheckedColor = ResourcesCompat.getColor(
|
||||
context.resources,
|
||||
R.color.switch_track_color_unchecked,
|
||||
context.theme
|
||||
)
|
||||
|
||||
val trackColor = Color.argb(
|
||||
SWITCH_COMPAT_TRACK_ALPHA,
|
||||
Color.red(scheme.primary),
|
||||
Color.green(scheme.primary),
|
||||
Color.blue(scheme.primary)
|
||||
)
|
||||
|
||||
switchCompat.thumbTintList = ColorStateList(
|
||||
arrayOf(intArrayOf(android.R.attr.state_checked), intArrayOf()),
|
||||
intArrayOf(scheme.primary, thumbUncheckedColor)
|
||||
)
|
||||
|
||||
switchCompat.trackTintList = ColorStateList(
|
||||
arrayOf(intArrayOf(android.R.attr.state_checked), intArrayOf()),
|
||||
intArrayOf(trackColor, trackUncheckedColor)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun themeSwipeRefreshLayout(swipeRefreshLayout: SwipeRefreshLayout) {
|
||||
withScheme(swipeRefreshLayout) { scheme ->
|
||||
swipeRefreshLayout.setColorSchemeColors(scheme.primary)
|
||||
@ -220,71 +63,6 @@ class ViewThemeUtils @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun getPlaceholderImage(context: Context, mimetype: String?): Drawable? {
|
||||
val drawableResourceId = DrawableUtils.getDrawableResourceIdForMimeType(mimetype)
|
||||
val drawable = AppCompatResources.getDrawable(
|
||||
context,
|
||||
drawableResourceId
|
||||
)
|
||||
if (drawable != null && THEMEABLE_PLACEHOLDER_IDS.contains(drawableResourceId)) {
|
||||
colorDrawable(context, drawable)
|
||||
}
|
||||
return drawable
|
||||
}
|
||||
|
||||
private fun colorDrawable(context: Context, drawable: Drawable) {
|
||||
val scheme = getScheme(context)
|
||||
drawable.setTint(scheme.primary)
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.O)
|
||||
fun themePlaceholderAvatar(avatar: View, @DrawableRes foreground: Int): Drawable? {
|
||||
var drawable: LayerDrawable? = null
|
||||
withScheme(avatar) { scheme ->
|
||||
val layers = arrayOfNulls<Drawable>(2)
|
||||
layers[0] = ContextCompat.getDrawable(avatar.context, R.drawable.ic_avatar_background)
|
||||
layers[0]?.setTint(scheme.surfaceVariant)
|
||||
layers[1] = ContextCompat.getDrawable(avatar.context, foreground)
|
||||
layers[1]?.setTint(scheme.onSurfaceVariant)
|
||||
drawable = LayerDrawable(layers)
|
||||
}
|
||||
|
||||
return drawable
|
||||
}
|
||||
|
||||
fun themePrimaryMentionChip(context: Context, chip: ChipDrawable) {
|
||||
withScheme(context) { scheme ->
|
||||
chip.chipBackgroundColor = ColorStateList.valueOf(scheme.primary)
|
||||
chip.setTextColor(scheme.onPrimary)
|
||||
}
|
||||
}
|
||||
|
||||
fun setCheckedBackground(emoji: EmojiTextView) {
|
||||
withScheme(emoji) { scheme ->
|
||||
val drawable = AppCompatResources
|
||||
.getDrawable(emoji.context, R.drawable.reaction_self_bottom_sheet_background)!!
|
||||
.mutate()
|
||||
DrawableCompat.setTintList(
|
||||
drawable,
|
||||
ColorStateList.valueOf(scheme.primary)
|
||||
)
|
||||
emoji.background = drawable
|
||||
}
|
||||
}
|
||||
|
||||
fun setCheckedBackground(linearLayout: LinearLayout, @ColorInt backgroundColor: Int) {
|
||||
withScheme(linearLayout) { scheme ->
|
||||
val drawable = AppCompatResources
|
||||
.getDrawable(linearLayout.context, R.drawable.reaction_self_background)!!
|
||||
.mutate()
|
||||
DrawableCompat.setTintList(
|
||||
drawable,
|
||||
ColorStateList.valueOf(backgroundColor)
|
||||
)
|
||||
linearLayout.background = drawable
|
||||
}
|
||||
}
|
||||
|
||||
fun colorDialogMenuText(button: MaterialButton) {
|
||||
withScheme(button) { scheme ->
|
||||
button.setTextColor(scheme.onSurface)
|
||||
@ -331,18 +109,4 @@ class ViewThemeUtils @Inject constructor(
|
||||
}
|
||||
return drawable
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val THEMEABLE_PLACEHOLDER_IDS = listOf(
|
||||
R.drawable.ic_mimetype_package_x_generic,
|
||||
R.drawable.ic_mimetype_folder
|
||||
)
|
||||
|
||||
private val ALPHA_80_INT: Int = (255 * 0.8).roundToInt()
|
||||
|
||||
private const val SWITCH_COMPAT_TRACK_ALPHA: Int = 77
|
||||
private const val HALF_ALPHA_INT: Int = 255 / 2
|
||||
|
||||
private const val SEARCH_TEXT_SIZE: Float = 16f
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Álvaro Brey
|
||||
* Copyright (C) 2022 Álvaro Brey
|
||||
* Copyright (C) 2022 Nextcloud GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.nextcloud.talk.ui.theme.viewthemeutils
|
||||
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.Color
|
||||
import android.widget.LinearLayout
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.appcompat.widget.SwitchCompat
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import com.nextcloud.android.common.ui.color.ColorUtil
|
||||
import com.nextcloud.android.common.ui.theme.MaterialSchemes
|
||||
import com.nextcloud.android.common.ui.theme.ViewThemeUtilsBase
|
||||
import com.nextcloud.talk.R
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* View theme utils for AppCompat views (androidx.appcompat.*)
|
||||
*/
|
||||
class AppCompatViewThemeUtils @Inject constructor(schemes: MaterialSchemes, private val colorUtil: ColorUtil) :
|
||||
ViewThemeUtilsBase(schemes) {
|
||||
fun themeSearchView(searchView: SearchView) {
|
||||
withScheme(searchView) { scheme ->
|
||||
// hacky as no default way is provided
|
||||
val editText = searchView.findViewById<SearchView.SearchAutoComplete>(R.id.search_src_text)
|
||||
val searchPlate = searchView.findViewById<LinearLayout>(R.id.search_plate)
|
||||
editText.textSize = SEARCH_TEXT_SIZE
|
||||
editText.setHintTextColor(scheme.onSurfaceVariant)
|
||||
editText.setTextColor(scheme.onSurface)
|
||||
editText.setBackgroundColor(scheme.surface)
|
||||
searchPlate.setBackgroundColor(scheme.surface)
|
||||
}
|
||||
}
|
||||
|
||||
fun colorSwitchCompat(switchCompat: SwitchCompat) {
|
||||
withScheme(switchCompat) { scheme ->
|
||||
|
||||
val context = switchCompat.context
|
||||
|
||||
val thumbUncheckedColor = ResourcesCompat.getColor(
|
||||
context.resources,
|
||||
R.color.switch_thumb_color_unchecked,
|
||||
context.theme
|
||||
)
|
||||
val trackUncheckedColor = ResourcesCompat.getColor(
|
||||
context.resources,
|
||||
R.color.switch_track_color_unchecked,
|
||||
context.theme
|
||||
)
|
||||
|
||||
val trackColor = Color.argb(
|
||||
SWITCH_COMPAT_TRACK_ALPHA,
|
||||
Color.red(scheme.primary),
|
||||
Color.green(scheme.primary),
|
||||
Color.blue(scheme.primary)
|
||||
)
|
||||
|
||||
switchCompat.thumbTintList = ColorStateList(
|
||||
arrayOf(intArrayOf(android.R.attr.state_checked), intArrayOf()),
|
||||
intArrayOf(scheme.primary, thumbUncheckedColor)
|
||||
)
|
||||
|
||||
switchCompat.trackTintList = ColorStateList(
|
||||
arrayOf(intArrayOf(android.R.attr.state_checked), intArrayOf()),
|
||||
intArrayOf(trackColor, trackUncheckedColor)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val SWITCH_COMPAT_TRACK_ALPHA: Int = 77
|
||||
private const val SEARCH_TEXT_SIZE: Float = 16f
|
||||
}
|
||||
}
|
@ -0,0 +1,234 @@
|
||||
/*
|
||||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Álvaro Brey
|
||||
* Copyright (C) 2022 Álvaro Brey
|
||||
* Copyright (C) 2022 Nextcloud GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.nextcloud.talk.ui.theme.viewthemeutils
|
||||
|
||||
import android.annotation.TargetApi
|
||||
import android.content.Context
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.graphics.drawable.LayerDrawable
|
||||
import android.os.Build
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.appcompat.content.res.AppCompatResources
|
||||
import androidx.appcompat.widget.SwitchCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import androidx.core.graphics.ColorUtils
|
||||
import androidx.core.graphics.drawable.DrawableCompat
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.children
|
||||
import com.google.android.material.card.MaterialCardView
|
||||
import com.google.android.material.chip.ChipDrawable
|
||||
import com.nextcloud.android.common.ui.theme.MaterialSchemes
|
||||
import com.nextcloud.android.common.ui.theme.ViewThemeUtilsBase
|
||||
import com.nextcloud.talk.R
|
||||
import com.nextcloud.talk.utils.DisplayUtils
|
||||
import com.nextcloud.talk.utils.DrawableUtils
|
||||
import com.vanniktech.emoji.EmojiTextView
|
||||
import com.yarolegovich.mp.MaterialPreferenceCategory
|
||||
import com.yarolegovich.mp.MaterialSwitchPreference
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
/**
|
||||
* View theme utils specific for the Talk app.
|
||||
*
|
||||
* TODO some of these can be renamed and made generic
|
||||
*/
|
||||
@Suppress("TooManyFunctions")
|
||||
class TalkSpecificViewThemeUtils @Inject constructor(
|
||||
schemes: MaterialSchemes,
|
||||
private val appcompat: AppCompatViewThemeUtils
|
||||
) :
|
||||
ViewThemeUtilsBase(schemes) {
|
||||
fun themeIncomingMessageBubble(bubble: ViewGroup, grouped: Boolean, deleted: Boolean) {
|
||||
val resources = bubble.resources
|
||||
|
||||
var bubbleResource = R.drawable.shape_incoming_message
|
||||
|
||||
if (grouped) {
|
||||
bubbleResource = R.drawable.shape_grouped_incoming_message
|
||||
}
|
||||
|
||||
val bgBubbleColor = if (deleted) {
|
||||
resources.getColor(R.color.bg_message_list_incoming_bubble_deleted)
|
||||
} else {
|
||||
resources.getColor(R.color.bg_message_list_incoming_bubble)
|
||||
}
|
||||
val bubbleDrawable = DisplayUtils.getMessageSelector(
|
||||
bgBubbleColor,
|
||||
resources.getColor(R.color.transparent),
|
||||
bgBubbleColor,
|
||||
bubbleResource
|
||||
)
|
||||
ViewCompat.setBackground(bubble, bubbleDrawable)
|
||||
}
|
||||
|
||||
fun themeOutgoingMessageBubble(bubble: ViewGroup, grouped: Boolean, deleted: Boolean) {
|
||||
withScheme(bubble) { scheme ->
|
||||
val bgBubbleColor = if (deleted) {
|
||||
ColorUtils.setAlphaComponent(scheme.surfaceVariant, HALF_ALPHA_INT)
|
||||
} else {
|
||||
scheme.surfaceVariant
|
||||
}
|
||||
|
||||
val layout = if (grouped) {
|
||||
R.drawable.shape_grouped_outcoming_message
|
||||
} else {
|
||||
R.drawable.shape_outcoming_message
|
||||
}
|
||||
val bubbleDrawable = DisplayUtils.getMessageSelector(
|
||||
bgBubbleColor,
|
||||
ResourcesCompat.getColor(bubble.resources, R.color.transparent, null),
|
||||
bgBubbleColor,
|
||||
layout
|
||||
)
|
||||
ViewCompat.setBackground(bubble, bubbleDrawable)
|
||||
}
|
||||
}
|
||||
|
||||
fun colorOutgoingQuoteText(textView: TextView) {
|
||||
withScheme(textView) { scheme ->
|
||||
textView.setTextColor(scheme.onSurfaceVariant)
|
||||
}
|
||||
}
|
||||
|
||||
fun colorOutgoingQuoteAuthorText(textView: TextView) {
|
||||
withScheme(textView) { scheme ->
|
||||
ColorUtils.setAlphaComponent(scheme.onSurfaceVariant, ALPHA_80_INT)
|
||||
}
|
||||
}
|
||||
|
||||
fun colorOutgoingQuoteBackground(view: View) {
|
||||
withScheme(view) { scheme ->
|
||||
view.setBackgroundColor(scheme.onSurfaceVariant)
|
||||
}
|
||||
}
|
||||
|
||||
fun colorContactChatItemName(contactName: androidx.emoji.widget.EmojiTextView) {
|
||||
withScheme(contactName) { scheme ->
|
||||
contactName.setTextColor(scheme.onPrimaryContainer)
|
||||
}
|
||||
}
|
||||
|
||||
fun colorContactChatItemBackground(card: MaterialCardView) {
|
||||
withScheme(card) { scheme ->
|
||||
card.setCardBackgroundColor(scheme.primaryContainer)
|
||||
}
|
||||
}
|
||||
|
||||
fun colorPreferenceCategory(category: MaterialPreferenceCategory) {
|
||||
withScheme(category) { scheme ->
|
||||
category.setTitleColor(scheme.primary)
|
||||
}
|
||||
}
|
||||
|
||||
fun colorSwitchPreference(preference: MaterialSwitchPreference) {
|
||||
val children = preference.children
|
||||
val switch = children.find { it is SwitchCompat }
|
||||
if (switch != null) {
|
||||
val switchCompat = (switch as SwitchCompat)
|
||||
appcompat.colorSwitchCompat(switchCompat)
|
||||
}
|
||||
}
|
||||
|
||||
fun setCheckedBackground(emoji: EmojiTextView) {
|
||||
withScheme(emoji) { scheme ->
|
||||
val drawable = AppCompatResources
|
||||
.getDrawable(emoji.context, R.drawable.reaction_self_bottom_sheet_background)!!
|
||||
.mutate()
|
||||
DrawableCompat.setTintList(
|
||||
drawable,
|
||||
ColorStateList.valueOf(scheme.primary)
|
||||
)
|
||||
emoji.background = drawable
|
||||
}
|
||||
}
|
||||
|
||||
fun setCheckedBackground(linearLayout: LinearLayout, @ColorInt backgroundColor: Int) {
|
||||
withScheme(linearLayout) { scheme ->
|
||||
val drawable = AppCompatResources
|
||||
.getDrawable(linearLayout.context, R.drawable.reaction_self_background)!!
|
||||
.mutate()
|
||||
DrawableCompat.setTintList(
|
||||
drawable,
|
||||
ColorStateList.valueOf(backgroundColor)
|
||||
)
|
||||
linearLayout.background = drawable
|
||||
}
|
||||
}
|
||||
|
||||
fun getPlaceholderImage(context: Context, mimetype: String?): Drawable? {
|
||||
val drawableResourceId = DrawableUtils.getDrawableResourceIdForMimeType(mimetype)
|
||||
val drawable = AppCompatResources.getDrawable(
|
||||
context,
|
||||
drawableResourceId
|
||||
)
|
||||
if (drawable != null && THEMEABLE_PLACEHOLDER_IDS.contains(drawableResourceId)) {
|
||||
colorDrawable(context, drawable)
|
||||
}
|
||||
return drawable
|
||||
}
|
||||
|
||||
private fun colorDrawable(context: Context, drawable: Drawable) {
|
||||
val scheme = getScheme(context)
|
||||
drawable.setTint(scheme.primary)
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.O)
|
||||
fun themePlaceholderAvatar(avatar: View, @DrawableRes foreground: Int): Drawable? {
|
||||
var drawable: LayerDrawable? = null
|
||||
withScheme(avatar) { scheme ->
|
||||
val layers = arrayOfNulls<Drawable>(2)
|
||||
layers[0] = ContextCompat.getDrawable(avatar.context, R.drawable.ic_avatar_background)
|
||||
layers[0]?.setTint(scheme.surfaceVariant)
|
||||
layers[1] = ContextCompat.getDrawable(avatar.context, foreground)
|
||||
layers[1]?.setTint(scheme.onSurfaceVariant)
|
||||
drawable = LayerDrawable(layers)
|
||||
}
|
||||
|
||||
return drawable
|
||||
}
|
||||
|
||||
fun themePrimaryMentionChip(context: Context, chip: ChipDrawable) {
|
||||
withScheme(context) { scheme ->
|
||||
chip.chipBackgroundColor = ColorStateList.valueOf(scheme.primary)
|
||||
chip.setTextColor(scheme.onPrimary)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val THEMEABLE_PLACEHOLDER_IDS = listOf(
|
||||
R.drawable.ic_mimetype_package_x_generic,
|
||||
R.drawable.ic_mimetype_folder
|
||||
)
|
||||
|
||||
private val ALPHA_80_INT: Int = (255 * 0.8).roundToInt()
|
||||
|
||||
private const val HALF_ALPHA_INT: Int = 255 / 2
|
||||
}
|
||||
}
|
@ -304,7 +304,7 @@ public class DisplayUtils {
|
||||
chip.setEllipsize(TextUtils.TruncateAt.MIDDLE);
|
||||
|
||||
if (chipResource == R.xml.chip_you) {
|
||||
viewThemeUtils.themePrimaryMentionChip(context, chip);
|
||||
viewThemeUtils.talk.themePrimaryMentionChip(context, chip);
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
|
Loading…
Reference in New Issue
Block a user