From 297d593d7f4d4dfbd13ecd38bda8ba6035756b6e Mon Sep 17 00:00:00 2001 From: SuperDragonXD <70206496+SuperDragonXD@users.noreply.github.com> Date: Wed, 3 Apr 2024 15:13:00 +0800 Subject: [PATCH] Improve UX and migrate text to strings.xml --- lawnchair/res/values/strings.xml | 9 +- ...Sheet.kt => SearchSuggestionPreference.kt} | 121 ++++++++++++------ .../controls/MainSwitchPreference.kt | 2 +- .../destinations/PreferencesDashboard.kt | 4 +- .../destinations/SearchPreferences.kt | 32 ++--- 5 files changed, 106 insertions(+), 62 deletions(-) rename lawnchair/src/app/lawnchair/ui/preferences/components/{ResultsBottomSheet.kt => SearchSuggestionPreference.kt} (54%) diff --git a/lawnchair/res/values/strings.xml b/lawnchair/res/values/strings.xml index fd6a3d0a8d..959c6f4067 100644 --- a/lawnchair/res/values/strings.xml +++ b/lawnchair/res/values/strings.xml @@ -30,6 +30,8 @@ Search Bar, Icon Count App Drawer Hidden Apps, Column Count, Icons + Drawer Search + Web Suggestions, Global Search Folders Row and Column Count Gestures @@ -467,22 +469,25 @@ Multiple new reports. + Apply Show in Search Results Apps & Shortcuts App Shortcuts People Pixel Tips - Phone Settings + Android Settings Files - Web suggestions (via Startpage) + Web suggestions Search History Media, files, and more Contacts and more + Via Startpage To search for contacts, grant Contacts and Phone permissions to Lawnchair. To search your files, grant Storage permissions to Lawnchair. + Grant Permissions Suggestions Search diff --git a/lawnchair/src/app/lawnchair/ui/preferences/components/ResultsBottomSheet.kt b/lawnchair/src/app/lawnchair/ui/preferences/components/SearchSuggestionPreference.kt similarity index 54% rename from lawnchair/src/app/lawnchair/ui/preferences/components/ResultsBottomSheet.kt rename to lawnchair/src/app/lawnchair/ui/preferences/components/SearchSuggestionPreference.kt index dad421696a..c20d548721 100644 --- a/lawnchair/src/app/lawnchair/ui/preferences/components/ResultsBottomSheet.kt +++ b/lawnchair/src/app/lawnchair/ui/preferences/components/SearchSuggestionPreference.kt @@ -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, maxCountAdapter: PreferenceAdapter, maxCountRange: ClosedRange, @@ -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, maxCountRange: ClosedRange, 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, ) } diff --git a/lawnchair/src/app/lawnchair/ui/preferences/components/controls/MainSwitchPreference.kt b/lawnchair/src/app/lawnchair/ui/preferences/components/controls/MainSwitchPreference.kt index aea7456ae0..9f43fd4586 100644 --- a/lawnchair/src/app/lawnchair/ui/preferences/components/controls/MainSwitchPreference.kt +++ b/lawnchair/src/app/lawnchair/ui/preferences/components/controls/MainSwitchPreference.kt @@ -46,7 +46,7 @@ fun MainSwitchPreference( MainSwitchPreference( checked = checked, onCheckedChange = onCheckedChange, - label = label, + label = label, enabled = enabled, ) diff --git a/lawnchair/src/app/lawnchair/ui/preferences/destinations/PreferencesDashboard.kt b/lawnchair/src/app/lawnchair/ui/preferences/destinations/PreferencesDashboard.kt index 11fc582442..b1205cd053 100644 --- a/lawnchair/src/app/lawnchair/ui/preferences/destinations/PreferencesDashboard.kt +++ b/lawnchair/src/app/lawnchair/ui/preferences/destinations/PreferencesDashboard.kt @@ -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 ) diff --git a/lawnchair/src/app/lawnchair/ui/preferences/destinations/SearchPreferences.kt b/lawnchair/src/app/lawnchair/ui/preferences/destinations/SearchPreferences.kt index 8553ef4bae..1ad815b16d 100644 --- a/lawnchair/src/app/lawnchair/ui/preferences/destinations/SearchPreferences.kt +++ b/lawnchair/src/app/lawnchair/ui/preferences/destinations/SearchPreferences.kt @@ -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,