diff --git a/app/src/main/java/com/nextcloud/talk/application/NextcloudTalkApplication.kt b/app/src/main/java/com/nextcloud/talk/application/NextcloudTalkApplication.kt index c8e05df8f..5407a12f4 100644 --- a/app/src/main/java/com/nextcloud/talk/application/NextcloudTalkApplication.kt +++ b/app/src/main/java/com/nextcloud/talk/application/NextcloudTalkApplication.kt @@ -61,6 +61,7 @@ import com.nextcloud.talk.dagger.modules.ViewModelModule import com.nextcloud.talk.jobs.AccountRemovalWorker import com.nextcloud.talk.jobs.CapabilitiesWorker import com.nextcloud.talk.jobs.SignalingSettingsWorker +import com.nextcloud.talk.ui.theme.ThemeModule import com.nextcloud.talk.utils.ClosedInterfaceImpl import com.nextcloud.talk.utils.DeviceUtils import com.nextcloud.talk.utils.DisplayUtils @@ -96,7 +97,8 @@ import javax.inject.Singleton ArbitraryStorageModule::class, ViewModelModule::class, RepositoryModule::class, - UtilsModule::class + UtilsModule::class, + ThemeModule::class ] ) @Singleton @@ -120,6 +122,7 @@ class NextcloudTalkApplication : MultiDexApplication(), LifecycleObserver { override fun preKey(database: SQLiteDatabase) { // unused atm } + override fun postKey(database: SQLiteDatabase) { Log.i("TalkApplication", "DB cipher_migrate START") database.rawExecSQL("PRAGMA cipher_migrate;") diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java b/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java index a15883a29..07de2674d 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java +++ b/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java @@ -92,6 +92,8 @@ import com.nextcloud.talk.models.json.statuses.StatusesOverall; import com.nextcloud.talk.repositories.unifiedsearch.UnifiedSearchRepository; import com.nextcloud.talk.ui.dialog.ChooseAccountDialogFragment; import com.nextcloud.talk.ui.dialog.ConversationsListBottomDialog; +import com.nextcloud.talk.ui.theme.ServerTheme; +import com.nextcloud.talk.ui.theme.ViewThemeUtils; import com.nextcloud.talk.users.UserManager; import com.nextcloud.talk.utils.ApiUtils; import com.nextcloud.talk.utils.AttendeePermissionsUtil; @@ -181,6 +183,9 @@ public class ConversationsListController extends BaseController implements Flexi @Inject UnifiedSearchRepository unifiedSearchRepository; + @Inject + ServerTheme serverTheme; + @BindView(R.id.recycler_view) RecyclerView recyclerView; @@ -784,6 +789,7 @@ public class ConversationsListController extends BaseController implements Flexi ContactAddressBookWorker.Companion.run(context); showNewConversationsScreen(); }); + new ViewThemeUtils(serverTheme).themeFAB(floatingActionButton); if (getActivity() != null && getActivity() instanceof MainActivity) { MainActivity activity = (MainActivity) getActivity(); diff --git a/app/src/main/java/com/nextcloud/talk/models/json/capabilities/ThemingCapability.kt b/app/src/main/java/com/nextcloud/talk/models/json/capabilities/ThemingCapability.kt index 6dfdcae7b..bfa86bb61 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/capabilities/ThemingCapability.kt +++ b/app/src/main/java/com/nextcloud/talk/models/json/capabilities/ThemingCapability.kt @@ -43,6 +43,11 @@ data class ThemingCapability( var colorText: String?, @JsonField(name = ["color-element"]) var colorElement: String?, + // TODO check what happens with users with already fetched capabilities + @JsonField(name = ["color-element-bright"]) + var colorElementBright: String?, + @JsonField(name = ["color-element-dark"]) + var colorElementDark: String?, @JsonField(name = ["logo"]) var logo: String?, @JsonField(name = ["background"]) @@ -53,5 +58,5 @@ data class ThemingCapability( var backgroundDefault: Boolean? ) : Parcelable { // This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject' - constructor() : this(null, null, null, null, null, null, null, null, null, null) + constructor() : this(null, null, null, null, null, null, null, null, null, null, null, null) } diff --git a/app/src/main/java/com/nextcloud/talk/ui/theme/ServerTheme.kt b/app/src/main/java/com/nextcloud/talk/ui/theme/ServerTheme.kt new file mode 100644 index 000000000..ad31f29d9 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/ServerTheme.kt @@ -0,0 +1,53 @@ +/* + * 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.nextcloud.talk.ui.theme + +import androidx.annotation.ColorInt + +interface ServerTheme { + @get:ColorInt + val primaryColor: Int + + /** + * Default element color + */ + @get:ColorInt + val colorElement: Int + + /** + * Element color for bright backgrounds + */ + @get:ColorInt + val colorElementBright: Int + + /** + * Element color for dark backgrounds + */ + @get:ColorInt + val colorElementDark: Int + + /** + * Text color for elements + */ + @get:ColorInt + val colorText: Int +} diff --git a/app/src/main/java/com/nextcloud/talk/ui/theme/ServerThemeImpl.kt b/app/src/main/java/com/nextcloud/talk/ui/theme/ServerThemeImpl.kt new file mode 100644 index 000000000..cd4607e22 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/ServerThemeImpl.kt @@ -0,0 +1,45 @@ +/* + * 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.nextcloud.talk.ui.theme + +import android.content.Context +import android.graphics.Color +import com.nextcloud.talk.models.json.capabilities.ThemingCapability + +internal class ServerThemeImpl(context: Context, themingCapability: ThemingCapability) : + ServerTheme { + + override val primaryColor: Int + override val colorElement: Int + override val colorElementBright: Int + override val colorElementDark: Int + override val colorText: Int + + // TODO fallback when some of these are null + init { + primaryColor = Color.parseColor(themingCapability.color!!) + colorElement = Color.parseColor(themingCapability.colorElement!!) + colorElementBright = Color.parseColor(themingCapability.colorElementBright!!) + colorElementDark = Color.parseColor(themingCapability.colorElementDark!!) + colorText = Color.parseColor(themingCapability.colorText!!) + } +} diff --git a/app/src/main/java/com/nextcloud/talk/ui/theme/ServerThemeProvider.kt b/app/src/main/java/com/nextcloud/talk/ui/theme/ServerThemeProvider.kt new file mode 100644 index 000000000..2646e9a79 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/ServerThemeProvider.kt @@ -0,0 +1,31 @@ +/* + * 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.nextcloud.talk.ui.theme + +import com.nextcloud.talk.data.user.model.User +import com.nextcloud.talk.models.json.capabilities.Capabilities + +interface ServerThemeProvider { + fun getServerThemeForUser(user: User): ServerTheme + fun getServerThemeForCurrentUser(): ServerTheme + fun getServerThemeForCapabilities(capabilities: Capabilities): ServerTheme +} diff --git a/app/src/main/java/com/nextcloud/talk/ui/theme/ServerThemeProviderImpl.kt b/app/src/main/java/com/nextcloud/talk/ui/theme/ServerThemeProviderImpl.kt new file mode 100644 index 000000000..f10ad61e4 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/ServerThemeProviderImpl.kt @@ -0,0 +1,46 @@ +/* + * 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.nextcloud.talk.ui.theme + +import android.content.Context +import com.nextcloud.talk.data.user.model.User +import com.nextcloud.talk.models.json.capabilities.Capabilities +import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew + +// TODO cache theme, keyed by server url +internal class ServerThemeProviderImpl( + private val context: Context, + private val userProvider: CurrentUserProviderNew +) : + ServerThemeProvider { + override fun getServerThemeForUser(user: User): ServerTheme { + return getServerThemeForCapabilities(user.capabilities!!) + } + + override fun getServerThemeForCurrentUser(): ServerTheme { + return getServerThemeForUser(userProvider.currentUser.blockingGet()) + } + + override fun getServerThemeForCapabilities(capabilities: Capabilities): ServerTheme { + return ServerThemeImpl(context, capabilities.themingCapability!!) + } +} diff --git a/app/src/main/java/com/nextcloud/talk/ui/theme/ThemeModule.kt b/app/src/main/java/com/nextcloud/talk/ui/theme/ThemeModule.kt new file mode 100644 index 000000000..f1db5ed26 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/ThemeModule.kt @@ -0,0 +1,45 @@ +/* + * 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.nextcloud.talk.ui.theme + +import android.content.Context +import com.nextcloud.talk.dagger.modules.ContextModule +import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew +import com.nextcloud.talk.utils.database.user.UserModule +import dagger.Module +import dagger.Provides +import dagger.Reusable + +@Module(includes = [ContextModule::class, UserModule::class]) +class ThemeModule { + + @Provides + @Reusable + fun provideServerThemeProvider(context: Context, userProvider: CurrentUserProviderNew): ServerThemeProvider { + return ServerThemeProviderImpl(context, userProvider) + } + + @Provides + fun provideCurrentServerTheme(themeProvider: ServerThemeProvider): ServerTheme { + return themeProvider.getServerThemeForCurrentUser() + } +} diff --git a/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt b/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt new file mode 100644 index 000000000..512189085 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt @@ -0,0 +1,48 @@ +/* + * 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.nextcloud.talk.ui.theme + +import android.content.Context +import android.content.res.ColorStateList +import android.content.res.Configuration +import com.google.android.material.floatingactionbutton.FloatingActionButton + +class ViewThemeUtils(val theme: ServerTheme) { + + private fun isDarkMode(context: Context): Boolean = when ( + context.resources.configuration.uiMode and + Configuration.UI_MODE_NIGHT_MASK + ) { + Configuration.UI_MODE_NIGHT_YES -> true + else -> false + } + + private fun getElementColor(context: Context): Int = when { + isDarkMode(context) -> theme.colorElementDark + else -> theme.colorElementBright + } + + fun themeFAB(fab: FloatingActionButton) { + fab.backgroundTintList = ColorStateList.valueOf(getElementColor(fab.context)) + fab.imageTintList = ColorStateList.valueOf(theme.colorText) + } +} diff --git a/app/src/main/res/layout/controller_conversations_rv.xml b/app/src/main/res/layout/controller_conversations_rv.xml index c595b9ed8..06aa71d2b 100644 --- a/app/src/main/res/layout/controller_conversations_rv.xml +++ b/app/src/main/res/layout/controller_conversations_rv.xml @@ -115,11 +115,11 @@ android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:layout_margin="16dp" - android:backgroundTint="@color/colorPrimary" android:contentDescription="@string/nc_new_conversation" app:borderWidth="0dp" app:srcCompat="@drawable/ic_add_white_24px" - app:tint="@color/white" /> + app:tint="@color/white" + app:backgroundTint="@color/colorPrimary"/>