move preferences to their own screen, for easier editing with preview

This commit is contained in:
Helium314 2025-01-26 17:58:36 +01:00
parent e1be94112e
commit 245c0f1678
3 changed files with 324 additions and 320 deletions

View file

@ -1,12 +1,34 @@
// SPDX-License-Identifier: GPL-3.0-only
package helium314.keyboard.settings
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.text.method.LinkMovementMethod
import android.view.View
import android.widget.TextView
import android.widget.Toast
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.core.net.toUri
import helium314.keyboard.latin.BuildConfig
import helium314.keyboard.latin.R
import helium314.keyboard.latin.settings.DebugSettings
import helium314.keyboard.latin.utils.DeviceProtectedUtils
import helium314.keyboard.latin.utils.Log
import helium314.keyboard.latin.utils.SpannableStringUtils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@Composable
fun AboutScreen(
@ -25,6 +47,116 @@ fun AboutScreen(
}
}
fun createAboutPrefs(context: Context) = listOf(
PrefDef(context, NonSettingsPrefs.APP, R.string.english_ime_name, R.string.app_slogan) {
Preference(
name = it.title,
description = it.description,
onClick = { },
icon = R.drawable.ic_launcher_foreground
)
},
PrefDef(context, NonSettingsPrefs.VERSION, R.string.version) {
var count by rememberSaveable { mutableIntStateOf(0) }
val ctx = LocalContext.current
val prefs = DeviceProtectedUtils.getSharedPreferences(ctx)
Preference(
name = it.title,
description = stringResource(R.string.version_text, BuildConfig.VERSION_NAME),
onClick = {
if (prefs.getBoolean(DebugSettings.PREF_SHOW_DEBUG_SETTINGS, false) || BuildConfig.DEBUG)
return@Preference
count++
if (count < 5) return@Preference
prefs.edit().putBoolean(DebugSettings.PREF_SHOW_DEBUG_SETTINGS, true).apply()
Toast.makeText(ctx, R.string.prefs_debug_settings_enabled, Toast.LENGTH_LONG).show()
},
icon = R.drawable.ic_settings_about_foreground
)
},
PrefDef(context, NonSettingsPrefs.LICENSE, R.string.license, R.string.gnu_gpl) {
val ctx = LocalContext.current
Preference(
name = it.title,
description = it.description,
onClick = {
val intent = Intent()
intent.data = "https://github.com/Helium314/HeliBoard/blob/main/LICENSE-GPL-3".toUri()
intent.action = Intent.ACTION_VIEW
ctx.startActivity(intent)
},
icon = R.drawable.ic_settings_about_license_foreground
)
},
PrefDef(context, NonSettingsPrefs.HIDDEN_FEATURES, R.string.hidden_features_title, R.string.hidden_features_summary) {
val ctx = LocalContext.current
Preference(
name = it.title,
description = it.description,
onClick = {
// Compose dialogs are in a rather sad state. They don't understand HTML, and don't scroll without customization.
// this should be re-done in compose, but... bah
val link = ("<a href=\"https://developer.android.com/reference/android/content/Context#createDeviceProtectedStorageContext()\">"
+ ctx.getString(R.string.hidden_features_text) + "</a>")
val message = ctx.getString(R.string.hidden_features_message, link)
val dialogMessage = SpannableStringUtils.fromHtml(message)
val builder = androidx.appcompat.app.AlertDialog.Builder(ctx)
.setIcon(R.drawable.ic_settings_about_hidden_features)
.setTitle(R.string.hidden_features_title)
.setMessage(dialogMessage)
.setPositiveButton(R.string.dialog_close, null)
.create()
builder.show()
(builder.findViewById<View>(android.R.id.message) as TextView).movementMethod = LinkMovementMethod.getInstance()
},
icon = R.drawable.ic_settings_about_hidden_features_foreground
)
},
PrefDef(context, NonSettingsPrefs.GITHUB, R.string.about_github_link) {
val ctx = LocalContext.current
Preference(
name = it.title,
description = it.description,
onClick = {
val intent = Intent()
intent.data = "https://github.com/Helium314/HeliBoard".toUri()
intent.action = Intent.ACTION_VIEW
ctx.startActivity(intent)
},
icon = R.drawable.ic_settings_about_github_foreground
)
},
PrefDef(context, NonSettingsPrefs.SAVE_LOG, R.string.save_log) {
val ctx = LocalContext.current
val scope = rememberCoroutineScope()
val launcher = rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode != Activity.RESULT_OK) return@rememberLauncherForActivityResult
val uri = result.data?.data ?: return@rememberLauncherForActivityResult
scope.launch(Dispatchers.IO) {
ctx.getActivity()?.contentResolver?.openOutputStream(uri)?.use { os ->
os.bufferedWriter().use { it.write(Log.getLog().joinToString("\n")) }
}
}
}
Preference(
name = it.title,
description = it.description,
onClick = {
val intent = Intent(Intent.ACTION_CREATE_DOCUMENT)
.addCategory(Intent.CATEGORY_OPENABLE)
.putExtra(
Intent.EXTRA_TITLE,
ctx.getString(R.string.english_ime_name)
.replace(" ", "_") + "_log_${System.currentTimeMillis()}.txt"
)
.setType("text/plain")
launcher.launch(intent)
},
icon = R.drawable.ic_settings_about_log_foreground
)
},
)
@Preview
@Composable
private fun Preview() {

View file

@ -1,42 +1,11 @@
// SPDX-License-Identifier: GPL-3.0-only
package helium314.keyboard.settings
import android.Manifest
import android.app.Activity
import android.content.Context
import android.content.ContextWrapper
import android.content.Intent
import android.text.method.LinkMovementMethod
import android.view.View
import android.widget.TextView
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.StringRes
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.core.net.toUri
import helium314.keyboard.latin.BuildConfig
import helium314.keyboard.latin.R
import helium314.keyboard.latin.permissions.PermissionsUtil
import helium314.keyboard.latin.settings.DebugSettings
import helium314.keyboard.latin.settings.Settings
import helium314.keyboard.latin.settings.UserDictionaryListFragment
import helium314.keyboard.latin.utils.DeviceProtectedUtils
import helium314.keyboard.latin.utils.Log
import helium314.keyboard.latin.utils.SpannableStringUtils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
class AllPrefs(context: Context) {
private val list = createPrefDefs(context)
@ -78,295 +47,7 @@ class PrefDef(
}
}
// this will be looooooong
private fun createPrefDefs(context: Context) = listOf(
// ---------------- correction ------------------
PrefDef(context, NonSettingsPrefs.EDIT_PERSONAL_DICTIONARY, R.string.edit_personal_dictionary) {
val ctx = LocalContext.current
Preference(
name = stringResource(R.string.edit_personal_dictionary),
onClick = { ctx.getActivity()?.switchTo(UserDictionaryListFragment()) },
)
},
PrefDef(context,
Settings.PREF_BLOCK_POTENTIALLY_OFFENSIVE,
R.string.prefs_block_potentially_offensive_title,
R.string.prefs_block_potentially_offensive_summary
) {
SwitchPreference(it, true)
},
PrefDef(context,
Settings.PREF_AUTO_CORRECTION,
R.string.autocorrect,
R.string.auto_correction_summary
) {
SwitchPreference(it, true)
},
PrefDef(context,
Settings.PREF_MORE_AUTO_CORRECTION,
R.string.more_autocorrect,
R.string.more_autocorrect_summary
) {
SwitchPreference(it, true) // todo: shouldn't it better be false?
},
PrefDef(context,
Settings.PREF_AUTOCORRECT_SHORTCUTS,
R.string.auto_correct_shortcuts,
R.string.auto_correct_shortcuts_summary
) {
SwitchPreference(it, true)
},
PrefDef(context,
Settings.PREF_AUTO_CORRECTION_CONFIDENCE,
R.string.auto_correction_confidence,
) { def ->
var showDialog by remember { mutableStateOf(false) }
// todo: arrays are arranged in a rather absurd way... this should be improved
val items = listOf(
stringResource(R.string.auto_correction_threshold_mode_modest) to "0",
stringResource(R.string.auto_correction_threshold_mode_aggressive) to "1",
stringResource(R.string.auto_correction_threshold_mode_very_aggressive) to "2",
)
val prefs = DeviceProtectedUtils.getSharedPreferences(LocalContext.current)
val selected = items.firstOrNull { it.second == prefs.getString(def.key, "0") }
Preference(
name = def.title,
description = selected?.first,
onClick = { showDialog = true }
)
if (showDialog) {
ListPickerDialog(
onDismissRequest = {showDialog = false },
items = items,
onItemSelected = {
if (it != selected)
prefs.edit().putString(def.key, it.second).apply()
},
selectedItem = selected,
title = { Text(def.title) },
getItemName = { it.first }
)
}
},
PrefDef(context,
Settings.PREF_AUTO_CAP,
R.string.auto_cap,
R.string.auto_cap_summary
) {
SwitchPreference(it, true)
},
PrefDef(context,
Settings.PREF_KEY_USE_DOUBLE_SPACE_PERIOD,
R.string.use_double_space_period,
R.string.use_double_space_period_summary
) {
SwitchPreference(it, true)
},
PrefDef(context,
Settings.PREF_AUTOSPACE_AFTER_PUNCTUATION,
R.string.autospace_after_punctuation,
R.string.autospace_after_punctuation_summary
) {
SwitchPreference(it, false)
},
PrefDef(context,
Settings.PREF_SHOW_SUGGESTIONS,
R.string.prefs_show_suggestions,
R.string.prefs_show_suggestions_summary
) {
SwitchPreference(it, true)
},
PrefDef(context,
Settings.PREF_ALWAYS_SHOW_SUGGESTIONS,
R.string.prefs_always_show_suggestions,
R.string.prefs_always_show_suggestions_summary
) {
SwitchPreference(it, false)
},
PrefDef(context,
Settings.PREF_KEY_USE_PERSONALIZED_DICTS,
R.string.use_personalized_dicts,
R.string.use_personalized_dicts_summary
) { prefDef ->
var showConfirmDialog by remember { mutableStateOf(false) }
SwitchPreference(
prefDef,
true,
allowCheckedChange = {
showConfirmDialog = !it
it
}
)
if (showConfirmDialog) {
val prefs = DeviceProtectedUtils.getSharedPreferences(LocalContext.current)
ConfirmationDialog(
onDismissRequest = { showConfirmDialog = false },
onConfirmed = {
prefs.edit().putBoolean(prefDef.key, false).apply()
},
text = { Text(stringResource(R.string.disable_personalized_dicts_message)) }
)
}
},
PrefDef(context,
Settings.PREF_BIGRAM_PREDICTIONS,
R.string.bigram_prediction,
R.string.bigram_prediction_summary
) {
SwitchPreference(it, true) { themeChanged = true }
},
PrefDef(context,
Settings.PREF_CENTER_SUGGESTION_TEXT_TO_ENTER,
R.string.center_suggestion_text_to_enter,
R.string.center_suggestion_text_to_enter_summary
) {
SwitchPreference(it, false)
},
PrefDef(context,
Settings.PREF_SUGGEST_CLIPBOARD_CONTENT,
R.string.suggest_clipboard_content,
R.string.suggest_clipboard_content_summary
) {
SwitchPreference(it, true)
},
PrefDef(context,
Settings.PREF_USE_CONTACTS,
R.string.use_contacts_dict,
R.string.use_contacts_dict_summary
) {
val activity = LocalContext.current.getActivity() ?: return@PrefDef
var granted by remember { mutableStateOf(PermissionsUtil.checkAllPermissionsGranted(activity, Manifest.permission.READ_CONTACTS)) }
val launcher = rememberLauncherForActivityResult(ActivityResultContracts.RequestPermission()) {
granted = it
}
SwitchPreference(
it,
false,
allowCheckedChange = {
if (it && !granted) {
launcher.launch(Manifest.permission.READ_CONTACTS)
false
} else true
}
)
},
PrefDef(context,
Settings.PREF_ADD_TO_PERSONAL_DICTIONARY,
R.string.add_to_personal_dictionary,
R.string.add_to_personal_dictionary_summary
) {
SwitchPreference(it, false)
},
// ---------------- about ------------------
PrefDef(context, NonSettingsPrefs.APP, R.string.english_ime_name, R.string.app_slogan) {
Preference(
name = it.title,
description = it.description,
onClick = { },
icon = R.drawable.ic_launcher_foreground
)
},
PrefDef(context, NonSettingsPrefs.VERSION, R.string.version) {
var count by rememberSaveable { mutableIntStateOf(0) }
val ctx = LocalContext.current
val prefs = DeviceProtectedUtils.getSharedPreferences(ctx)
Preference(
name = it.title,
description = stringResource(R.string.version_text, BuildConfig.VERSION_NAME),
onClick = {
if (prefs.getBoolean(DebugSettings.PREF_SHOW_DEBUG_SETTINGS, false) || BuildConfig.DEBUG)
return@Preference
count++
if (count < 5) return@Preference
prefs.edit().putBoolean(DebugSettings.PREF_SHOW_DEBUG_SETTINGS, true).apply()
Toast.makeText(ctx, R.string.prefs_debug_settings_enabled, Toast.LENGTH_LONG).show()
},
icon = R.drawable.ic_settings_about_foreground
)
},
PrefDef(context, NonSettingsPrefs.LICENSE, R.string.license, R.string.gnu_gpl) {
val ctx = LocalContext.current
Preference(
name = it.title,
description = it.description,
onClick = {
val intent = Intent()
intent.data = "https://github.com/Helium314/HeliBoard/blob/main/LICENSE-GPL-3".toUri()
intent.action = Intent.ACTION_VIEW
ctx.startActivity(intent)
},
icon = R.drawable.ic_settings_about_license_foreground
)
},
PrefDef(context, NonSettingsPrefs.HIDDEN_FEATURES, R.string.hidden_features_title, R.string.hidden_features_summary) {
val ctx = LocalContext.current
Preference(
name = it.title,
description = it.description,
onClick = {
// Compose dialogs are in a rather sad state. They don't understand HTML, and don't scroll without customization.
// this should be re-done in compose, but... bah
val link = ("<a href=\"https://developer.android.com/reference/android/content/Context#createDeviceProtectedStorageContext()\">"
+ ctx.getString(R.string.hidden_features_text) + "</a>")
val message = ctx.getString(R.string.hidden_features_message, link)
val dialogMessage = SpannableStringUtils.fromHtml(message)
val builder = androidx.appcompat.app.AlertDialog.Builder(ctx)
.setIcon(R.drawable.ic_settings_about_hidden_features)
.setTitle(R.string.hidden_features_title)
.setMessage(dialogMessage)
.setPositiveButton(R.string.dialog_close, null)
.create()
builder.show()
(builder.findViewById<View>(android.R.id.message) as TextView).movementMethod = LinkMovementMethod.getInstance()
},
icon = R.drawable.ic_settings_about_hidden_features_foreground
)
},
PrefDef(context, NonSettingsPrefs.GITHUB, R.string.about_github_link) {
val ctx = LocalContext.current
Preference(
name = it.title,
description = it.description,
onClick = {
val intent = Intent()
intent.data = "https://github.com/Helium314/HeliBoard".toUri()
intent.action = Intent.ACTION_VIEW
ctx.startActivity(intent)
},
icon = R.drawable.ic_settings_about_github_foreground
)
},
PrefDef(context, NonSettingsPrefs.SAVE_LOG, R.string.save_log) {
val ctx = LocalContext.current
val scope = rememberCoroutineScope()
val launcher = rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode != Activity.RESULT_OK) return@rememberLauncherForActivityResult
val uri = result.data?.data ?: return@rememberLauncherForActivityResult
scope.launch(Dispatchers.IO) {
ctx.getActivity()?.contentResolver?.openOutputStream(uri)?.use { os ->
os.bufferedWriter().use { it.write(Log.getLog().joinToString("\n")) }
}
}
}
Preference(
name = it.title,
description = it.description,
onClick = {
val intent = Intent(Intent.ACTION_CREATE_DOCUMENT)
.addCategory(Intent.CATEGORY_OPENABLE)
.putExtra(
Intent.EXTRA_TITLE,
ctx.getString(R.string.english_ime_name)
.replace(" ", "_") + "_log_${System.currentTimeMillis()}.txt"
)
.setType("text/plain")
launcher.launch(intent)
},
icon = R.drawable.ic_settings_about_log_foreground
)
},
)
private fun createPrefDefs(context: Context) = createAboutPrefs(context) + createCorrectionPrefs(context)
// todo: move somewhere else
fun Context.getActivity(): ComponentActivity? {

View file

@ -1,17 +1,28 @@
// SPDX-License-Identifier: GPL-3.0-only
package helium314.keyboard.settings
import android.Manifest
import android.content.Context
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import helium314.keyboard.latin.R
import helium314.keyboard.latin.permissions.PermissionsUtil
import helium314.keyboard.latin.settings.Settings
import helium314.keyboard.latin.settings.UserDictionaryListFragment
import helium314.keyboard.latin.utils.DeviceProtectedUtils
import helium314.keyboard.latin.utils.Log
@ -67,6 +78,186 @@ fun TextCorrectionScreen(
}
}
fun createCorrectionPrefs(context: Context) = listOf(
PrefDef(context, NonSettingsPrefs.EDIT_PERSONAL_DICTIONARY, R.string.edit_personal_dictionary) {
val ctx = LocalContext.current
Preference(
name = stringResource(R.string.edit_personal_dictionary),
onClick = { ctx.getActivity()?.switchTo(UserDictionaryListFragment()) },
)
},
PrefDef(context,
Settings.PREF_BLOCK_POTENTIALLY_OFFENSIVE,
R.string.prefs_block_potentially_offensive_title,
R.string.prefs_block_potentially_offensive_summary
) {
SwitchPreference(it, true)
},
PrefDef(context,
Settings.PREF_AUTO_CORRECTION,
R.string.autocorrect,
R.string.auto_correction_summary
) {
SwitchPreference(it, true)
},
PrefDef(context,
Settings.PREF_MORE_AUTO_CORRECTION,
R.string.more_autocorrect,
R.string.more_autocorrect_summary
) {
SwitchPreference(it, true) // todo: shouldn't it better be false?
},
PrefDef(context,
Settings.PREF_AUTOCORRECT_SHORTCUTS,
R.string.auto_correct_shortcuts,
R.string.auto_correct_shortcuts_summary
) {
SwitchPreference(it, true)
},
PrefDef(context,
Settings.PREF_AUTO_CORRECTION_CONFIDENCE,
R.string.auto_correction_confidence,
) { def ->
var showDialog by remember { mutableStateOf(false) }
// todo: arrays are arranged in a rather absurd way... this should be improved
val items = listOf(
stringResource(R.string.auto_correction_threshold_mode_modest) to "0",
stringResource(R.string.auto_correction_threshold_mode_aggressive) to "1",
stringResource(R.string.auto_correction_threshold_mode_very_aggressive) to "2",
)
val prefs = DeviceProtectedUtils.getSharedPreferences(LocalContext.current)
val selected = items.firstOrNull { it.second == prefs.getString(def.key, "0") }
Preference(
name = def.title,
description = selected?.first,
onClick = { showDialog = true }
)
if (showDialog) {
ListPickerDialog(
onDismissRequest = {showDialog = false },
items = items,
onItemSelected = {
if (it != selected)
prefs.edit().putString(def.key, it.second).apply()
},
selectedItem = selected,
title = { Text(def.title) },
getItemName = { it.first }
)
}
},
PrefDef(context,
Settings.PREF_AUTO_CAP,
R.string.auto_cap,
R.string.auto_cap_summary
) {
SwitchPreference(it, true)
},
PrefDef(context,
Settings.PREF_KEY_USE_DOUBLE_SPACE_PERIOD,
R.string.use_double_space_period,
R.string.use_double_space_period_summary
) {
SwitchPreference(it, true)
},
PrefDef(context,
Settings.PREF_AUTOSPACE_AFTER_PUNCTUATION,
R.string.autospace_after_punctuation,
R.string.autospace_after_punctuation_summary
) {
SwitchPreference(it, false)
},
PrefDef(context,
Settings.PREF_SHOW_SUGGESTIONS,
R.string.prefs_show_suggestions,
R.string.prefs_show_suggestions_summary
) {
SwitchPreference(it, true)
},
PrefDef(context,
Settings.PREF_ALWAYS_SHOW_SUGGESTIONS,
R.string.prefs_always_show_suggestions,
R.string.prefs_always_show_suggestions_summary
) {
SwitchPreference(it, false)
},
PrefDef(context,
Settings.PREF_KEY_USE_PERSONALIZED_DICTS,
R.string.use_personalized_dicts,
R.string.use_personalized_dicts_summary
) { prefDef ->
var showConfirmDialog by remember { mutableStateOf(false) }
SwitchPreference(
prefDef,
true,
allowCheckedChange = {
showConfirmDialog = !it
it
}
)
if (showConfirmDialog) {
val prefs = DeviceProtectedUtils.getSharedPreferences(LocalContext.current)
ConfirmationDialog(
onDismissRequest = { showConfirmDialog = false },
onConfirmed = {
prefs.edit().putBoolean(prefDef.key, false).apply()
},
text = { Text(stringResource(R.string.disable_personalized_dicts_message)) }
)
}
},
PrefDef(context,
Settings.PREF_BIGRAM_PREDICTIONS,
R.string.bigram_prediction,
R.string.bigram_prediction_summary
) {
SwitchPreference(it, true) { themeChanged = true }
},
PrefDef(context,
Settings.PREF_CENTER_SUGGESTION_TEXT_TO_ENTER,
R.string.center_suggestion_text_to_enter,
R.string.center_suggestion_text_to_enter_summary
) {
SwitchPreference(it, false)
},
PrefDef(context,
Settings.PREF_SUGGEST_CLIPBOARD_CONTENT,
R.string.suggest_clipboard_content,
R.string.suggest_clipboard_content_summary
) {
SwitchPreference(it, true)
},
PrefDef(context,
Settings.PREF_USE_CONTACTS,
R.string.use_contacts_dict,
R.string.use_contacts_dict_summary
) {
val activity = LocalContext.current.getActivity() ?: return@PrefDef
var granted by remember { mutableStateOf(PermissionsUtil.checkAllPermissionsGranted(activity, Manifest.permission.READ_CONTACTS)) }
val launcher = rememberLauncherForActivityResult(ActivityResultContracts.RequestPermission()) {
granted = it
}
SwitchPreference(
it,
false,
allowCheckedChange = {
if (it && !granted) {
launcher.launch(Manifest.permission.READ_CONTACTS)
false
} else true
}
)
},
PrefDef(context,
Settings.PREF_ADD_TO_PERSONAL_DICTIONARY,
R.string.add_to_personal_dictionary,
R.string.add_to_personal_dictionary_summary
) {
SwitchPreference(it, false)
},
)
@Preview
@Composable
private fun PreferencePreview() {