Improve UX and migrate text to strings.xml

This commit is contained in:
SuperDragonXD
2024-04-03 15:13:00 +08:00
parent 067fd11a09
commit 297d593d7f
5 changed files with 106 additions and 62 deletions

View File

@@ -30,6 +30,8 @@
<string name="dock_description">Search Bar, Icon Count</string>
<string name="app_drawer_label">App Drawer</string>
<string name="app_drawer_description">Hidden Apps, Column Count, Icons</string>
<string name="drawer_search_label">Drawer Search</string>
<string name="drawer_search_description">Web Suggestions, Global Search</string>
<string name="folders_label">Folders</string>
<string name="folders_description">Row and Column Count</string>
<string name="gestures_label">Gestures</string>
@@ -467,22 +469,25 @@
<string name="bugreport_group_summary_multiple">Multiple new reports.</string>
<!-- Search ig -->
<string name="action_apply">Apply</string>
<string name="show_search_result_types">Show in Search Results</string>
<string name="search_pref_result_apps_and_shortcuts_title">Apps &amp; Shortcuts</string>
<string name="search_pref_result_shortcuts_title">App Shortcuts</string>
<string name="search_pref_result_people_title">People</string>
<string name="search_pref_result_tips_title">Pixel Tips</string>
<string name="search_pref_result_settings_title">Phone Settings</string>
<string name="search_pref_result_settings_title">Android Settings</string>
<string name="search_pref_result_files_title">Files</string>
<string name="search_pref_result_web_title">Web suggestions (via <xliff:g id="startpage">Startpage</xliff:g>)</string>
<string name="search_pref_result_web_title">Web suggestions</string>
<string name="search_pref_result_history_title">Search History</string>
<string name="search_pref_result_files_description">Media, files, and more</string>
<string name="search_pref_result_contacts_description">Contacts and more</string>
<string name="search_pref_result_web_description">Via <xliff:g id="startpage">Startpage</xliff:g></string>
<string name="warn_contact_permission_content">To search for contacts, grant Contacts and Phone permissions to Lawnchair.</string>
<string name="warn_files_permission_content">To search your files, grant Storage permissions to Lawnchair.</string>
<string name="grant_requested_permissions">Grant Permissions</string>
<string name="pref_suggestion_label">Suggestions</string>
<string name="all_apps_device_search_hint">Search</string>

View File

@@ -1,18 +1,23 @@
package app.lawnchair.ui.preferences.components
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Button
import androidx.compose.material3.Card
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import app.lawnchair.preferences.PreferenceAdapter
import app.lawnchair.ui.ModalBottomSheetContent
@@ -20,11 +25,13 @@ import app.lawnchair.ui.preferences.components.controls.MainSwitchPreference
import app.lawnchair.ui.preferences.components.controls.SliderPreference
import app.lawnchair.ui.preferences.components.layout.PreferenceTemplate
import app.lawnchair.ui.theme.LawnchairTheme
import app.lawnchair.ui.theme.dividerColor
import app.lawnchair.ui.util.PreviewLawnchair
import app.lawnchair.ui.util.bottomSheetHandler
import com.android.launcher3.R
@Composable
fun ResultsBottomSheet(
fun SearchSuggestionPreference(
adapter: PreferenceAdapter<Boolean>,
maxCountAdapter: PreferenceAdapter<Int>,
maxCountRange: ClosedRange<Int>,
@@ -32,23 +39,24 @@ fun ResultsBottomSheet(
maxCountLabel: String,
preventSwitchChange: Boolean = false,
description: String? = null,
enabled: Boolean = true,
requestEnabled: (() -> Unit)? = null,
requestEnabledDescription: String = "Requested permission not granted.",
isPermissionGranted: Boolean = true,
onPermissionRequest: (() -> Unit)? = null,
requestPermissionDescription: String? = null,
content: @Composable (() -> Unit)? = null
) {
val bottomSheetHandler = bottomSheetHandler
CustomSwitchPreference(
SearchSuggestionsSwitchPreference(
label = label,
description = description,
checked = adapter.state.value,
enabled = enabled,
enabled = isPermissionGranted,
preventSwitchChange = preventSwitchChange,
onClick = {
bottomSheetHandler.show {
ResultsBottomSheetContent(
BottomSheetContent(
onHide = { bottomSheetHandler.hide() },
enabled = enabled,
isPermissionGranted = isPermissionGranted,
adapterValue = adapter.state.value,
adapterOnChange = adapter::onChange,
label = label,
@@ -57,8 +65,10 @@ fun ResultsBottomSheet(
maxCountAdapter = maxCountAdapter,
maxCountRange = maxCountRange,
content = content,
requestEnabled = requestEnabled,
requestEnabledDescription = requestEnabledDescription,
onPermissionRequest = onPermissionRequest,
onPermissionDenied = {},
onPermissionGranted = {},
requestPermissionDescription = requestPermissionDescription,
preventSwitchChange = preventSwitchChange
)
}
@@ -67,9 +77,9 @@ fun ResultsBottomSheet(
}
@Composable
private fun ResultsBottomSheetContent(
private fun BottomSheetContent(
onHide: () -> Unit,
enabled: Boolean,
isPermissionGranted: Boolean,
adapterValue: Boolean,
adapterOnChange: (Boolean) -> Unit,
label: String,
@@ -78,49 +88,69 @@ private fun ResultsBottomSheetContent(
maxCountAdapter: PreferenceAdapter<Int>,
maxCountRange: ClosedRange<Int>,
content: @Composable (() -> Unit)?,
requestEnabled: (() -> Unit)?,
requestEnabledDescription: String,
onPermissionRequest: (() -> Unit)?,
// TODO optimize permission requesting code
onPermissionDenied: (() -> Unit)?,
onPermissionGranted: (() -> Unit)?,
requestPermissionDescription: String?,
preventSwitchChange: Boolean = false,
) {
LaunchedEffect(null) {
if (!isPermissionGranted && adapterValue) { adapterOnChange(false) }
}
ModalBottomSheetContent(
buttons = {
OutlinedButton(onClick = { onHide() }) {
Text(text = "Apply")
Text(text = stringResource(id = R.string.action_apply))
}
},
) {
Column {
MainSwitchPreference(
checked = adapterValue,
onCheckedChange = { if (!preventSwitchChange) adapterOnChange(it) },
onCheckedChange = {
if (!preventSwitchChange) {
adapterOnChange(it)
}
},
label = label,
description = description,
enabled = enabled,
enabled = if (preventSwitchChange) false else isPermissionGranted,
) {
Column(modifier = Modifier.padding(horizontal = 16.dp)) {
if (!enabled) {
if (requestEnabled != null) {
Card(
modifier = Modifier.fillMaxWidth(),
SliderPreference(
label = maxCountLabel,
adapter = maxCountAdapter,
valueRange = maxCountRange,
step = 1,
)
content?.invoke()
}
}
if (!isPermissionGranted) {
if (onPermissionRequest != null && requestPermissionDescription != null) {
Card(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp),
) {
Column(
modifier = Modifier
.padding(16.dp)
) {
Text(
text = requestPermissionDescription,
)
Button(
onClick = {
onHide()
onPermissionRequest()
},
) {
Text(
text = requestEnabledDescription,
)
Button(
onClick = { requestEnabled() }
) {
Text(text = "Grant permissions")
}
Text(text = stringResource(id = R.string.grant_requested_permissions))
}
}
} else {
SliderPreference(
label = maxCountLabel,
adapter = maxCountAdapter,
valueRange = maxCountRange,
step = 1,
)
content?.invoke()
}
}
}
@@ -130,10 +160,11 @@ private fun ResultsBottomSheetContent(
@Composable
private fun CustomSwitchPreference(
private fun SearchSuggestionsSwitchPreference(
label: String,
description: String? = null,
checked: Boolean,
preventSwitchChange: Boolean,
onClick: () -> Unit,
enabled: Boolean,
) {
@@ -148,13 +179,20 @@ private fun CustomSwitchPreference(
title = { Text(text = label) },
description = { description?.let { Text(text = it) } },
endWidget = {
Spacer(
modifier = Modifier
.height(32.dp)
.width(1.dp)
.fillMaxHeight()
.background(dividerColor()),
)
Switch(
modifier = Modifier
.padding(all = 16.dp)
.height(24.dp),
checked = checked,
onCheckedChange = { onClick() },
enabled = enabled,
enabled = if (preventSwitchChange) false else enabled,
)
},
applyPaddings = false,
@@ -163,12 +201,13 @@ private fun CustomSwitchPreference(
@PreviewLawnchair
@Composable
fun CustomSwitchPreferencePreview() {
fun SearchSuggestionsSwitchPreferencePreview() {
LawnchairTheme {
CustomSwitchPreference(
SearchSuggestionsSwitchPreference(
label = "example",
checked = true,
onClick = { /*TODO*/ },
preventSwitchChange = false,
enabled = true,
)
}

View File

@@ -46,7 +46,7 @@ fun MainSwitchPreference(
MainSwitchPreference(
checked = checked,
onCheckedChange = onCheckedChange,
label = label,
label = label,
enabled = enabled,
)

View File

@@ -105,8 +105,8 @@ fun PreferencesDashboard() {
)
PreferenceCategory(
label = "Drawer Search",
description = "Global Search, Web Suggestions",
label = stringResource(R.string.drawer_search_label),
description = stringResource(R.string.drawer_search_description),
iconResource = R.drawable.ic_search,
route = Routes.SEARCH
)

View File

@@ -9,7 +9,7 @@ import app.lawnchair.preferences.not
import app.lawnchair.preferences.preferenceManager
import app.lawnchair.preferences2.preferenceManager2
import app.lawnchair.ui.preferences.components.HiddenAppsInSearchPreference
import app.lawnchair.ui.preferences.components.ResultsBottomSheet
import app.lawnchair.ui.preferences.components.SearchSuggestionPreference
import app.lawnchair.ui.preferences.components.controls.MainSwitchPreference
import app.lawnchair.ui.preferences.components.controls.SliderPreference
import app.lawnchair.ui.preferences.components.controls.SwitchPreference
@@ -37,7 +37,7 @@ fun SearchPreferences() {
val hiddenApps = prefs2.hiddenApps.getAdapter().state.value
PreferenceLayout(label = "Drawer Search") {
PreferenceLayout(label = stringResource(id = R.string.drawer_search_label)) {
MainSwitchPreference(adapter = showDrawerSearchBar, label = stringResource(id = R.string.show_app_search_bar)) {
PreferenceGroup (heading = stringResource(R.string.general_label)){
@@ -53,7 +53,7 @@ fun SearchPreferences() {
val isDeviceSearch = prefs2.performWideSearch.getAdapter().state.value
PreferenceGroup(heading = stringResource(id = R.string.show_search_result_types)) {
ResultsBottomSheet(
SearchSuggestionPreference(
adapter = prefs.searchResultApps.getAdapter(),
maxCountAdapter = prefs2.maxSearchResultCount.getAdapter(),
maxCountRange = 3 .. 15,
@@ -67,13 +67,13 @@ fun SearchPreferences() {
description = stringResource(id = R.string.fuzzy_search_desc),
)
}
ResultsBottomSheet(
SearchSuggestionPreference(
adapter = prefs.searchResultStartPageSuggestion.getAdapter(),
maxCountAdapter = prefs2.maxSuggestionResultCount.getAdapter(),
maxCountRange = 3..10,
label = stringResource(id = R.string.search_pref_result_web_title),
maxCountLabel = stringResource(id = R.string.max_suggestion_result_count_title),
description = "Search the web",
description = stringResource(id = R.string.search_pref_result_web_description),
) {
SliderPreference(
label = stringResource(id = R.string.max_web_suggestion_delay),
@@ -84,7 +84,7 @@ fun SearchPreferences() {
)
}
ResultsBottomSheet(
SearchSuggestionPreference(
adapter = prefs.searchResultSettingsEntry.getAdapter(),
maxCountAdapter = prefs2.maxSettingsEntryResultCount.getAdapter(),
maxCountRange = 2..10,
@@ -93,29 +93,29 @@ fun SearchPreferences() {
)
if (isDeviceSearch) {
ResultsBottomSheet(
SearchSuggestionPreference(
adapter = prefs.searchResultPeople.getAdapter(),
maxCountAdapter = prefs2.maxPeopleResultCount.getAdapter(),
maxCountRange = 3..15,
label = stringResource(id = R.string.search_pref_result_people_title),
maxCountLabel = stringResource(id = R.string.max_people_result_count_title),
description = stringResource(id = R.string.search_pref_result_contacts_description),
enabled = contactPermissionGranted(context),
requestEnabled = { requestContactPermissionGranted(context, prefs) },
requestEnabledDescription = stringResource(id = R.string.warn_contact_permission_content),
isPermissionGranted = contactPermissionGranted(context),
onPermissionRequest = { requestContactPermissionGranted(context, prefs) },
requestPermissionDescription = stringResource(id = R.string.warn_contact_permission_content),
)
ResultsBottomSheet(
SearchSuggestionPreference(
adapter = prefs.searchResultFiles.getAdapter(),
maxCountAdapter = prefs2.maxFileResultCount.getAdapter(),
maxCountRange = 3..10,
label = stringResource(id = R.string.search_pref_result_files_title),
maxCountLabel = stringResource(id = R.string.max_file_result_count_title),
description = stringResource(id = R.string.search_pref_result_files_description),
enabled = filesAndStorageGranted(context),
requestEnabled = { checkAndRequestFilesPermission(context, prefs) },
requestEnabledDescription = stringResource(id = R.string.warn_files_permission_content),
isPermissionGranted = filesAndStorageGranted(context),
onPermissionRequest = { checkAndRequestFilesPermission(context, prefs) },
requestPermissionDescription = stringResource(id = R.string.warn_files_permission_content),
)
ResultsBottomSheet(
SearchSuggestionPreference(
adapter = prefs.searchResultSettingsEntry.getAdapter(),
maxCountAdapter = prefs2.maxSettingsEntryResultCount.getAdapter(),
maxCountRange = 2..10,
@@ -123,7 +123,7 @@ fun SearchPreferences() {
maxCountLabel = stringResource(id = R.string.max_settings_entry_result_count_title),
)
}
ResultsBottomSheet(
SearchSuggestionPreference(
adapter = prefs.searchResulRecentSuggestion.getAdapter(),
maxCountAdapter = prefs2.maxRecentResultCount.getAdapter(),
maxCountRange = 1..10,