Browse Source

Initial setup for material 3 utils from library

Signed-off-by: Álvaro Brey <alvaro.brey@nextcloud.com>
Álvaro Brey 2 năm trước cách đây
mục cha
commit
7fedeeb797

+ 3 - 0
app/build.gradle

@@ -352,6 +352,9 @@ dependencies {
 
     // upon each update first test: new registration, receive push
     gplayImplementation "com.google.firebase:firebase-messaging:23.0.7"
+
+    // TODO change back to tag before merging
+    implementation 'com.github.nextcloud.android-common:ui:feature/more-theming-files-SNAPSHOT'
 }
 
 configurations.all {

+ 90 - 74
app/src/main/java/com/nextcloud/client/di/ThemeModule.kt

@@ -21,6 +21,7 @@
 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.ThemeBarUtils
 import com.owncloud.android.utils.theme.ThemeButtonUtils
@@ -35,97 +36,112 @@ import com.owncloud.android.utils.theme.ThemeTextInputUtils
 import com.owncloud.android.utils.theme.ThemeTextUtils
 import com.owncloud.android.utils.theme.ThemeToolbarUtils
 import com.owncloud.android.utils.theme.ThemeUtils
+import com.owncloud.android.utils.theme.newm3.MaterialSchemesProvider
+import com.owncloud.android.utils.theme.newm3.MaterialSchemesProviderImpl
+import dagger.Binds
 import dagger.Module
 import dagger.Provides
 import javax.inject.Singleton
 
 @Module
-internal class ThemeModule {
-    @Provides
-    @Singleton
-    fun themeColorUtils(): ThemeColorUtils {
-        return ThemeColorUtils()
-    }
+internal abstract class ThemeModule {
 
-    @Provides
-    @Singleton
-    fun themeFabUtils(themeColorUtils: ThemeColorUtils?, themeDrawableUtils: ThemeDrawableUtils?): ThemeFabUtils {
-        return ThemeFabUtils(themeColorUtils, themeDrawableUtils)
-    }
+    @Binds
+    abstract fun bindMaterialSchemesProvider(provider: MaterialSchemesProviderImpl): MaterialSchemesProvider
 
-    @Provides
-    @Singleton
-    fun themeLayoutUtils(themeColorUtils: ThemeColorUtils?): ThemeLayoutUtils {
-        return ThemeLayoutUtils(themeColorUtils)
-    }
+    companion object {
 
-    @Provides
-    @Singleton
-    fun themeToolbarUtils(
-        themeColorUtils: ThemeColorUtils?,
-        themeDrawableUtils: ThemeDrawableUtils?,
-        themeTextInputUtils: ThemeTextInputUtils?
-    ): ThemeToolbarUtils {
-        return ThemeToolbarUtils(themeColorUtils, themeDrawableUtils, themeTextInputUtils)
-    }
+        @Provides
+        @Singleton
+        fun themeColorUtils(): ThemeColorUtils {
+            return ThemeColorUtils()
+        }
 
-    @Provides
-    @Singleton
-    fun themeDrawableUtils(context: Context?): ThemeDrawableUtils {
-        return ThemeDrawableUtils(context)
-    }
+        @Provides
+        @Singleton
+        fun themeFabUtils(themeColorUtils: ThemeColorUtils?, themeDrawableUtils: ThemeDrawableUtils?): ThemeFabUtils {
+            return ThemeFabUtils(themeColorUtils, themeDrawableUtils)
+        }
 
-    @Provides
-    @Singleton
-    fun themeUtils(): ThemeUtils {
-        return ThemeUtils()
-    }
+        @Provides
+        @Singleton
+        fun themeLayoutUtils(themeColorUtils: ThemeColorUtils?): ThemeLayoutUtils {
+            return ThemeLayoutUtils(themeColorUtils)
+        }
 
-    @Provides
-    @Singleton
-    fun themeMenuUtils(): ThemeMenuUtils {
-        return ThemeMenuUtils()
-    }
+        @Provides
+        @Singleton
+        fun themeToolbarUtils(
+            themeColorUtils: ThemeColorUtils?,
+            themeDrawableUtils: ThemeDrawableUtils?,
+            themeTextInputUtils: ThemeTextInputUtils?
+        ): ThemeToolbarUtils {
+            return ThemeToolbarUtils(themeColorUtils, themeDrawableUtils, themeTextInputUtils)
+        }
 
-    @Provides
-    @Singleton
-    fun themeSnackbarUtils(): ThemeSnackbarUtils {
-        return ThemeSnackbarUtils()
-    }
+        @Provides
+        @Singleton
+        fun themeDrawableUtils(context: Context?): ThemeDrawableUtils {
+            return ThemeDrawableUtils(context)
+        }
 
-    @Provides
-    @Singleton
-    fun themeTextUtils(): ThemeTextUtils {
-        return ThemeTextUtils()
-    }
+        @Provides
+        @Singleton
+        fun themeUtils(): ThemeUtils {
+            return ThemeUtils()
+        }
 
-    @Provides
-    @Singleton
-    fun themeButtonUtils(): ThemeButtonUtils {
-        return ThemeButtonUtils()
-    }
+        @Provides
+        @Singleton
+        fun themeMenuUtils(): ThemeMenuUtils {
+            return ThemeMenuUtils()
+        }
 
-    @Provides
-    @Singleton
-    fun themeBarUtils(): ThemeBarUtils {
-        return ThemeBarUtils()
-    }
+        @Provides
+        @Singleton
+        fun themeSnackbarUtils(): ThemeSnackbarUtils {
+            return ThemeSnackbarUtils()
+        }
 
-    @Provides
-    @Singleton
-    fun themeTextInputUtils(): ThemeTextInputUtils {
-        return ThemeTextInputUtils()
-    }
+        @Provides
+        @Singleton
+        fun themeTextUtils(): ThemeTextUtils {
+            return ThemeTextUtils()
+        }
 
-    @Provides
-    @Singleton
-    fun themeCheckableUtils(): ThemeCheckableUtils {
-        return ThemeCheckableUtils()
-    }
+        @Provides
+        @Singleton
+        fun themeButtonUtils(): ThemeButtonUtils {
+            return ThemeButtonUtils()
+        }
+
+        @Provides
+        @Singleton
+        fun themeBarUtils(): ThemeBarUtils {
+            return ThemeBarUtils()
+        }
+
+        @Provides
+        @Singleton
+        fun themeTextInputUtils(): ThemeTextInputUtils {
+            return ThemeTextInputUtils()
+        }
+
+        @Provides
+        @Singleton
+        fun themeCheckableUtils(): ThemeCheckableUtils {
+            return ThemeCheckableUtils()
+        }
+
+        @Provides
+        @Singleton
+        fun themeAvatarUtils(): ThemeAvatarUtils {
+            return ThemeAvatarUtils()
+        }
 
-    @Provides
-    @Singleton
-    fun themeAvatarUtils(): ThemeAvatarUtils {
-        return ThemeAvatarUtils()
+        @Provides
+        fun provideMaterialSchemes(materialSchemesProvider: MaterialSchemesProvider): MaterialSchemes {
+            return materialSchemesProvider.getMaterialSchemesForCurrentUser()
+        }
     }
 }

+ 7 - 7
app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java

@@ -111,9 +111,9 @@ import com.owncloud.android.utils.FileStorageUtils;
 import com.owncloud.android.utils.MimeTypeUtil;
 import com.owncloud.android.utils.theme.ThemeAvatarUtils;
 import com.owncloud.android.utils.theme.ThemeColorUtils;
-import com.owncloud.android.utils.theme.ThemeFabUtils;
 import com.owncloud.android.utils.theme.ThemeToolbarUtils;
 import com.owncloud.android.utils.theme.ThemeUtils;
+import com.owncloud.android.utils.theme.newm3.ViewThemeUtils;
 
 import org.apache.commons.httpclient.HttpStatus;
 import org.greenrobot.eventbus.EventBus;
@@ -196,12 +196,12 @@ public class OCFileListFragment extends ExtendedListFragment implements
     @Inject ClientFactory clientFactory;
     @Inject Throttler throttler;
     @Inject ThemeColorUtils themeColorUtils;
-    @Inject ThemeFabUtils themeFabUtils;
     @Inject ThemeToolbarUtils themeToolbarUtils;
     @Inject ThemeUtils themeUtils;
     @Inject ThemeAvatarUtils themeAvatarUtils;
     @Inject ArbitraryDataProvider arbitraryDataProvider;
     @Inject BackgroundJobManager backgroundJobManager;
+    @Inject ViewThemeUtils viewThemeUtils;
 
     protected FileFragment.ContainerActivity mContainerActivity;
 
@@ -321,7 +321,7 @@ public class OCFileListFragment extends ExtendedListFragment implements
         mFabMain = requireActivity().findViewById(R.id.fab_main);
 
         if (mFabMain != null) { // is not available in FolderPickerActivity
-            themeFabUtils.colorFloatingActionButton(mFabMain, R.drawable.ic_plus, requireContext());
+            viewThemeUtils.material.themeFAB(mFabMain);
         }
 
         Log_OC.i(TAG, "onCreateView() end");
@@ -472,7 +472,7 @@ public class OCFileListFragment extends ExtendedListFragment implements
         FileActivity activity = (FileActivity) getActivity();
 
         if (mFabMain != null) { // is not available in FolderPickerActivity
-            themeFabUtils.colorFloatingActionButton(mFabMain, R.drawable.ic_plus, requireContext());
+            viewThemeUtils.material.themeFAB(mFabMain);
             mFabMain.setOnClickListener(v -> {
                 final OCFileListBottomSheetDialogFragment dialog =
                     new OCFileListBottomSheetDialogFragment(activity,
@@ -1871,7 +1871,7 @@ public class OCFileListFragment extends ExtendedListFragment implements
             getActivity().runOnUiThread(() -> {
                 if (visible) {
                     mFabMain.show();
-                    themeFabUtils.colorFloatingActionButton(mFabMain, requireContext());
+                    viewThemeUtils.material.themeFAB(mFabMain);
                 } else {
                     mFabMain.hide();
                 }
@@ -1921,10 +1921,10 @@ public class OCFileListFragment extends ExtendedListFragment implements
             getActivity().runOnUiThread(() -> {
                 if (enabled) {
                     mFabMain.setEnabled(true);
-                    themeFabUtils.colorFloatingActionButton(mFabMain, requireContext());
+                    viewThemeUtils.material.themeFAB(mFabMain);
                 } else {
                     mFabMain.setEnabled(false);
-                    themeFabUtils.colorFloatingActionButton(mFabMain, requireContext(), Color.GRAY);
+                    viewThemeUtils.material.themeFAB(mFabMain);
                 }
             });
         }

+ 33 - 0
app/src/main/java/com/owncloud/android/utils/theme/newm3/MaterialSchemesProvider.kt

@@ -0,0 +1,33 @@
+/*
+ * Nextcloud Android client 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 AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or 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 AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+package com.owncloud.android.utils.theme.newm3
+
+import com.nextcloud.android.common.ui.theme.MaterialSchemes
+import com.nextcloud.client.account.User
+import com.owncloud.android.lib.resources.status.OCCapability
+
+interface MaterialSchemesProvider {
+    fun getMaterialSchemesForUser(user: User): MaterialSchemes
+    fun getMaterialSchemesForCapability(capability: OCCapability): MaterialSchemes
+    fun getMaterialSchemesForCurrentUser(): MaterialSchemes
+}

+ 63 - 0
app/src/main/java/com/owncloud/android/utils/theme/newm3/MaterialSchemesProviderImpl.kt

@@ -0,0 +1,63 @@
+/*
+ * Nextcloud Android client 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 AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or 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 AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+package com.owncloud.android.utils.theme.newm3
+
+import android.content.Context
+import com.nextcloud.android.common.ui.theme.MaterialSchemes
+import com.nextcloud.client.account.User
+import com.nextcloud.client.account.UserAccountManager
+import com.owncloud.android.lib.resources.status.OCCapability
+import com.owncloud.android.utils.theme.CapabilityUtils
+import java.util.concurrent.ConcurrentHashMap
+import javax.inject.Inject
+
+// TODO think about assisted inject to pass user instead of fetching it from userAccountManager, thus making it more efficient
+// or cache the user, IDK
+internal class MaterialSchemesProviderImpl @Inject constructor(
+    private val context: Context,
+    private val userAccountManager: UserAccountManager,
+    private val themeFactory: ServerThemeImpl.Factory
+) : MaterialSchemesProvider {
+
+    private val themeCache: MutableMap<String, MaterialSchemes> = ConcurrentHashMap()
+
+    override fun getMaterialSchemesForUser(user: User): MaterialSchemes {
+        val url: String = user.server.uri.toString()
+
+        if (!themeCache.containsKey(url)) {
+            val capability = CapabilityUtils.getCapability(user, context)
+            themeCache[url] = getMaterialSchemesForCapability(capability)
+        }
+
+        return themeCache[url]!!
+    }
+
+    override fun getMaterialSchemesForCapability(capability: OCCapability): MaterialSchemes {
+        val serverTheme = themeFactory.create(capability)
+        return MaterialSchemes.fromServerTheme(serverTheme)
+    }
+
+    override fun getMaterialSchemesForCurrentUser(): MaterialSchemes {
+        return getMaterialSchemesForUser(userAccountManager.user)
+    }
+}

+ 55 - 0
app/src/main/java/com/owncloud/android/utils/theme/newm3/ServerThemeImpl.kt

@@ -0,0 +1,55 @@
+/*
+ * Nextcloud Android client 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 AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or 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 AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+package com.owncloud.android.utils.theme.newm3
+
+import com.nextcloud.android.common.ui.color.ColorUtil
+import com.nextcloud.android.common.ui.theme.ServerTheme
+import com.owncloud.android.R
+import com.owncloud.android.lib.resources.status.OCCapability
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+
+class ServerThemeImpl @AssistedInject constructor(colorUtil: ColorUtil, @Assisted capability: OCCapability) :
+    ServerTheme {
+    override val colorElement: Int
+    override val colorElementBright: Int
+    override val colorElementDark: Int
+    override val colorText: Int
+    override val primaryColor: Int
+
+    init {
+        primaryColor =
+            colorUtil.getNullSafeColorWithFallbackRes(capability.serverColor, R.color.colorPrimary)
+        colorElement = colorUtil.getNullSafeColor(capability.serverElementColor, primaryColor)
+        colorElementBright =
+            colorUtil.getNullSafeColor(capability.serverElementColorBright, primaryColor)
+        colorElementDark = colorUtil.getNullSafeColor(capability.serverElementColorDark, primaryColor)
+        colorText = colorUtil.getTextColor(capability.serverTextColor, primaryColor)
+    }
+
+    @AssistedFactory
+    interface Factory {
+        fun create(capability: OCCapability): ServerThemeImpl
+    }
+}

+ 43 - 0
app/src/main/java/com/owncloud/android/utils/theme/newm3/ViewThemeUtils.kt

@@ -0,0 +1,43 @@
+/*
+ * 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.owncloud.android.utils.theme.newm3
+
+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.nextcloud.android.common.ui.theme.utils.AndroidXViewThemeUtils
+import com.nextcloud.android.common.ui.theme.utils.DialogViewThemeUtils
+import com.nextcloud.android.common.ui.theme.utils.MaterialViewThemeUtils
+import javax.inject.Inject
+
+@Suppress("TooManyFunctions")
+class ViewThemeUtils @Inject constructor(
+    schemes: MaterialSchemes,
+    @JvmField
+    val platform: AndroidViewThemeUtils,
+    @JvmField
+    val material: MaterialViewThemeUtils,
+    @JvmField
+    val androidx: AndroidXViewThemeUtils,
+    @JvmField
+    val dialog: DialogViewThemeUtils
+) : ViewThemeUtilsBase(schemes)

+ 5 - 1
app/src/main/res/layout/files.xml

@@ -18,6 +18,8 @@
   -->
 <androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+
     android:id="@+id/drawer_layout"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
@@ -60,7 +62,9 @@
             android:layout_marginBottom="@dimen/standard_margin"
             android:contentDescription="@string/fab_label"
             android:visibility="gone"
-            app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior" />
+            app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior"
+            app:srcCompat="@drawable/ic_plus"
+            tools:visibility="visible"/>
 
     </androidx.coordinatorlayout.widget.CoordinatorLayout>
 

+ 6 - 0
settings.gradle

@@ -1,3 +1,9 @@
 rootProject.name = 'Nextcloud'
 
 include ':app'
+
+//includeBuild('../android-common') {
+//    dependencySubstitution {
+//        substitute module('com.github.nextcloud.android-common:ui') using project(':ui')
+//    }
+//}