From f048b895b5d5b7073037b8be0fb0748798de8123 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 24 Apr 2024 16:03:41 +0200 Subject: [PATCH] Added main color theme selector in settings --- app/src/main/AndroidManifest.xml | 1 - .../java/org/linphone/core/CorePreferences.kt | 11 ++++ .../java/org/linphone/ui/GenericActivity.kt | 14 +++++ .../java/org/linphone/ui/call/CallActivity.kt | 12 +++++ .../settings/fragment/SettingsFragment.kt | 33 +++++++++++- .../settings/viewmodel/SettingsViewModel.kt | 23 +++++++- ...ape_primary_button_disabled_background.xml | 2 +- app/src/main/res/layout/settings_fragment.xml | 3 +- .../res/layout/settings_user_interface.xml | 53 +++++++++++++++++++ app/src/main/res/values-fr/strings.xml | 1 + app/src/main/res/values-night/themes.xml | 1 + app/src/main/res/values/attrs.xml | 1 + app/src/main/res/values/colors.xml | 6 +++ app/src/main/res/values/strings.xml | 1 + app/src/main/res/values/themes.xml | 15 ++++++ 15 files changed, 170 insertions(+), 7 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d4385d2a7..bd21fcd50 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -41,7 +41,6 @@ android:roundIcon="@mipmap/ic_launcher_round" android:label="@string/app_name" android:enableOnBackInvokedCallback="true" - android:theme="@style/Theme.Linphone" android:localeConfig="@xml/locales_config" tools:targetApi="34"> diff --git a/app/src/main/java/org/linphone/core/CorePreferences.kt b/app/src/main/java/org/linphone/core/CorePreferences.kt index d6e3db597..32703c3fe 100644 --- a/app/src/main/java/org/linphone/core/CorePreferences.kt +++ b/app/src/main/java/org/linphone/core/CorePreferences.kt @@ -137,6 +137,13 @@ class CorePreferences @UiThread constructor(private val context: Context) { config.setInt("app", "dark_mode", value) } + @get:WorkerThread @set:WorkerThread + var themeMainColor: String + get() = config.getString("ui", "theme_main_color", "orange")!! + set(value) { + config.setString("ui", "theme_main_color", value) + } + @get:WorkerThread @set:WorkerThread var linphoneConfigurationVersion: Int get() = config.getInt("app", "config_version", 50200) @@ -148,6 +155,10 @@ class CorePreferences @UiThread constructor(private val context: Context) { val darkModeAllowed: Boolean get() = config.getBool("ui", "dark_mode_allowed", true) + @get:WorkerThread + val changeMainColorAllowed: Boolean + get() = config.getBool("ui", "change_main_color_allowed", true) + @get:WorkerThread val onlyDisplaySipUriUsername: Boolean get() = config.getBool("ui", "only_display_sip_uri_username", false) diff --git a/app/src/main/java/org/linphone/ui/GenericActivity.kt b/app/src/main/java/org/linphone/ui/GenericActivity.kt index 7a68b6c8a..1defc24f4 100644 --- a/app/src/main/java/org/linphone/ui/GenericActivity.kt +++ b/app/src/main/java/org/linphone/ui/GenericActivity.kt @@ -21,9 +21,11 @@ package org.linphone.ui import android.annotation.SuppressLint import android.content.res.Configuration +import android.content.res.Resources import android.os.Bundle import android.view.ViewGroup import androidx.annotation.DrawableRes +import androidx.annotation.MainThread import androidx.appcompat.app.AppCompatActivity import androidx.core.view.WindowCompat import androidx.core.view.children @@ -32,12 +34,14 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.linphone.LinphoneApplication.Companion.corePreferences +import org.linphone.R import org.linphone.compatibility.Compatibility import org.linphone.core.tools.Log import org.linphone.utils.ToastUtils import org.linphone.utils.slideInToastFromTop import org.linphone.utils.slideInToastFromTopForDuration +@MainThread open class GenericActivity : AppCompatActivity() { companion object { private const val TAG = "[Generic Activity]" @@ -45,6 +49,16 @@ open class GenericActivity : AppCompatActivity() { private lateinit var toastsArea: ViewGroup + override fun getTheme(): Resources.Theme { + val mainColor = corePreferences.themeMainColor + val theme = super.getTheme() + when (mainColor) { + "yellow" -> theme.applyStyle(R.style.Theme_LinphoneYellow, true) + else -> theme.applyStyle(R.style.Theme_Linphone, true) + } + return theme + } + @SuppressLint("SourceLockedOrientationActivity") override fun onCreate(savedInstanceState: Bundle?) { WindowCompat.setDecorFitsSystemWindows(window, true) diff --git a/app/src/main/java/org/linphone/ui/call/CallActivity.kt b/app/src/main/java/org/linphone/ui/call/CallActivity.kt index 91e6684f2..2bd8931c0 100644 --- a/app/src/main/java/org/linphone/ui/call/CallActivity.kt +++ b/app/src/main/java/org/linphone/ui/call/CallActivity.kt @@ -22,6 +22,7 @@ package org.linphone.ui.call import android.Manifest import android.content.Intent import android.content.pm.PackageManager +import android.content.res.Resources import android.os.Bundle import androidx.activity.result.contract.ActivityResultContracts import androidx.annotation.UiThread @@ -39,6 +40,7 @@ import com.google.android.material.bottomsheet.BottomSheetDialogFragment import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import org.linphone.LinphoneApplication.Companion.coreContext +import org.linphone.LinphoneApplication.Companion.corePreferences import org.linphone.R import org.linphone.compatibility.Compatibility import org.linphone.core.tools.Log @@ -94,6 +96,16 @@ class CallActivity : GenericActivity() { } } + override fun getTheme(): Resources.Theme { + val mainColor = corePreferences.themeMainColor + val theme = super.getTheme() + when (mainColor) { + "yellow" -> theme.applyStyle(R.style.Theme_LinphoneInCallYellow, true) + else -> theme.applyStyle(R.style.Theme_LinphoneInCall, true) + } + return theme + } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) diff --git a/app/src/main/java/org/linphone/ui/main/settings/fragment/SettingsFragment.kt b/app/src/main/java/org/linphone/ui/main/settings/fragment/SettingsFragment.kt index 0a68d3691..21bf32110 100644 --- a/app/src/main/java/org/linphone/ui/main/settings/fragment/SettingsFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/settings/fragment/SettingsFragment.kt @@ -75,6 +75,22 @@ class SettingsFragment : GenericFragment() { } } + private val colorListener = object : AdapterView.OnItemSelectedListener { + override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { + val label = viewModel.availableColorsNames[position] + val value = viewModel.availableColorsValues[position] + Log.i("$TAG Selected color is now [$label] ($value)") + // Be carefull not to create an infinite loop + if (value != viewModel.color.value.orEmpty()) { + viewModel.setColor(value) + requireActivity().recreate() + } + } + + override fun onNothingSelected(parent: AdapterView<*>?) { + } + } + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -169,9 +185,24 @@ class SettingsFragment : GenericFragment() { binding.userInterfaceSettings.themeSpinner.setSelection( viewModel.availableThemesValues.indexOf(theme) ) + binding.userInterfaceSettings.themeSpinner.onItemSelectedListener = themeListener } - binding.userInterfaceSettings.themeSpinner.onItemSelectedListener = themeListener + // Choose main color + val colorAdapter = ArrayAdapter( + requireContext(), + R.layout.drop_down_item, + viewModel.availableColorsNames + ) + colorAdapter.setDropDownViewResource(R.layout.generic_dropdown_cell) + binding.userInterfaceSettings.colorSpinner.adapter = colorAdapter + + viewModel.color.observe(viewLifecycleOwner) { color -> + binding.userInterfaceSettings.colorSpinner.setSelection( + viewModel.availableColorsValues.indexOf(color) + ) + binding.userInterfaceSettings.colorSpinner.onItemSelectedListener = colorListener + } startPostponedEnterTransition() } diff --git a/app/src/main/java/org/linphone/ui/main/settings/viewmodel/SettingsViewModel.kt b/app/src/main/java/org/linphone/ui/main/settings/viewmodel/SettingsViewModel.kt index 40793f628..31599fe23 100644 --- a/app/src/main/java/org/linphone/ui/main/settings/viewmodel/SettingsViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/settings/viewmodel/SettingsViewModel.kt @@ -115,6 +115,14 @@ class SettingsViewModel @UiThread constructor() : ViewModel() { ) val availableThemesValues = arrayListOf(-1, 0, 1) + val showColorSelector = MutableLiveData() + val color = MutableLiveData() + val availableColorsNames = arrayListOf( + "Orange", + "Yellow" + ) + val availableColorsValues = arrayListOf("orange", "yellow") + // Advanced settings val keepAliveThirdPartyAccountsService = MutableLiveData() @@ -126,6 +134,7 @@ class SettingsViewModel @UiThread constructor() : ViewModel() { showMeetingsSettings.postValue(!corePreferences.disableMeetings) ldapAvailable.postValue(core.ldapAvailable()) showThemeSelector.postValue(corePreferences.darkModeAllowed) + showColorSelector.postValue(corePreferences.changeMainColorAllowed) } showContactsSettings.value = true @@ -160,6 +169,7 @@ class SettingsViewModel @UiThread constructor() : ViewModel() { defaultLayout.postValue(core.defaultConferenceLayout.toInt()) theme.postValue(corePreferences.darkMode) + color.postValue(corePreferences.themeMainColor) keepAliveThirdPartyAccountsService.postValue(corePreferences.keepServiceAlive) @@ -355,9 +365,18 @@ class SettingsViewModel @UiThread constructor() : ViewModel() { fun setTheme(themeValue: Int) { coreContext.postOnCoreThread { corePreferences.darkMode = themeValue - Log.i("$TAG Theme [$theme] saved") - theme.postValue(themeValue) + Log.i("$TAG Theme [$themeValue] saved") } + theme.value = themeValue + } + + @UiThread + fun setColor(colorName: String) { + coreContext.postOnCoreThread { + corePreferences.themeMainColor = colorName + Log.i("$TAG Color [$colorName] saved") + } + color.value = colorName } @UiThread diff --git a/app/src/main/res/drawable/shape_primary_button_disabled_background.xml b/app/src/main/res/drawable/shape_primary_button_disabled_background.xml index 41e28b7e1..64e0de18a 100644 --- a/app/src/main/res/drawable/shape_primary_button_disabled_background.xml +++ b/app/src/main/res/drawable/shape_primary_button_disabled_background.xml @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/app/src/main/res/layout/settings_fragment.xml b/app/src/main/res/layout/settings_fragment.xml index 5a111f541..40e387811 100644 --- a/app/src/main/res/layout/settings_fragment.xml +++ b/app/src/main/res/layout/settings_fragment.xml @@ -251,7 +251,6 @@ android:text="@string/settings_user_interface_title" android:drawableEnd="@{viewModel.expandUserInterface ? @drawable/caret_up : @drawable/caret_down, default=@drawable/caret_up}" android:drawableTint="?attr/color_main2_600" - android:visibility="@{viewModel.showThemeSelector ? View.VISIBLE : View.GONE}" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toBottomOf="@id/network_settings"/> @@ -264,7 +263,7 @@ android:layout_marginTop="8dp" android:layout_marginStart="16dp" android:layout_marginEnd="16dp" - android:visibility="@{viewModel.showThemeSelector && viewModel.expandUserInterface ? View.VISIBLE : View.GONE}" + android:visibility="@{viewModel.expandUserInterface ? View.VISIBLE : View.GONE}" app:layout_constraintTop_toBottomOf="@id/user_interface" bind:viewModel="@{viewModel}"/> diff --git a/app/src/main/res/layout/settings_user_interface.xml b/app/src/main/res/layout/settings_user_interface.xml index 9eb17b2da..f4ceac963 100644 --- a/app/src/main/res/layout/settings_user_interface.xml +++ b/app/src/main/res/layout/settings_user_interface.xml @@ -16,6 +16,18 @@ android:paddingBottom="20dp" android:background="@drawable/shape_squircle_white_background"> + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 340a5500b..d6b58b5e3 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -258,6 +258,7 @@ Sombre Clair Auto + Couleur principale Paramètres avancés Garder l\'app en vie via un Service diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml index b9648c10b..ef1656c5e 100644 --- a/app/src/main/res/values-night/themes.xml +++ b/app/src/main/res/values-night/themes.xml @@ -16,6 +16,7 @@ @color/black @color/orange_main_900 + @color/orange_main_100_alpha_50 @color/orange_main_300 @color/orange_main_500 @color/orange_main_700 diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml index 27ab5f9c5..12bc7efdf 100644 --- a/app/src/main/res/values/attrs.xml +++ b/app/src/main/res/values/attrs.xml @@ -12,6 +12,7 @@ + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 56f196a0b..d541a812f 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -66,4 +66,10 @@ #FF923F #80FFFFFF + + #FFE799 + #80FFE799 + #FFDE70 + #FFD23F + #FFCB1F \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8632faa94..e070c004c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -293,6 +293,7 @@ Dark theme Light theme Auto + Main color Advanced settings Keep app alive using Service diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index ffc6e0944..55d0cc34a 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -17,6 +17,7 @@ @color/white @color/orange_main_100 + @color/orange_main_100_alpha_50 @color/orange_main_300 @color/orange_main_500 @color/orange_main_700 @@ -56,12 +57,26 @@ @color/white + + + +