Added light/dark/auto theme setting

This commit is contained in:
Sylvain Berfini 2023-09-29 13:59:27 +02:00
parent 429553a6df
commit f1c410deaa
5 changed files with 129 additions and 8 deletions

View file

@ -86,6 +86,21 @@ class CorePreferences @UiThread constructor(private val context: Context) {
config.setBool("app", "auto_start_call_record", value)
}
/** -1 means auto, 0 no, 1 yes */
@get:WorkerThread @set:WorkerThread
var darkMode: Int
get() {
if (!darkModeAllowed) return 0
return config.getInt("app", "dark_mode", -1)
}
set(value) {
config.setInt("app", "dark_mode", value)
}
@get:WorkerThread
private val darkModeAllowed: Boolean
get() = config.getBool("app", "dark_mode_allowed", true)
// Will disable chat feature completely
@get:WorkerThread
val disableChat: Boolean

View file

@ -7,6 +7,7 @@ import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.ArrayAdapter
import androidx.annotation.UiThread
import androidx.appcompat.app.AppCompatDelegate
import androidx.navigation.navGraphViewModels
import org.linphone.R
import org.linphone.core.tools.Log
@ -38,6 +39,26 @@ class SettingsFragment : GenericFragment() {
}
}
private val themeListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
val label = viewModel.availableThemesNames[position]
val value = viewModel.availableThemesValues[position]
Log.i("$TAG Selected theme is now [$label] ($value)")
viewModel.setTheme(value)
AppCompatDelegate.setDefaultNightMode(
when (value) {
0 -> AppCompatDelegate.MODE_NIGHT_NO
1 -> AppCompatDelegate.MODE_NIGHT_YES
else -> AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
}
)
}
override fun onNothingSelected(parent: AdapterView<*>?) {
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
@ -74,5 +95,22 @@ class SettingsFragment : GenericFragment() {
}
binding.deviceRingtoneSpinner.onItemSelectedListener = ringtoneListener
// Light/Dark theme related
val themeAdapter = ArrayAdapter(
requireContext(),
R.layout.drop_down_item,
viewModel.availableThemesNames
)
themeAdapter.setDropDownViewResource(R.layout.assistant_transport_dropdown_cell)
binding.themeSpinner.adapter = themeAdapter
viewModel.theme.observe(viewLifecycleOwner) { theme ->
viewModel.availableThemesValues.indexOf(
theme
)
}
binding.themeSpinner.onItemSelectedListener = themeListener
}
}

View file

@ -50,11 +50,15 @@ class SettingsViewModel @UiThread constructor() : ViewModel() {
val videoEnabled = MutableLiveData<Boolean>()
val autoInitiateVideoCalls = MutableLiveData<Boolean>()
val autoAcceptVideoRequests = MutableLiveData<Boolean>()
val availableRingtonesPaths = arrayListOf<String>()
val availableRingtonesNames = arrayListOf<String>()
val selectedRingtone = MutableLiveData<String>()
val isRingtonePlaying = MutableLiveData<Boolean>()
val isVibrationAvailable = MutableLiveData<Boolean>()
val vibrateDuringIncomingCall = MutableLiveData<Boolean>()
val autoRecordCalls = MutableLiveData<Boolean>()
// Network settings
@ -62,7 +66,9 @@ class SettingsViewModel @UiThread constructor() : ViewModel() {
// User Interface settings
val isVibrationAvailable = MutableLiveData<Boolean>()
val theme = MutableLiveData<Int>()
val availableThemesNames = arrayListOf<String>()
val availableThemesValues = arrayListOf(-1, 0, 1)
// Other
@ -86,6 +92,16 @@ class SettingsViewModel @UiThread constructor() : ViewModel() {
computeAvailableRingtones()
availableThemesNames.add(
AppUtils.getString(R.string.settings_user_interface_auto_theme_label)
)
availableThemesNames.add(
AppUtils.getString(R.string.settings_user_interface_light_theme_label)
)
availableThemesNames.add(
AppUtils.getString(R.string.settings_user_interface_dark_theme_label)
)
coreContext.postOnCoreThread { core ->
echoCancellerEnabled.postValue(core.isEchoCancellationEnabled)
routeAudioToBluetooth.postValue(corePreferences.routeAudioToBluetoothIfAvailable)
@ -97,6 +113,8 @@ class SettingsViewModel @UiThread constructor() : ViewModel() {
useWifiOnly.postValue(core.isWifiOnlyEnabled)
selectedRingtone.postValue(core.ring.orEmpty())
theme.postValue(corePreferences.darkMode)
}
}
@ -245,6 +263,11 @@ class SettingsViewModel @UiThread constructor() : ViewModel() {
expandUserInterface.value = expandUserInterface.value == false
}
@UiThread
fun setTheme(theme: Int) {
corePreferences.darkMode = theme
}
@UiThread
private fun computeAvailableRingtones() {
availableRingtonesNames.add(

View file

@ -126,7 +126,7 @@
android:visibility="@{viewModel.expandCalls ? View.VISIBLE : View.GONE}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="21dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="16dp"
android:checked="@{viewModel.echoCancellerEnabled}"
app:layout_constraintEnd_toEndOf="@id/calls_background"
@ -413,7 +413,7 @@
android:visibility="@{viewModel.expandCalls ? View.VISIBLE : View.GONE}"
android:layout_width="1dp"
android:layout_height="1dp"
android:layout_marginTop="21dp"
android:layout_marginTop="20dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/auto_record_switch"/>
@ -472,7 +472,7 @@
android:visibility="@{viewModel.expandNetwork ? View.VISIBLE : View.GONE}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="21dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="16dp"
android:checked="@{viewModel.useWifiOnly}"
app:layout_constraintEnd_toEndOf="@id/network_background"
@ -483,7 +483,7 @@
android:visibility="@{viewModel.expandNetwork ? View.VISIBLE : View.GONE}"
android:layout_width="1dp"
android:layout_height="1dp"
android:layout_marginTop="21dp"
android:layout_marginTop="20dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/wifi_only_switch"/>
@ -518,14 +518,55 @@
app:layout_constraintTop_toBottomOf="@id/user_interface"
app:layout_constraintBottom_toBottomOf="@id/user_interface_bottom_anchor"/>
<androidx.appcompat.widget.AppCompatTextView
style="@style/settings_title_style"
android:id="@+id/theme_title"
android:visibility="@{viewModel.expandUserInterface ? View.VISIBLE : View.GONE}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="10dp"
android:text="@string/settings_user_interface_theme_title"
android:maxLines="2"
android:ellipsize="end"
app:layout_constraintTop_toBottomOf="@id/user_interface"
app:layout_constraintStart_toStartOf="@id/user_interface_background"
app:layout_constraintEnd_toEndOf="@id/user_interface_background"/>
<androidx.appcompat.widget.AppCompatSpinner
style="@style/material_switch_style"
android:id="@+id/theme_spinner"
android:visibility="@{viewModel.expandUserInterface ? View.VISIBLE : View.GONE}"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginEnd="10dp"
android:background="@drawable/edit_text_background"
android:paddingStart="20dp"
android:paddingEnd="20dp"
app:layout_constraintTop_toBottomOf="@id/theme_title"
app:layout_constraintStart_toStartOf="@id/theme_title"
app:layout_constraintEnd_toEndOf="@id/theme_title" />
<ImageView
android:id="@+id/theme_spinner_caret"
android:visibility="@{viewModel.expandUserInterface ? View.VISIBLE : View.GONE}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="20dp"
android:src="@drawable/caret_down"
app:layout_constraintTop_toTopOf="@id/theme_spinner"
app:layout_constraintBottom_toBottomOf="@id/theme_spinner"
app:layout_constraintEnd_toEndOf="@id/theme_spinner"/>
<View
android:id="@+id/user_interface_bottom_anchor"
android:visibility="@{viewModel.expandUserInterface ? View.VISIBLE : View.GONE}"
android:layout_width="1dp"
android:layout_height="1dp"
android:layout_marginTop="21dp"
android:layout_marginTop="20dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/network_bottom_anchor"/>
app:layout_constraintTop_toBottomOf="@id/theme_spinner"/>
<androidx.appcompat.widget.AppCompatTextView
style="@style/section_header_style"
@ -543,7 +584,7 @@
app:layout_constraintVertical_bias="0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/user_interface"
app:layout_constraintTop_toBottomOf="@id/user_interface_background"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -194,6 +194,10 @@
<string name="settings_network_title">Network</string>
<string name="settings_network_use_wifi_only">Use only Wi-Fi networks</string>
<string name="settings_user_interface_title">User interface</string>
<string name="settings_user_interface_theme_title">User interface</string>
<string name="settings_user_interface_dark_theme_label">Dark theme</string>
<string name="settings_user_interface_light_theme_label">Light theme</string>
<string name="settings_user_interface_auto_theme_label">Auto</string>
<string name="settings_advanced_title">Advanced settings</string>
<string name="manage_account_title">Manage account</string>