From 9bbeb9b420d4db3a24daea78f203a5bf79db0b7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Thu, 14 Jul 2022 17:46:11 +0200 Subject: [PATCH 01/58] Base framework for server theming MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Includes PoC with ConversationListController's FAB Signed-off-by: Álvaro Brey --- .../application/NextcloudTalkApplication.kt | 5 +- .../ConversationsListController.java | 6 +++ .../json/capabilities/ThemingCapability.kt | 7 ++- .../nextcloud/talk/ui/theme/ServerTheme.kt | 53 +++++++++++++++++++ .../talk/ui/theme/ServerThemeImpl.kt | 45 ++++++++++++++++ .../talk/ui/theme/ServerThemeProvider.kt | 31 +++++++++++ .../talk/ui/theme/ServerThemeProviderImpl.kt | 46 ++++++++++++++++ .../nextcloud/talk/ui/theme/ThemeModule.kt | 45 ++++++++++++++++ .../nextcloud/talk/ui/theme/ViewThemeUtils.kt | 48 +++++++++++++++++ .../layout/controller_conversations_rv.xml | 4 +- 10 files changed, 286 insertions(+), 4 deletions(-) create mode 100644 app/src/main/java/com/nextcloud/talk/ui/theme/ServerTheme.kt create mode 100644 app/src/main/java/com/nextcloud/talk/ui/theme/ServerThemeImpl.kt create mode 100644 app/src/main/java/com/nextcloud/talk/ui/theme/ServerThemeProvider.kt create mode 100644 app/src/main/java/com/nextcloud/talk/ui/theme/ServerThemeProviderImpl.kt create mode 100644 app/src/main/java/com/nextcloud/talk/ui/theme/ThemeModule.kt create mode 100644 app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt 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"/> Date: Fri, 15 Jul 2022 14:24:13 +0200 Subject: [PATCH 02/58] Automatically update current user with room observable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Brey --- .../ConversationsListController.java | 1 + .../com/nextcloud/talk/data/user/UsersDao.kt | 5 +++++ .../talk/data/user/UsersRepository.kt | 2 ++ .../talk/data/user/UsersRepositoryImpl.kt | 5 +++++ .../talk/ui/theme/ServerThemeProvider.kt | 2 +- .../talk/ui/theme/ServerThemeProviderImpl.kt | 22 ++++++++++++++++++- .../com/nextcloud/talk/users/UserManager.kt | 8 ++++++- .../database/user/CurrentUserProviderNew.kt | 2 ++ 8 files changed, 44 insertions(+), 3 deletions(-) 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 07de2674d..c57041ca7 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java +++ b/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java @@ -93,6 +93,7 @@ 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.ServerThemeProvider; import com.nextcloud.talk.ui.theme.ViewThemeUtils; import com.nextcloud.talk.users.UserManager; import com.nextcloud.talk.utils.ApiUtils; diff --git a/app/src/main/java/com/nextcloud/talk/data/user/UsersDao.kt b/app/src/main/java/com/nextcloud/talk/data/user/UsersDao.kt index 16e72e20c..dc0cd86cc 100644 --- a/app/src/main/java/com/nextcloud/talk/data/user/UsersDao.kt +++ b/app/src/main/java/com/nextcloud/talk/data/user/UsersDao.kt @@ -32,6 +32,7 @@ import androidx.room.Transaction import androidx.room.Update import com.nextcloud.talk.data.user.model.UserEntity import io.reactivex.Maybe +import io.reactivex.Observable import io.reactivex.Single @Dao @@ -41,6 +42,10 @@ abstract class UsersDao { @Query("SELECT * FROM User where current = 1") abstract fun getActiveUser(): Maybe + // get active user + @Query("SELECT * FROM User where current = 1") + abstract fun getActiveUserObservable(): Observable + @Query("SELECT * FROM User where current = 1") abstract fun getActiveUserSynchronously(): UserEntity? diff --git a/app/src/main/java/com/nextcloud/talk/data/user/UsersRepository.kt b/app/src/main/java/com/nextcloud/talk/data/user/UsersRepository.kt index 624d8df2b..4d15a97b8 100644 --- a/app/src/main/java/com/nextcloud/talk/data/user/UsersRepository.kt +++ b/app/src/main/java/com/nextcloud/talk/data/user/UsersRepository.kt @@ -24,11 +24,13 @@ package com.nextcloud.talk.data.user import com.nextcloud.talk.data.user.model.User import io.reactivex.Maybe +import io.reactivex.Observable import io.reactivex.Single @Suppress("TooManyFunctions") interface UsersRepository { fun getActiveUser(): Maybe + fun getActiveUserObservable(): Observable fun getUsers(): Single> fun getUserWithId(id: Long): Maybe fun getUserWithIdNotScheduledForDeletion(id: Long): Maybe diff --git a/app/src/main/java/com/nextcloud/talk/data/user/UsersRepositoryImpl.kt b/app/src/main/java/com/nextcloud/talk/data/user/UsersRepositoryImpl.kt index 5dbda623c..d88d2147a 100644 --- a/app/src/main/java/com/nextcloud/talk/data/user/UsersRepositoryImpl.kt +++ b/app/src/main/java/com/nextcloud/talk/data/user/UsersRepositoryImpl.kt @@ -24,6 +24,7 @@ package com.nextcloud.talk.data.user import com.nextcloud.talk.data.user.model.User import io.reactivex.Maybe +import io.reactivex.Observable import io.reactivex.Single @Suppress("TooManyFunctions") @@ -33,6 +34,10 @@ class UsersRepositoryImpl(private val usersDao: UsersDao) : UsersRepository { return usersDao.getActiveUser().map { UserMapper.toModel(it) } } + override fun getActiveUserObservable(): Observable { + return usersDao.getActiveUserObservable().map { UserMapper.toModel(it) } + } + override fun getUsers(): Single> { return usersDao.getUsers().map { UserMapper.toModel(it) } } 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 index 2646e9a79..1d299ca7b 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/theme/ServerThemeProvider.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/ServerThemeProvider.kt @@ -26,6 +26,6 @@ import com.nextcloud.talk.models.json.capabilities.Capabilities interface ServerThemeProvider { fun getServerThemeForUser(user: User): ServerTheme - fun getServerThemeForCurrentUser(): ServerTheme fun getServerThemeForCapabilities(capabilities: Capabilities): ServerTheme + fun getServerThemeForCurrentUser(): 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 index f10ad61e4..949288ce2 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/theme/ServerThemeProviderImpl.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/ServerThemeProviderImpl.kt @@ -21,6 +21,7 @@ package com.nextcloud.talk.ui.theme +import android.annotation.SuppressLint import android.content.Context import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.models.json.capabilities.Capabilities @@ -32,12 +33,31 @@ internal class ServerThemeProviderImpl( private val userProvider: CurrentUserProviderNew ) : ServerThemeProvider { + // TODO move this logic to currentUserProvider or something + private var _currentUser: User? = null + private val currentUser: User + @SuppressLint("CheckResult") + get() { + return when (_currentUser) { + null -> { + // immediately get a result synchronously + _currentUser = userProvider.currentUser.blockingGet() + // start observable for auto-updates + userProvider.currentUserObservable.subscribe { _currentUser = it } + _currentUser!! + } + else -> { + _currentUser!! + } + } + } + override fun getServerThemeForUser(user: User): ServerTheme { return getServerThemeForCapabilities(user.capabilities!!) } override fun getServerThemeForCurrentUser(): ServerTheme { - return getServerThemeForUser(userProvider.currentUser.blockingGet()) + return getServerThemeForUser(currentUser) } override fun getServerThemeForCapabilities(capabilities: Capabilities): ServerTheme { diff --git a/app/src/main/java/com/nextcloud/talk/users/UserManager.kt b/app/src/main/java/com/nextcloud/talk/users/UserManager.kt index 06f70b4ee..485022992 100644 --- a/app/src/main/java/com/nextcloud/talk/users/UserManager.kt +++ b/app/src/main/java/com/nextcloud/talk/users/UserManager.kt @@ -30,6 +30,7 @@ import com.nextcloud.talk.models.json.capabilities.Capabilities import com.nextcloud.talk.models.json.push.PushConfigurationState import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew import io.reactivex.Maybe +import io.reactivex.Observable import io.reactivex.Single @Suppress("TooManyFunctions") @@ -45,7 +46,12 @@ class UserManager internal constructor(private val userRepository: UsersReposito return userRepository.getActiveUser() } - fun deleteUser(internalId: Long): Int { + override val currentUserObservable: Observable + get() { + return userRepository.getActiveUserObservable() + } + + fun deleteUser(internalId: Long) { return userRepository.deleteUser(userRepository.getUserWithId(internalId).blockingGet()) } diff --git a/app/src/main/java/com/nextcloud/talk/utils/database/user/CurrentUserProviderNew.kt b/app/src/main/java/com/nextcloud/talk/utils/database/user/CurrentUserProviderNew.kt index b1b457ce5..cf92b9925 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/database/user/CurrentUserProviderNew.kt +++ b/app/src/main/java/com/nextcloud/talk/utils/database/user/CurrentUserProviderNew.kt @@ -22,7 +22,9 @@ package com.nextcloud.talk.utils.database.user import com.nextcloud.talk.data.user.model.User import io.reactivex.Maybe +import io.reactivex.Observable interface CurrentUserProviderNew { val currentUser: Maybe + val currentUserObservable: Observable } From 5ec18780ff009bd5daa5c9db295cdea78c02ef8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Thu, 21 Jul 2022 13:45:07 +0200 Subject: [PATCH 03/58] Color list headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Brey --- .../adapters/items/GenericTextHeaderItem.java | 6 +++++- .../talk/adapters/items/MessageResultItem.kt | 6 ++++-- .../adapters/items/MessagesTextHeaderItem.kt | 4 +++- .../talk/controllers/ContactsController.kt | 6 +++++- .../ConversationsListController.java | 13 ++++++------- .../messagesearch/MessageSearchActivity.kt | 10 ++++++++-- .../talk/ui/theme/ServerThemeProviderImpl.kt | 3 ++- .../nextcloud/talk/ui/theme/ThemeModule.kt | 19 +++++++++---------- .../nextcloud/talk/ui/theme/ViewThemeUtils.kt | 8 +++++++- 9 files changed, 49 insertions(+), 26 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/adapters/items/GenericTextHeaderItem.java b/app/src/main/java/com/nextcloud/talk/adapters/items/GenericTextHeaderItem.java index c3e63df75..017a0e926 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/items/GenericTextHeaderItem.java +++ b/app/src/main/java/com/nextcloud/talk/adapters/items/GenericTextHeaderItem.java @@ -27,6 +27,7 @@ import android.view.View; import com.nextcloud.talk.R; import com.nextcloud.talk.databinding.RvItemTitleHeaderBinding; +import com.nextcloud.talk.ui.theme.ViewThemeUtils; import java.util.List; @@ -39,12 +40,14 @@ public class GenericTextHeaderItem extends AbstractHeaderItem(), IFilterable, @@ -104,7 +106,7 @@ data class MessageResultItem constructor( const val VIEW_TYPE: Int = R.layout.rv_item_search_message } - override fun getHeader(): GenericTextHeaderItem = MessagesTextHeaderItem(context) + override fun getHeader(): GenericTextHeaderItem = MessagesTextHeaderItem(context, viewThemeUtils) .apply { isHidden = showHeader // FlexibleAdapter needs this hack for some reason } diff --git a/app/src/main/java/com/nextcloud/talk/adapters/items/MessagesTextHeaderItem.kt b/app/src/main/java/com/nextcloud/talk/adapters/items/MessagesTextHeaderItem.kt index 24ddeabc5..3ade534b6 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/items/MessagesTextHeaderItem.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/items/MessagesTextHeaderItem.kt @@ -23,8 +23,10 @@ package com.nextcloud.talk.adapters.items import android.content.Context import com.nextcloud.talk.R +import com.nextcloud.talk.ui.theme.ViewThemeUtils -class MessagesTextHeaderItem(context: Context) : GenericTextHeaderItem(context.getString(R.string.messages)) { +class MessagesTextHeaderItem(context: Context, viewThemeUtils: ViewThemeUtils) : + GenericTextHeaderItem(context.getString(R.string.messages), viewThemeUtils) { companion object { /** * "Random" value, just has to be different than other view types diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ContactsController.kt b/app/src/main/java/com/nextcloud/talk/controllers/ContactsController.kt index 8aea30693..2868f430d 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ContactsController.kt +++ b/app/src/main/java/com/nextcloud/talk/controllers/ContactsController.kt @@ -65,6 +65,7 @@ import com.nextcloud.talk.models.json.converters.EnumActorTypeConverter import com.nextcloud.talk.models.json.participants.Participant import com.nextcloud.talk.ui.dialog.ContactsBottomDialog import com.nextcloud.talk.users.UserManager +import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.ConductorRemapping import com.nextcloud.talk.utils.bundle.BundleKeys @@ -103,6 +104,9 @@ class ContactsController(args: Bundle) : @Inject lateinit var ncApi: NcApi + @Inject + lateinit var viewThemeUtils: ViewThemeUtils + private var credentials: String? = null private var currentUser: User? = null private var contactsQueryDisposable: Disposable? = null @@ -492,7 +496,7 @@ class ContactsController(args: Bundle) : val headerTitle = getHeaderTitle(participant) var genericTextHeaderItem: GenericTextHeaderItem if (!userHeaderItems.containsKey(headerTitle)) { - genericTextHeaderItem = GenericTextHeaderItem(headerTitle) + genericTextHeaderItem = GenericTextHeaderItem(headerTitle, viewThemeUtils) userHeaderItems.put(headerTitle, genericTextHeaderItem) } val newContactItem = ContactItem( 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 c57041ca7..edc5c8d66 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java +++ b/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java @@ -92,8 +92,6 @@ 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.ServerThemeProvider; import com.nextcloud.talk.ui.theme.ViewThemeUtils; import com.nextcloud.talk.users.UserManager; import com.nextcloud.talk.utils.ApiUtils; @@ -185,7 +183,7 @@ public class ConversationsListController extends BaseController implements Flexi UnifiedSearchRepository unifiedSearchRepository; @Inject - ServerTheme serverTheme; + ViewThemeUtils viewThemeUtils; @BindView(R.id.recycler_view) RecyclerView recyclerView; @@ -624,7 +622,7 @@ public class ConversationsListController extends BaseController implements Flexi GenericTextHeaderItem genericTextHeaderItem; if (!callHeaderItems.containsKey(headerTitle)) { - genericTextHeaderItem = new GenericTextHeaderItem(headerTitle); + genericTextHeaderItem = new GenericTextHeaderItem(headerTitle, viewThemeUtils); callHeaderItems.put(headerTitle, genericTextHeaderItem); } @@ -705,7 +703,7 @@ public class ConversationsListController extends BaseController implements Flexi GenericTextHeaderItem genericTextHeaderItem; if (!callHeaderItems.containsKey(headerTitle)) { - genericTextHeaderItem = new GenericTextHeaderItem(headerTitle); + genericTextHeaderItem = new GenericTextHeaderItem(headerTitle, viewThemeUtils); callHeaderItems.put(headerTitle, genericTextHeaderItem); } @@ -790,7 +788,8 @@ public class ConversationsListController extends BaseController implements Flexi ContactAddressBookWorker.Companion.run(context); showNewConversationsScreen(); }); - new ViewThemeUtils(serverTheme).themeFAB(floatingActionButton); + + viewThemeUtils.themeFAB(floatingActionButton); if (getActivity() != null && getActivity() instanceof MainActivity) { MainActivity activity = (MainActivity) getActivity(); @@ -1416,7 +1415,7 @@ public class ConversationsListController extends BaseController implements Flexi List adapterItems = new ArrayList<>(entries.size() + 1); for (int i = 0; i < entries.size(); i++) { final boolean showHeader = i == 0; - adapterItems.add(new MessageResultItem(context, currentUser, entries.get(i), showHeader)); + adapterItems.add(new MessageResultItem(context, currentUser, entries.get(i), showHeader, viewThemeUtils)); } if (results.getHasMore()) { adapterItems.add(LoadMoreResultsItem.INSTANCE); diff --git a/app/src/main/java/com/nextcloud/talk/messagesearch/MessageSearchActivity.kt b/app/src/main/java/com/nextcloud/talk/messagesearch/MessageSearchActivity.kt index 7c2883258..a9d553b25 100644 --- a/app/src/main/java/com/nextcloud/talk/messagesearch/MessageSearchActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/messagesearch/MessageSearchActivity.kt @@ -41,6 +41,7 @@ import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.controllers.ConversationsListController import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.databinding.ActivityMessageSearchBinding +import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.utils.DisplayUtils import com.nextcloud.talk.utils.bundle.BundleKeys import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew @@ -64,6 +65,9 @@ class MessageSearchActivity : BaseActivity() { @Inject lateinit var userProvider: CurrentUserProviderNew + @Inject + lateinit var viewThemeUtils: ViewThemeUtils + private lateinit var binding: ActivityMessageSearchBinding private lateinit var searchView: SearchView @@ -105,7 +109,9 @@ class MessageSearchActivity : BaseActivity() { DisplayUtils.applyColorToStatusBar( this, ResourcesCompat.getColor( - resources, R.color.appbar, null + resources, + R.color.appbar, + null ) ) DisplayUtils.applyColorToNavigationBar( @@ -154,7 +160,7 @@ class MessageSearchActivity : BaseActivity() { emptyList() } val newItems = - state.results.map { MessageResultItem(this, user, it) } + loadMoreItems + state.results.map { MessageResultItem(this, user, it, false, viewThemeUtils) } + loadMoreItems if (adapter != null) { adapter!!.updateDataSet(newItems) 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 index 949288ce2..b4a4df43f 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/theme/ServerThemeProviderImpl.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/ServerThemeProviderImpl.kt @@ -26,9 +26,10 @@ 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 +import javax.inject.Inject // TODO cache theme, keyed by server url -internal class ServerThemeProviderImpl( +internal class ServerThemeProviderImpl @Inject constructor( private val context: Context, private val userProvider: CurrentUserProviderNew ) : 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 index f1db5ed26..54410e609 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/theme/ThemeModule.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/ThemeModule.kt @@ -21,25 +21,24 @@ 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.Binds import dagger.Module import dagger.Provides import dagger.Reusable @Module(includes = [ContextModule::class, UserModule::class]) -class ThemeModule { +internal abstract class ThemeModule { - @Provides + @Binds @Reusable - fun provideServerThemeProvider(context: Context, userProvider: CurrentUserProviderNew): ServerThemeProvider { - return ServerThemeProviderImpl(context, userProvider) - } + abstract fun bindServerThemeProvider(provider: ServerThemeProviderImpl): ServerThemeProvider - @Provides - fun provideCurrentServerTheme(themeProvider: ServerThemeProvider): ServerTheme { - return themeProvider.getServerThemeForCurrentUser() + companion object { + @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 index 512189085..13361a9f4 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt @@ -24,9 +24,11 @@ package com.nextcloud.talk.ui.theme import android.content.Context import android.content.res.ColorStateList import android.content.res.Configuration +import android.widget.TextView import com.google.android.material.floatingactionbutton.FloatingActionButton +import javax.inject.Inject -class ViewThemeUtils(val theme: ServerTheme) { +class ViewThemeUtils @Inject constructor(val theme: ServerTheme) { private fun isDarkMode(context: Context): Boolean = when ( context.resources.configuration.uiMode and @@ -45,4 +47,8 @@ class ViewThemeUtils(val theme: ServerTheme) { fab.backgroundTintList = ColorStateList.valueOf(getElementColor(fab.context)) fab.imageTintList = ColorStateList.valueOf(theme.colorText) } + + fun colorTextView(titleTextView: TextView) { + titleTextView.setTextColor(getElementColor(titleTextView.context)) + } } From 54d1ac9de748352cc7ad9317d3f9c7fc20172846 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Thu, 21 Jul 2022 13:56:12 +0200 Subject: [PATCH 04/58] ContactsController: tint "public conversation" button MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Brey --- .../talk/controllers/ContactsController.kt | 7 +------ .../com/nextcloud/talk/ui/theme/ViewThemeUtils.kt | 13 +++++++++++-- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ContactsController.kt b/app/src/main/java/com/nextcloud/talk/controllers/ContactsController.kt index 2868f430d..523d09a73 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ContactsController.kt +++ b/app/src/main/java/com/nextcloud/talk/controllers/ContactsController.kt @@ -631,12 +631,7 @@ class ContactsController(args: Bundle) : ResourcesCompat.getColor(resources!!, R.color.colorBackgroundDarker, null), PorterDuff.Mode.SRC_IN ) - binding.conversationPrivacyToggle.publicCallLink - .background - .setColorFilter( - ResourcesCompat.getColor(resources!!, R.color.colorPrimary, null), - PorterDuff.Mode.SRC_IN - ) + viewThemeUtils.colorImageViewButton(binding.conversationPrivacyToggle.publicCallLink) disengageProgressBar() } 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 index 13361a9f4..2dfc3c41f 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt @@ -24,6 +24,7 @@ package com.nextcloud.talk.ui.theme import android.content.Context import android.content.res.ColorStateList import android.content.res.Configuration +import android.widget.ImageView import android.widget.TextView import com.google.android.material.floatingactionbutton.FloatingActionButton import javax.inject.Inject @@ -48,7 +49,15 @@ class ViewThemeUtils @Inject constructor(val theme: ServerTheme) { fab.imageTintList = ColorStateList.valueOf(theme.colorText) } - fun colorTextView(titleTextView: TextView) { - titleTextView.setTextColor(getElementColor(titleTextView.context)) + fun colorTextView(textView: TextView) { + textView.setTextColor(getElementColor(textView.context)) + } + + /** + * Colors the background as element color and the foreground as text color. + */ + fun colorImageViewButton(imageView: ImageView) { + imageView.imageTintList = ColorStateList.valueOf(theme.colorText) + imageView.backgroundTintList = ColorStateList.valueOf(getElementColor(imageView.context)) } } From 4af491c7df7948713dff16fd4922bc3d410faad0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Thu, 21 Jul 2022 15:00:09 +0200 Subject: [PATCH 05/58] Color search highlights MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Brey --- .../talk/adapters/items/ConversationItem.java | 19 ++++++++----------- .../talk/adapters/items/MessageResultItem.kt | 3 +-- .../ConversationsListController.java | 9 ++++++--- .../nextcloud/talk/ui/theme/ViewThemeUtils.kt | 5 ++++- 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/adapters/items/ConversationItem.java b/app/src/main/java/com/nextcloud/talk/adapters/items/ConversationItem.java index 7f4b69070..d6c7ff7ad 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/items/ConversationItem.java +++ b/app/src/main/java/com/nextcloud/talk/adapters/items/ConversationItem.java @@ -46,6 +46,7 @@ import com.nextcloud.talk.models.json.chat.ChatMessage; import com.nextcloud.talk.models.json.conversations.Conversation; import com.nextcloud.talk.models.json.status.Status; import com.nextcloud.talk.ui.StatusDrawable; +import com.nextcloud.talk.ui.theme.ViewThemeUtils; import com.nextcloud.talk.utils.ApiUtils; import com.nextcloud.talk.utils.DisplayUtils; import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew; @@ -76,22 +77,22 @@ public class ConversationItem extends AbstractFlexibleItem false } - private fun getElementColor(context: Context): Int = when { + /** + * Color for painting elements + */ + fun getElementColor(context: Context): Int = when { isDarkMode(context) -> theme.colorElementDark else -> theme.colorElementBright } From d60fdd03c5c4940b0845e67be2b653354202f42c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Thu, 21 Jul 2022 15:53:05 +0200 Subject: [PATCH 06/58] Color SetStatusDialog and ChooseAccountDialog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Brey --- .../adapters/items/GenericTextHeaderItem.java | 2 +- .../dialog/ChooseAccountDialogFragment.java | 7 +++ .../talk/ui/dialog/SetStatusDialogFragment.kt | 56 +++++++++-------- .../talk/ui/theme/ServerThemeProviderImpl.kt | 1 + .../nextcloud/talk/ui/theme/ViewThemeUtils.kt | 62 +++++++++++++++++-- .../main/res/layout/current_account_item.xml | 1 + .../main/res/layout/dialog_choose_account.xml | 1 + 7 files changed, 96 insertions(+), 34 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/adapters/items/GenericTextHeaderItem.java b/app/src/main/java/com/nextcloud/talk/adapters/items/GenericTextHeaderItem.java index 017a0e926..657a605b7 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/items/GenericTextHeaderItem.java +++ b/app/src/main/java/com/nextcloud/talk/adapters/items/GenericTextHeaderItem.java @@ -74,7 +74,7 @@ public class GenericTextHeaderItem extends AbstractHeaderItem { - binding.onlineStatus.setCardBackgroundColor(resources.getColor(R.color.colorPrimary)) - binding.onlineHeadline.setTextColor(resources.getColor(R.color.high_emphasis_text_dark_background)) + val views: Triple = when (statusType) { + StatusType.ONLINE -> Triple(binding.onlineStatus, binding.onlineHeadline, binding.onlineIcon) + StatusType.AWAY -> Triple(binding.awayStatus, binding.awayHeadline, binding.awayIcon) + StatusType.DND -> Triple(binding.dndStatus, binding.dndHeadline, binding.dndIcon) + StatusType.INVISIBLE -> Triple(binding.invisibleStatus, binding.invisibleHeadline, binding.invisibleIcon) + else -> { + Log.d(TAG, "unknown status") + return } - StatusType.AWAY -> { - binding.awayStatus.setCardBackgroundColor(resources.getColor(R.color.colorPrimary)) - binding.awayHeadline.setTextColor(resources.getColor(R.color.high_emphasis_text_dark_background)) - } - StatusType.DND -> { - binding.dndStatus.setCardBackgroundColor(resources.getColor(R.color.colorPrimary)) - binding.dndHeadline.setTextColor(resources.getColor(R.color.high_emphasis_text_dark_background)) - } - StatusType.INVISIBLE -> { - binding.invisibleStatus.setCardBackgroundColor(resources.getColor(R.color.colorPrimary)) - binding.invisibleHeadline.setTextColor(resources.getColor(R.color.high_emphasis_text_dark_background)) - } - else -> Log.d(TAG, "unknown status") } + viewThemeUtils.colorCardViewBackground(views.first) + viewThemeUtils.colorTextViewText(views.second) + viewThemeUtils.colorImageViewText(views.third) } private fun clearTopStatus() { @@ -433,11 +432,15 @@ class SetStatusDialogFragment : binding.awayHeadline.setTextColor(resources.getColor(R.color.high_emphasis_text)) binding.dndHeadline.setTextColor(resources.getColor(R.color.high_emphasis_text)) binding.invisibleHeadline.setTextColor(resources.getColor(R.color.high_emphasis_text)) + + binding.onlineIcon.imageTintList = null + binding.awayIcon.imageTintList = null + binding.dndIcon.imageTintList = null + binding.invisibleIcon.imageTintList = null } } private fun setStatusMessage() { - val inputText = binding.customStatusInput.text.toString().ifEmpty { "" } // The endpoint '/message/custom' expects a valid emoji as string or null val statusIcon = binding.emoji.text.toString().ifEmpty { null } @@ -446,7 +449,6 @@ class SetStatusDialogFragment : selectedPredefinedStatus!!.message != inputText || selectedPredefinedStatus!!.icon != binding.emoji.text.toString() ) { - ncApi.setCustomStatusMessage( credentials, ApiUtils.getUrlForSetCustomStatus(currentUser?.baseUrl), @@ -476,12 +478,13 @@ class SetStatusDialogFragment : } }) } else { - val clearAt = clearAtToUnixTime(selectedPredefinedStatus!!.clearAt) ncApi.setPredefinedStatusMessage( - credentials, ApiUtils.getUrlForSetPredefinedStatus(currentUser?.baseUrl), - selectedPredefinedStatus!!.id, if (clearAt == -1L) null else clearAt + credentials, + ApiUtils.getUrlForSetPredefinedStatus(currentUser?.baseUrl), + selectedPredefinedStatus!!.id, + if (clearAt == -1L) null else clearAt ) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread())?.subscribe(object : Observer { @@ -506,7 +509,6 @@ class SetStatusDialogFragment : } override fun onClick(predefinedStatus: PredefinedStatus) { - selectedPredefinedStatus = predefinedStatus clearAt = clearAtToUnixTime(predefinedStatus.clearAt) 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 index b4a4df43f..87cdcee6b 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/theme/ServerThemeProviderImpl.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/ServerThemeProviderImpl.kt @@ -29,6 +29,7 @@ import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew import javax.inject.Inject // TODO cache theme, keyed by server url +// TODO reload UI when account changes internal class ServerThemeProviderImpl @Inject constructor( private val context: Context, private val userProvider: CurrentUserProviderNew 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 index 7dcb23c6b..99373ba76 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt @@ -24,8 +24,11 @@ package com.nextcloud.talk.ui.theme import android.content.Context import android.content.res.ColorStateList import android.content.res.Configuration +import android.view.View import android.widget.ImageView import android.widget.TextView +import com.google.android.material.button.MaterialButton +import com.google.android.material.card.MaterialCardView import com.google.android.material.floatingactionbutton.FloatingActionButton import javax.inject.Inject @@ -47,20 +50,67 @@ class ViewThemeUtils @Inject constructor(val theme: ServerTheme) { else -> theme.colorElementBright } - fun themeFAB(fab: FloatingActionButton) { - fab.backgroundTintList = ColorStateList.valueOf(getElementColor(fab.context)) - fab.imageTintList = ColorStateList.valueOf(theme.colorText) + private fun withElementColor(view: View, block: (Int) -> Unit) { + block(getElementColor(view.context)) } - fun colorTextView(textView: TextView) { - textView.setTextColor(getElementColor(textView.context)) + fun themeFAB(fab: FloatingActionButton) { + withElementColor(fab) { color -> + fab.backgroundTintList = ColorStateList.valueOf(color) + fab.imageTintList = ColorStateList.valueOf(theme.colorText) + } + } + + fun colorTextViewElement(textView: TextView) { + withElementColor(textView) { color -> + textView.setTextColor(color) + } + } + + fun colorTextViewText(textView: TextView) { + textView.setTextColor(theme.colorText) } /** * Colors the background as element color and the foreground as text color. */ fun colorImageViewButton(imageView: ImageView) { + withElementColor(imageView) { color -> + imageView.imageTintList = ColorStateList.valueOf(theme.colorText) + imageView.backgroundTintList = ColorStateList.valueOf(color) + } + } + + /** + * Tints the image with element color + */ + fun colorImageView(imageView: ImageView) { + withElementColor(imageView) { color -> + imageView.imageTintList = ColorStateList.valueOf(color) + } + } + + /** + * Tints the image with text color + */ + fun colorImageViewText(imageView: ImageView) { imageView.imageTintList = ColorStateList.valueOf(theme.colorText) - imageView.backgroundTintList = ColorStateList.valueOf(getElementColor(imageView.context)) + } + + fun colorMaterialButtonText(button: MaterialButton) { + colorTextViewElement(button) + } + + fun colorMaterialButtonBackground(button: MaterialButton) { + withElementColor(button) { color -> + button.setBackgroundColor(color) + button.setTextColor(theme.colorText) + } + } + + fun colorCardViewBackground(card: MaterialCardView) { + withElementColor(card) { color -> + card.setCardBackgroundColor(color) + } } } diff --git a/app/src/main/res/layout/current_account_item.xml b/app/src/main/res/layout/current_account_item.xml index 680fb3a36..d1972e62a 100644 --- a/app/src/main/res/layout/current_account_item.xml +++ b/app/src/main/res/layout/current_account_item.xml @@ -31,6 +31,7 @@ app:cardElevation="0dp"> From 5abdacab2509025da316cdb53a3c8f847f4cdc5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Thu, 21 Jul 2022 16:06:26 +0200 Subject: [PATCH 07/58] SettingsController: color section headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Brey --- .../talk/controllers/SettingsController.kt | 25 +++++++++++++++++-- .../nextcloud/talk/ui/theme/ViewThemeUtils.kt | 8 ++++++ .../main/res/layout/controller_settings.xml | 8 +++++- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.kt b/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.kt index 98f7c5364..8eede30cd 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.kt +++ b/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.kt @@ -78,6 +78,7 @@ import com.nextcloud.talk.jobs.ContactAddressBookWorker.Companion.deleteAll import com.nextcloud.talk.models.json.generic.GenericOverall import com.nextcloud.talk.models.json.userprofile.UserProfileOverall import com.nextcloud.talk.users.UserManager +import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.DisplayUtils import com.nextcloud.talk.utils.LoggingUtils.sendMailWithAttachment @@ -118,6 +119,9 @@ class SettingsController : NewBaseController(R.layout.controller_settings) { @Inject lateinit var currentUserProvider: CurrentUserProviderNew + @Inject + lateinit var viewThemeUtils: ViewThemeUtils + private var saveStateHandler: LovelySaveStateHandler? = null private var currentUser: User? = null private var credentials: String? = null @@ -402,7 +406,8 @@ class SettingsController : NewBaseController(R.layout.controller_settings) { .setIcon( DisplayUtils.getTintedDrawable( resources, - R.drawable.ic_delete_black_24dp, R.color.bg_default + R.drawable.ic_delete_black_24dp, + R.color.bg_default ) ) .setPositiveButtonColor(context!!.resources.getColor(R.color.nc_darkRed)) @@ -511,6 +516,20 @@ class SettingsController : NewBaseController(R.layout.controller_settings) { ) } + + themeCategories() + } + + private fun themeCategories() { + binding.run { + listOf( + settingsNotificationsCategory, + settingsAboutCategory, + settingsAdvancedCategory, + settingsAppearanceCategory, + settingsPrivacyCategory + ).forEach(viewThemeUtils::colorPreferenceCategory) + } } private fun setupProxyTypeSettings() { @@ -952,7 +971,9 @@ class SettingsController : NewBaseController(R.layout.controller_settings) { val phoneNumber = textInputLayout.editText!!.text.toString() ncApi.setUserData( ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token), - ApiUtils.getUrlForUserData(currentUser!!.baseUrl, currentUser!!.userId), "phone", phoneNumber + ApiUtils.getUrlForUserData(currentUser!!.baseUrl, currentUser!!.userId), + "phone", + phoneNumber ).subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(object : Observer { 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 index 99373ba76..4ad72b83a 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt @@ -30,6 +30,7 @@ import android.widget.TextView import com.google.android.material.button.MaterialButton import com.google.android.material.card.MaterialCardView import com.google.android.material.floatingactionbutton.FloatingActionButton +import com.yarolegovich.mp.MaterialPreferenceCategory import javax.inject.Inject class ViewThemeUtils @Inject constructor(val theme: ServerTheme) { @@ -113,4 +114,11 @@ class ViewThemeUtils @Inject constructor(val theme: ServerTheme) { card.setCardBackgroundColor(color) } } + + // TODO split this util into classes depending on framework views vs library views + fun colorPreferenceCategory(category: MaterialPreferenceCategory) { + withElementColor(category) { color -> + category.setTitleColor(color) + } + } } diff --git a/app/src/main/res/layout/controller_settings.xml b/app/src/main/res/layout/controller_settings.xml index 04c19a4d1..7c239a303 100644 --- a/app/src/main/res/layout/controller_settings.xml +++ b/app/src/main/res/layout/controller_settings.xml @@ -27,6 +27,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:fresco="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" + tools:background="@color/white" android:id="@+id/settings_screen" android:layout_width="match_parent" android:layout_height="match_parent"> @@ -43,6 +44,7 @@ android:id="@+id/message_text" android:layout_width="match_parent" android:layout_height="match_parent" + tools:text="This is a test message" android:gravity="center" /> @@ -105,10 +107,10 @@ android:id="@+id/server_age_warning_text" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_centerHorizontal="true" android:layout_toEndOf="@id/server_age_warning_icon" android:paddingStart="@dimen/standard_padding" android:paddingEnd="0dp" - android:layout_centerHorizontal="true" android:textAlignment="viewStart" android:textColor="@color/nc_darkRed" tools:text="@string/nc_settings_server_almost_eol" /> @@ -142,6 +144,7 @@ Date: Thu, 21 Jul 2022 17:24:42 +0200 Subject: [PATCH 08/58] SettingsController: theme switch preferences MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Brey --- .../talk/controllers/SettingsController.kt | 14 ++++++ .../nextcloud/talk/ui/theme/ViewThemeUtils.kt | 45 +++++++++++++++++++ app/src/main/res/values-night/colors.xml | 4 ++ app/src/main/res/values/colors.xml | 3 ++ 4 files changed, 66 insertions(+) diff --git a/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.kt b/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.kt index 8eede30cd..3ad36737b 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.kt +++ b/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.kt @@ -518,6 +518,20 @@ class SettingsController : NewBaseController(R.layout.controller_settings) { } themeCategories() + themeSwitchPreferences() + } + + private fun themeSwitchPreferences() { + binding.run { + listOf( + settingsScreenLock, + settingsScreenSecurity, + settingsIncognitoKeyboard, + settingsPhoneBookIntegration, + settingsReadPrivacy, + settingsProxyUseCredentials + ).forEach(viewThemeUtils::colorSwitchPreference) + } } private fun themeCategories() { 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 index 4ad72b83a..df5b587f6 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt @@ -24,13 +24,19 @@ package com.nextcloud.talk.ui.theme import android.content.Context import android.content.res.ColorStateList import android.content.res.Configuration +import android.graphics.Color import android.view.View import android.widget.ImageView import android.widget.TextView +import androidx.appcompat.widget.SwitchCompat +import androidx.core.content.res.ResourcesCompat +import androidx.core.view.children import com.google.android.material.button.MaterialButton import com.google.android.material.card.MaterialCardView import com.google.android.material.floatingactionbutton.FloatingActionButton +import com.nextcloud.talk.R import com.yarolegovich.mp.MaterialPreferenceCategory +import com.yarolegovich.mp.MaterialSwitchPreference import javax.inject.Inject class ViewThemeUtils @Inject constructor(val theme: ServerTheme) { @@ -121,4 +127,43 @@ class ViewThemeUtils @Inject constructor(val theme: ServerTheme) { category.setTitleColor(color) } } + + fun colorSwitchPreference(preference: MaterialSwitchPreference) { + val children = preference.children + val switch = children.find { it is SwitchCompat } + if (switch != null) { + val switchCompat = (switch as SwitchCompat) + colorSwitchCompat(switchCompat) + } + } + + // TODO cleanup + fun colorSwitchCompat(switchCompat: SwitchCompat) { + withElementColor(switchCompat) { color -> + + val context = switchCompat.context + + val thumbUncheckedColor = ResourcesCompat.getColor( + context.resources, + R.color.switch_thumb_color_unchecked, + context.theme + ) + val trackUncheckedColor = ResourcesCompat.getColor( + context.resources, + R.color.switch_track_color_unchecked, + context.theme + ) + + val trackColor = Color.argb(77, Color.red(color), Color.green(color), Color.blue(color)) + switchCompat.thumbTintList = ColorStateList( + arrayOf(intArrayOf(android.R.attr.state_checked), intArrayOf()), + intArrayOf(color, thumbUncheckedColor) + ) + + switchCompat.trackTintList = ColorStateList( + arrayOf(intArrayOf(android.R.attr.state_checked), intArrayOf()), + intArrayOf(trackColor, trackUncheckedColor) + ) + } + } } diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml index 86f4044a5..ae1bcea4d 100644 --- a/app/src/main/res/values-night/colors.xml +++ b/app/src/main/res/values-night/colors.xml @@ -76,4 +76,8 @@ #353535 #424242 + + #cbcbcb + #5a5a5a + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 2993412c9..28ff0ff06 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -111,4 +111,7 @@ #FFFFFF #FFFFFF + #ececec + #b2b2b2 + From a4c01978a8de44da3da150166416e6dd85eec4a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Fri, 22 Jul 2022 14:28:09 +0200 Subject: [PATCH 09/58] Theme ProfileController MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Brey --- .../talk/controllers/ProfileController.kt | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ProfileController.kt b/app/src/main/java/com/nextcloud/talk/controllers/ProfileController.kt index 52631f15f..9db7d8781 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ProfileController.kt +++ b/app/src/main/java/com/nextcloud/talk/controllers/ProfileController.kt @@ -69,6 +69,7 @@ import com.nextcloud.talk.models.json.userprofile.UserProfileFieldsOverall import com.nextcloud.talk.models.json.userprofile.UserProfileOverall import com.nextcloud.talk.remotefilebrowser.activities.RemoteFileBrowserActivity import com.nextcloud.talk.ui.dialog.ScopeDialog +import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.users.UserManager import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.DisplayUtils @@ -110,6 +111,9 @@ class ProfileController : NewBaseController(R.layout.controller_profile) { @Inject lateinit var permissionUtil: PlatformPermissionUtil + @Inject + lateinit var viewThemeUtils: ViewThemeUtils + private var currentUser: User? = null private var edit = false private var adapter: UserInfoAdapter? = null @@ -196,7 +200,7 @@ class ProfileController : NewBaseController(R.layout.controller_profile) { override fun onAttach(view: View) { super.onAttach(view) - adapter = UserInfoAdapter(null, activity!!.resources.getColor(R.color.colorPrimary), this) + adapter = UserInfoAdapter(null, viewThemeUtils.getElementColor(activity!!), this) binding.userinfoList.adapter = adapter binding.userinfoList.setItemViewCacheSize(DEFAULT_CACHE_SIZE) currentUser = userManager.currentUser.blockingGet() @@ -260,6 +264,13 @@ class ProfileController : NewBaseController(R.layout.controller_profile) { // unused atm } }) + + colorIcons() + } + + private fun colorIcons() { + viewThemeUtils.colorImageView(binding.avatarChoose) + viewThemeUtils.colorImageView(binding.avatarCamera) } private fun isAllEmpty(items: Array): Boolean { @@ -301,7 +312,8 @@ class ProfileController : NewBaseController(R.layout.controller_profile) { binding.emptyList.root.visibility = View.VISIBLE setErrorMessageForMultiList( activity!!.getString(R.string.userinfo_no_info_headline), - activity!!.getString(R.string.userinfo_no_info_text), R.drawable.ic_user + activity!!.getString(R.string.userinfo_no_info_text), + R.drawable.ic_user ) } else { binding.emptyList.root.visibility = View.GONE @@ -616,11 +628,13 @@ class ProfileController : NewBaseController(R.layout.controller_profile) { val builder = MultipartBody.Builder() builder.setType(MultipartBody.FORM) builder.addFormDataPart( - "files[]", file!!.name, + "files[]", + file!!.name, file.asRequestBody(IMAGE_PREFIX_GENERIC.toMediaTypeOrNull()) ) val filePart: MultipartBody.Part = MultipartBody.Part.createFormData( - "files[]", file.name, + "files[]", + file.name, file.asRequestBody(IMAGE_JPG.toMediaTypeOrNull()) ) @@ -643,7 +657,8 @@ class ProfileController : NewBaseController(R.layout.controller_profile) { override fun onError(e: Throwable) { Toast.makeText( - applicationContext, context.getString(R.string.default_error_msg), + applicationContext, + context.getString(R.string.default_error_msg), Toast .LENGTH_LONG ).show() @@ -688,7 +703,8 @@ class ProfileController : NewBaseController(R.layout.controller_profile) { } class UserInfoDetailsItem( - @field:DrawableRes @param:DrawableRes var icon: Int, + @field:DrawableRes @param:DrawableRes + var icon: Int, var text: String?, var hint: String, val field: Field, From 49f9e0ffc4055bb6cefb154273c3ee60421eda8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Fri, 22 Jul 2022 15:04:15 +0200 Subject: [PATCH 10/58] Theme RemoteFileBrowser MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Brey --- .../activities/RemoteFileBrowserActivity.kt | 8 ++++-- .../adapters/RemoteFileBrowserItemsAdapter.kt | 9 ++++--- .../RemoteFileBrowserItemsListViewHolder.kt | 26 ++++++++++++++++--- .../ui/dialog/SortingOrderDialogFragment.java | 16 ++++++------ .../nextcloud/talk/ui/theme/ViewThemeUtils.kt | 23 ++++++++++++++++ 5 files changed, 65 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/remotefilebrowser/activities/RemoteFileBrowserActivity.kt b/app/src/main/java/com/nextcloud/talk/remotefilebrowser/activities/RemoteFileBrowserActivity.kt index 75f87bf93..da0d78049 100644 --- a/app/src/main/java/com/nextcloud/talk/remotefilebrowser/activities/RemoteFileBrowserActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/remotefilebrowser/activities/RemoteFileBrowserActivity.kt @@ -44,6 +44,7 @@ import com.nextcloud.talk.remotefilebrowser.SelectionInterface import com.nextcloud.talk.remotefilebrowser.adapters.RemoteFileBrowserItemsAdapter import com.nextcloud.talk.remotefilebrowser.viewmodels.RemoteFileBrowserItemsViewModel import com.nextcloud.talk.ui.dialog.SortingOrderDialogFragment +import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.utils.DisplayUtils import com.nextcloud.talk.utils.FileSortOrder import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_MIME_TYPE_FILTER @@ -59,6 +60,9 @@ class RemoteFileBrowserActivity : AppCompatActivity(), SelectionInterface, Swipe @Inject lateinit var currentUserProvider: CurrentUserProviderNew + @Inject + lateinit var viewThemeUtils: ViewThemeUtils + private lateinit var binding: ActivityRemoteFileBrowserBinding private lateinit var viewModel: RemoteFileBrowserItemsViewModel @@ -91,8 +95,7 @@ class RemoteFileBrowserActivity : AppCompatActivity(), SelectionInterface, Swipe initViewModel(mimeTypeSelectionFilter) binding.swipeRefreshList.setOnRefreshListener(this) - binding.swipeRefreshList.setColorSchemeResources(R.color.colorPrimary) - binding.swipeRefreshList.setProgressBackgroundColorSchemeResource(R.color.refresh_spinner_background) + viewThemeUtils.themeSwipeRefreshLayout(binding.swipeRefreshList) binding.pathNavigationBackButton.setOnClickListener { viewModel.navigateUp() } binding.sortButton.setOnClickListener { changeSorting() } @@ -160,6 +163,7 @@ class RemoteFileBrowserActivity : AppCompatActivity(), SelectionInterface, Swipe mimeTypeSelectionFilter = mimeTypeSelectionFilter, user = currentUserProvider.currentUser.blockingGet(), selectionInterface = this, + viewThemeUtils = viewThemeUtils, onItemClicked = viewModel::onItemClicked ) adapter.items = remoteFileBrowserItems diff --git a/app/src/main/java/com/nextcloud/talk/remotefilebrowser/adapters/RemoteFileBrowserItemsAdapter.kt b/app/src/main/java/com/nextcloud/talk/remotefilebrowser/adapters/RemoteFileBrowserItemsAdapter.kt index 5a146cb11..d63da5449 100644 --- a/app/src/main/java/com/nextcloud/talk/remotefilebrowser/adapters/RemoteFileBrowserItemsAdapter.kt +++ b/app/src/main/java/com/nextcloud/talk/remotefilebrowser/adapters/RemoteFileBrowserItemsAdapter.kt @@ -28,19 +28,20 @@ import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.databinding.RvItemBrowserFileBinding import com.nextcloud.talk.remotefilebrowser.SelectionInterface import com.nextcloud.talk.remotefilebrowser.model.RemoteFileBrowserItem +import com.nextcloud.talk.ui.theme.ViewThemeUtils class RemoteFileBrowserItemsAdapter( private val showGrid: Boolean = false, private val mimeTypeSelectionFilter: String? = null, private val user: User, private val selectionInterface: SelectionInterface, + private val viewThemeUtils: ViewThemeUtils, private val onItemClicked: (RemoteFileBrowserItem) -> Unit ) : RecyclerView.Adapter() { var items: List = emptyList() override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RemoteFileBrowserItemsViewHolder { - return if (showGrid) { RemoteFileBrowserItemsListViewHolder( RvItemBrowserFileBinding.inflate( @@ -50,7 +51,8 @@ class RemoteFileBrowserItemsAdapter( ), mimeTypeSelectionFilter, user, - selectionInterface + selectionInterface, + viewThemeUtils ) { onItemClicked(items[it]) } @@ -63,7 +65,8 @@ class RemoteFileBrowserItemsAdapter( ), mimeTypeSelectionFilter, user, - selectionInterface + selectionInterface, + viewThemeUtils ) { onItemClicked(items[it]) } diff --git a/app/src/main/java/com/nextcloud/talk/remotefilebrowser/adapters/RemoteFileBrowserItemsListViewHolder.kt b/app/src/main/java/com/nextcloud/talk/remotefilebrowser/adapters/RemoteFileBrowserItemsListViewHolder.kt index 22ad32704..5ef9d2852 100644 --- a/app/src/main/java/com/nextcloud/talk/remotefilebrowser/adapters/RemoteFileBrowserItemsListViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/remotefilebrowser/adapters/RemoteFileBrowserItemsListViewHolder.kt @@ -20,6 +20,7 @@ package com.nextcloud.talk.remotefilebrowser.adapters +import android.graphics.drawable.Drawable import android.text.format.Formatter import android.view.View import androidx.appcompat.content.res.AppCompatResources @@ -33,6 +34,7 @@ import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.databinding.RvItemBrowserFileBinding import com.nextcloud.talk.remotefilebrowser.SelectionInterface import com.nextcloud.talk.remotefilebrowser.model.RemoteFileBrowserItem +import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.DateUtils.getLocalDateTimeStringFromTimestamp import com.nextcloud.talk.utils.DisplayUtils @@ -45,6 +47,7 @@ class RemoteFileBrowserItemsListViewHolder( mimeTypeSelectionFilter: String?, currentUser: User, selectionInterface: SelectionInterface, + private val viewThemeUtils: ViewThemeUtils, onItemClicked: (Int) -> Unit ) : RemoteFileBrowserItemsViewHolder(binding, mimeTypeSelectionFilter, currentUser, selectionInterface) { @@ -66,7 +69,6 @@ class RemoteFileBrowserItemsListViewHolder( } override fun onBind(item: RemoteFileBrowserItem) { - super.onBind(item) binding.fileIcon.controller = null @@ -99,9 +101,7 @@ class RemoteFileBrowserItemsListViewHolder( binding.fileIcon .hierarchy .setPlaceholderImage( - AppCompatResources.getDrawable( - binding.fileIcon.context, getDrawableResourceIdForMimeType(item.mimeType) - ) + getPlaceholderImage(item) ) if (item.hasPreview) { @@ -129,9 +129,23 @@ class RemoteFileBrowserItemsListViewHolder( binding.selectFileCheckbox.isChecked = selectionInterface.isPathSelected(item.path!!) } + private fun getPlaceholderImage(item: RemoteFileBrowserItem): Drawable? { + val drawableResourceId = getDrawableResourceIdForMimeType(item.mimeType) + val context = binding.fileIcon.context + val drawable = AppCompatResources.getDrawable( + context, + drawableResourceId + ) + if (drawable != null && THEMEABLE_PLACEHOLDER_IDS.contains(drawableResourceId)) { + viewThemeUtils.colorDrawable(context, drawable) + } + return drawable + } + private fun setSelectability() { if (selectable) { binding.selectFileCheckbox.visibility = View.VISIBLE + viewThemeUtils.themeCheckbox(binding.selectFileCheckbox) } else { binding.selectFileCheckbox.visibility = View.GONE } @@ -150,5 +164,9 @@ class RemoteFileBrowserItemsListViewHolder( companion object { private const val DISABLED_ALPHA: Float = 0.38f private const val ENABLED_ALPHA: Float = 1.0f + private val THEMEABLE_PLACEHOLDER_IDS = listOf( + R.drawable.ic_mimetype_package_x_generic, + R.drawable.ic_mimetype_folder + ) } } diff --git a/app/src/main/java/com/nextcloud/talk/ui/dialog/SortingOrderDialogFragment.java b/app/src/main/java/com/nextcloud/talk/ui/dialog/SortingOrderDialogFragment.java index f2d5c8d66..e348504cd 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/dialog/SortingOrderDialogFragment.java +++ b/app/src/main/java/com/nextcloud/talk/ui/dialog/SortingOrderDialogFragment.java @@ -33,9 +33,9 @@ import android.widget.TextView; import com.google.android.material.button.MaterialButton; import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import com.nextcloud.talk.R; import com.nextcloud.talk.application.NextcloudTalkApplication; import com.nextcloud.talk.databinding.SortingOrderFragmentBinding; +import com.nextcloud.talk.ui.theme.ViewThemeUtils; import com.nextcloud.talk.utils.FileSortOrder; import com.nextcloud.talk.utils.preferences.AppPreferences; @@ -46,7 +46,6 @@ import javax.inject.Inject; import androidx.annotation.NonNull; import androidx.fragment.app.DialogFragment; import autodagger.AutoInjector; -import kotlin.jvm.JvmField; /** * Dialog to show and choose the sorting order for the file listing. @@ -60,9 +59,11 @@ public class SortingOrderDialogFragment extends DialogFragment implements View.O private static final String KEY_SORT_ORDER = "SORT_ORDER"; @Inject - @JvmField AppPreferences appPreferences; + @Inject + ViewThemeUtils viewThemeUtils; + private SortingOrderFragmentBinding binding; private View dialogView; @@ -119,7 +120,7 @@ public class SortingOrderDialogFragment extends DialogFragment implements View.O * find all relevant UI elements and set their values. */ private void setupDialogElements() { - binding.cancel.setTextColor(getResources().getColor(R.color.colorPrimary)); + viewThemeUtils.colorMaterialButtonText(binding.cancel); taggedViews = new View[12]; taggedViews[0] = binding.sortByNameAscending; @@ -154,18 +155,17 @@ public class SortingOrderDialogFragment extends DialogFragment implements View.O * tints the icon reflecting the actual sorting choice in the apps primary color. */ private void setupActiveOrderSelection() { - final int color = getResources().getColor(R.color.colorPrimary); - Log.i("SortOrder", "currentSortOrderName="+currentSortOrderName); + Log.i("SortOrder", "currentSortOrderName=" + currentSortOrderName); for (View view : taggedViews) { Log.i("SortOrder", ((FileSortOrder) view.getTag()).getName()); if (!((FileSortOrder) view.getTag()).getName().equals(currentSortOrderName)) { continue; } if (view instanceof MaterialButton) { - ((MaterialButton) view).setIconTintResource(R.color.colorPrimary); + viewThemeUtils.colorMaterialButtonText((MaterialButton) view); } if (view instanceof TextView) { - ((TextView) view).setTextColor(color); + viewThemeUtils.colorTextViewElement((TextView) view); ((TextView) view).setTypeface(Typeface.DEFAULT_BOLD); } } 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 index df5b587f6..eaf5496ab 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt @@ -25,12 +25,15 @@ import android.content.Context import android.content.res.ColorStateList import android.content.res.Configuration import android.graphics.Color +import android.graphics.drawable.Drawable import android.view.View +import android.widget.CheckBox import android.widget.ImageView import android.widget.TextView import androidx.appcompat.widget.SwitchCompat import androidx.core.content.res.ResourcesCompat import androidx.core.view.children +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import com.google.android.material.button.MaterialButton import com.google.android.material.card.MaterialCardView import com.google.android.material.floatingactionbutton.FloatingActionButton @@ -106,6 +109,7 @@ class ViewThemeUtils @Inject constructor(val theme: ServerTheme) { fun colorMaterialButtonText(button: MaterialButton) { colorTextViewElement(button) + button.iconTint = ColorStateList.valueOf(getElementColor(button.context)) } fun colorMaterialButtonBackground(button: MaterialButton) { @@ -166,4 +170,23 @@ class ViewThemeUtils @Inject constructor(val theme: ServerTheme) { ) } } + + fun colorDrawable(context: Context, drawable: Drawable) { + val color = getElementColor(context) + drawable.setTint(color) + } + + fun themeCheckbox(checkbox: CheckBox) { + withElementColor(checkbox) { color -> + checkbox.setTextColor(color) + checkbox.buttonTintList = ColorStateList.valueOf(color) + } + } + + fun themeSwipeRefreshLayout(swipeRefreshLayout: SwipeRefreshLayout) { + withElementColor(swipeRefreshLayout) { color -> + swipeRefreshLayout.setColorSchemeColors(color) + swipeRefreshLayout.setProgressBackgroundColorSchemeResource(R.color.refresh_spinner_background) + } + } } From b4ed79dc3894ff4e749779aa1d28fd6c99420e6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Fri, 22 Jul 2022 15:47:26 +0200 Subject: [PATCH 11/58] Theme EntryMenuController MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Brey --- .../bottomsheet/EntryMenuController.kt | 23 +++++++++++-------- .../nextcloud/talk/ui/theme/ViewThemeUtils.kt | 8 +++++++ .../main/res/layout/controller_entry_menu.xml | 2 +- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/EntryMenuController.kt b/app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/EntryMenuController.kt index 801ea39ac..b592b2a54 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/EntryMenuController.kt +++ b/app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/EntryMenuController.kt @@ -25,7 +25,7 @@ package com.nextcloud.talk.controllers.bottomsheet import android.content.ComponentName import android.content.Intent -import android.graphics.PorterDuff +import android.content.res.ColorStateList import android.os.Bundle import android.os.Parcelable import android.text.Editable @@ -34,6 +34,7 @@ import android.text.TextUtils import android.text.TextWatcher import android.view.View import android.view.inputmethod.EditorInfo +import androidx.core.content.res.ResourcesCompat import autodagger.AutoInjector import com.bluelinelabs.conductor.RouterTransaction import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler @@ -45,6 +46,7 @@ import com.nextcloud.talk.controllers.base.NewBaseController import com.nextcloud.talk.controllers.util.viewBinding import com.nextcloud.talk.databinding.ControllerEntryMenuBinding import com.nextcloud.talk.models.json.conversations.Conversation +import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.users.UserManager import com.nextcloud.talk.utils.ShareUtils import com.nextcloud.talk.utils.UriUtils @@ -71,6 +73,9 @@ class EntryMenuController(args: Bundle) : @Inject lateinit var userManager: UserManager + @Inject + lateinit var viewThemeUtils: ViewThemeUtils + private val operation: ConversationOperationEnum private var conversation: Conversation? = null private var shareIntent: Intent? = null @@ -125,17 +130,11 @@ class EntryMenuController(args: Bundle) : rootView = view, editText = binding.textEdit, onEmojiPopupShownListener = { - if (resources != null) { - binding.smileyButton.setColorFilter( - resources!!.getColor(R.color.colorPrimary), - PorterDuff.Mode.SRC_IN - ) - } + viewThemeUtils.colorImageView(binding.smileyButton) }, onEmojiPopupDismissListener = { - binding.smileyButton.setColorFilter( - resources!!.getColor(R.color.emoji_icons), - PorterDuff.Mode.SRC_IN + binding.smileyButton.imageTintList = ColorStateList.valueOf( + ResourcesCompat.getColor(resources!!, R.color.medium_emphasis_text, context.theme) ) }, onEmojiClickListener = { @@ -171,6 +170,10 @@ class EntryMenuController(args: Bundle) : binding.textInputLayout.endIconMode = TextInputLayout.END_ICON_NONE } + viewThemeUtils.colorTextInputLayout(binding.textInputLayout) + binding.textEdit.setTextColor(viewThemeUtils.theme.colorText) + viewThemeUtils.colorMaterialButtonText(binding.okButton) + binding.textInputLayout.hint = labelText binding.textInputLayout.requestFocus() 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 index eaf5496ab..916b1b981 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt @@ -37,6 +37,7 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import com.google.android.material.button.MaterialButton import com.google.android.material.card.MaterialCardView import com.google.android.material.floatingactionbutton.FloatingActionButton +import com.google.android.material.textfield.TextInputLayout import com.nextcloud.talk.R import com.yarolegovich.mp.MaterialPreferenceCategory import com.yarolegovich.mp.MaterialSwitchPreference @@ -189,4 +190,11 @@ class ViewThemeUtils @Inject constructor(val theme: ServerTheme) { swipeRefreshLayout.setProgressBackgroundColorSchemeResource(R.color.refresh_spinner_background) } } + + fun colorTextInputLayout(textInputLayout: TextInputLayout) { + withElementColor(textInputLayout) { color -> + textInputLayout.hintTextColor = ColorStateList.valueOf(color) + textInputLayout.boxStrokeColor = color + } + } } diff --git a/app/src/main/res/layout/controller_entry_menu.xml b/app/src/main/res/layout/controller_entry_menu.xml index 8bf6fc674..2f50f3d68 100644 --- a/app/src/main/res/layout/controller_entry_menu.xml +++ b/app/src/main/res/layout/controller_entry_menu.xml @@ -78,7 +78,7 @@ android:contentDescription="@string/nc_add_emojis" android:src="@drawable/ic_insert_emoticon_black_24dp" android:visibility="gone" - app:tint="@color/emoji_icons" + app:tint="@color/medium_emphasis_text" tools:visibility="visible" /> From b66ec4a1501f05dc1df531b9bf377f0e91513173 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Fri, 22 Jul 2022 16:06:09 +0200 Subject: [PATCH 12/58] Theme ConversationInfoController MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Brey --- .../controllers/ConversationInfoController.kt | 94 +++++++++++++------ .../layout/controller_conversation_info.xml | 2 + .../res/layout/notification_settings_item.xml | 1 + 3 files changed, 66 insertions(+), 31 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.kt b/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.kt index 866a5024f..6347acbb8 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.kt +++ b/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.kt @@ -73,6 +73,7 @@ import com.nextcloud.talk.models.json.participants.Participant.ActorType.GROUPS import com.nextcloud.talk.models.json.participants.Participant.ActorType.USERS import com.nextcloud.talk.models.json.participants.ParticipantsOverall import com.nextcloud.talk.shareditems.activities.SharedItemsActivity +import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.DateConstants import com.nextcloud.talk.utils.DateUtils @@ -112,6 +113,9 @@ class ConversationInfoController(args: Bundle) : @Inject lateinit var eventBus: EventBus + @Inject + lateinit var viewThemeUtils: ViewThemeUtils + private val conversationToken: String? private val conversationUser: User? private val hasAvatarSpacing: Boolean @@ -181,6 +185,34 @@ class ConversationInfoController(args: Bundle) : } fetchRoomInfo() + + themeCategories() + themeSwitchPreferences() + } + + private fun themeSwitchPreferences() { + binding.run { + listOf( + binding.webinarInfoView.conversationInfoLobby, + binding.notificationSettingsView.callNotifications, + binding.notificationSettingsView.conversationInfoPriorityConversation + ).forEach(viewThemeUtils::colorSwitchPreference) + } + } + + private fun themeCategories() { + binding.run { + listOf( + conversationInfoName, + conversationDescription, + otherRoomOptions, + participantsListCategory, + ownOptions, + categorySharedItems, + binding.webinarInfoView.conversationInfoWebinar, + binding.notificationSettingsView.notificationSettingsCategory + ).forEach(viewThemeUtils::colorPreferenceCategory) + } } private fun showSharedItems() { @@ -299,7 +331,7 @@ class ConversationInfoController(args: Bundle) : val apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1)) - ncApi?.setLobbyForConversation( + ncApi.setLobbyForConversation( ApiUtils.getCredentials(conversationUser!!.username, conversationUser.token), ApiUtils.getUrlForRoomWebinaryLobby(apiVersion, conversationUser.baseUrl, conversation!!.token), state, @@ -343,7 +375,7 @@ class ConversationInfoController(args: Bundle) : override fun onDetach(view: View) { super.onDetach(view) - eventBus?.unregister(this) + eventBus.unregister(this) } private fun showDeleteConversationDialog(savedInstanceState: Bundle?) { @@ -352,11 +384,11 @@ class ConversationInfoController(args: Bundle) : .setTopColorRes(R.color.nc_darkRed) .setIcon( DisplayUtils.getTintedDrawable( - context!!.resources, + context.resources, R.drawable.ic_delete_black_24dp, R.color.bg_default ) ) - .setPositiveButtonColor(context!!.resources.getColor(R.color.nc_darkRed)) + .setPositiveButtonColor(context.resources.getColor(R.color.nc_darkRed)) .setTitle(R.string.nc_delete_call) .setMessage(R.string.nc_delete_conversation_more) .setPositiveButton(R.string.nc_delete) { deleteConversation() } @@ -409,7 +441,7 @@ class ConversationInfoController(args: Bundle) : if (participant.sessionId != null) { userItem.isOnline = !participant.sessionId.equals("0") } else { - userItem.isOnline = !participant.sessionIds!!.isEmpty() + userItem.isOnline = !participant.sessionIds.isEmpty() } if (participant.calculatedActorType == USERS && @@ -453,7 +485,7 @@ class ConversationInfoController(args: Bundle) : val fieldMap = HashMap() fieldMap["includeStatus"] = true - ncApi?.getPeersForCall( + ncApi.getPeersForCall( credentials, ApiUtils.getUrlForParticipants( apiVersion, @@ -504,7 +536,7 @@ class ConversationInfoController(args: Bundle) : bundle.putStringArrayList(BundleKeys.KEY_EXISTING_PARTICIPANTS, existingParticipantsId) bundle.putString(BundleKeys.KEY_TOKEN, conversation!!.token) - getRouter().pushController( + router.pushController( ( RouterTransaction.with( ContactsController(bundle) @@ -537,11 +569,11 @@ class ConversationInfoController(args: Bundle) : .setTopColorRes(R.color.nc_darkRed) .setIcon( DisplayUtils.getTintedDrawable( - context!!.resources, + context.resources, R.drawable.ic_delete_black_24dp, R.color.bg_default ) ) - .setPositiveButtonColor(context!!.resources.getColor(R.color.nc_darkRed)) + .setPositiveButtonColor(context.resources.getColor(R.color.nc_darkRed)) .setTitle(R.string.nc_clear_history) .setMessage(R.string.nc_clear_history_warning) .setPositiveButton(R.string.nc_delete_all) { clearHistory() } @@ -555,7 +587,7 @@ class ConversationInfoController(args: Bundle) : private fun clearHistory() { val apiVersion = ApiUtils.getChatApiVersion(conversationUser, intArrayOf(1)) - ncApi?.clearChatHistory( + ncApi.clearChatHistory( credentials, ApiUtils.getUrlForChat(apiVersion, conversationUser!!.baseUrl, conversationToken) ) @@ -567,7 +599,7 @@ class ConversationInfoController(args: Bundle) : } override fun onNext(genericOverall: GenericOverall) { - Toast.makeText(context, context?.getString(R.string.nc_clear_history_success), Toast.LENGTH_LONG) + Toast.makeText(context, context.getString(R.string.nc_clear_history_success), Toast.LENGTH_LONG) .show() } @@ -606,7 +638,7 @@ class ConversationInfoController(args: Bundle) : apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1)) } - ncApi?.getRoom(credentials, ApiUtils.getUrlForRoom(apiVersion, conversationUser!!.baseUrl, conversationToken)) + ncApi.getRoom(credentials, ApiUtils.getUrlForRoom(apiVersion, conversationUser!!.baseUrl, conversationToken)) ?.subscribeOn(Schedulers.io()) ?.observeOn(AndroidSchedulers.mainThread()) ?.subscribe(object : Observer { @@ -765,8 +797,8 @@ class ConversationInfoController(args: Bundle) : ) Conversation.ConversationType.ROOM_SYSTEM -> { val layers = arrayOfNulls(2) - layers[0] = ContextCompat.getDrawable(context!!, R.drawable.ic_launcher_background) - layers[1] = ContextCompat.getDrawable(context!!, R.drawable.ic_launcher_foreground) + layers[0] = ContextCompat.getDrawable(context, R.drawable.ic_launcher_background) + layers[1] = ContextCompat.getDrawable(context, R.drawable.ic_launcher_foreground) val layerDrawable = LayerDrawable(layers) binding.avatarImage.hierarchy.setPlaceholderImage(DisplayUtils.getRoundedDrawable(layerDrawable)) } @@ -800,7 +832,7 @@ class ConversationInfoController(args: Bundle) : if (participant.type == Participant.ParticipantType.MODERATOR || participant.type == Participant.ParticipantType.GUEST_MODERATOR ) { - ncApi?.demoteAttendeeFromModerator( + ncApi.demoteAttendeeFromModerator( credentials, ApiUtils.getUrlForRoomModerators( apiVersion, @@ -815,7 +847,7 @@ class ConversationInfoController(args: Bundle) : } else if (participant.type == Participant.ParticipantType.USER || participant.type == Participant.ParticipantType.GUEST ) { - ncApi?.promoteAttendeeToModerator( + ncApi.promoteAttendeeToModerator( credentials, ApiUtils.getUrlForRoomModerators( apiVersion, @@ -851,7 +883,7 @@ class ConversationInfoController(args: Bundle) : } if (participant.type == Participant.ParticipantType.MODERATOR) { - ncApi?.demoteModeratorToUser( + ncApi.demoteModeratorToUser( credentials, ApiUtils.getUrlForRoomModerators( apiVersion, @@ -864,7 +896,7 @@ class ConversationInfoController(args: Bundle) : ?.observeOn(AndroidSchedulers.mainThread()) ?.subscribe(subscriber) } else if (participant.type == Participant.ParticipantType.USER) { - ncApi?.promoteUserToModerator( + ncApi.promoteUserToModerator( credentials, ApiUtils.getUrlForRoomModerators( apiVersion, @@ -881,7 +913,7 @@ class ConversationInfoController(args: Bundle) : fun removeAttendeeFromConversation(apiVersion: Int, participant: Participant) { if (apiVersion >= ApiUtils.APIv4) { - ncApi?.removeAttendeeFromConversation( + ncApi.removeAttendeeFromConversation( credentials, ApiUtils.getUrlForAttendees( apiVersion, @@ -914,7 +946,7 @@ class ConversationInfoController(args: Bundle) : if (participant.type == Participant.ParticipantType.GUEST || participant.type == Participant.ParticipantType.USER_FOLLOWING_LINK ) { - ncApi?.removeParticipantFromConversation( + ncApi.removeParticipantFromConversation( credentials, ApiUtils.getUrlForRemovingParticipantFromConversation( conversationUser!!.baseUrl, @@ -944,7 +976,7 @@ class ConversationInfoController(args: Bundle) : } }) } else { - ncApi?.removeParticipantFromConversation( + ncApi.removeParticipantFromConversation( credentials, ApiUtils.getUrlForRemovingParticipantFromConversation( conversationUser!!.baseUrl, @@ -987,12 +1019,12 @@ class ConversationInfoController(args: Bundle) : val apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1)) - if (participant.calculatedActorType == USERS && participant.calculatedActorId == conversationUser!!.userId) { + if (participant.calculatedActorType == USERS && participant.calculatedActorId == conversationUser.userId) { if (participant.attendeePin?.isNotEmpty() == true) { val items = mutableListOf( BasicListItemWithImage( R.drawable.ic_lock_grey600_24px, - context!!.getString(R.string.nc_attendee_pin, participant.attendeePin) + context.getString(R.string.nc_attendee_pin, participant.attendeePin) ) ) MaterialDialog(activity!!, BottomSheet(WRAP_CONTENT)).show { @@ -1018,7 +1050,7 @@ class ConversationInfoController(args: Bundle) : val items = mutableListOf( BasicListItemWithImage( R.drawable.ic_delete_grey600_24dp, - context!!.getString(R.string.nc_remove_group_and_members) + context.getString(R.string.nc_remove_group_and_members) ) ) MaterialDialog(activity!!, BottomSheet(WRAP_CONTENT)).show { @@ -1038,7 +1070,7 @@ class ConversationInfoController(args: Bundle) : val items = mutableListOf( BasicListItemWithImage( R.drawable.ic_delete_grey600_24dp, - context!!.getString(R.string.nc_remove_circle_and_members) + context.getString(R.string.nc_remove_circle_and_members) ) ) MaterialDialog(activity!!, BottomSheet(WRAP_CONTENT)).show { @@ -1057,19 +1089,19 @@ class ConversationInfoController(args: Bundle) : val items = mutableListOf( BasicListItemWithImage( R.drawable.ic_lock_grey600_24px, - context!!.getString(R.string.nc_attendee_pin, participant.attendeePin) + context.getString(R.string.nc_attendee_pin, participant.attendeePin) ), BasicListItemWithImage( R.drawable.ic_pencil_grey600_24dp, - context!!.getString(R.string.nc_promote) + context.getString(R.string.nc_promote) ), BasicListItemWithImage( R.drawable.ic_pencil_grey600_24dp, - context!!.getString(R.string.nc_demote) + context.getString(R.string.nc_demote) ), BasicListItemWithImage( R.drawable.ic_delete_grey600_24dp, - context!!.getString(R.string.nc_remove_participant) + context.getString(R.string.nc_remove_participant) ) ) @@ -1167,8 +1199,8 @@ class ConversationInfoController(args: Bundle) : return 1 } - return left.model.displayName!!.toLowerCase(Locale.ROOT).compareTo( - right.model.displayName!!.toLowerCase(Locale.ROOT) + return left.model.displayName!!.lowercase(Locale.ROOT).compareTo( + right.model.displayName!!.lowercase(Locale.ROOT) ) } } diff --git a/app/src/main/res/layout/controller_conversation_info.xml b/app/src/main/res/layout/controller_conversation_info.xml index 269449006..42944cdd3 100644 --- a/app/src/main/res/layout/controller_conversation_info.xml +++ b/app/src/main/res/layout/controller_conversation_info.xml @@ -23,6 +23,7 @@ @@ -76,6 +77,7 @@ android:layout_width="@dimen/avatar_size_big" android:layout_height="@dimen/avatar_size_big" android:layout_centerHorizontal="true" + tools:background="@color/hwSecurityRed" apc:roundAsCircle="true" /> diff --git a/app/src/main/res/layout/notification_settings_item.xml b/app/src/main/res/layout/notification_settings_item.xml index 4834b4942..8551de884 100644 --- a/app/src/main/res/layout/notification_settings_item.xml +++ b/app/src/main/res/layout/notification_settings_item.xml @@ -27,6 +27,7 @@ android:layout_height="wrap_content"> Date: Fri, 22 Jul 2022 16:14:45 +0200 Subject: [PATCH 13/58] Theme TakePhotoActivity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Brey --- .../talk/activities/TakePhotoActivity.java | 13 +++++++++++++ app/src/main/res/layout/activity_take_picture.xml | 1 + 2 files changed, 14 insertions(+) diff --git a/app/src/main/java/com/nextcloud/talk/activities/TakePhotoActivity.java b/app/src/main/java/com/nextcloud/talk/activities/TakePhotoActivity.java index 5eea1d84c..08b972545 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/TakePhotoActivity.java +++ b/app/src/main/java/com/nextcloud/talk/activities/TakePhotoActivity.java @@ -41,8 +41,10 @@ import android.widget.Toast; import com.google.common.util.concurrent.ListenableFuture; import com.nextcloud.talk.R; +import com.nextcloud.talk.application.NextcloudTalkApplication; import com.nextcloud.talk.databinding.ActivityTakePictureBinding; import com.nextcloud.talk.models.TakePictureViewModel; +import com.nextcloud.talk.ui.theme.ViewThemeUtils; import com.nextcloud.talk.utils.BitmapShrinker; import com.nextcloud.talk.utils.FileUtils; @@ -52,6 +54,8 @@ import java.util.Date; import java.util.Locale; import java.util.concurrent.ExecutionException; +import javax.inject.Inject; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.OptIn; @@ -66,9 +70,11 @@ import androidx.camera.lifecycle.ProcessCameraProvider; import androidx.core.content.ContextCompat; import androidx.exifinterface.media.ExifInterface; import androidx.lifecycle.ViewModelProvider; +import autodagger.AutoInjector; import static com.nextcloud.talk.utils.Mimetype.IMAGE_JPEG; +@AutoInjector(NextcloudTalkApplication.class) public class TakePhotoActivity extends AppCompatActivity { private static final String TAG = TakePhotoActivity.class.getSimpleName(); @@ -86,15 +92,22 @@ public class TakePhotoActivity extends AppCompatActivity { private Camera camera; + @Inject + ViewThemeUtils viewThemeUtils; + @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); + NextcloudTalkApplication.Companion.getSharedApplication().getComponentApplication().inject(this); binding = ActivityTakePictureBinding.inflate(getLayoutInflater()); viewModel = new ViewModelProvider(this).get(TakePictureViewModel.class); setContentView(binding.getRoot()); + viewThemeUtils.themeFAB(binding.takePhoto); + viewThemeUtils.colorMaterialButtonBackground(binding.send); + cameraProviderFuture = ProcessCameraProvider.getInstance(this); cameraProviderFuture.addListener(() -> { try { diff --git a/app/src/main/res/layout/activity_take_picture.xml b/app/src/main/res/layout/activity_take_picture.xml index 8f4d1de80..5382eb3e4 100644 --- a/app/src/main/res/layout/activity_take_picture.xml +++ b/app/src/main/res/layout/activity_take_picture.xml @@ -222,6 +222,7 @@ android:theme="@style/Button.Primary" android:tint="@android:color/white" android:visibility="gone" + tools:visibility="visible" app:backgroundTint="@color/colorPrimary" app:cornerRadius="48dp" app:elevation="0dp" From 4de7d06e8ef701fb4c4896fe44d619ed614a719f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Fri, 22 Jul 2022 16:35:04 +0200 Subject: [PATCH 14/58] Theme SharedItemsActivity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Brey --- .../RemoteFileBrowserItemsListViewHolder.kt | 22 +-------------- .../activities/SharedItemsActivity.kt | 14 ++++++++-- .../adapters/SharedItemsAdapter.kt | 11 +++++--- .../adapters/SharedItemsGridViewHolder.kt | 6 ++-- .../adapters/SharedItemsListViewHolder.kt | 8 ++++-- .../adapters/SharedItemsViewHolder.kt | 17 +++-------- .../nextcloud/talk/ui/theme/ViewThemeUtils.kt | 28 +++++++++++++++++++ 7 files changed, 60 insertions(+), 46 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/remotefilebrowser/adapters/RemoteFileBrowserItemsListViewHolder.kt b/app/src/main/java/com/nextcloud/talk/remotefilebrowser/adapters/RemoteFileBrowserItemsListViewHolder.kt index 5ef9d2852..241707a91 100644 --- a/app/src/main/java/com/nextcloud/talk/remotefilebrowser/adapters/RemoteFileBrowserItemsListViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/remotefilebrowser/adapters/RemoteFileBrowserItemsListViewHolder.kt @@ -20,10 +20,8 @@ package com.nextcloud.talk.remotefilebrowser.adapters -import android.graphics.drawable.Drawable import android.text.format.Formatter import android.view.View -import androidx.appcompat.content.res.AppCompatResources import autodagger.AutoInjector import com.facebook.drawee.backends.pipeline.Fresco import com.facebook.drawee.interfaces.DraweeController @@ -38,7 +36,6 @@ import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.DateUtils.getLocalDateTimeStringFromTimestamp import com.nextcloud.talk.utils.DisplayUtils -import com.nextcloud.talk.utils.DrawableUtils.getDrawableResourceIdForMimeType import com.nextcloud.talk.utils.Mimetype.FOLDER @AutoInjector(NextcloudTalkApplication::class) @@ -101,7 +98,7 @@ class RemoteFileBrowserItemsListViewHolder( binding.fileIcon .hierarchy .setPlaceholderImage( - getPlaceholderImage(item) + viewThemeUtils.getPlaceholderImage(binding.root.context, item.mimeType) ) if (item.hasPreview) { @@ -129,19 +126,6 @@ class RemoteFileBrowserItemsListViewHolder( binding.selectFileCheckbox.isChecked = selectionInterface.isPathSelected(item.path!!) } - private fun getPlaceholderImage(item: RemoteFileBrowserItem): Drawable? { - val drawableResourceId = getDrawableResourceIdForMimeType(item.mimeType) - val context = binding.fileIcon.context - val drawable = AppCompatResources.getDrawable( - context, - drawableResourceId - ) - if (drawable != null && THEMEABLE_PLACEHOLDER_IDS.contains(drawableResourceId)) { - viewThemeUtils.colorDrawable(context, drawable) - } - return drawable - } - private fun setSelectability() { if (selectable) { binding.selectFileCheckbox.visibility = View.VISIBLE @@ -164,9 +148,5 @@ class RemoteFileBrowserItemsListViewHolder( companion object { private const val DISABLED_ALPHA: Float = 0.38f private const val ENABLED_ALPHA: Float = 1.0f - private val THEMEABLE_PLACEHOLDER_IDS = listOf( - R.drawable.ic_mimetype_package_x_generic, - R.drawable.ic_mimetype_folder - ) } } diff --git a/app/src/main/java/com/nextcloud/talk/shareditems/activities/SharedItemsActivity.kt b/app/src/main/java/com/nextcloud/talk/shareditems/activities/SharedItemsActivity.kt index 2689e0829..48b415c59 100644 --- a/app/src/main/java/com/nextcloud/talk/shareditems/activities/SharedItemsActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/shareditems/activities/SharedItemsActivity.kt @@ -41,6 +41,7 @@ import com.nextcloud.talk.databinding.ActivitySharedItemsBinding import com.nextcloud.talk.shareditems.adapters.SharedItemsAdapter import com.nextcloud.talk.shareditems.model.SharedItemType import com.nextcloud.talk.shareditems.viewmodels.SharedItemsViewModel +import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.utils.DisplayUtils import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CONVERSATION_NAME import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN @@ -53,6 +54,9 @@ class SharedItemsActivity : AppCompatActivity() { @Inject lateinit var viewModelFactory: ViewModelProvider.Factory + @Inject + lateinit var viewThemeUtils: ViewThemeUtils + private lateinit var binding: ActivitySharedItemsBinding private lateinit var viewModel: SharedItemsViewModel @@ -72,7 +76,9 @@ class SharedItemsActivity : AppCompatActivity() { DisplayUtils.applyColorToStatusBar( this, ResourcesCompat.getColor( - resources, R.color.appbar, null + resources, + R.color.appbar, + null ) ) DisplayUtils.applyColorToNavigationBar( @@ -130,7 +136,8 @@ class SharedItemsActivity : AppCompatActivity() { showGrid, user, roomToken, - isUserConversationOwnerOrModerator + isUserConversationOwnerOrModerator, + viewThemeUtils ).apply { items = sharedMediaItems.items } @@ -142,6 +149,8 @@ class SharedItemsActivity : AppCompatActivity() { } else -> {} } + + viewThemeUtils.colorTabLayout(binding.sharedItemsTabs) } private fun clearEmptyLoading() { @@ -161,7 +170,6 @@ class SharedItemsActivity : AppCompatActivity() { } private fun initTabs(sharedItemTypes: Set) { - binding.sharedItemsTabs.removeAllTabs() if (sharedItemTypes.contains(SharedItemType.MEDIA)) { diff --git a/app/src/main/java/com/nextcloud/talk/shareditems/adapters/SharedItemsAdapter.kt b/app/src/main/java/com/nextcloud/talk/shareditems/adapters/SharedItemsAdapter.kt index ac98b91b1..5c2719e9d 100644 --- a/app/src/main/java/com/nextcloud/talk/shareditems/adapters/SharedItemsAdapter.kt +++ b/app/src/main/java/com/nextcloud/talk/shareditems/adapters/SharedItemsAdapter.kt @@ -37,18 +37,19 @@ import com.nextcloud.talk.shareditems.model.SharedItem import com.nextcloud.talk.shareditems.model.SharedLocationItem import com.nextcloud.talk.shareditems.model.SharedOtherItem import com.nextcloud.talk.shareditems.model.SharedPollItem +import com.nextcloud.talk.ui.theme.ViewThemeUtils class SharedItemsAdapter( private val showGrid: Boolean, private val user: User, private val roomToken: String, - private val isUserConversationOwnerOrModerator: Boolean + private val isUserConversationOwnerOrModerator: Boolean, + private val viewThemeUtils: ViewThemeUtils ) : RecyclerView.Adapter() { var items: List = emptyList() override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SharedItemsViewHolder { - return if (showGrid) { SharedItemsGridViewHolder( SharedItemGridBinding.inflate( @@ -56,7 +57,8 @@ class SharedItemsAdapter( parent, false ), - user + user, + viewThemeUtils ) } else { SharedItemsListViewHolder( @@ -65,7 +67,8 @@ class SharedItemsAdapter( parent, false ), - user + user, + viewThemeUtils ) } } diff --git a/app/src/main/java/com/nextcloud/talk/shareditems/adapters/SharedItemsGridViewHolder.kt b/app/src/main/java/com/nextcloud/talk/shareditems/adapters/SharedItemsGridViewHolder.kt index 4e672754e..30977e6c8 100644 --- a/app/src/main/java/com/nextcloud/talk/shareditems/adapters/SharedItemsGridViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/shareditems/adapters/SharedItemsGridViewHolder.kt @@ -27,11 +27,13 @@ import android.widget.ProgressBar import com.facebook.drawee.view.SimpleDraweeView import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.databinding.SharedItemGridBinding +import com.nextcloud.talk.ui.theme.ViewThemeUtils class SharedItemsGridViewHolder( override val binding: SharedItemGridBinding, - user: User -) : SharedItemsViewHolder(binding, user) { + user: User, + viewThemeUtils: ViewThemeUtils +) : SharedItemsViewHolder(binding, user, viewThemeUtils) { override val image: SimpleDraweeView get() = binding.image diff --git a/app/src/main/java/com/nextcloud/talk/shareditems/adapters/SharedItemsListViewHolder.kt b/app/src/main/java/com/nextcloud/talk/shareditems/adapters/SharedItemsListViewHolder.kt index fa611d839..6aa5722ca 100644 --- a/app/src/main/java/com/nextcloud/talk/shareditems/adapters/SharedItemsListViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/shareditems/adapters/SharedItemsListViewHolder.kt @@ -38,11 +38,14 @@ import com.nextcloud.talk.shareditems.model.SharedItem import com.nextcloud.talk.shareditems.model.SharedLocationItem import com.nextcloud.talk.shareditems.model.SharedOtherItem import com.nextcloud.talk.shareditems.model.SharedPollItem +import com.nextcloud.talk.ui.theme.ViewThemeUtils +import com.nextcloud.talk.utils.DateUtils class SharedItemsListViewHolder( override val binding: SharedItemListBinding, - user: User -) : SharedItemsViewHolder(binding, user) { + user: User, + viewThemeUtils: ViewThemeUtils +) : SharedItemsViewHolder(binding, user, viewThemeUtils) { override val image: SimpleDraweeView get() = binding.fileImage @@ -52,7 +55,6 @@ class SharedItemsListViewHolder( get() = binding.progressBar override fun onBind(item: SharedFileItem) { - super.onBind(item) binding.fileName.text = item.name diff --git a/app/src/main/java/com/nextcloud/talk/shareditems/adapters/SharedItemsViewHolder.kt b/app/src/main/java/com/nextcloud/talk/shareditems/adapters/SharedItemsViewHolder.kt index 205bbcb7c..184ef3091 100644 --- a/app/src/main/java/com/nextcloud/talk/shareditems/adapters/SharedItemsViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/shareditems/adapters/SharedItemsViewHolder.kt @@ -28,7 +28,6 @@ import android.net.Uri import android.util.Log import android.view.View import android.widget.ProgressBar -import androidx.core.content.ContextCompat import androidx.recyclerview.widget.RecyclerView import androidx.viewbinding.ViewBinding import com.facebook.drawee.backends.pipeline.Fresco @@ -43,16 +42,17 @@ import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.shareditems.model.SharedDeckCardItem import com.nextcloud.talk.shareditems.model.SharedFileItem import com.nextcloud.talk.shareditems.model.SharedItem +import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.shareditems.model.SharedLocationItem import com.nextcloud.talk.shareditems.model.SharedOtherItem import com.nextcloud.talk.shareditems.model.SharedPollItem import com.nextcloud.talk.utils.ApiUtils -import com.nextcloud.talk.utils.DrawableUtils import com.nextcloud.talk.utils.FileViewerUtils abstract class SharedItemsViewHolder( open val binding: ViewBinding, - internal val user: User + internal val user: User, + private val viewThemeUtils: ViewThemeUtils ) : RecyclerView.ViewHolder(binding.root) { companion object { @@ -71,7 +71,7 @@ abstract class SharedItemsViewHolder( ) open fun onBind(item: SharedFileItem) { - image.hierarchy.setPlaceholderImage(staticImage(item.mimeType, image)) + image.hierarchy.setPlaceholderImage(viewThemeUtils.getPlaceholderImage(image.context, item.mimeType)) if (item.previewAvailable) { image.controller = configurePreview(item) } @@ -107,7 +107,6 @@ abstract class SharedItemsViewHolder( } private fun configurePreview(item: SharedFileItem): DraweeController { - val imageRequest = ImageRequestBuilder.newBuilderWithSource(Uri.parse(item.previewLink)) .setProgressiveRenderingEnabled(true) .setRotationOptions(RotationOptions.autoRotate()) @@ -136,12 +135,4 @@ abstract class SharedItemsViewHolder( open fun onBind(item: SharedOtherItem) {} open fun onBind(item: SharedDeckCardItem) {} - - private fun staticImage( - mimeType: String?, - image: SimpleDraweeView - ): Drawable { - val drawableResourceId = DrawableUtils.getDrawableResourceIdForMimeType(mimeType) - return ContextCompat.getDrawable(image.context, drawableResourceId)!! - } } 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 index 916b1b981..d7de88750 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt @@ -30,6 +30,7 @@ import android.view.View import android.widget.CheckBox import android.widget.ImageView import android.widget.TextView +import androidx.appcompat.content.res.AppCompatResources import androidx.appcompat.widget.SwitchCompat import androidx.core.content.res.ResourcesCompat import androidx.core.view.children @@ -37,8 +38,10 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import com.google.android.material.button.MaterialButton import com.google.android.material.card.MaterialCardView import com.google.android.material.floatingactionbutton.FloatingActionButton +import com.google.android.material.tabs.TabLayout import com.google.android.material.textfield.TextInputLayout import com.nextcloud.talk.R +import com.nextcloud.talk.utils.DrawableUtils import com.yarolegovich.mp.MaterialPreferenceCategory import com.yarolegovich.mp.MaterialSwitchPreference import javax.inject.Inject @@ -197,4 +200,29 @@ class ViewThemeUtils @Inject constructor(val theme: ServerTheme) { textInputLayout.boxStrokeColor = color } } + + fun colorTabLayout(tabLayout: TabLayout) { + withElementColor(tabLayout) { color -> + tabLayout.setSelectedTabIndicatorColor(color) + } + } + + fun getPlaceholderImage(context: Context, mimetype: String?): Drawable? { + val drawableResourceId = DrawableUtils.getDrawableResourceIdForMimeType(mimetype) + val drawable = AppCompatResources.getDrawable( + context, + drawableResourceId + ) + if (drawable != null && THEMEABLE_PLACEHOLDER_IDS.contains(drawableResourceId)) { + colorDrawable(context, drawable) + } + return drawable + } + + companion object { + private val THEMEABLE_PLACEHOLDER_IDS = listOf( + R.drawable.ic_mimetype_package_x_generic, + R.drawable.ic_mimetype_folder + ) + } } From 3283e5b4f6e6cdf2f7bafc5fcbe88c9c4cce9607 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Fri, 22 Jul 2022 16:51:38 +0200 Subject: [PATCH 15/58] ConversationItem: theme unread message bubbles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Brey --- .../talk/adapters/items/ConversationItem.java | 19 ++++--------------- .../nextcloud/talk/ui/theme/ViewThemeUtils.kt | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/adapters/items/ConversationItem.java b/app/src/main/java/com/nextcloud/talk/adapters/items/ConversationItem.java index d6c7ff7ad..e9c172173 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/items/ConversationItem.java +++ b/app/src/main/java/com/nextcloud/talk/adapters/items/ConversationItem.java @@ -168,29 +168,18 @@ public class ConversationItem extends AbstractFlexibleItem + chip.chipBackgroundColor = ColorStateList.valueOf(color) + chip.setTextColor(theme.colorText) + } + } + + fun colorChipOutlined(chip: Chip, strokeWidth: Float) { + withElementColor(chip) { color -> + chip.chipBackgroundColor = ColorStateList.valueOf(Color.TRANSPARENT) + chip.chipStrokeWidth = strokeWidth + chip.chipStrokeColor = ColorStateList.valueOf(color) + chip.setTextColor(color) + } + } + companion object { private val THEMEABLE_PLACEHOLDER_IDS = listOf( R.drawable.ic_mimetype_package_x_generic, From e5bf5ec2618a15b7fe2557ef3d7aa4396505e5db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Fri, 22 Jul 2022 17:37:03 +0200 Subject: [PATCH 16/58] WIP: theme chat controller and message viewholders MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Brey --- .../MagicOutcomingTextMessageViewHolder.kt | 33 ++++++++++++------- .../talk/controllers/ChatController.kt | 6 ++++ .../bottomsheet/EntryMenuController.kt | 6 +++- .../nextcloud/talk/ui/theme/ViewThemeUtils.kt | 2 +- 4 files changed, 33 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/MagicOutcomingTextMessageViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/MagicOutcomingTextMessageViewHolder.kt index d4508c8e1..90d36e70b 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/MagicOutcomingTextMessageViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/MagicOutcomingTextMessageViewHolder.kt @@ -25,7 +25,6 @@ package com.nextcloud.talk.adapters.messages import android.content.Context import android.content.Intent -import android.graphics.PorterDuff import android.net.Uri import android.text.Spannable import android.text.SpannableString @@ -33,6 +32,7 @@ import android.util.TypedValue import android.view.View import androidx.core.content.ContextCompat import androidx.core.content.res.ResourcesCompat +import androidx.core.graphics.ColorUtils import androidx.core.view.ViewCompat import autodagger.AutoInjector import coil.load @@ -44,22 +44,29 @@ import com.nextcloud.talk.databinding.ItemCustomOutcomingTextMessageBinding import com.nextcloud.talk.models.json.chat.ChatMessage import com.nextcloud.talk.models.json.chat.ReadStatus import com.nextcloud.talk.ui.recyclerview.MessageSwipeCallback +import com.nextcloud.talk.ui.theme.ServerTheme +import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.DisplayUtils.getMessageSelector import com.nextcloud.talk.utils.DisplayUtils.searchAndReplaceWithMentionSpan import com.nextcloud.talk.utils.TextMatchers import com.stfalcon.chatkit.messages.MessageHolders.OutcomingTextMessageViewHolder -import java.util.HashMap import javax.inject.Inject +import kotlin.math.roundToInt @AutoInjector(NextcloudTalkApplication::class) class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessageViewHolder(itemView) { private val binding: ItemCustomOutcomingTextMessageBinding = ItemCustomOutcomingTextMessageBinding.bind(itemView) private val realView: View = itemView - @JvmField @Inject - var context: Context? = null + lateinit var context: Context + + @Inject + lateinit var viewThemeUtils: ViewThemeUtils + + @Inject + lateinit var serverTheme: ServerTheme lateinit var reactionsInterface: ReactionsInterface @@ -69,7 +76,7 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage val messageParameters: HashMap>? = message.messageParameters var messageString: Spannable = SpannableString(message.text) realView.isSelected = false - binding.messageTime.setTextColor(context!!.resources.getColor(R.color.white60)) + binding.messageTime.setTextColor(ColorUtils.setAlphaComponent(serverTheme.colorText, ALPHA_60_INT)) val layoutParams = binding.messageTime.layoutParams as FlexboxLayout.LayoutParams layoutParams.isWrapBefore = false var textSize = context!!.resources.getDimension(R.dimen.chat_text_size) @@ -89,6 +96,7 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage binding.messageText.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize) binding.messageTime.layoutParams = layoutParams binding.messageText.text = messageString + binding.messageText.setTextColor(serverTheme.colorText) // parent message handling if (!message.isDeleted && message.parentMessage != null) { @@ -112,8 +120,8 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage readStatusDrawableInt?.let { drawableInt -> ResourcesCompat.getDrawable(context!!.resources, drawableInt, null)?.let { - it.setColorFilter(ContextCompat.getColor(context!!, R.color.white60), PorterDuff.Mode.SRC_ATOP) binding.checkMark.setImageDrawable(it) + viewThemeUtils.colorImageViewText(binding.checkMark) } } @@ -148,20 +156,19 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage binding.messageQuote.quotedMessageAuthor.text = parentChatMessage.actorDisplayName ?: context!!.getText(R.string.nc_nick_guest) binding.messageQuote.quotedMessage.text = parentChatMessage.text - binding.messageQuote.quotedMessage.setTextColor( - ContextCompat.getColor(context!!, R.color.nc_outcoming_text_default) - ) - binding.messageQuote.quotedMessageAuthor.setTextColor(ContextCompat.getColor(context!!, R.color.nc_grey)) + binding.messageQuote.quotedMessage.setTextColor(serverTheme.colorText) + binding.messageQuote.quotedMessageAuthor.setTextColor(ContextCompat.getColor(context, R.color.nc_grey)) binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.white) } private fun setBubbleOnChatMessage(message: ChatMessage) { val resources = sharedApplication!!.resources + val elementColor = viewThemeUtils.getElementColor(binding.root.context) val bgBubbleColor = if (message.isDeleted) { - ResourcesCompat.getColor(resources, R.color.bg_message_list_outcoming_bubble_deleted, null) + ColorUtils.setAlphaComponent(elementColor, HALF_ALPHA_INT) } else { - ResourcesCompat.getColor(resources, R.color.bg_message_list_outcoming_bubble, null) + elementColor } if (message.isGrouped) { val bubbleDrawable = getMessageSelector( @@ -221,5 +228,7 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage companion object { const val TEXT_SIZE_MULTIPLIER = 2.5 + private const val HALF_ALPHA_INT: Int = 255 / 2 + private val ALPHA_60_INT: Int = (255 * 0.6).roundToInt() } } diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt b/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt index 170ddc447..e925039b3 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt +++ b/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt @@ -154,6 +154,7 @@ import com.nextcloud.talk.ui.dialog.MessageActionsDialog import com.nextcloud.talk.ui.dialog.ShowReactionsDialog import com.nextcloud.talk.ui.recyclerview.MessageSwipeActions import com.nextcloud.talk.ui.recyclerview.MessageSwipeCallback +import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.AttendeePermissionsUtil import com.nextcloud.talk.utils.ConductorRemapping @@ -235,6 +236,9 @@ class ChatController(args: Bundle) : @Inject lateinit var permissionUtil: PlatformPermissionUtil + @Inject + lateinit var viewThemeUtils: ViewThemeUtils + val disposables = DisposableSet() var roomToken: String? = null @@ -872,6 +876,8 @@ class ChatController(args: Bundle) : .nc_description_send_message_button ) + viewThemeUtils.colorImageView(binding.messageInputView.button) + if (currentConversation != null && currentConversation?.roomId != null) { loadAvatarForStatusBar() setTitle() diff --git a/app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/EntryMenuController.kt b/app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/EntryMenuController.kt index b592b2a54..f652b427e 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/EntryMenuController.kt +++ b/app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/EntryMenuController.kt @@ -46,6 +46,7 @@ import com.nextcloud.talk.controllers.base.NewBaseController import com.nextcloud.talk.controllers.util.viewBinding import com.nextcloud.talk.databinding.ControllerEntryMenuBinding import com.nextcloud.talk.models.json.conversations.Conversation +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.ShareUtils @@ -76,6 +77,9 @@ class EntryMenuController(args: Bundle) : @Inject lateinit var viewThemeUtils: ViewThemeUtils + @Inject + lateinit var serverTheme: ServerTheme + private val operation: ConversationOperationEnum private var conversation: Conversation? = null private var shareIntent: Intent? = null @@ -171,7 +175,7 @@ class EntryMenuController(args: Bundle) : } viewThemeUtils.colorTextInputLayout(binding.textInputLayout) - binding.textEdit.setTextColor(viewThemeUtils.theme.colorText) + binding.textEdit.setTextColor(serverTheme.colorText) viewThemeUtils.colorMaterialButtonText(binding.okButton) binding.textInputLayout.hint = labelText 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 index 8ddc46d52..0aa31d674 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt @@ -47,7 +47,7 @@ import com.yarolegovich.mp.MaterialPreferenceCategory import com.yarolegovich.mp.MaterialSwitchPreference import javax.inject.Inject -class ViewThemeUtils @Inject constructor(val theme: ServerTheme) { +class ViewThemeUtils @Inject constructor(private val theme: ServerTheme) { private fun isDarkMode(context: Context): Boolean = when ( context.resources.configuration.uiMode and From d1a562cf80d70199e3491a88824354df7662b1d0 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Tue, 26 Jul 2022 22:38:14 +0200 Subject: [PATCH 17/58] fix after rebase Signed-off-by: Andy Scherzinger --- app/src/main/java/com/nextcloud/talk/users/UserManager.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/nextcloud/talk/users/UserManager.kt b/app/src/main/java/com/nextcloud/talk/users/UserManager.kt index 485022992..978e04c18 100644 --- a/app/src/main/java/com/nextcloud/talk/users/UserManager.kt +++ b/app/src/main/java/com/nextcloud/talk/users/UserManager.kt @@ -51,7 +51,7 @@ class UserManager internal constructor(private val userRepository: UsersReposito return userRepository.getActiveUserObservable() } - fun deleteUser(internalId: Long) { + fun deleteUser(internalId: Long): Int { return userRepository.deleteUser(userRepository.getUserWithId(internalId).blockingGet()) } From 9be4358ae0c375d7598bbbceec1500996cc4b006 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Tue, 26 Jul 2022 23:45:04 +0200 Subject: [PATCH 18/58] theme contacts selector icon Signed-off-by: Andy Scherzinger --- .../com/nextcloud/talk/adapters/items/ContactItem.java | 7 ++++++- .../com/nextcloud/talk/controllers/ContactsController.kt | 3 ++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/adapters/items/ContactItem.java b/app/src/main/java/com/nextcloud/talk/adapters/items/ContactItem.java index a358c931c..5090bc761 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/items/ContactItem.java +++ b/app/src/main/java/com/nextcloud/talk/adapters/items/ContactItem.java @@ -35,6 +35,7 @@ import com.nextcloud.talk.application.NextcloudTalkApplication; import com.nextcloud.talk.data.user.model.User; import com.nextcloud.talk.databinding.RvItemContactBinding; import com.nextcloud.talk.models.json.participants.Participant; +import com.nextcloud.talk.ui.theme.ViewThemeUtils; import com.nextcloud.talk.utils.ApiUtils; import com.nextcloud.talk.utils.DisplayUtils; @@ -59,14 +60,17 @@ public class ContactItem extends AbstractFlexibleItem Date: Wed, 27 Jul 2022 00:09:43 +0200 Subject: [PATCH 19/58] first steps to theme poll creation Signed-off-by: Andy Scherzinger --- .../talk/polls/ui/PollCreateDialogFragment.kt | 20 +++++++++++++++++++ .../main/res/layout/dialog_poll_create.xml | 3 +++ 2 files changed, 23 insertions(+) diff --git a/app/src/main/java/com/nextcloud/talk/polls/ui/PollCreateDialogFragment.kt b/app/src/main/java/com/nextcloud/talk/polls/ui/PollCreateDialogFragment.kt index e94f1e750..33e12c1aa 100644 --- a/app/src/main/java/com/nextcloud/talk/polls/ui/PollCreateDialogFragment.kt +++ b/app/src/main/java/com/nextcloud/talk/polls/ui/PollCreateDialogFragment.kt @@ -43,6 +43,7 @@ import com.nextcloud.talk.polls.adapters.PollCreateOptionItem import com.nextcloud.talk.polls.adapters.PollCreateOptionsAdapter import com.nextcloud.talk.polls.adapters.PollCreateOptionsItemListener import com.nextcloud.talk.polls.viewmodels.PollCreateViewModel +import com.nextcloud.talk.ui.theme.ViewThemeUtils import javax.inject.Inject @AutoInjector(NextcloudTalkApplication::class) @@ -51,6 +52,9 @@ class PollCreateDialogFragment : DialogFragment(), PollCreateOptionsItemListener @Inject lateinit var viewModelFactory: ViewModelProvider.Factory + @Inject + lateinit var viewThemeUtils: ViewThemeUtils + private lateinit var binding: DialogPollCreateBinding private lateinit var viewModel: PollCreateViewModel @@ -88,10 +92,26 @@ class PollCreateDialogFragment : DialogFragment(), PollCreateOptionsItemListener adapter = PollCreateOptionsAdapter(this) binding.pollCreateOptionsList.adapter = adapter + themeDialog() + setupListeners() setupStateObserver() } + private fun themeDialog() { + viewThemeUtils.colorTextViewText(binding.pollQuestion) + viewThemeUtils.colorTextViewText(binding.pollOptions) + viewThemeUtils.colorTextViewText(binding.pollSettings) + + viewThemeUtils.colorMaterialButtonText(binding.pollAddOptionsItem) + // TODO button also needs a disabled state handling for colors + viewThemeUtils.colorMaterialButtonText(binding.pollDismiss) + viewThemeUtils.colorMaterialButtonBackground(binding.pollCreateButton) + + viewThemeUtils.themeCheckbox(binding.pollPrivatePollCheckbox) + viewThemeUtils.themeCheckbox(binding.pollMultipleAnswersCheckbox) + } + private fun setupListeners() { binding.pollAddOptionsItem.setOnClickListener { viewModel.addOption() diff --git a/app/src/main/res/layout/dialog_poll_create.xml b/app/src/main/res/layout/dialog_poll_create.xml index da0fe5f7f..b03a5c146 100644 --- a/app/src/main/res/layout/dialog_poll_create.xml +++ b/app/src/main/res/layout/dialog_poll_create.xml @@ -35,6 +35,7 @@ android:paddingTop="@dimen/dialog_padding_top_bottom"> Date: Wed, 27 Jul 2022 00:10:17 +0200 Subject: [PATCH 20/58] add proper checkbox- state coloring Signed-off-by: Andy Scherzinger --- .../java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) 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 index 0aa31d674..f3b9050e3 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt @@ -183,8 +183,13 @@ class ViewThemeUtils @Inject constructor(private val theme: ServerTheme) { fun themeCheckbox(checkbox: CheckBox) { withElementColor(checkbox) { color -> - checkbox.setTextColor(color) - checkbox.buttonTintList = ColorStateList.valueOf(color) + checkbox.buttonTintList = ColorStateList( + arrayOf( + intArrayOf(-android.R.attr.state_checked), + intArrayOf(android.R.attr.state_checked), + ), + intArrayOf(Color.GRAY, color) + ) } } From 907386e9b7d1f949cfbbefa3c33d5e32b9deee36 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Wed, 27 Jul 2022 00:18:54 +0200 Subject: [PATCH 21/58] add proper button-state coloring for button text/icon Signed-off-by: Andy Scherzinger --- .../com/nextcloud/talk/ui/theme/ViewThemeUtils.kt | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) 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 index f3b9050e3..e10977819 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt @@ -32,6 +32,7 @@ import android.widget.ImageView import android.widget.TextView import androidx.appcompat.content.res.AppCompatResources import androidx.appcompat.widget.SwitchCompat +import androidx.core.content.ContextCompat import androidx.core.content.res.ResourcesCompat import androidx.core.view.children import androidx.swiperefreshlayout.widget.SwipeRefreshLayout @@ -113,8 +114,17 @@ class ViewThemeUtils @Inject constructor(private val theme: ServerTheme) { } fun colorMaterialButtonText(button: MaterialButton) { - colorTextViewElement(button) - button.iconTint = ColorStateList.valueOf(getElementColor(button.context)) + withElementColor(button) { color -> + val disabledColor = ContextCompat.getColor(button.context, R.color.disabled_text) + val colorStateList = ColorStateList( + arrayOf( + intArrayOf(android.R.attr.state_enabled), + intArrayOf(-android.R.attr.state_enabled)), + intArrayOf(color, disabledColor) + ) + button.setTextColor(colorStateList) + button.iconTint = colorStateList + } } fun colorMaterialButtonBackground(button: MaterialButton) { From 28aae006418e53c86bbc68cb470f820bab68bf6d Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Wed, 27 Jul 2022 00:31:25 +0200 Subject: [PATCH 22/58] extend text input layout theming Signed-off-by: Andy Scherzinger --- .../nextcloud/talk/ui/theme/ViewThemeUtils.kt | 52 ++++++++++++++++++- 1 file changed, 50 insertions(+), 2 deletions(-) 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 index e10977819..a2670f4af 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt @@ -119,7 +119,8 @@ class ViewThemeUtils @Inject constructor(private val theme: ServerTheme) { val colorStateList = ColorStateList( arrayOf( intArrayOf(android.R.attr.state_enabled), - intArrayOf(-android.R.attr.state_enabled)), + intArrayOf(-android.R.attr.state_enabled) + ), intArrayOf(color, disabledColor) ) button.setTextColor(colorStateList) @@ -212,8 +213,55 @@ class ViewThemeUtils @Inject constructor(private val theme: ServerTheme) { fun colorTextInputLayout(textInputLayout: TextInputLayout) { withElementColor(textInputLayout) { color -> - textInputLayout.hintTextColor = ColorStateList.valueOf(color) + // TODO calculate error color based on primary color, dark/light aware + val errorColor = Color.GRAY textInputLayout.boxStrokeColor = color + textInputLayout.setErrorIconTintList( + ColorStateList( + arrayOf( + intArrayOf(-android.R.attr.state_focused), + intArrayOf(android.R.attr.state_focused) + ), + intArrayOf( + errorColor, + errorColor + ) + ) + ) + textInputLayout.setErrorTextColor( + ColorStateList( + arrayOf( + intArrayOf(-android.R.attr.state_focused), + intArrayOf(android.R.attr.state_focused) + ), + intArrayOf( + errorColor, + errorColor + ) + ) + ) + textInputLayout.boxStrokeErrorColor = + ColorStateList( + arrayOf( + intArrayOf(-android.R.attr.state_focused), + intArrayOf(android.R.attr.state_focused) + ), + intArrayOf( + errorColor, + errorColor + ) + ) + textInputLayout.defaultHintTextColor = + ColorStateList( + arrayOf( + intArrayOf(-android.R.attr.state_focused), + intArrayOf(android.R.attr.state_focused) + ), + intArrayOf( + Color.GRAY, + color + ) + ) } } From 0463a39bfb71dbfa1b93c6de5a7698e1afc5b7e5 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Wed, 27 Jul 2022 00:40:46 +0200 Subject: [PATCH 23/58] Add EditText coloring Signed-off-by: Andy Scherzinger --- .../adapters/PollCreateOptionViewHolder.kt | 5 ++++- .../adapters/PollCreateOptionsAdapter.kt | 6 ++++-- .../talk/polls/ui/PollCreateDialogFragment.kt | 4 +++- .../nextcloud/talk/ui/theme/ViewThemeUtils.kt | 20 +++++++++++++++++++ 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/polls/adapters/PollCreateOptionViewHolder.kt b/app/src/main/java/com/nextcloud/talk/polls/adapters/PollCreateOptionViewHolder.kt index 91afdd16c..c84060b5e 100644 --- a/app/src/main/java/com/nextcloud/talk/polls/adapters/PollCreateOptionViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/polls/adapters/PollCreateOptionViewHolder.kt @@ -26,10 +26,12 @@ import android.text.TextWatcher import androidx.recyclerview.widget.RecyclerView import com.nextcloud.talk.R import com.nextcloud.talk.databinding.PollCreateOptionsItemBinding +import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.utils.EmojiTextInputEditText class PollCreateOptionViewHolder( - private val binding: PollCreateOptionsItemBinding + private val binding: PollCreateOptionsItemBinding, + private val viewThemeUtils: ViewThemeUtils ) : RecyclerView.ViewHolder(binding.root) { lateinit var optionText: EmojiTextInputEditText @@ -48,6 +50,7 @@ class PollCreateOptionViewHolder( } binding.pollOptionTextEdit.setText(pollCreateOptionItem.pollOption) + viewThemeUtils.colorEditText(binding.pollOptionText) if (focus) { itemsListener.requestFocus(binding.pollOptionTextEdit) diff --git a/app/src/main/java/com/nextcloud/talk/polls/adapters/PollCreateOptionsAdapter.kt b/app/src/main/java/com/nextcloud/talk/polls/adapters/PollCreateOptionsAdapter.kt index e827a56a6..724d87f40 100644 --- a/app/src/main/java/com/nextcloud/talk/polls/adapters/PollCreateOptionsAdapter.kt +++ b/app/src/main/java/com/nextcloud/talk/polls/adapters/PollCreateOptionsAdapter.kt @@ -24,9 +24,11 @@ import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import com.nextcloud.talk.databinding.PollCreateOptionsItemBinding +import com.nextcloud.talk.ui.theme.ViewThemeUtils class PollCreateOptionsAdapter( - private val clickListener: PollCreateOptionsItemListener + private val clickListener: PollCreateOptionsItemListener, + private val viewThemeUtils: ViewThemeUtils ) : RecyclerView.Adapter() { internal var list: ArrayList = ArrayList() @@ -34,7 +36,7 @@ class PollCreateOptionsAdapter( override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PollCreateOptionViewHolder { val itemBinding = PollCreateOptionsItemBinding.inflate(LayoutInflater.from(parent.context), parent, false) - return PollCreateOptionViewHolder(itemBinding) + return PollCreateOptionViewHolder(itemBinding, viewThemeUtils) } override fun onBindViewHolder(holder: PollCreateOptionViewHolder, position: Int) { diff --git a/app/src/main/java/com/nextcloud/talk/polls/ui/PollCreateDialogFragment.kt b/app/src/main/java/com/nextcloud/talk/polls/ui/PollCreateDialogFragment.kt index 33e12c1aa..080c9fadb 100644 --- a/app/src/main/java/com/nextcloud/talk/polls/ui/PollCreateDialogFragment.kt +++ b/app/src/main/java/com/nextcloud/talk/polls/ui/PollCreateDialogFragment.kt @@ -89,7 +89,7 @@ class PollCreateDialogFragment : DialogFragment(), PollCreateOptionsItemListener binding.pollCreateOptionsList.layoutManager = LinearLayoutManager(context) - adapter = PollCreateOptionsAdapter(this) + adapter = PollCreateOptionsAdapter(this, viewThemeUtils) binding.pollCreateOptionsList.adapter = adapter themeDialog() @@ -103,6 +103,8 @@ class PollCreateDialogFragment : DialogFragment(), PollCreateOptionsItemListener viewThemeUtils.colorTextViewText(binding.pollOptions) viewThemeUtils.colorTextViewText(binding.pollSettings) + viewThemeUtils.colorEditText(binding.pollCreateQuestion) + viewThemeUtils.colorMaterialButtonText(binding.pollAddOptionsItem) // TODO button also needs a disabled state handling for colors viewThemeUtils.colorMaterialButtonText(binding.pollDismiss) 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 index a2670f4af..57a21b52d 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt @@ -25,9 +25,11 @@ import android.content.Context import android.content.res.ColorStateList import android.content.res.Configuration import android.graphics.Color +import android.graphics.PorterDuff import android.graphics.drawable.Drawable import android.view.View import android.widget.CheckBox +import android.widget.EditText import android.widget.ImageView import android.widget.TextView import androidx.appcompat.content.res.AppCompatResources @@ -211,6 +213,24 @@ class ViewThemeUtils @Inject constructor(private val theme: ServerTheme) { } } + fun colorEditText(editText: EditText) { + withElementColor(editText) { color -> + editText.setTextColor(color) + // TODO check API-level compatibility + //editText.background.setColorFilter(color, PorterDuff.Mode.SRC_ATOP) + editText.backgroundTintList = ColorStateList( + arrayOf( + intArrayOf(-android.R.attr.state_focused), + intArrayOf(android.R.attr.state_focused) + ), + intArrayOf( + Color.GRAY, + color + ) + ) + } + } + fun colorTextInputLayout(textInputLayout: TextInputLayout) { withElementColor(textInputLayout) { color -> // TODO calculate error color based on primary color, dark/light aware From e54abe63f18c0c9f056fc30b7b445a0845665bae Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Wed, 27 Jul 2022 20:15:26 +0200 Subject: [PATCH 24/58] theme polls and add further theming functions to the utils Signed-off-by: Andy Scherzinger --- .../adapters/PollResultHeaderViewHolder.kt | 6 ++- .../talk/polls/adapters/PollResultsAdapter.kt | 4 +- .../talk/polls/ui/PollResultsFragment.kt | 15 ++++++- .../talk/polls/ui/PollVoteFragment.kt | 14 ++++++ .../nextcloud/talk/ui/theme/ViewThemeUtils.kt | 45 +++++++++++++++++-- 5 files changed, 77 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/polls/adapters/PollResultHeaderViewHolder.kt b/app/src/main/java/com/nextcloud/talk/polls/adapters/PollResultHeaderViewHolder.kt index b963f515d..f08cb68cf 100644 --- a/app/src/main/java/com/nextcloud/talk/polls/adapters/PollResultHeaderViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/polls/adapters/PollResultHeaderViewHolder.kt @@ -23,15 +23,19 @@ package com.nextcloud.talk.polls.adapters import android.annotation.SuppressLint import android.graphics.Typeface import com.nextcloud.talk.databinding.PollResultHeaderItemBinding +import com.nextcloud.talk.ui.theme.ViewThemeUtils class PollResultHeaderViewHolder( - override val binding: PollResultHeaderItemBinding + override val binding: PollResultHeaderItemBinding, + private val viewThemeUtils: ViewThemeUtils ) : PollResultViewHolder(binding) { @SuppressLint("SetTextI18n") override fun bind(pollResultItem: PollResultItem, clickListener: PollResultItemClickListener) { val item = pollResultItem as PollResultHeaderItem + viewThemeUtils.colorProgressBar(binding.pollOptionBar) + binding.root.setOnClickListener { clickListener.onClick() } binding.pollOptionText.text = item.name diff --git a/app/src/main/java/com/nextcloud/talk/polls/adapters/PollResultsAdapter.kt b/app/src/main/java/com/nextcloud/talk/polls/adapters/PollResultsAdapter.kt index 98a576cba..df600fd37 100644 --- a/app/src/main/java/com/nextcloud/talk/polls/adapters/PollResultsAdapter.kt +++ b/app/src/main/java/com/nextcloud/talk/polls/adapters/PollResultsAdapter.kt @@ -27,10 +27,12 @@ import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.databinding.PollResultHeaderItemBinding import com.nextcloud.talk.databinding.PollResultVoterItemBinding import com.nextcloud.talk.databinding.PollResultVotersOverviewItemBinding +import com.nextcloud.talk.ui.theme.ViewThemeUtils class PollResultsAdapter( private val user: User, private val clickListener: PollResultItemClickListener, + private val viewThemeUtils: ViewThemeUtils ) : RecyclerView.Adapter() { internal var list: MutableList = ArrayList() @@ -43,7 +45,7 @@ class PollResultsAdapter( LayoutInflater.from(parent.context), parent, false ) - viewHolder = PollResultHeaderViewHolder(itemBinding) + viewHolder = PollResultHeaderViewHolder(itemBinding, viewThemeUtils) } PollResultVoterItem.VIEW_TYPE -> { val itemBinding = PollResultVoterItemBinding.inflate( diff --git a/app/src/main/java/com/nextcloud/talk/polls/ui/PollResultsFragment.kt b/app/src/main/java/com/nextcloud/talk/polls/ui/PollResultsFragment.kt index b1cbe4392..0a9c3db12 100644 --- a/app/src/main/java/com/nextcloud/talk/polls/ui/PollResultsFragment.kt +++ b/app/src/main/java/com/nextcloud/talk/polls/ui/PollResultsFragment.kt @@ -38,6 +38,7 @@ import com.nextcloud.talk.polls.adapters.PollResultItemClickListener import com.nextcloud.talk.polls.adapters.PollResultsAdapter import com.nextcloud.talk.polls.viewmodels.PollMainViewModel import com.nextcloud.talk.polls.viewmodels.PollResultsViewModel +import com.nextcloud.talk.ui.theme.ViewThemeUtils import javax.inject.Inject @AutoInjector(NextcloudTalkApplication::class) @@ -46,6 +47,9 @@ class PollResultsFragment : Fragment(), PollResultItemClickListener { @Inject lateinit var viewModelFactory: ViewModelProvider.Factory + @Inject + lateinit var viewThemeUtils: ViewThemeUtils + private lateinit var parentViewModel: PollMainViewModel lateinit var viewModel: PollResultsViewModel @@ -82,17 +86,24 @@ class PollResultsFragment : Fragment(), PollResultItemClickListener { } viewModel.items.observe(viewLifecycleOwner) { - val adapter = PollResultsAdapter(parentViewModel.user, this).apply { + val adapter = PollResultsAdapter(parentViewModel.user, this, viewThemeUtils).apply { if (it != null) { list = it } } binding.pollResultsList.adapter = adapter } + + themeDialog() + } + + private fun themeDialog() { + viewThemeUtils.colorMaterialButtonBackground(binding.editVoteButton) + viewThemeUtils.colorMaterialButtonText(binding.pollResultsEndPollButton) } private fun initAdapter() { - adapter = PollResultsAdapter(parentViewModel.user, this) + adapter = PollResultsAdapter(parentViewModel.user, this, viewThemeUtils) binding.pollResultsList.adapter = adapter binding.pollResultsList.layoutManager = LinearLayoutManager(context) } diff --git a/app/src/main/java/com/nextcloud/talk/polls/ui/PollVoteFragment.kt b/app/src/main/java/com/nextcloud/talk/polls/ui/PollVoteFragment.kt index 67b878442..39b637637 100644 --- a/app/src/main/java/com/nextcloud/talk/polls/ui/PollVoteFragment.kt +++ b/app/src/main/java/com/nextcloud/talk/polls/ui/PollVoteFragment.kt @@ -43,6 +43,7 @@ import com.nextcloud.talk.databinding.DialogPollVoteBinding import com.nextcloud.talk.polls.model.Poll import com.nextcloud.talk.polls.viewmodels.PollMainViewModel import com.nextcloud.talk.polls.viewmodels.PollVoteViewModel +import com.nextcloud.talk.ui.theme.ViewThemeUtils import javax.inject.Inject @AutoInjector(NextcloudTalkApplication::class) @@ -51,6 +52,9 @@ class PollVoteFragment : Fragment() { @Inject lateinit var viewModelFactory: ViewModelProvider.Factory + @Inject + lateinit var viewThemeUtils: ViewThemeUtils + private lateinit var parentViewModel: PollMainViewModel lateinit var viewModel: PollVoteViewModel @@ -117,6 +121,14 @@ class PollVoteFragment : Fragment() { binding.pollVoteEditDismiss.setOnClickListener { parentViewModel.dismissEditVotes() } + + themeDialog() + } + + private fun themeDialog() { + viewThemeUtils.colorMaterialButtonBackground(binding.pollVoteSubmitButton) + viewThemeUtils.colorMaterialButtonText(binding.pollVoteEndPollButton) + viewThemeUtils.colorMaterialButtonText(binding.pollVoteEndPollButton) } private fun updateDismissEditButton(showDismissEditButton: Boolean) { @@ -136,6 +148,7 @@ class PollVoteFragment : Fragment() { RadioButton(context).apply { text = option } }?.forEachIndexed { index, radioButton -> radioButton.id = index + viewThemeUtils.themeRadioButton(radioButton) makeOptionBoldIfSelfVoted(radioButton, poll, index) binding.pollVoteRadioGroup.addView(radioButton) @@ -156,6 +169,7 @@ class PollVoteFragment : Fragment() { setLayoutParams(layoutParams) } }?.forEachIndexed { index, checkBox -> + viewThemeUtils.themeCheckbox(checkBox) checkBox.id = index makeOptionBoldIfSelfVoted(checkBox, poll, index) binding.voteOptionsCheckboxesWrapper.addView(checkBox) 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 index 57a21b52d..9778e12f2 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt @@ -25,23 +25,25 @@ import android.content.Context import android.content.res.ColorStateList import android.content.res.Configuration import android.graphics.Color -import android.graphics.PorterDuff import android.graphics.drawable.Drawable import android.view.View import android.widget.CheckBox import android.widget.EditText import android.widget.ImageView +import android.widget.RadioButton import android.widget.TextView import androidx.appcompat.content.res.AppCompatResources import androidx.appcompat.widget.SwitchCompat import androidx.core.content.ContextCompat import androidx.core.content.res.ResourcesCompat +import androidx.core.graphics.ColorUtils import androidx.core.view.children import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import com.google.android.material.button.MaterialButton import com.google.android.material.card.MaterialCardView import com.google.android.material.chip.Chip import com.google.android.material.floatingactionbutton.FloatingActionButton +import com.google.android.material.progressindicator.LinearProgressIndicator import com.google.android.material.tabs.TabLayout import com.google.android.material.textfield.TextInputLayout import com.nextcloud.talk.R @@ -50,6 +52,7 @@ import com.yarolegovich.mp.MaterialPreferenceCategory import com.yarolegovich.mp.MaterialSwitchPreference import javax.inject.Inject +@Suppress("Detekt.TooManyFunctions") class ViewThemeUtils @Inject constructor(private val theme: ServerTheme) { private fun isDarkMode(context: Context): Boolean = when ( @@ -176,7 +179,7 @@ class ViewThemeUtils @Inject constructor(private val theme: ServerTheme) { context.theme ) - val trackColor = Color.argb(77, Color.red(color), Color.green(color), Color.blue(color)) + val trackColor = Color.argb(TRACK_ALPHA, Color.red(color), Color.green(color), Color.blue(color)) switchCompat.thumbTintList = ColorStateList( arrayOf(intArrayOf(android.R.attr.state_checked), intArrayOf()), intArrayOf(color, thumbUncheckedColor) @@ -206,6 +209,18 @@ class ViewThemeUtils @Inject constructor(private val theme: ServerTheme) { } } + fun themeRadioButton(radioButton: RadioButton) { + withElementColor(radioButton) { color -> + radioButton.buttonTintList = ColorStateList( + arrayOf( + intArrayOf(-android.R.attr.state_checked), + intArrayOf(android.R.attr.state_checked), + ), + intArrayOf(Color.GRAY, color) + ) + } + } + fun themeSwipeRefreshLayout(swipeRefreshLayout: SwipeRefreshLayout) { withElementColor(swipeRefreshLayout) { color -> swipeRefreshLayout.setColorSchemeColors(color) @@ -213,11 +228,17 @@ class ViewThemeUtils @Inject constructor(private val theme: ServerTheme) { } } + fun colorProgressBar(progressIndicator: LinearProgressIndicator) { + withElementColor(progressIndicator) { color -> + progressIndicator.setIndicatorColor(progressColor(progressIndicator.context, color)) + } + } + fun colorEditText(editText: EditText) { withElementColor(editText) { color -> editText.setTextColor(color) // TODO check API-level compatibility - //editText.background.setColorFilter(color, PorterDuff.Mode.SRC_ATOP) + // editText.background.setColorFilter(color, PorterDuff.Mode.SRC_ATOP) editText.backgroundTintList = ColorStateList( arrayOf( intArrayOf(-android.R.attr.state_focused), @@ -319,10 +340,28 @@ class ViewThemeUtils @Inject constructor(private val theme: ServerTheme) { } } + private fun progressColor(context: Context, color: Int): Int { + val hsl = FloatArray(HSL_SIZE) + ColorUtils.RGBToHSL(Color.red(color), Color.green(color), Color.blue(color), hsl) + + if (isDarkMode(context)) { + hsl[INDEX_LUMINATION] = LUMINATION_DARK_THEME + } else { + hsl[INDEX_LUMINATION] = LUMINATION_LIGHT_THEME + } + + return ColorUtils.HSLToColor(hsl) + } + companion object { private val THEMEABLE_PLACEHOLDER_IDS = listOf( R.drawable.ic_mimetype_package_x_generic, R.drawable.ic_mimetype_folder ) + private const val TRACK_ALPHA: Int = 77 + private const val HSL_SIZE: Int = 3 + private const val INDEX_LUMINATION: Int = 2 + private const val LUMINATION_LIGHT_THEME: Float = 0.76f + private const val LUMINATION_DARK_THEME: Float = 0.28f } } From 9aabb8804ed6c588be71734db2894474c1c842ff Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Wed, 27 Jul 2022 20:25:46 +0200 Subject: [PATCH 25/58] extend button theming for primary actions to respect states and also cover icons Signed-off-by: Andy Scherzinger --- .../com/nextcloud/talk/ui/theme/ViewThemeUtils.kt | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) 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 index 9778e12f2..5769c2ca3 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt @@ -136,7 +136,18 @@ class ViewThemeUtils @Inject constructor(private val theme: ServerTheme) { fun colorMaterialButtonBackground(button: MaterialButton) { withElementColor(button) { color -> button.setBackgroundColor(color) - button.setTextColor(theme.colorText) + + val disabledColor = ContextCompat.getColor(button.context, R.color.disabled_text) + val colorStateList = ColorStateList( + arrayOf( + intArrayOf(android.R.attr.state_enabled), + intArrayOf(-android.R.attr.state_enabled) + ), + intArrayOf(theme.colorText, disabledColor) + ) + + button.setTextColor(colorStateList) + button.iconTint = colorStateList } } From a907b1ba519da8ffc4dbf9ce8f0cd2fff0ff725a Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Wed, 27 Jul 2022 22:50:26 +0200 Subject: [PATCH 26/58] fix theming for poll button Signed-off-by: Andy Scherzinger --- .../main/java/com/nextcloud/talk/polls/ui/PollVoteFragment.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/nextcloud/talk/polls/ui/PollVoteFragment.kt b/app/src/main/java/com/nextcloud/talk/polls/ui/PollVoteFragment.kt index 39b637637..5972334db 100644 --- a/app/src/main/java/com/nextcloud/talk/polls/ui/PollVoteFragment.kt +++ b/app/src/main/java/com/nextcloud/talk/polls/ui/PollVoteFragment.kt @@ -128,7 +128,7 @@ class PollVoteFragment : Fragment() { private fun themeDialog() { viewThemeUtils.colorMaterialButtonBackground(binding.pollVoteSubmitButton) viewThemeUtils.colorMaterialButtonText(binding.pollVoteEndPollButton) - viewThemeUtils.colorMaterialButtonText(binding.pollVoteEndPollButton) + viewThemeUtils.colorMaterialButtonText(binding.pollVoteEditDismiss) } private fun updateDismissEditButton(showDismissEditButton: Boolean) { From 0f94b8c473f08c467ee020c335a24a3e2d28c7e9 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Wed, 27 Jul 2022 22:50:54 +0200 Subject: [PATCH 27/58] theme outgoing poll bubble Signed-off-by: Andy Scherzinger --- .../OutcomingPollMessageViewHolder.kt | 35 +++++++++++++++---- .../item_custom_outcoming_poll_message.xml | 8 ++--- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingPollMessageViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingPollMessageViewHolder.kt index 2d1726d57..497e2841a 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingPollMessageViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingPollMessageViewHolder.kt @@ -23,9 +23,12 @@ package com.nextcloud.talk.adapters.messages import android.annotation.SuppressLint import android.content.Context +import android.content.res.ColorStateList import android.graphics.PorterDuff import android.view.View import androidx.appcompat.content.res.AppCompatResources +import androidx.core.content.res.ResourcesCompat +import androidx.core.graphics.ColorUtils import androidx.core.view.ViewCompat import autodagger.AutoInjector import coil.load @@ -38,11 +41,14 @@ import com.nextcloud.talk.databinding.ItemCustomOutcomingPollMessageBinding import com.nextcloud.talk.models.json.chat.ChatMessage import com.nextcloud.talk.models.json.chat.ReadStatus import com.nextcloud.talk.polls.ui.PollMainDialogFragment +import com.nextcloud.talk.ui.theme.ServerTheme +import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.DisplayUtils import com.nextcloud.talk.utils.preferences.AppPreferences import com.stfalcon.chatkit.messages.MessageHolders import javax.inject.Inject +import kotlin.math.roundToInt @AutoInjector(NextcloudTalkApplication::class) class OutcomingPollMessageViewHolder(outcomingView: View, payload: Any) : MessageHolders @@ -54,6 +60,12 @@ class OutcomingPollMessageViewHolder(outcomingView: View, payload: Any) : Messag @Inject lateinit var context: Context + @Inject + lateinit var viewThemeUtils: ViewThemeUtils + + @Inject + lateinit var serverTheme: ServerTheme + @Inject lateinit var appPreferences: AppPreferences @@ -73,7 +85,12 @@ class OutcomingPollMessageViewHolder(outcomingView: View, payload: Any) : Messag colorizeMessageBubble(message) itemView.isSelected = false - binding.messageTime.setTextColor(context.resources.getColor(R.color.white60)) + binding.messageTime.setTextColor( + ColorUtils.setAlphaComponent( + serverTheme.colorText, + ALPHA_60_INT + ) + ) // parent message handling setParentMessageDataOnMessageItem(message) @@ -92,8 +109,8 @@ class OutcomingPollMessageViewHolder(outcomingView: View, payload: Any) : Messag readStatusDrawableInt?.let { drawableInt -> AppCompatResources.getDrawable(context, drawableInt)?.let { - it.setColorFilter(context.resources!!.getColor(R.color.white60), PorterDuff.Mode.SRC_ATOP) binding.checkMark.setImageDrawable(it) + viewThemeUtils.colorImageViewText(binding.checkMark) } } @@ -126,6 +143,9 @@ class OutcomingPollMessageViewHolder(outcomingView: View, payload: Any) : Messag } if (pollId != null && pollName != null) { + binding.messagePollTitle.setTextColor(serverTheme.colorText) + binding.messagePollSubtitle.setTextColor(serverTheme.colorText) + binding.messagePollIcon.imageTintList = ColorStateList.valueOf(serverTheme.colorText) binding.messagePollTitle.text = pollName val roomToken = (payload as? MessagePayload)!!.roomToken @@ -180,15 +200,16 @@ class OutcomingPollMessageViewHolder(outcomingView: View, payload: Any) : Messag private fun colorizeMessageBubble(message: ChatMessage) { val resources = sharedApplication!!.resources + val elementColor = viewThemeUtils.getElementColor(binding.root.context) val bgBubbleColor = if (message.isDeleted) { - resources.getColor(R.color.bg_message_list_outcoming_bubble_deleted) + ColorUtils.setAlphaComponent(elementColor, HALF_ALPHA_INT) } else { - resources.getColor(R.color.bg_message_list_outcoming_bubble) + elementColor } if (message.isGrouped) { val bubbleDrawable = DisplayUtils.getMessageSelector( bgBubbleColor, - resources.getColor(R.color.transparent), + ResourcesCompat.getColor(resources, R.color.transparent, null), bgBubbleColor, R.drawable.shape_grouped_outcoming_message ) @@ -196,7 +217,7 @@ class OutcomingPollMessageViewHolder(outcomingView: View, payload: Any) : Messag } else { val bubbleDrawable = DisplayUtils.getMessageSelector( bgBubbleColor, - resources.getColor(R.color.transparent), + ResourcesCompat.getColor(resources, R.color.transparent, null), bgBubbleColor, R.drawable.shape_outcoming_message ) @@ -210,5 +231,7 @@ class OutcomingPollMessageViewHolder(outcomingView: View, payload: Any) : Messag companion object { private val TAG = NextcloudTalkApplication::class.java.simpleName + private val ALPHA_60_INT: Int = (255 * 0.6).roundToInt() + private const val HALF_ALPHA_INT: Int = 255 / 2 } } diff --git a/app/src/main/res/layout/item_custom_outcoming_poll_message.xml b/app/src/main/res/layout/item_custom_outcoming_poll_message.xml index 1f3cfbdfb..d19fc3282 100644 --- a/app/src/main/res/layout/item_custom_outcoming_poll_message.xml +++ b/app/src/main/res/layout/item_custom_outcoming_poll_message.xml @@ -63,8 +63,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:textAlignment="viewStart" - android:textStyle="bold" android:textColor="@color/nc_outcoming_text_default" + android:textStyle="bold" tools:text="This is the poll title?" /> @@ -83,8 +83,8 @@ android:layout_height="wrap_content" android:layout_below="@id/messageText" android:layout_marginStart="8dp" - app:layout_alignSelf="center" android:textColor="@color/nc_outcoming_text_default" + app:layout_alignSelf="center" tools:text="10:35" /> + app:layout_alignSelf="center" /> Date: Wed, 27 Jul 2022 23:40:28 +0200 Subject: [PATCH 28/58] extend outgoing messages' theming Signed-off-by: Andy Scherzinger --- .../MagicOutcomingTextMessageViewHolder.kt | 12 ++++-- .../OutcomingLocationMessageViewHolder.kt | 38 +++++++++++++------ .../OutcomingPollMessageViewHolder.kt | 12 +++--- .../OutcomingVoiceMessageViewHolder.kt | 32 ++++++++++++---- 4 files changed, 67 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/MagicOutcomingTextMessageViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/MagicOutcomingTextMessageViewHolder.kt index 90d36e70b..757e0563b 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/MagicOutcomingTextMessageViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/MagicOutcomingTextMessageViewHolder.kt @@ -30,7 +30,6 @@ import android.text.Spannable import android.text.SpannableString import android.util.TypedValue import android.view.View -import androidx.core.content.ContextCompat import androidx.core.content.res.ResourcesCompat import androidx.core.graphics.ColorUtils import androidx.core.view.ViewCompat @@ -157,9 +156,15 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage ?: context!!.getText(R.string.nc_nick_guest) binding.messageQuote.quotedMessage.text = parentChatMessage.text binding.messageQuote.quotedMessage.setTextColor(serverTheme.colorText) - binding.messageQuote.quotedMessageAuthor.setTextColor(ContextCompat.getColor(context, R.color.nc_grey)) - binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.white) + binding.messageQuote.quotedMessageAuthor.setTextColor( + ColorUtils.setAlphaComponent( + serverTheme.colorText, + ALPHA_80_INT + ) + ) + + binding.messageQuote.quoteColoredView.setBackgroundColor(serverTheme.colorText) } private fun setBubbleOnChatMessage(message: ChatMessage) { @@ -230,5 +235,6 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage const val TEXT_SIZE_MULTIPLIER = 2.5 private const val HALF_ALPHA_INT: Int = 255 / 2 private val ALPHA_60_INT: Int = (255 * 0.6).roundToInt() + private val ALPHA_80_INT: Int = (255 * 0.8).roundToInt() } } diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingLocationMessageViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingLocationMessageViewHolder.kt index 91fb93583..04eca1e4d 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingLocationMessageViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingLocationMessageViewHolder.kt @@ -25,7 +25,6 @@ package com.nextcloud.talk.adapters.messages import android.annotation.SuppressLint import android.content.Context import android.content.Intent -import android.graphics.PorterDuff import android.net.Uri import android.util.Log import android.util.TypedValue @@ -35,6 +34,8 @@ import android.webkit.WebView import android.webkit.WebViewClient import android.widget.Toast import androidx.appcompat.content.res.AppCompatResources +import androidx.core.content.res.ResourcesCompat +import androidx.core.graphics.ColorUtils import androidx.core.view.ViewCompat import autodagger.AutoInjector import coil.load @@ -45,12 +46,15 @@ import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedA import com.nextcloud.talk.databinding.ItemCustomOutcomingLocationMessageBinding import com.nextcloud.talk.models.json.chat.ChatMessage import com.nextcloud.talk.models.json.chat.ReadStatus +import com.nextcloud.talk.ui.theme.ServerTheme +import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.DisplayUtils import com.nextcloud.talk.utils.UriUtils import com.stfalcon.chatkit.messages.MessageHolders import java.net.URLEncoder import javax.inject.Inject +import kotlin.math.roundToInt @AutoInjector(NextcloudTalkApplication::class) class OutcomingLocationMessageViewHolder(incomingView: View) : MessageHolders @@ -68,6 +72,12 @@ class OutcomingLocationMessageViewHolder(incomingView: View) : MessageHolders @Inject var context: Context? = null + @Inject + lateinit var viewThemeUtils: ViewThemeUtils + + @Inject + lateinit var serverTheme: ServerTheme + lateinit var reactionsInterface: ReactionsInterface @SuppressLint("SetTextI18n") @@ -76,7 +86,6 @@ class OutcomingLocationMessageViewHolder(incomingView: View) : MessageHolders sharedApplication!!.componentApplication.inject(this) realView.isSelected = false - binding.messageTime.setTextColor(context!!.resources.getColor(R.color.white60)) val layoutParams = binding.messageTime.layoutParams as FlexboxLayout.LayoutParams layoutParams.isWrapBefore = false @@ -85,7 +94,10 @@ class OutcomingLocationMessageViewHolder(incomingView: View) : MessageHolders colorizeMessageBubble(message) binding.messageText.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize) binding.messageTime.layoutParams = layoutParams + binding.messageTime.setTextColor(ColorUtils.setAlphaComponent(serverTheme.colorText, ALPHA_60_INT)) + binding.messageText.text = message.text + binding.messageText.setTextColor(serverTheme.colorText) // parent message handling setParentMessageDataOnMessageItem(message) @@ -104,8 +116,8 @@ class OutcomingLocationMessageViewHolder(incomingView: View) : MessageHolders readStatusDrawableInt?.let { drawableInt -> AppCompatResources.getDrawable(context!!, drawableInt)?.let { - it.setColorFilter(context?.resources!!.getColor(R.color.white60), PorterDuff.Mode.SRC_ATOP) binding.checkMark.setImageDrawable(it) + viewThemeUtils.colorImageViewText(binding.checkMark) } } @@ -200,12 +212,12 @@ class OutcomingLocationMessageViewHolder(incomingView: View) : MessageHolders binding.messageQuote.quotedMessageAuthor.text = parentChatMessage.actorDisplayName ?: context!!.getText(R.string.nc_nick_guest) binding.messageQuote.quotedMessage.text = parentChatMessage.text - binding.messageQuote.quotedMessage.setTextColor( - context!!.resources.getColor(R.color.nc_outcoming_text_default) + binding.messageQuote.quotedMessage.setTextColor(serverTheme.colorText) + binding.messageQuote.quotedMessageAuthor.setTextColor( + ColorUtils.setAlphaComponent(serverTheme.colorText, ALPHA_80_INT) ) - binding.messageQuote.quotedMessageAuthor.setTextColor(context!!.resources.getColor(R.color.nc_grey)) - binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.white) + binding.messageQuote.quoteColoredView.setBackgroundColor(serverTheme.colorText) binding.messageQuote.quotedChatMessageView.visibility = View.VISIBLE } else { @@ -215,15 +227,16 @@ class OutcomingLocationMessageViewHolder(incomingView: View) : MessageHolders private fun colorizeMessageBubble(message: ChatMessage) { val resources = sharedApplication!!.resources + val elementColor = viewThemeUtils.getElementColor(binding.root.context) val bgBubbleColor = if (message.isDeleted) { - resources.getColor(R.color.bg_message_list_outcoming_bubble_deleted) + ColorUtils.setAlphaComponent(elementColor, HALF_ALPHA_INT) } else { - resources.getColor(R.color.bg_message_list_outcoming_bubble) + elementColor } if (message.isGrouped) { val bubbleDrawable = DisplayUtils.getMessageSelector( bgBubbleColor, - resources.getColor(R.color.transparent), + ResourcesCompat.getColor(resources, R.color.transparent, null), bgBubbleColor, R.drawable.shape_grouped_outcoming_message ) @@ -231,7 +244,7 @@ class OutcomingLocationMessageViewHolder(incomingView: View) : MessageHolders } else { val bubbleDrawable = DisplayUtils.getMessageSelector( bgBubbleColor, - resources.getColor(R.color.transparent), + ResourcesCompat.getColor(resources, R.color.transparent, null), bgBubbleColor, R.drawable.shape_outcoming_message ) @@ -261,5 +274,8 @@ class OutcomingLocationMessageViewHolder(incomingView: View) : MessageHolders companion object { private const val TAG = "LocOutMessageView" + private const val HALF_ALPHA_INT: Int = 255 / 2 + private val ALPHA_60_INT: Int = (255 * 0.6).roundToInt() + private val ALPHA_80_INT: Int = (255 * 0.8).roundToInt() } } diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingPollMessageViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingPollMessageViewHolder.kt index 497e2841a..302929188 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingPollMessageViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingPollMessageViewHolder.kt @@ -24,7 +24,6 @@ package com.nextcloud.talk.adapters.messages import android.annotation.SuppressLint import android.content.Context import android.content.res.ColorStateList -import android.graphics.PorterDuff import android.view.View import androidx.appcompat.content.res.AppCompatResources import androidx.core.content.res.ResourcesCompat @@ -185,12 +184,14 @@ class OutcomingPollMessageViewHolder(outcomingView: View, payload: Any) : Messag binding.messageQuote.quotedMessageAuthor.text = parentChatMessage.actorDisplayName ?: context.getText(R.string.nc_nick_guest) binding.messageQuote.quotedMessage.text = parentChatMessage.text - binding.messageQuote.quotedMessage.setTextColor( - context.resources.getColor(R.color.nc_outcoming_text_default) + binding.messageQuote.quotedMessage.setTextColor(serverTheme.colorText) + binding.messageQuote.quotedMessageAuthor.setTextColor( + ColorUtils.setAlphaComponent(serverTheme.colorText, + ALPHA_80_INT + ) ) - binding.messageQuote.quotedMessageAuthor.setTextColor(context.resources.getColor(R.color.nc_grey)) - binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.white) + binding.messageQuote.quoteColoredView.setBackgroundColor(serverTheme.colorText) binding.messageQuote.quotedChatMessageView.visibility = View.VISIBLE } else { @@ -232,6 +233,7 @@ class OutcomingPollMessageViewHolder(outcomingView: View, payload: Any) : Messag companion object { private val TAG = NextcloudTalkApplication::class.java.simpleName private val ALPHA_60_INT: Int = (255 * 0.6).roundToInt() + private val ALPHA_80_INT: Int = (255 * 0.8).roundToInt() private const val HALF_ALPHA_INT: Int = 255 / 2 } } diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingVoiceMessageViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingVoiceMessageViewHolder.kt index b964d3b1f..bbbba64d5 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingVoiceMessageViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingVoiceMessageViewHolder.kt @@ -31,6 +31,8 @@ import android.view.View import android.widget.SeekBar import androidx.appcompat.content.res.AppCompatResources import androidx.core.content.ContextCompat +import androidx.core.content.res.ResourcesCompat +import androidx.core.graphics.ColorUtils import androidx.core.view.ViewCompat import androidx.work.WorkInfo import androidx.work.WorkManager @@ -42,12 +44,15 @@ import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedA import com.nextcloud.talk.databinding.ItemCustomOutcomingVoiceMessageBinding import com.nextcloud.talk.models.json.chat.ChatMessage import com.nextcloud.talk.models.json.chat.ReadStatus +import com.nextcloud.talk.ui.theme.ServerTheme +import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.DisplayUtils import com.nextcloud.talk.utils.preferences.AppPreferences import com.stfalcon.chatkit.messages.MessageHolders import java.util.concurrent.ExecutionException import javax.inject.Inject +import kotlin.math.roundToInt @AutoInjector(NextcloudTalkApplication::class) class OutcomingVoiceMessageViewHolder(outcomingView: View) : MessageHolders @@ -60,6 +65,12 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) : MessageHolders @Inject var context: Context? = null + @Inject + lateinit var viewThemeUtils: ViewThemeUtils + + @Inject + lateinit var serverTheme: ServerTheme + @JvmField @Inject var appPreferences: AppPreferences? = null @@ -250,12 +261,14 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) : MessageHolders binding.messageQuote.quotedMessageAuthor.text = parentChatMessage.actorDisplayName ?: context!!.getText(R.string.nc_nick_guest) binding.messageQuote.quotedMessage.text = parentChatMessage.text - binding.messageQuote.quotedMessage.setTextColor( - context!!.resources.getColor(R.color.nc_outcoming_text_default) + binding.messageQuote.quotedMessage.setTextColor(serverTheme.colorText) + binding.messageQuote.quotedMessageAuthor.setTextColor( + ColorUtils.setAlphaComponent(serverTheme.colorText, + ALPHA_80_INT + ) ) - binding.messageQuote.quotedMessageAuthor.setTextColor(context!!.resources.getColor(R.color.nc_grey)) - binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.white) + binding.messageQuote.quoteColoredView.setBackgroundColor(serverTheme.colorText) binding.messageQuote.quotedChatMessageView.visibility = View.VISIBLE } else { @@ -265,15 +278,16 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) : MessageHolders private fun colorizeMessageBubble(message: ChatMessage) { val resources = sharedApplication!!.resources + val elementColor = viewThemeUtils.getElementColor(binding.root.context) val bgBubbleColor = if (message.isDeleted) { - resources.getColor(R.color.bg_message_list_outcoming_bubble_deleted) + ColorUtils.setAlphaComponent(elementColor, HALF_ALPHA_INT) } else { - resources.getColor(R.color.bg_message_list_outcoming_bubble) + elementColor } if (message.isGrouped) { val bubbleDrawable = DisplayUtils.getMessageSelector( bgBubbleColor, - resources.getColor(R.color.transparent), + ResourcesCompat.getColor(resources, R.color.transparent, null), bgBubbleColor, R.drawable.shape_grouped_outcoming_message ) @@ -281,7 +295,7 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) : MessageHolders } else { val bubbleDrawable = DisplayUtils.getMessageSelector( bgBubbleColor, - resources.getColor(R.color.transparent), + ResourcesCompat.getColor(resources, R.color.transparent, null), bgBubbleColor, R.drawable.shape_outcoming_message ) @@ -300,5 +314,7 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) : MessageHolders companion object { private const val TAG = "VoiceOutMessageView" private const val SEEKBAR_START: Int = 0 + private const val HALF_ALPHA_INT: Int = 255 / 2 + private val ALPHA_80_INT: Int = (255 * 0.8).roundToInt() } } From f68384e69da171638f08eae424cae7c90efce937 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Wed, 27 Jul 2022 23:51:28 +0200 Subject: [PATCH 29/58] theme folder/archive icon Signed-off-by: Andy Scherzinger --- .../messages/MagicPreviewMessageViewHolder.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/MagicPreviewMessageViewHolder.java b/app/src/main/java/com/nextcloud/talk/adapters/messages/MagicPreviewMessageViewHolder.java index 48e33915e..e6c5a7d23 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/MagicPreviewMessageViewHolder.java +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/MagicPreviewMessageViewHolder.java @@ -29,6 +29,7 @@ package com.nextcloud.talk.adapters.messages; import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; +import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; import android.net.Uri; @@ -49,6 +50,7 @@ import com.nextcloud.talk.components.filebrowser.webdav.ReadFilesystemOperation; import com.nextcloud.talk.data.user.model.User; import com.nextcloud.talk.databinding.ReactionsInsideMessageBinding; import com.nextcloud.talk.models.json.chat.ChatMessage; +import com.nextcloud.talk.ui.theme.ServerTheme; import com.nextcloud.talk.utils.DisplayUtils; import com.nextcloud.talk.utils.DrawableUtils; import com.nextcloud.talk.utils.FileViewerUtils; @@ -91,6 +93,9 @@ public abstract class MagicPreviewMessageViewHolder extends MessageHolders.Incom @Inject Context context; + @Inject + ServerTheme serverTheme; + @Inject OkHttpClient okHttpClient; @@ -175,6 +180,13 @@ public abstract class MagicPreviewMessageViewHolder extends MessageHolders.Incom String mimetype = message.getSelectedIndividualHashMap().get(KEY_MIMETYPE); int drawableResourceId = DrawableUtils.INSTANCE.getDrawableResourceIdForMimeType(mimetype); Drawable drawable = ContextCompat.getDrawable(context, drawableResourceId); + + if (drawable != null && + (drawableResourceId == R.drawable.ic_mimetype_folder || + drawableResourceId == R.drawable.ic_mimetype_package_x_generic)) { + drawable.setColorFilter(serverTheme.getPrimaryColor(), PorterDuff.Mode.SRC_ATOP); + } + image.getHierarchy().setPlaceholderImage(drawable); } else { fetchFileInformation("/" + message.getSelectedIndividualHashMap().get(KEY_PATH), From b7006230b8cd1dde6df29756abf1fe2fa3eeb615 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Wed, 27 Jul 2022 23:59:16 +0200 Subject: [PATCH 30/58] theme incoming voice message Signed-off-by: Andy Scherzinger --- .../messages/IncomingVoiceMessageViewHolder.kt | 5 +++++ .../nextcloud/talk/ui/theme/ViewThemeUtils.kt | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingVoiceMessageViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingVoiceMessageViewHolder.kt index e06604763..8546dea0d 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingVoiceMessageViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingVoiceMessageViewHolder.kt @@ -48,6 +48,7 @@ import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication import com.nextcloud.talk.databinding.ItemCustomIncomingVoiceMessageBinding import com.nextcloud.talk.models.json.chat.ChatMessage +import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.DisplayUtils import com.nextcloud.talk.utils.preferences.AppPreferences @@ -66,6 +67,9 @@ class IncomingVoiceMessageViewHolder(incomingView: View, payload: Any) : Message @Inject var context: Context? = null + @Inject + lateinit var viewThemeUtils: ViewThemeUtils + @JvmField @Inject var appPreferences: AppPreferences? = null @@ -93,6 +97,7 @@ class IncomingVoiceMessageViewHolder(incomingView: View, payload: Any) : Message updateDownloadState(message) binding.seekbar.max = message.voiceMessageDuration + viewThemeUtils.themeHorizontalSeekBar(binding.seekbar) if (message.isPlayingVoiceMessage) { showPlayButton() 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 index 5769c2ca3..3abf3bcfd 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt @@ -25,13 +25,17 @@ import android.content.Context import android.content.res.ColorStateList import android.content.res.Configuration import android.graphics.Color +import android.graphics.PorterDuff import android.graphics.drawable.Drawable import android.view.View import android.widget.CheckBox import android.widget.EditText import android.widget.ImageView +import android.widget.ProgressBar import android.widget.RadioButton +import android.widget.SeekBar import android.widget.TextView +import androidx.annotation.ColorInt import androidx.appcompat.content.res.AppCompatResources import androidx.appcompat.widget.SwitchCompat import androidx.core.content.ContextCompat @@ -82,6 +86,20 @@ class ViewThemeUtils @Inject constructor(private val theme: ServerTheme) { } } + fun themeHorizontalSeekBar(seekBar: SeekBar) { + withElementColor(seekBar) { color -> + themeHorizontalProgressBar(seekBar, color) + seekBar.thumb.setColorFilter(color, PorterDuff.Mode.SRC_IN) + } + } + + fun themeHorizontalProgressBar(progressBar: ProgressBar?, @ColorInt color: Int) { + if (progressBar != null) { + progressBar.indeterminateDrawable.setColorFilter(color, PorterDuff.Mode.SRC_IN) + progressBar.progressDrawable.setColorFilter(color, PorterDuff.Mode.SRC_IN) + } + } + fun colorTextViewElement(textView: TextView) { withElementColor(textView) { color -> textView.setTextColor(color) From e9d304a79bf11d0d801902d89bedf693611b606d Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Thu, 28 Jul 2022 00:08:19 +0200 Subject: [PATCH 31/58] theme outgoing voice message seekbar Signed-off-by: Andy Scherzinger --- .../messages/OutcomingVoiceMessageViewHolder.kt | 17 ++++++++++++++--- .../nextcloud/talk/ui/theme/ViewThemeUtils.kt | 8 ++++++-- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingVoiceMessageViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingVoiceMessageViewHolder.kt index bbbba64d5..060897ba8 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingVoiceMessageViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingVoiceMessageViewHolder.kt @@ -91,13 +91,19 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) : MessageHolders colorizeMessageBubble(message) itemView.isSelected = false - binding.messageTime.setTextColor(context!!.resources.getColor(R.color.white60)) + binding.messageTime.setTextColor( + ColorUtils.setAlphaComponent( + serverTheme.colorText, + ALPHA_60_INT + ) + ) // parent message handling setParentMessageDataOnMessageItem(message) updateDownloadState(message) binding.seekbar.max = message.voiceMessageDuration + viewThemeUtils.themeHorizontalSeekBar(binding.seekbar, serverTheme.colorText) handleIsPlayingVoiceMessageState(message) @@ -135,8 +141,8 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) : MessageHolders readStatusDrawableInt?.let { drawableInt -> AppCompatResources.getDrawable(context!!, drawableInt)?.let { - it.setColorFilter(context?.resources!!.getColor(R.color.white60), PorterDuff.Mode.SRC_ATOP) binding.checkMark.setImageDrawable(it) + viewThemeUtils.colorImageViewText(binding.checkMark) } } @@ -159,6 +165,7 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) : MessageHolders context!!, R.drawable.ic_baseline_play_arrow_voice_message_24 ) + binding.playPauseBtn.icon.setColorFilter(serverTheme.colorText, PorterDuff.Mode.SRC_ATOP) binding.seekbar.progress = SEEKBAR_START message.resetVoiceMessage = false } @@ -179,6 +186,7 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) : MessageHolders context!!, R.drawable.ic_baseline_pause_voice_message_24 ) + binding.playPauseBtn.icon.setColorFilter(serverTheme.colorText, PorterDuff.Mode.SRC_ATOP) binding.seekbar.progress = message.voiceMessagePlayedSeconds } else { binding.playPauseBtn.visibility = View.VISIBLE @@ -186,6 +194,7 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) : MessageHolders context!!, R.drawable.ic_baseline_play_arrow_voice_message_24 ) + binding.playPauseBtn.icon.setColorFilter(serverTheme.colorText, PorterDuff.Mode.SRC_ATOP) } } @@ -263,7 +272,8 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) : MessageHolders binding.messageQuote.quotedMessage.text = parentChatMessage.text binding.messageQuote.quotedMessage.setTextColor(serverTheme.colorText) binding.messageQuote.quotedMessageAuthor.setTextColor( - ColorUtils.setAlphaComponent(serverTheme.colorText, + ColorUtils.setAlphaComponent( + serverTheme.colorText, ALPHA_80_INT ) ) @@ -316,5 +326,6 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) : MessageHolders private const val SEEKBAR_START: Int = 0 private const val HALF_ALPHA_INT: Int = 255 / 2 private val ALPHA_80_INT: Int = (255 * 0.8).roundToInt() + private val ALPHA_60_INT: Int = (255 * 0.6).roundToInt() } } 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 index 3abf3bcfd..796df1325 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt @@ -88,11 +88,15 @@ class ViewThemeUtils @Inject constructor(private val theme: ServerTheme) { fun themeHorizontalSeekBar(seekBar: SeekBar) { withElementColor(seekBar) { color -> - themeHorizontalProgressBar(seekBar, color) - seekBar.thumb.setColorFilter(color, PorterDuff.Mode.SRC_IN) + themeHorizontalSeekBar(seekBar, color) } } + fun themeHorizontalSeekBar(seekBar: SeekBar, @ColorInt color: Int) { + themeHorizontalProgressBar(seekBar, color) + seekBar.thumb.setColorFilter(color, PorterDuff.Mode.SRC_IN) + } + fun themeHorizontalProgressBar(progressBar: ProgressBar?, @ColorInt color: Int) { if (progressBar != null) { progressBar.indeterminateDrawable.setColorFilter(color, PorterDuff.Mode.SRC_IN) From 234e97502be6e2c49369ac1c5f6e2c5b3e31ee37 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Thu, 28 Jul 2022 00:16:18 +0200 Subject: [PATCH 32/58] theme reactions bottomsheet Signed-off-by: Andy Scherzinger --- .../java/com/nextcloud/talk/controllers/ChatController.kt | 7 ++++++- .../com/nextcloud/talk/ui/dialog/ShowReactionsDialog.kt | 5 ++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt b/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt index e925039b3..e868911c4 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt +++ b/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt @@ -154,6 +154,7 @@ import com.nextcloud.talk.ui.dialog.MessageActionsDialog import com.nextcloud.talk.ui.dialog.ShowReactionsDialog import com.nextcloud.talk.ui.recyclerview.MessageSwipeActions import com.nextcloud.talk.ui.recyclerview.MessageSwipeCallback +import com.nextcloud.talk.ui.theme.ServerTheme import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.AttendeePermissionsUtil @@ -239,6 +240,9 @@ class ChatController(args: Bundle) : @Inject lateinit var viewThemeUtils: ViewThemeUtils + @Inject + lateinit var serverTheme: ServerTheme + val disposables = DisposableSet() var roomToken: String? = null @@ -2681,7 +2685,8 @@ class ChatController(args: Bundle) : chatMessage, conversationUser, hasChatPermission, - ncApi!! + ncApi!!, + serverTheme ).show() } } diff --git a/app/src/main/java/com/nextcloud/talk/ui/dialog/ShowReactionsDialog.kt b/app/src/main/java/com/nextcloud/talk/ui/dialog/ShowReactionsDialog.kt index 602c68cdc..554fc27b7 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/dialog/ShowReactionsDialog.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/dialog/ShowReactionsDialog.kt @@ -51,6 +51,7 @@ import com.nextcloud.talk.models.json.chat.ChatMessage import com.nextcloud.talk.models.json.conversations.Conversation import com.nextcloud.talk.models.json.generic.GenericOverall import com.nextcloud.talk.models.json.reactions.ReactionsOverall +import com.nextcloud.talk.ui.theme.ServerTheme import com.nextcloud.talk.utils.ApiUtils import io.reactivex.Observer import io.reactivex.android.schedulers.AndroidSchedulers @@ -65,7 +66,8 @@ class ShowReactionsDialog( private val chatMessage: ChatMessage, private val user: User?, private val hasChatPermission: Boolean, - private val ncApi: NcApi + private val ncApi: NcApi, + private val serverTheme: ServerTheme ) : BottomSheetDialog(activity), ReactionItemClickListener { private lateinit var binding: DialogMessageReactionsBinding @@ -96,6 +98,7 @@ class ShowReactionsDialog( adapter?.list?.clear() if (chatMessage.reactions != null && chatMessage.reactions!!.isNotEmpty()) { var reactionsTotal = 0 + binding.emojiReactionsTabs.setSelectedTabIndicatorColor(serverTheme.primaryColor) for ((emoji, amount) in chatMessage.reactions!!) { reactionsTotal = reactionsTotal.plus(amount as Int) val tab: TabLayout.Tab = binding.emojiReactionsTabs.newTab() // Create a new Tab names "First Tab" From 9eac0d3615b476e71f4f8e90a99f8733a166dcc2 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Thu, 28 Jul 2022 00:26:32 +0200 Subject: [PATCH 33/58] theme audio device list Signed-off-by: Andy Scherzinger --- .../talk/ui/dialog/AudioOutputDialog.kt | 64 +++++++------------ 1 file changed, 24 insertions(+), 40 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt b/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt index e4f9105f4..c627605f9 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt @@ -25,17 +25,33 @@ import android.util.Log import android.view.View import android.view.ViewGroup import androidx.core.content.ContextCompat +import autodagger.AutoInjector import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetDialog import com.nextcloud.talk.R import com.nextcloud.talk.activities.CallActivity +import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.databinding.DialogAudioOutputBinding +import com.nextcloud.talk.ui.theme.ServerTheme +import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.webrtc.WebRtcAudioManager +import javax.inject.Inject +@AutoInjector(NextcloudTalkApplication::class) class AudioOutputDialog(val callActivity: CallActivity) : BottomSheetDialog(callActivity) { + @Inject + lateinit var viewThemeUtils: ViewThemeUtils + + @Inject + lateinit var serverTheme: ServerTheme + private lateinit var dialogAudioOutputBinding: DialogAudioOutputBinding + init { + NextcloudTalkApplication.sharedApplication?.componentApplication?.inject(this) + } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) dialogAudioOutputBinding = DialogAudioOutputBinding.inflate(layoutInflater) @@ -82,55 +98,23 @@ class AudioOutputDialog(val callActivity: CallActivity) : BottomSheetDialog(call private fun highlightActiveOutputChannel() { when (callActivity.audioManager?.currentAudioDevice) { WebRtcAudioManager.AudioDevice.BLUETOOTH -> { - dialogAudioOutputBinding.audioOutputBluetoothIcon.setColorFilter( - ContextCompat.getColor( - context, - R.color.colorPrimary - ), - android.graphics.PorterDuff.Mode.SRC_IN - ) - dialogAudioOutputBinding.audioOutputBluetoothText.setTextColor( - callActivity.resources.getColor(R.color.colorPrimary) - ) + viewThemeUtils.colorImageView(dialogAudioOutputBinding.audioOutputBluetoothIcon) + dialogAudioOutputBinding.audioOutputBluetoothText.setTextColor(serverTheme.primaryColor) } WebRtcAudioManager.AudioDevice.SPEAKER_PHONE -> { - dialogAudioOutputBinding.audioOutputSpeakerIcon.setColorFilter( - ContextCompat.getColor( - context, - R.color.colorPrimary - ), - android.graphics.PorterDuff.Mode.SRC_IN - ) - dialogAudioOutputBinding.audioOutputSpeakerText.setTextColor( - callActivity.resources.getColor(R.color.colorPrimary) - ) + viewThemeUtils.colorImageView(dialogAudioOutputBinding.audioOutputSpeakerIcon) + dialogAudioOutputBinding.audioOutputSpeakerText.setTextColor(serverTheme.primaryColor) } WebRtcAudioManager.AudioDevice.EARPIECE -> { - dialogAudioOutputBinding.audioOutputEarspeakerIcon.setColorFilter( - ContextCompat.getColor( - context, - R.color.colorPrimary - ), - android.graphics.PorterDuff.Mode.SRC_IN - ) - dialogAudioOutputBinding.audioOutputEarspeakerText.setTextColor( - callActivity.resources.getColor(R.color.colorPrimary) - ) + viewThemeUtils.colorImageView(dialogAudioOutputBinding.audioOutputEarspeakerIcon) + dialogAudioOutputBinding.audioOutputEarspeakerText.setTextColor(serverTheme.primaryColor) } WebRtcAudioManager.AudioDevice.WIRED_HEADSET -> { - dialogAudioOutputBinding.audioOutputWiredHeadsetIcon.setColorFilter( - ContextCompat.getColor( - context, - R.color.colorPrimary - ), - android.graphics.PorterDuff.Mode.SRC_IN - ) - dialogAudioOutputBinding.audioOutputWiredHeadsetText.setTextColor( - callActivity.resources.getColor(R.color.colorPrimary) - ) + viewThemeUtils.colorImageView(dialogAudioOutputBinding.audioOutputWiredHeadsetIcon) + dialogAudioOutputBinding.audioOutputWiredHeadsetText.setTextColor(serverTheme.primaryColor) } else -> Log.d(TAG, "AudioOutputDialog doesn't know this AudioDevice") From 278aaa437fb97948dd2b7ac3d3e3595d818db748 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Thu, 28 Jul 2022 00:39:23 +0200 Subject: [PATCH 34/58] fix ktlint issues Signed-off-by: Andy Scherzinger --- .../talk/adapters/messages/OutcomingPollMessageViewHolder.kt | 4 +--- .../java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingPollMessageViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingPollMessageViewHolder.kt index 302929188..a418ac686 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingPollMessageViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingPollMessageViewHolder.kt @@ -186,9 +186,7 @@ class OutcomingPollMessageViewHolder(outcomingView: View, payload: Any) : Messag binding.messageQuote.quotedMessage.text = parentChatMessage.text binding.messageQuote.quotedMessage.setTextColor(serverTheme.colorText) binding.messageQuote.quotedMessageAuthor.setTextColor( - ColorUtils.setAlphaComponent(serverTheme.colorText, - ALPHA_80_INT - ) + ColorUtils.setAlphaComponent(serverTheme.colorText, ALPHA_80_INT) ) binding.messageQuote.quoteColoredView.setBackgroundColor(serverTheme.colorText) diff --git a/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt b/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt index c627605f9..5e879e736 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt @@ -24,7 +24,6 @@ import android.os.Bundle import android.util.Log import android.view.View import android.view.ViewGroup -import androidx.core.content.ContextCompat import autodagger.AutoInjector import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetDialog From d9c59b6f879027453a471f220dc83fedafbc0ea3 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Thu, 28 Jul 2022 00:40:52 +0200 Subject: [PATCH 35/58] organize imports Signed-off-by: Andy Scherzinger --- .../java/com/nextcloud/talk/adapters/items/ConversationItem.java | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/java/com/nextcloud/talk/adapters/items/ConversationItem.java b/app/src/main/java/com/nextcloud/talk/adapters/items/ConversationItem.java index e9c172173..0b3cddd86 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/items/ConversationItem.java +++ b/app/src/main/java/com/nextcloud/talk/adapters/items/ConversationItem.java @@ -27,7 +27,6 @@ package com.nextcloud.talk.adapters.items; import android.annotation.SuppressLint; import android.content.Context; import android.content.res.ColorStateList; -import android.graphics.Color; import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; From d4c07f12786db25b58a1c185e9855c4c6ddc0bf1 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Thu, 28 Jul 2022 16:06:52 +0200 Subject: [PATCH 36/58] safeguard theme values in case of null values Signed-off-by: Andy Scherzinger --- .../com/nextcloud/talk/ui/theme/ColorUtil.kt | 70 +++++++++++++++++++ .../talk/ui/theme/ServerThemeImpl.kt | 17 +++-- app/src/main/res/values/colors.xml | 1 + 3 files changed, 81 insertions(+), 7 deletions(-) create mode 100644 app/src/main/java/com/nextcloud/talk/ui/theme/ColorUtil.kt diff --git a/app/src/main/java/com/nextcloud/talk/ui/theme/ColorUtil.kt b/app/src/main/java/com/nextcloud/talk/ui/theme/ColorUtil.kt new file mode 100644 index 000000000..4f2daa222 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/ColorUtil.kt @@ -0,0 +1,70 @@ +/* + * Nextcloud Talk application + * + * @author Andy Scherzinger + * Copyright (C) 2022 Andy Scherzinger + * + * 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 androidx.annotation.ColorInt +import androidx.annotation.ColorRes +import androidx.core.content.ContextCompat +import androidx.core.graphics.ColorUtils +import com.nextcloud.talk.R + +object ColorUtil { + private const val HSL_SIZE: Int = 3 + private const val INDEX_LUMINATION: Int = 2 + private const val LUMINATION_DARK_THRESHOLD: Float = 0.6f + + fun getPrimaryColor(context: Context, primaryColor: String?, @ColorRes fallbackColor: Int): Int { + return if (primaryColor != null) { + Color.parseColor(primaryColor) + } else { + ContextCompat.getColor(context, fallbackColor) + } + } + + fun getNullsafeColor(color: String?, @ColorInt fallbackColor: Int): Int { + return if (color != null) { + Color.parseColor(color) + } else { + fallbackColor + } + } + + fun getTextColor(context: Context, colorText: String?, @ColorInt fallBackPrimaryColor: Int): Int { + return if (colorText != null) { + Color.parseColor(colorText) + } else { + getForegroundColorForBackgroundColor(context, fallBackPrimaryColor) + } + } + + @ColorInt + public fun getForegroundColorForBackgroundColor(context: Context, @ColorInt color: Int): Int { + val hsl = FloatArray(HSL_SIZE) + ColorUtils.RGBToHSL(Color.red(color), Color.green(color), Color.blue(color), hsl) + + return if (hsl[INDEX_LUMINATION] < LUMINATION_DARK_THRESHOLD) { + Color.WHITE + } else { + ContextCompat.getColor(context, R.color.grey_900) + } + } +} 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 index cd4607e22..6d4c5f47f 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/theme/ServerThemeImpl.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/ServerThemeImpl.kt @@ -2,7 +2,9 @@ * Nextcloud Talk application * * @author Álvaro Brey + * @author Andy Scherzinger * Copyright (C) 2022 Álvaro Brey + * Copyright (C) 2022 Andy Scherzinger * Copyright (C) 2022 Nextcloud GmbH * * This program is free software: you can redistribute it and/or modify @@ -22,7 +24,7 @@ package com.nextcloud.talk.ui.theme import android.content.Context -import android.graphics.Color +import com.nextcloud.talk.R import com.nextcloud.talk.models.json.capabilities.ThemingCapability internal class ServerThemeImpl(context: Context, themingCapability: ThemingCapability) : @@ -34,12 +36,13 @@ internal class ServerThemeImpl(context: Context, themingCapability: ThemingCapab 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!!) + primaryColor = ColorUtil.getPrimaryColor(context, themingCapability.color, R.color.colorPrimary) + + colorElement = ColorUtil.getNullsafeColor(themingCapability.colorElement, primaryColor) + colorElementBright = ColorUtil.getNullsafeColor(themingCapability.colorElementBright, primaryColor) + colorElementDark = ColorUtil.getNullsafeColor(themingCapability.colorElementDark, primaryColor) + + colorText = ColorUtil.getTextColor(context, themingCapability.colorText, primaryColor) } } diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 28ff0ff06..9fcf53e79 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -63,6 +63,7 @@ #006400 #E8E8E8 #757575 + #212121 #D5D5D5 #E9FFFFFF #111111 From eb967fbf7d0d36b807091e8d3e69e37969589bcb Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Thu, 28 Jul 2022 16:37:18 +0200 Subject: [PATCH 37/58] harden theming calculations to handle null values Signed-off-by: Andy Scherzinger --- .../com/nextcloud/talk/ui/theme/ServerThemeImpl.kt | 12 ++++++------ .../nextcloud/talk/ui/theme/ServerThemeProvider.kt | 2 +- .../talk/ui/theme/ServerThemeProviderImpl.kt | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) 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 index 6d4c5f47f..0ad068eac 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/theme/ServerThemeImpl.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/ServerThemeImpl.kt @@ -27,7 +27,7 @@ import android.content.Context import com.nextcloud.talk.R import com.nextcloud.talk.models.json.capabilities.ThemingCapability -internal class ServerThemeImpl(context: Context, themingCapability: ThemingCapability) : +internal class ServerThemeImpl(context: Context, themingCapability: ThemingCapability?) : ServerTheme { override val primaryColor: Int @@ -37,12 +37,12 @@ internal class ServerThemeImpl(context: Context, themingCapability: ThemingCapab override val colorText: Int init { - primaryColor = ColorUtil.getPrimaryColor(context, themingCapability.color, R.color.colorPrimary) + primaryColor = ColorUtil.getPrimaryColor(context, themingCapability?.color, R.color.colorPrimary) - colorElement = ColorUtil.getNullsafeColor(themingCapability.colorElement, primaryColor) - colorElementBright = ColorUtil.getNullsafeColor(themingCapability.colorElementBright, primaryColor) - colorElementDark = ColorUtil.getNullsafeColor(themingCapability.colorElementDark, primaryColor) + colorElement = ColorUtil.getNullsafeColor(themingCapability?.colorElement, primaryColor) + colorElementBright = ColorUtil.getNullsafeColor(themingCapability?.colorElementBright, primaryColor) + colorElementDark = ColorUtil.getNullsafeColor(themingCapability?.colorElementDark, primaryColor) - colorText = ColorUtil.getTextColor(context, themingCapability.colorText, primaryColor) + colorText = ColorUtil.getTextColor(context, themingCapability?.colorText, primaryColor) } } 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 index 1d299ca7b..274616432 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/theme/ServerThemeProvider.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/ServerThemeProvider.kt @@ -26,6 +26,6 @@ import com.nextcloud.talk.models.json.capabilities.Capabilities interface ServerThemeProvider { fun getServerThemeForUser(user: User): ServerTheme - fun getServerThemeForCapabilities(capabilities: Capabilities): ServerTheme + fun getServerThemeForCapabilities(capabilities: Capabilities?): ServerTheme fun getServerThemeForCurrentUser(): 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 index 87cdcee6b..7becbda62 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/theme/ServerThemeProviderImpl.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/ServerThemeProviderImpl.kt @@ -55,14 +55,14 @@ internal class ServerThemeProviderImpl @Inject constructor( } override fun getServerThemeForUser(user: User): ServerTheme { - return getServerThemeForCapabilities(user.capabilities!!) + return getServerThemeForCapabilities(user.capabilities) } override fun getServerThemeForCurrentUser(): ServerTheme { return getServerThemeForUser(currentUser) } - override fun getServerThemeForCapabilities(capabilities: Capabilities): ServerTheme { - return ServerThemeImpl(context, capabilities.themingCapability!!) + override fun getServerThemeForCapabilities(capabilities: Capabilities?): ServerTheme { + return ServerThemeImpl(context, capabilities?.themingCapability) } } From b9e9c35df547e9c6c2c167f7a6a440d90fcfbef1 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Thu, 28 Jul 2022 16:50:34 +0200 Subject: [PATCH 38/58] don't tint status icons on cardViews Signed-off-by: Andy Scherzinger --- .../java/com/nextcloud/talk/ui/dialog/SetStatusDialogFragment.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/java/com/nextcloud/talk/ui/dialog/SetStatusDialogFragment.kt b/app/src/main/java/com/nextcloud/talk/ui/dialog/SetStatusDialogFragment.kt index 69407cc5f..6c6dfb9d6 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/dialog/SetStatusDialogFragment.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/dialog/SetStatusDialogFragment.kt @@ -417,7 +417,6 @@ class SetStatusDialogFragment : } viewThemeUtils.colorCardViewBackground(views.first) viewThemeUtils.colorTextViewText(views.second) - viewThemeUtils.colorImageViewText(views.third) } private fun clearTopStatus() { From e3c535722dd9919a68b3b1b80dbc09f1dfdf8d5d Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Thu, 28 Jul 2022 17:00:09 +0200 Subject: [PATCH 39/58] theme all swipe to refresh layouts Signed-off-by: Andy Scherzinger --- .../com/nextcloud/talk/controllers/ContactsController.kt | 6 +++--- .../talk/controllers/ConversationsListController.java | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ContactsController.kt b/app/src/main/java/com/nextcloud/talk/controllers/ContactsController.kt index bb370d3f3..04398483f 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ContactsController.kt +++ b/app/src/main/java/com/nextcloud/talk/controllers/ContactsController.kt @@ -623,9 +623,9 @@ class ContactsController(args: Bundle) : binding.controllerGenericRv.recyclerView.setHasFixedSize(true) binding.controllerGenericRv.recyclerView.adapter = adapter binding.controllerGenericRv.swipeRefreshLayout.setOnRefreshListener { fetchData() } - binding.controllerGenericRv.swipeRefreshLayout.setColorSchemeResources(R.color.colorPrimary) - binding.controllerGenericRv.swipeRefreshLayout - .setProgressBackgroundColorSchemeResource(R.color.refresh_spinner_background) + + viewThemeUtils.themeSwipeRefreshLayout(binding.controllerGenericRv.swipeRefreshLayout) + binding.joinConversationViaLink.joinConversationViaLinkImageView .background .setColorFilter( 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 4b9399d2a..72a953d8b 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java +++ b/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java @@ -783,8 +783,7 @@ public class ConversationsListController extends BaseController implements Flexi }); swipeRefreshLayout.setOnRefreshListener(() -> fetchData()); - swipeRefreshLayout.setColorSchemeResources(R.color.colorPrimary); - swipeRefreshLayout.setProgressBackgroundColorSchemeResource(R.color.refresh_spinner_background); + viewThemeUtils.themeSwipeRefreshLayout(swipeRefreshLayout); emptyLayoutView.setOnClickListener(v -> showNewConversationsScreen()); floatingActionButton.setOnClickListener(v -> { From 96c29260ab2361d1499af80a91d075aa42f457e8 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Thu, 28 Jul 2022 17:22:57 +0200 Subject: [PATCH 40/58] set link colors correctly Signed-off-by: Andy Scherzinger --- .../adapters/messages/MagicOutcomingTextMessageViewHolder.kt | 1 + .../talk/adapters/messages/OutcomingLocationMessageViewHolder.kt | 1 + 2 files changed, 2 insertions(+) diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/MagicOutcomingTextMessageViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/MagicOutcomingTextMessageViewHolder.kt index 757e0563b..6102446e5 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/MagicOutcomingTextMessageViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/MagicOutcomingTextMessageViewHolder.kt @@ -96,6 +96,7 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage binding.messageTime.layoutParams = layoutParams binding.messageText.text = messageString binding.messageText.setTextColor(serverTheme.colorText) + binding.messageText.setLinkTextColor(serverTheme.colorText) // parent message handling if (!message.isDeleted && message.parentMessage != null) { diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingLocationMessageViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingLocationMessageViewHolder.kt index 04eca1e4d..fecf4af64 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingLocationMessageViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingLocationMessageViewHolder.kt @@ -98,6 +98,7 @@ class OutcomingLocationMessageViewHolder(incomingView: View) : MessageHolders binding.messageText.text = message.text binding.messageText.setTextColor(serverTheme.colorText) + binding.messageText.setLinkTextColor(serverTheme.colorText) // parent message handling setParentMessageDataOnMessageItem(message) From 6e0afac7f6fe6cf3d5829663a63033da50816b49 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Thu, 28 Jul 2022 17:23:15 +0200 Subject: [PATCH 41/58] format layout Signed-off-by: Andy Scherzinger --- .../res/layout/item_custom_outcoming_location_message.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/layout/item_custom_outcoming_location_message.xml b/app/src/main/res/layout/item_custom_outcoming_location_message.xml index d5c953071..5af1bab92 100644 --- a/app/src/main/res/layout/item_custom_outcoming_location_message.xml +++ b/app/src/main/res/layout/item_custom_outcoming_location_message.xml @@ -77,8 +77,8 @@ android:layout_height="wrap_content" android:layout_below="@id/messageTime" android:layout_marginStart="8dp" - app:layout_alignSelf="center" - android:contentDescription="@null" /> + android:contentDescription="@null" + app:layout_alignSelf="center" /> Date: Thu, 28 Jul 2022 18:22:16 +0200 Subject: [PATCH 42/58] Add caching Signed-off-by: Andy Scherzinger --- .../talk/ui/theme/ServerThemeProviderImpl.kt | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) 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 index 7becbda62..389785cd4 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/theme/ServerThemeProviderImpl.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/ServerThemeProviderImpl.kt @@ -2,7 +2,9 @@ * Nextcloud Talk application * * @author Álvaro Brey + * @author Andy Scherzinger * Copyright (C) 2022 Álvaro Brey + * Copyright (C) 2022 Andy Scherzinger * Copyright (C) 2022 Nextcloud GmbH * * This program is free software: you can redistribute it and/or modify @@ -26,15 +28,16 @@ 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 +import java.util.concurrent.ConcurrentHashMap import javax.inject.Inject -// TODO cache theme, keyed by server url -// TODO reload UI when account changes internal class ServerThemeProviderImpl @Inject constructor( private val context: Context, private val userProvider: CurrentUserProviderNew -) : - ServerThemeProvider { +) : ServerThemeProvider { + + val themeCache: ConcurrentHashMap = ConcurrentHashMap() + // TODO move this logic to currentUserProvider or something private var _currentUser: User? = null private val currentUser: User @@ -55,7 +58,10 @@ internal class ServerThemeProviderImpl @Inject constructor( } override fun getServerThemeForUser(user: User): ServerTheme { - return getServerThemeForCapabilities(user.capabilities) + if (user.baseUrl != null && !themeCache.containsKey(user.baseUrl)) { + themeCache[user.baseUrl!!] = getServerThemeForCapabilities(user.capabilities) + } + return themeCache[user.baseUrl]!! } override fun getServerThemeForCurrentUser(): ServerTheme { From 6e42a52a9a5190f3fcb6818445373742b19628af Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Fri, 29 Jul 2022 00:17:38 +0200 Subject: [PATCH 43/58] fix entry menu bottom sheet input layout text color Signed-off-by: Andy Scherzinger --- .../talk/controllers/bottomsheet/EntryMenuController.kt | 1 - app/src/main/res/layout/controller_entry_menu.xml | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/EntryMenuController.kt b/app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/EntryMenuController.kt index f652b427e..c7e45e489 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/EntryMenuController.kt +++ b/app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/EntryMenuController.kt @@ -175,7 +175,6 @@ class EntryMenuController(args: Bundle) : } viewThemeUtils.colorTextInputLayout(binding.textInputLayout) - binding.textEdit.setTextColor(serverTheme.colorText) viewThemeUtils.colorMaterialButtonText(binding.okButton) binding.textInputLayout.hint = labelText diff --git a/app/src/main/res/layout/controller_entry_menu.xml b/app/src/main/res/layout/controller_entry_menu.xml index 2f50f3d68..4c851cc3f 100644 --- a/app/src/main/res/layout/controller_entry_menu.xml +++ b/app/src/main/res/layout/controller_entry_menu.xml @@ -63,7 +63,7 @@ android:inputType="textUri" android:singleLine="true" android:textAlignment="viewStart" - android:textColor="@color/colorPrimary" /> + android:textColor="@color/high_emphasis_text" /> From 23d436f31442506e801fd7e668d8fbf5bbd1a678 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Fri, 29 Jul 2022 00:18:21 +0200 Subject: [PATCH 44/58] fix input layout theming dark/light Signed-off-by: Andy Scherzinger --- .../com/nextcloud/talk/ui/theme/ViewThemeUtils.kt | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) 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 index 796df1325..572fb1259 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/theme/ViewThemeUtils.kt @@ -287,9 +287,19 @@ class ViewThemeUtils @Inject constructor(private val theme: ServerTheme) { fun colorTextInputLayout(textInputLayout: TextInputLayout) { withElementColor(textInputLayout) { color -> - // TODO calculate error color based on primary color, dark/light aware val errorColor = Color.GRAY - textInputLayout.boxStrokeColor = color + textInputLayout.setBoxStrokeColorStateList( + ColorStateList( + arrayOf( + intArrayOf(-android.R.attr.state_focused), + intArrayOf(android.R.attr.state_focused) + ), + intArrayOf( + Color.GRAY, + color + ) + ) + ) textInputLayout.setErrorIconTintList( ColorStateList( arrayOf( From b34765ccf4eacb4423a18380dcf2b38c55152caa Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Fri, 29 Jul 2022 00:18:54 +0200 Subject: [PATCH 45/58] migrate profile fields to input layouts for Material3 Signed-off-by: Andy Scherzinger --- .../talk/controllers/ProfileController.kt | 40 +++++--------- .../main/res/layout/controller_profile.xml | 3 +- .../layout/user_info_details_table_item.xml | 54 +++++++++++-------- app/src/main/res/values/dimens.xml | 1 + 4 files changed, 50 insertions(+), 48 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ProfileController.kt b/app/src/main/java/com/nextcloud/talk/controllers/ProfileController.kt index 9db7d8781..add4ac128 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ProfileController.kt +++ b/app/src/main/java/com/nextcloud/talk/controllers/ProfileController.kt @@ -24,10 +24,8 @@ package com.nextcloud.talk.controllers import android.app.Activity import android.content.Intent import android.content.pm.PackageManager -import android.content.res.ColorStateList import android.graphics.Bitmap import android.graphics.BitmapFactory -import android.graphics.Color import android.net.Uri import android.os.Bundle import android.text.Editable @@ -43,7 +41,6 @@ import android.view.ViewGroup import android.widget.Toast import androidx.annotation.ColorInt import androidx.annotation.DrawableRes -import androidx.core.content.ContextCompat import androidx.core.graphics.drawable.DrawableCompat import androidx.core.view.ViewCompat import androidx.recyclerview.widget.RecyclerView @@ -764,22 +761,14 @@ class ProfileController : NewBaseController(R.layout.controller_profile) { DrawableCompat.setTint(holder.binding.icon.drawable, mTintColor) if (!TextUtils.isEmpty(item.text) || controller.edit) { holder.binding.userInfoDetailContainer.visibility = View.VISIBLE - if (controller.activity != null) { - holder.binding.userInfoEditText.setTextColor( - ContextCompat.getColor( - controller.activity!!, - R.color.conversation_item_header - ) - ) - } + controller.viewThemeUtils.colorTextInputLayout(holder.binding.userInfoInputLayout) if (controller.edit && controller.editableFields.contains(item.field.toString().lowercase()) ) { - holder.binding.userInfoEditText.isEnabled = true - holder.binding.userInfoEditText.isFocusableInTouchMode = true - holder.binding.userInfoEditText.isEnabled = true - holder.binding.userInfoEditText.isCursorVisible = true - holder.binding.userInfoEditText.backgroundTintList = ColorStateList.valueOf(mTintColor) + holder.binding.userInfoEditTextEdit.isEnabled = true + holder.binding.userInfoEditTextEdit.isFocusableInTouchMode = true + holder.binding.userInfoEditTextEdit.isEnabled = true + holder.binding.userInfoEditTextEdit.isCursorVisible = true holder.binding.scope.setOnClickListener { ScopeDialog( controller.activity!!, @@ -790,11 +779,10 @@ class ProfileController : NewBaseController(R.layout.controller_profile) { } holder.binding.scope.alpha = HIGH_EMPHASIS_ALPHA } else { - holder.binding.userInfoEditText.isEnabled = false - holder.binding.userInfoEditText.isFocusableInTouchMode = false - holder.binding.userInfoEditText.isEnabled = false - holder.binding.userInfoEditText.isCursorVisible = false - holder.binding.userInfoEditText.backgroundTintList = ColorStateList.valueOf(Color.TRANSPARENT) + holder.binding.userInfoEditTextEdit.isEnabled = false + holder.binding.userInfoEditTextEdit.isFocusableInTouchMode = false + holder.binding.userInfoEditTextEdit.isEnabled = false + holder.binding.userInfoEditTextEdit.isCursorVisible = false holder.binding.scope.setOnClickListener(null) holder.binding.scope.alpha = MEDIUM_EMPHASIS_ALPHA } @@ -807,19 +795,19 @@ class ProfileController : NewBaseController(R.layout.controller_profile) { holder: ViewHolder, item: UserInfoDetailsItem ) { - holder.binding.userInfoEditText.setText(item.text) - holder.binding.userInfoEditText.hint = item.hint - holder.binding.userInfoEditText.addTextChangedListener(object : TextWatcher { + holder.binding.userInfoEditTextEdit.setText(item.text) + holder.binding.userInfoInputLayout.hint = item.hint + holder.binding.userInfoEditTextEdit.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) { // unused atm } override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { if (controller.edit) { - displayList!![holder.adapterPosition].text = holder.binding.userInfoEditText.text.toString() + displayList!![holder.adapterPosition].text = holder.binding.userInfoEditTextEdit.text.toString() } else { filteredDisplayList[holder.adapterPosition].text = - holder.binding.userInfoEditText.text.toString() + holder.binding.userInfoEditTextEdit.text.toString() } } diff --git a/app/src/main/res/layout/controller_profile.xml b/app/src/main/res/layout/controller_profile.xml index 21447143d..4d850c72c 100644 --- a/app/src/main/res/layout/controller_profile.xml +++ b/app/src/main/res/layout/controller_profile.xml @@ -29,7 +29,8 @@ + android:layout_height="wrap_content" + android:paddingBottom="@dimen/standard_padding"> - #61000000 - #666666 #FFFFFF @@ -83,8 +80,6 @@ #EFEFEF #66EFEFEF - @color/colorPrimary - #800082C9 #FFFFFF #121212