mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-11 06:44:00 +00:00
fix(search): Correct regressions found during final testing
This commit is contained in:
@@ -796,6 +796,8 @@
|
|||||||
<string name="all_apps_search_result_calculator">Calculator</string>
|
<string name="all_apps_search_result_calculator">Calculator</string>
|
||||||
|
|
||||||
<!-- Description for each search result type -->
|
<!-- Description for each search result type -->
|
||||||
|
<string name="search_pref_files_search_on">Search on</string>
|
||||||
|
|
||||||
<string name="search_pref_result_files_description">Media, files, and more</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_contacts_description">Contacts and more</string>
|
||||||
<string name="search_pref_result_web_provider_description">Via <xliff:g id="web_search_provider">%1$s</xliff:g></string>
|
<string name="search_pref_result_web_provider_description">Via <xliff:g id="web_search_provider">%1$s</xliff:g></string>
|
||||||
|
|||||||
@@ -238,16 +238,23 @@ class SearchTargetFactory(
|
|||||||
|
|
||||||
fun createWebSearchActionTarget(
|
fun createWebSearchActionTarget(
|
||||||
query: String,
|
query: String,
|
||||||
providerName: String, // The actual display name, not an ID
|
providerName: String,
|
||||||
searchUrl: String, // The final, pre-formatted search URL
|
searchUrl: String,
|
||||||
@DrawableRes providerIconRes: Int,
|
@DrawableRes providerIconRes: Int,
|
||||||
|
tintIcon: Boolean = false,
|
||||||
): SearchTargetCompat {
|
): SearchTargetCompat {
|
||||||
val id = "browser:$query:$providerName"
|
val id = "browser:$query:$providerName"
|
||||||
val browserIntent = Intent(Intent.ACTION_VIEW, searchUrl.toUri())
|
val browserIntent = Intent(Intent.ACTION_VIEW, searchUrl.toUri())
|
||||||
val title = context.getString(R.string.all_apps_search_on_web_message, providerName)
|
val title = context.getString(R.string.all_apps_search_on_web_message, providerName)
|
||||||
|
|
||||||
|
val icon = Icon.createWithResource(context, providerIconRes).apply {
|
||||||
|
if (tintIcon) {
|
||||||
|
setTint(ColorTokens.TextColorSecondary.resolveColor(context))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val action = SearchActionCompat.Builder(id, title)
|
val action = SearchActionCompat.Builder(id, title)
|
||||||
.setIcon(Icon.createWithResource(context, providerIconRes))
|
.setIcon(icon)
|
||||||
.setIntent(browserIntent)
|
.setIntent(browserIntent)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ class LawnchairLocalSearchAlgorithm(context: Context) : LawnchairSearchAlgorithm
|
|||||||
val webProvider = provider.configure(context)
|
val webProvider = provider.configure(context)
|
||||||
|
|
||||||
val providerName = if (webProvider is CustomWebSearchProvider) {
|
val providerName = if (webProvider is CustomWebSearchProvider) {
|
||||||
webProvider.getDisplayName(context.getString(webProvider.label))
|
webProvider.getDisplayName()
|
||||||
} else {
|
} else {
|
||||||
context.getString(webProvider.label)
|
context.getString(webProvider.label)
|
||||||
}
|
}
|
||||||
@@ -158,6 +158,7 @@ class LawnchairLocalSearchAlgorithm(context: Context) : LawnchairSearchAlgorithm
|
|||||||
providerName = providerName,
|
providerName = providerName,
|
||||||
searchUrl = webProvider.getSearchUrl(query),
|
searchUrl = webProvider.getSearchUrl(query),
|
||||||
providerIconRes = webProvider.iconRes,
|
providerIconRes = webProvider.iconRes,
|
||||||
|
tintIcon = webProvider is CustomWebSearchProvider,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -174,8 +175,8 @@ class LawnchairLocalSearchAlgorithm(context: Context) : LawnchairSearchAlgorithm
|
|||||||
|
|
||||||
private val sectionBuilders: List<SectionBuilder> = listOf(
|
private val sectionBuilders: List<SectionBuilder> = listOf(
|
||||||
AppsAndShortcutsSectionBuilder,
|
AppsAndShortcutsSectionBuilder,
|
||||||
WebSuggestionsSectionBuilder,
|
|
||||||
CalculationSectionBuilder,
|
CalculationSectionBuilder,
|
||||||
|
WebSuggestionsSectionBuilder,
|
||||||
ContactsSectionBuilder,
|
ContactsSectionBuilder,
|
||||||
FilesSectionBuilder,
|
FilesSectionBuilder,
|
||||||
SettingsSectionBuilder,
|
SettingsSectionBuilder,
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ sealed class SearchResult {
|
|||||||
val providerName: String,
|
val providerName: String,
|
||||||
val searchUrl: String,
|
val searchUrl: String,
|
||||||
@DrawableRes val providerIconRes: Int,
|
@DrawableRes val providerIconRes: Int,
|
||||||
|
val tintIcon: Boolean = false,
|
||||||
) : Action()
|
) : Action()
|
||||||
data class EmptyState(
|
data class EmptyState(
|
||||||
@StringRes val titleRes: Int,
|
@StringRes val titleRes: Int,
|
||||||
|
|||||||
@@ -176,6 +176,7 @@ object ActionsSectionBuilder : SectionBuilder {
|
|||||||
providerName = webSearch.first().providerName,
|
providerName = webSearch.first().providerName,
|
||||||
searchUrl = webSearch.first().searchUrl,
|
searchUrl = webSearch.first().searchUrl,
|
||||||
providerIconRes = webSearch.first().providerIconRes,
|
providerIconRes = webSearch.first().providerIconRes,
|
||||||
|
tintIcon = webSearch.first().tintIcon,
|
||||||
).let {
|
).let {
|
||||||
targets.add(it)
|
targets.add(it)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ object CustomWebSearchProvider : WebSearchProvider {
|
|||||||
private var displayName: String = ""
|
private var displayName: String = ""
|
||||||
private val okHttpClient = OkHttpClient()
|
private val okHttpClient = OkHttpClient()
|
||||||
|
|
||||||
fun getDisplayName(getDisplayNamedefault: String): String = displayName
|
fun getDisplayName(): String = displayName
|
||||||
|
|
||||||
override fun configure(context: Context): WebSearchProvider {
|
override fun configure(context: Context): WebSearchProvider {
|
||||||
val prefs = PreferenceManager2.getInstance(context)
|
val prefs = PreferenceManager2.getInstance(context)
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import androidx.compose.material3.Text
|
|||||||
import androidx.compose.material3.TextButton
|
import androidx.compose.material3.TextButton
|
||||||
import androidx.compose.material3.ripple
|
import androidx.compose.material3.ripple
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
@@ -81,6 +82,10 @@ fun FileSearchProvider(
|
|||||||
val mainAdapter = prefs.searchResultFilesToggle.getAdapter()
|
val mainAdapter = prefs.searchResultFilesToggle.getAdapter()
|
||||||
val hasAnyPermissions by viewModel.hasAnyPermissions.collectAsStateWithLifecycle()
|
val hasAnyPermissions by viewModel.hasAnyPermissions.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
viewModel.refreshAccessStates()
|
||||||
|
}
|
||||||
|
|
||||||
LifecycleResumeEffect(Unit) {
|
LifecycleResumeEffect(Unit) {
|
||||||
viewModel.refreshAccessStates()
|
viewModel.refreshAccessStates()
|
||||||
onPauseOrDispose {}
|
onPauseOrDispose {}
|
||||||
@@ -93,18 +98,21 @@ fun FileSearchProvider(
|
|||||||
enabled = hasAnyPermissions,
|
enabled = hasAnyPermissions,
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
)
|
)
|
||||||
PreferenceGroup {
|
PreferenceGroup(
|
||||||
|
heading = stringResource(R.string.search_pref_files_search_on),
|
||||||
|
) {
|
||||||
val allFilesAccessState by viewModel.allFilesAccessState.collectAsStateWithLifecycle()
|
val allFilesAccessState by viewModel.allFilesAccessState.collectAsStateWithLifecycle()
|
||||||
|
val allFilesAccessAdapter = prefs.searchResultAllFiles.getAdapter()
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||||
ManageExternalStorageSetting(
|
ManageExternalStorageSetting(
|
||||||
accessState = allFilesAccessState,
|
accessState = allFilesAccessState,
|
||||||
adapter = prefs.searchResultAllFiles.getAdapter(),
|
adapter = allFilesAccessAdapter,
|
||||||
onPermissionRequest = viewModel::refreshAccessStates,
|
onPermissionRequest = viewModel::refreshAccessStates,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
GenericAccessSetting(
|
GenericAccessSetting(
|
||||||
adapter = prefs.searchResultAllFiles.getAdapter(),
|
adapter = allFilesAccessAdapter,
|
||||||
requiredPermission = android.Manifest.permission.READ_EXTERNAL_STORAGE,
|
requiredPermission = android.Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||||
switchEnabled = { allFilesAccessState != FileAccessState.Denied },
|
switchEnabled = { allFilesAccessState != FileAccessState.Denied },
|
||||||
label = stringResource(R.string.search_pref_result_all_files_title),
|
label = stringResource(R.string.search_pref_result_all_files_title),
|
||||||
@@ -122,6 +130,7 @@ fun FileSearchProvider(
|
|||||||
accessState = visualMediaAccessState,
|
accessState = visualMediaAccessState,
|
||||||
adapter = prefs.searchResultVisualMedia.getAdapter(),
|
adapter = prefs.searchResultVisualMedia.getAdapter(),
|
||||||
onPermissionRequest = viewModel::refreshAccessStates,
|
onPermissionRequest = viewModel::refreshAccessStates,
|
||||||
|
alwaysEnabled = allFilesAccessAdapter.state.value && allFilesAccessState == FileAccessState.Full,
|
||||||
)
|
)
|
||||||
|
|
||||||
GenericAccessSetting(
|
GenericAccessSetting(
|
||||||
@@ -132,6 +141,7 @@ fun FileSearchProvider(
|
|||||||
permissionTitle = stringResource(R.string.permissions_music_audio),
|
permissionTitle = stringResource(R.string.permissions_music_audio),
|
||||||
permissionDescription = stringResource(R.string.permissions_music_audio_description),
|
permissionDescription = stringResource(R.string.permissions_music_audio_description),
|
||||||
onPermissionResult = { viewModel.refreshAccessStates() },
|
onPermissionResult = { viewModel.refreshAccessStates() },
|
||||||
|
alwaysEnabled = allFilesAccessAdapter.state.value && allFilesAccessState == FileAccessState.Full,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -182,7 +192,7 @@ private fun ManageExternalStorageSetting(
|
|||||||
showPermissionDialog = true
|
showPermissionDialog = true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
switchEnabled = !isPlayStoreFlavor(),
|
switchEnabled = !isPlayStoreFlavor() && (accessState != FileAccessState.Denied),
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -190,8 +200,8 @@ private fun ManageExternalStorageSetting(
|
|||||||
if (showPermissionDialog) {
|
if (showPermissionDialog) {
|
||||||
if (!isPlayStoreFlavor()) {
|
if (!isPlayStoreFlavor()) {
|
||||||
PermissionDialog(
|
PermissionDialog(
|
||||||
title = stringResource(R.string.permissions_photos_videos),
|
title = stringResource(R.string.permissions_manage_storage),
|
||||||
text = stringResource(R.string.permissions_photos_videos_description),
|
text = stringResource(R.string.permissions_manage_storage_description),
|
||||||
isPermanentlyDenied = true,
|
isPermanentlyDenied = true,
|
||||||
onConfirm = { },
|
onConfirm = { },
|
||||||
onDismiss = { showPermissionDialog = false },
|
onDismiss = { showPermissionDialog = false },
|
||||||
@@ -273,7 +283,7 @@ private fun VisualMediaSetting(
|
|||||||
PermissionDialog(
|
PermissionDialog(
|
||||||
title = stringResource(R.string.permissions_photos_videos),
|
title = stringResource(R.string.permissions_photos_videos),
|
||||||
text = stringResource(R.string.permissions_photos_videos_description),
|
text = stringResource(R.string.permissions_photos_videos_description),
|
||||||
isPermanentlyDenied = !permissionState.shouldShowRationale && !permissionState.allPermissionsGranted,
|
isPermanentlyDenied = permissionState.allPermissionsGranted,
|
||||||
onConfirm = { permissionState.launchMultiplePermissionRequest() },
|
onConfirm = { permissionState.launchMultiplePermissionRequest() },
|
||||||
onDismiss = { showPermissionDialog = false },
|
onDismiss = { showPermissionDialog = false },
|
||||||
onGoToSettings = { context.openAppPermissionSettings() },
|
onGoToSettings = { context.openAppPermissionSettings() },
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ fun ContactsSearchProvider(
|
|||||||
PermissionDialog(
|
PermissionDialog(
|
||||||
title = stringResource(R.string.warn_contact_permission_title),
|
title = stringResource(R.string.warn_contact_permission_title),
|
||||||
text = stringResource(id = R.string.warn_contact_permission_content),
|
text = stringResource(id = R.string.warn_contact_permission_content),
|
||||||
isPermanentlyDenied = !contactsPermissionState.status.isGranted && !contactsPermissionState.status.shouldShowRationale,
|
isPermanentlyDenied = contactsPermissionState.status.shouldShowRationale,
|
||||||
onConfirm = { contactsPermissionState.launchPermissionRequest() },
|
onConfirm = { contactsPermissionState.launchPermissionRequest() },
|
||||||
onDismiss = {
|
onDismiss = {
|
||||||
backDispatcher?.onBackPressed()
|
backDispatcher?.onBackPressed()
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ class FileAccessManager private constructor(private val context: Context) : Safe
|
|||||||
_allFilesAccessState.value = getCurrentAllFilesAccessState()
|
_allFilesAccessState.value = getCurrentAllFilesAccessState()
|
||||||
_visualMediaAccessState.value = getCurrentVisualMediaState()
|
_visualMediaAccessState.value = getCurrentVisualMediaState()
|
||||||
_audioAccessState.value = getCurrentAudioState()
|
_audioAccessState.value = getCurrentAudioState()
|
||||||
|
_hasAnyPermission.value = hasAnyPermissions()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun hasAnyPermissions(): Boolean {
|
private fun hasAnyPermissions(): Boolean {
|
||||||
|
|||||||
Submodule platform_frameworks_libs_systemui updated: efa9b01922...970a3b2f14
Reference in New Issue
Block a user