diff --git a/app/build.gradle b/app/build.gradle
index 88b8c510507f..f1c1c232af52 100644
--- a/app/build.gradle
+++ b/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 {
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 26e9c1a07de3..52e8a6930f9f 100644
--- a/app/src/main/java/com/nextcloud/client/di/ThemeModule.kt
+++ b/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()
+ }
}
}
diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java
index a188cddbfd5f..250c34009e21 100644
--- a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java
+++ b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java
@@ -111,9 +111,9 @@
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 View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
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 void registerFabListener() {
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 void setFabVisible(final boolean visible) {
getActivity().runOnUiThread(() -> {
if (visible) {
mFabMain.show();
- themeFabUtils.colorFloatingActionButton(mFabMain, requireContext());
+ viewThemeUtils.material.themeFAB(mFabMain);
} else {
mFabMain.hide();
}
@@ -1921,10 +1921,10 @@ public void setFabEnabled(final boolean enabled) {
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);
}
});
}
diff --git a/app/src/main/java/com/owncloud/android/utils/theme/newm3/MaterialSchemesProvider.kt b/app/src/main/java/com/owncloud/android/utils/theme/newm3/MaterialSchemesProvider.kt
new file mode 100644
index 000000000000..9237407f1abd
--- /dev/null
+++ b/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 .
+ *
+ */
+
+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
+}
diff --git a/app/src/main/java/com/owncloud/android/utils/theme/newm3/MaterialSchemesProviderImpl.kt b/app/src/main/java/com/owncloud/android/utils/theme/newm3/MaterialSchemesProviderImpl.kt
new file mode 100644
index 000000000000..a6365a87cd25
--- /dev/null
+++ b/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 .
+ *
+ */
+
+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 = 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)
+ }
+}
diff --git a/app/src/main/java/com/owncloud/android/utils/theme/newm3/ServerThemeImpl.kt b/app/src/main/java/com/owncloud/android/utils/theme/newm3/ServerThemeImpl.kt
new file mode 100644
index 000000000000..d87e07c57450
--- /dev/null
+++ b/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 .
+ *
+ */
+
+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
+ }
+}
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
new file mode 100644
index 000000000000..2b29b108d770
--- /dev/null
+++ b/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 .
+ */
+
+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)
diff --git a/app/src/main/res/layout/files.xml b/app/src/main/res/layout/files.xml
index 2e58f45e3ede..2dff26476047 100644
--- a/app/src/main/res/layout/files.xml
+++ b/app/src/main/res/layout/files.xml
@@ -18,6 +18,8 @@
-->
+ app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior"
+ app:srcCompat="@drawable/ic_plus"
+ tools:visibility="visible"/>
diff --git a/settings.gradle b/settings.gradle
index 40b70bd250d3..bb095760ccf5 100644
--- a/settings.gradle
+++ b/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')
+// }
+//}