Initial setup for material 3 utils from library

Signed-off-by: Álvaro Brey <alvaro.brey@nextcloud.com>
This commit is contained in:
Álvaro Brey 2022-09-06 18:14:36 +02:00
parent 0308ace17f
commit 7fedeeb797
No known key found for this signature in database
GPG Key ID: 2585783189A62105
9 changed files with 305 additions and 82 deletions

View File

@ -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 {

View File

@ -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 themeAvatarUtils(): ThemeAvatarUtils {
return ThemeAvatarUtils()
@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
fun provideMaterialSchemes(materialSchemesProvider: MaterialSchemesProvider): MaterialSchemes {
return materialSchemesProvider.getMaterialSchemesForCurrentUser()
}
}
}

View File

@ -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);
}
});
}

View File

@ -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
}

View File

@ -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)
}
}

View File

@ -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
}
}

View File

@ -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)

View File

@ -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>

View File

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