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,