fix(search): Correct regressions found during final testing

This commit is contained in:
SuperDragonXD
2025-07-28 23:16:42 +08:00
parent 64f0d29671
commit 0a40691711
10 changed files with 38 additions and 15 deletions

View File

@@ -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>

View File

@@ -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()

View File

@@ -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,

View File

@@ -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,

View File

@@ -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)
} }

View File

@@ -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)

View File

@@ -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() },

View File

@@ -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()

View File

@@ -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 {