From b3a4a5f29f439895fb67d03724e194321ab74b0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Mon, 12 Sep 2022 18:36:04 +0200 Subject: [PATCH] Replace ThemeAvatarUtils with common material3 utils MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Brey --- app/build.gradle | 2 +- .../com/nextcloud/client/di/ThemeModule.kt | 7 -- .../android/ui/AvatarGroupLayout.java | 8 +- .../ui/adapter/LinkShareViewHolder.java | 14 +-- .../android/ui/adapter/OCFileListAdapter.java | 11 +- .../android/ui/adapter/ShareViewHolder.java | 18 ++- .../android/ui/adapter/ShareeListAdapter.java | 18 +-- .../fragment/FileDetailSharingFragment.java | 7 +- .../ui/fragment/OCFileListFragment.java | 6 +- .../android/utils/theme/ThemeAvatarUtils.java | 104 ------------------ .../newm3/FilesSpecificViewThemeUtils.kt | 68 +++++++++++- .../utils/theme/newm3/ViewThemeUtils.kt | 2 +- .../ui/adapter/ShareeListAdapterTest.kt | 11 +- 13 files changed, 102 insertions(+), 174 deletions(-) delete mode 100644 app/src/main/java/com/owncloud/android/utils/theme/ThemeAvatarUtils.java diff --git a/app/build.gradle b/app/build.gradle index b43f20c518..3fa2306706 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -355,7 +355,7 @@ dependencies { gplayImplementation "com.google.firebase:firebase-messaging:23.0.7" // TODO change back to tag before merging - implementation 'com.github.nextcloud.android-common:ui:f02df7f' + implementation 'com.github.nextcloud.android-common:ui:8d8cd09' } configurations.all { diff --git a/app/src/main/java/com/nextcloud/client/di/ThemeModule.kt b/app/src/main/java/com/nextcloud/client/di/ThemeModule.kt index 0334e032f6..a7b7eedfaf 100644 --- a/app/src/main/java/com/nextcloud/client/di/ThemeModule.kt +++ b/app/src/main/java/com/nextcloud/client/di/ThemeModule.kt @@ -22,7 +22,6 @@ package com.nextcloud.client.di import android.content.Context import com.nextcloud.android.common.ui.theme.MaterialSchemes -import com.owncloud.android.utils.theme.ThemeAvatarUtils import com.owncloud.android.utils.theme.ThemeColorUtils import com.owncloud.android.utils.theme.ThemeDrawableUtils import com.owncloud.android.utils.theme.ThemeSnackbarUtils @@ -78,12 +77,6 @@ internal abstract class ThemeModule { return ThemeSnackbarUtils() } - @Provides - @Singleton - fun themeAvatarUtils(): ThemeAvatarUtils { - return ThemeAvatarUtils() - } - @Provides fun provideMaterialSchemes(materialSchemesProvider: MaterialSchemesProvider): MaterialSchemes { return materialSchemesProvider.getMaterialSchemesForCurrentUser() diff --git a/app/src/main/java/com/owncloud/android/ui/AvatarGroupLayout.java b/app/src/main/java/com/owncloud/android/ui/AvatarGroupLayout.java index fd1a0a742e..2a9abadf16 100644 --- a/app/src/main/java/com/owncloud/android/ui/AvatarGroupLayout.java +++ b/app/src/main/java/com/owncloud/android/ui/AvatarGroupLayout.java @@ -38,9 +38,8 @@ import com.owncloud.android.R; import com.owncloud.android.lib.common.utils.Log_OC; import com.owncloud.android.lib.resources.shares.ShareeUser; import com.owncloud.android.utils.DisplayUtils; -import com.owncloud.android.utils.theme.ThemeAvatarUtils; -import com.owncloud.android.utils.theme.ThemeColorUtils; import com.owncloud.android.utils.theme.ThemeDrawableUtils; +import com.owncloud.android.utils.theme.newm3.ViewThemeUtils; import java.util.List; @@ -86,9 +85,8 @@ public class AvatarGroupLayout extends RelativeLayout implements DisplayUtils.Av public void setAvatars(@NonNull User user, @NonNull List sharees, - ThemeColorUtils themeColorUtils, ThemeDrawableUtils themeDrawableUtils, - ThemeAvatarUtils themeAvatarUtils) { + final ViewThemeUtils viewThemeUtils) { @NonNull Context context = getContext(); removeAllViews(); RelativeLayout.LayoutParams avatarLayoutParams; @@ -122,7 +120,7 @@ public class AvatarGroupLayout extends RelativeLayout implements DisplayUtils.Av case EMAIL: case ROOM: case CIRCLE: - themeAvatarUtils.createAvatar(sharee.getShareType(), avatar, context, themeColorUtils); + viewThemeUtils.files.createAvatar(sharee.getShareType(), avatar, context); break; case FEDERATED: showFederatedShareAvatar(context, diff --git a/app/src/main/java/com/owncloud/android/ui/adapter/LinkShareViewHolder.java b/app/src/main/java/com/owncloud/android/ui/adapter/LinkShareViewHolder.java index 07c24e3a09..f47dc3e6c7 100644 --- a/app/src/main/java/com/owncloud/android/ui/adapter/LinkShareViewHolder.java +++ b/app/src/main/java/com/owncloud/android/ui/adapter/LinkShareViewHolder.java @@ -35,8 +35,7 @@ import com.owncloud.android.databinding.FileDetailsShareLinkShareItemBinding; import com.owncloud.android.lib.resources.shares.OCShare; import com.owncloud.android.lib.resources.shares.ShareType; import com.owncloud.android.ui.fragment.util.SharingMenuHelper; -import com.owncloud.android.utils.theme.ThemeAvatarUtils; -import com.owncloud.android.utils.theme.ThemeColorUtils; +import com.owncloud.android.utils.theme.newm3.ViewThemeUtils; import androidx.annotation.NonNull; import androidx.core.content.res.ResourcesCompat; @@ -45,8 +44,7 @@ import androidx.recyclerview.widget.RecyclerView; class LinkShareViewHolder extends RecyclerView.ViewHolder { private FileDetailsShareLinkShareItemBinding binding; private Context context; - private ThemeColorUtils themeColorUtils; - private ThemeAvatarUtils themeAvatarUtils; + private ViewThemeUtils viewThemeUtils; public LinkShareViewHolder(@NonNull View itemView) { super(itemView); @@ -54,13 +52,11 @@ class LinkShareViewHolder extends RecyclerView.ViewHolder { public LinkShareViewHolder(FileDetailsShareLinkShareItemBinding binding, Context context, - ThemeColorUtils themeColorUtils, - ThemeAvatarUtils themeAvatarUtils) { + final ViewThemeUtils viewThemeUtils) { this(binding.getRoot()); this.binding = binding; this.context = context; - this.themeColorUtils = themeColorUtils; - this.themeAvatarUtils = themeAvatarUtils; + this.viewThemeUtils = viewThemeUtils; } public void bind(OCShare publicShare, ShareeListAdapterListener listener) { @@ -83,7 +79,7 @@ class LinkShareViewHolder extends RecyclerView.ViewHolder { binding.name.setText(R.string.share_link); } - themeAvatarUtils.colorIconImageViewWithBackground(binding.icon, context, themeColorUtils); + viewThemeUtils.platform.colorImageViewBackgroundAndIcon(binding.icon); } String permissionName = SharingMenuHelper.getPermissionName(context, publicShare); diff --git a/app/src/main/java/com/owncloud/android/ui/adapter/OCFileListAdapter.java b/app/src/main/java/com/owncloud/android/ui/adapter/OCFileListAdapter.java index 2d6b6440ff..279c04d0ab 100644 --- a/app/src/main/java/com/owncloud/android/ui/adapter/OCFileListAdapter.java +++ b/app/src/main/java/com/owncloud/android/ui/adapter/OCFileListAdapter.java @@ -76,9 +76,9 @@ import com.owncloud.android.utils.FileSortOrder; import com.owncloud.android.utils.FileStorageUtils; import com.owncloud.android.utils.MimeTypeUtil; import com.owncloud.android.utils.theme.CapabilityUtils; -import com.owncloud.android.utils.theme.ThemeAvatarUtils; import com.owncloud.android.utils.theme.ThemeColorUtils; import com.owncloud.android.utils.theme.ThemeDrawableUtils; +import com.owncloud.android.utils.theme.newm3.ViewThemeUtils; import java.io.File; import java.io.IOException; @@ -133,7 +133,7 @@ public class OCFileListAdapter extends RecyclerView.Adapter ocFileListFragmentInterface.onShareIconClick(file)); } else { diff --git a/app/src/main/java/com/owncloud/android/ui/adapter/ShareViewHolder.java b/app/src/main/java/com/owncloud/android/ui/adapter/ShareViewHolder.java index 4f561b979e..b7b75c6d0a 100644 --- a/app/src/main/java/com/owncloud/android/ui/adapter/ShareViewHolder.java +++ b/app/src/main/java/com/owncloud/android/ui/adapter/ShareViewHolder.java @@ -36,8 +36,7 @@ import com.owncloud.android.lib.resources.shares.OCShare; import com.owncloud.android.ui.TextDrawable; import com.owncloud.android.ui.fragment.util.SharingMenuHelper; import com.owncloud.android.utils.DisplayUtils; -import com.owncloud.android.utils.theme.ThemeAvatarUtils; -import com.owncloud.android.utils.theme.ThemeColorUtils; +import com.owncloud.android.utils.theme.newm3.ViewThemeUtils; import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; @@ -48,8 +47,7 @@ class ShareViewHolder extends RecyclerView.ViewHolder { private float avatarRadiusDimension; private User user; private Context context; - private ThemeColorUtils themeColorUtils; - private ThemeAvatarUtils themeAvatarUtils; + private ViewThemeUtils viewThemeUtils; public ShareViewHolder(@NonNull View itemView) { super(itemView); @@ -58,14 +56,12 @@ class ShareViewHolder extends RecyclerView.ViewHolder { public ShareViewHolder(FileDetailsShareShareItemBinding binding, User user, Context context, - ThemeColorUtils themeColorUtils, - ThemeAvatarUtils themeAvatarUtils) { + final ViewThemeUtils viewThemeUtils) { this(binding.getRoot()); this.binding = binding; this.user = user; this.context = context; - this.themeColorUtils = themeColorUtils; - this.themeAvatarUtils = themeAvatarUtils; + this.viewThemeUtils = viewThemeUtils; } public void bind(OCShare share, @@ -80,14 +76,14 @@ class ShareViewHolder extends RecyclerView.ViewHolder { switch (share.getShareType()) { case GROUP: name = context.getString(R.string.share_group_clarification, name); - themeAvatarUtils.createAvatar(share.getShareType(), binding.icon, context, themeColorUtils); + viewThemeUtils.files.createAvatar(share.getShareType(), binding.icon, context); break; case ROOM: name = context.getString(R.string.share_room_clarification, name); - themeAvatarUtils.createAvatar(share.getShareType(), binding.icon, context, themeColorUtils); + viewThemeUtils.files.createAvatar(share.getShareType(), binding.icon, context); break; case CIRCLE: - themeAvatarUtils.createAvatar(share.getShareType(), binding.icon, context, themeColorUtils); + viewThemeUtils.files.createAvatar(share.getShareType(), binding.icon, context); break; case FEDERATED: name = context.getString(R.string.share_remote_clarification, name); diff --git a/app/src/main/java/com/owncloud/android/ui/adapter/ShareeListAdapter.java b/app/src/main/java/com/owncloud/android/ui/adapter/ShareeListAdapter.java index 673de1518a..54866d0464 100644 --- a/app/src/main/java/com/owncloud/android/ui/adapter/ShareeListAdapter.java +++ b/app/src/main/java/com/owncloud/android/ui/adapter/ShareeListAdapter.java @@ -40,8 +40,7 @@ import com.owncloud.android.lib.resources.shares.OCShare; import com.owncloud.android.lib.resources.shares.ShareType; import com.owncloud.android.ui.activity.FileActivity; import com.owncloud.android.utils.DisplayUtils; -import com.owncloud.android.utils.theme.ThemeAvatarUtils; -import com.owncloud.android.utils.theme.ThemeColorUtils; +import com.owncloud.android.utils.theme.newm3.ViewThemeUtils; import java.util.ArrayList; import java.util.Collections; @@ -62,23 +61,20 @@ public class ShareeListAdapter extends RecyclerView.Adapter shares, ShareeListAdapterListener listener, String userId, User user, - ThemeColorUtils themeColorUtils, - ThemeAvatarUtils themeAvatarUtils) { + final ViewThemeUtils viewThemeUtils) { this.fileActivity = fileActivity; this.shares = shares; this.listener = listener; this.userId = userId; this.user = user; - this.themeColorUtils = themeColorUtils; - this.themeAvatarUtils = themeAvatarUtils; + this.viewThemeUtils = viewThemeUtils; avatarRadiusDimension = fileActivity.getResources().getDimension(R.dimen.user_icon_radius); @@ -101,8 +97,7 @@ public class ShareeListAdapter extends RecyclerView.Adapter. - */ -package com.owncloud.android.utils.theme; - -import android.content.Context; -import android.graphics.PorterDuff; -import android.widget.ImageView; - -import com.owncloud.android.R; -import com.owncloud.android.lib.resources.shares.ShareType; - -import androidx.core.content.res.ResourcesCompat; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; - -/** - * Utility class with methods for client side button theming. - */ -public final class ThemeAvatarUtils { - public void colorIconImageViewWithBackground(ImageView imageView, - Context context, - ThemeColorUtils themeColorUtils) { - int primaryColor = themeColorUtils.primaryColor(null, true, false, context); - - imageView.getBackground().setColorFilter(primaryColor, PorterDuff.Mode.SRC_IN); - imageView.getDrawable().mutate().setColorFilter(themeColorUtils.getColorForPrimary(primaryColor, context), - PorterDuff.Mode.SRC_IN); - } - - @SuppressFBWarnings( - value = "SF_SWITCH_NO_DEFAULT", - justification = "We only create avatars for a subset of share types") - public void createAvatar(ShareType type, - ImageView avatar, - Context context, - ThemeColorUtils themeColorUtils) { - switch (type) { - case GROUP: - avatar.setImageResource(R.drawable.ic_group); - avatar.setBackground(ResourcesCompat.getDrawable(context.getResources(), - R.drawable.round_bgnd, - null)); - avatar.setCropToPadding(true); - avatar.setPadding(4, 4, 4, 4); - colorIconImageViewWithBackground(avatar, context, themeColorUtils); - break; - - case ROOM: - avatar.setImageResource(R.drawable.first_run_talk); - avatar.setBackground(ResourcesCompat.getDrawable(context.getResources(), - R.drawable.round_bgnd, - null)); - avatar.setCropToPadding(true); - avatar.setPadding(8, 8, 8, 8); - colorIconImageViewWithBackground(avatar, context, themeColorUtils); - break; - - case CIRCLE: - avatar.setImageResource(R.drawable.ic_circles); - avatar.setBackground(ResourcesCompat.getDrawable(context.getResources(), - R.drawable.round_bgnd, - null)); - avatar.getBackground().setColorFilter(context.getResources().getColor(R.color.nc_grey), - PorterDuff.Mode.SRC_IN); - avatar.getDrawable().mutate().setColorFilter(context.getResources().getColor(R.color.icon_on_nc_grey), - PorterDuff.Mode.SRC_IN); - avatar.setCropToPadding(true); - avatar.setPadding(4, 4, 4, 4); - break; - - case EMAIL: - avatar.setImageResource(R.drawable.ic_email); - avatar.setBackground(ResourcesCompat.getDrawable(context.getResources(), - R.drawable.round_bgnd, - null)); - avatar.setCropToPadding(true); - avatar.setPadding(8, 8, 8, 8); - avatar.getBackground().setColorFilter(context.getResources().getColor(R.color.nc_grey), - PorterDuff.Mode.SRC_IN); - avatar.getDrawable().mutate().setColorFilter(context.getResources().getColor(R.color.icon_on_nc_grey), - PorterDuff.Mode.SRC_IN); - break; - } - } -} diff --git a/app/src/main/java/com/owncloud/android/utils/theme/newm3/FilesSpecificViewThemeUtils.kt b/app/src/main/java/com/owncloud/android/utils/theme/newm3/FilesSpecificViewThemeUtils.kt index 44982bf2e6..cf7fcf7278 100644 --- a/app/src/main/java/com/owncloud/android/utils/theme/newm3/FilesSpecificViewThemeUtils.kt +++ b/app/src/main/java/com/owncloud/android/utils/theme/newm3/FilesSpecificViewThemeUtils.kt @@ -22,15 +22,28 @@ package com.owncloud.android.utils.theme.newm3 +import android.content.Context +import android.graphics.PorterDuff import android.preference.PreferenceCategory import android.text.Spannable import android.text.SpannableString import android.text.style.ForegroundColorSpan +import android.widget.ImageView +import androidx.annotation.DrawableRes +import androidx.annotation.Px +import androidx.core.content.res.ResourcesCompat import com.nextcloud.android.common.ui.theme.MaterialSchemes import com.nextcloud.android.common.ui.theme.ViewThemeUtilsBase +import com.nextcloud.android.common.ui.theme.utils.AndroidViewThemeUtils +import com.owncloud.android.R +import com.owncloud.android.lib.common.utils.Log_OC +import com.owncloud.android.lib.resources.shares.ShareType import javax.inject.Inject -class FilesSpecificViewThemeUtils @Inject constructor(schemes: MaterialSchemes) : ViewThemeUtilsBase(schemes) { +class FilesSpecificViewThemeUtils @Inject constructor( + schemes: MaterialSchemes, + private val androidViewThemeUtils: AndroidViewThemeUtils +) : ViewThemeUtilsBase(schemes) { // not ported to common lib because PreferenceCategory is deprecated fun themePreferenceCategory(category: PreferenceCategory) { withScheme(category.context) { @@ -44,4 +57,57 @@ class FilesSpecificViewThemeUtils @Inject constructor(schemes: MaterialSchemes) category.title = text } } + + fun createAvatar(type: ShareType?, avatar: ImageView, context: Context) { + fun createAvatarBase(@DrawableRes icon: Int, padding: Int = AvatarPadding.SMALL) { + avatar.setImageResource(icon) + avatar.background = ResourcesCompat.getDrawable( + context.resources, + R.drawable.round_bgnd, + null + ) + avatar.cropToPadding = true + avatar.setPadding(padding, padding, padding, padding) + } + + // TODO figure out why circle and email use grey background instead of primary + when (type) { + ShareType.GROUP -> { + createAvatarBase(R.drawable.ic_group) + androidViewThemeUtils.colorImageViewBackgroundAndIcon(avatar) + } + ShareType.ROOM -> { + createAvatarBase(R.drawable.first_run_talk, AvatarPadding.LARGE) + androidViewThemeUtils.colorImageViewBackgroundAndIcon(avatar) + } + ShareType.CIRCLE -> { + createAvatarBase(R.drawable.ic_circles) + avatar.background.setColorFilter( + context.resources.getColor(R.color.nc_grey), + PorterDuff.Mode.SRC_IN + ) + avatar.drawable.mutate().setColorFilter( + context.resources.getColor(R.color.icon_on_nc_grey), + PorterDuff.Mode.SRC_IN + ) + } + ShareType.EMAIL -> { + createAvatarBase(R.drawable.ic_email, AvatarPadding.LARGE) + androidViewThemeUtils.colorImageViewBackgroundAndIcon(avatar) + } + else -> Log_OC.d(TAG, "Unknown share type") + } + } + + companion object { + private val TAG = FilesSpecificViewThemeUtils::class.simpleName + + private object AvatarPadding { + @Px + const val SMALL = 4 + + @Px + const val LARGE = 8 + } + } } diff --git a/app/src/main/java/com/owncloud/android/utils/theme/newm3/ViewThemeUtils.kt b/app/src/main/java/com/owncloud/android/utils/theme/newm3/ViewThemeUtils.kt index 497012d5d6..57f67e8f4f 100644 --- a/app/src/main/java/com/owncloud/android/utils/theme/newm3/ViewThemeUtils.kt +++ b/app/src/main/java/com/owncloud/android/utils/theme/newm3/ViewThemeUtils.kt @@ -50,5 +50,5 @@ class ViewThemeUtils @Inject constructor( val dialog = DialogViewThemeUtils(schemes) @JvmField - val files = FilesSpecificViewThemeUtils(schemes) + val files = FilesSpecificViewThemeUtils(schemes, platform) } diff --git a/app/src/test/java/com/owncloud/android/ui/adapter/ShareeListAdapterTest.kt b/app/src/test/java/com/owncloud/android/ui/adapter/ShareeListAdapterTest.kt index dffd5e1169..6ac6af06eb 100644 --- a/app/src/test/java/com/owncloud/android/ui/adapter/ShareeListAdapterTest.kt +++ b/app/src/test/java/com/owncloud/android/ui/adapter/ShareeListAdapterTest.kt @@ -27,8 +27,7 @@ import com.nextcloud.client.account.AnonymousUser import com.owncloud.android.lib.resources.shares.OCShare import com.owncloud.android.lib.resources.shares.ShareType import com.owncloud.android.ui.activity.FileActivity -import com.owncloud.android.utils.theme.ThemeAvatarUtils -import com.owncloud.android.utils.theme.ThemeColorUtils +import com.owncloud.android.utils.theme.newm3.ViewThemeUtils import org.junit.Assert import org.junit.Test import org.mockito.Mock @@ -43,10 +42,7 @@ class ShareeListAdapterTest { private val fileActivity: FileActivity? = null @Mock - private lateinit var themeColorUtils: ThemeColorUtils - - @Mock - private lateinit var themeAvatarUtils: ThemeAvatarUtils + private lateinit var viewThemeUtils: ViewThemeUtils private val orderedShares = listOf( OCShare("/1").apply { @@ -91,8 +87,7 @@ class ShareeListAdapterTest { null, user.accountName, user, - themeColorUtils, - themeAvatarUtils + viewThemeUtils ) sut.sortShares()