From e1fe3e22484c88349f5be0ee3f6f50ac6f21adf1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Jul 2026 13:29:13 +0000 Subject: [PATCH 1/3] build: bump the gradle-minor-patch group across 1 directory with 11 updates Bumps the gradle-minor-patch group with 11 updates in the / directory: | Package | From | To | | --- | --- | --- | | [gradle-wrapper](https://github.com/gradle/gradle) | `9.6.0` | `9.6.1` | | androidx.lifecycle:lifecycle-runtime-ktx | `2.10.0` | `2.11.0` | | androidx.lifecycle:lifecycle-process | `2.10.0` | `2.11.0` | | androidx.lifecycle:lifecycle-viewmodel-compose | `2.10.0` | `2.11.0` | | androidx.lifecycle:lifecycle-runtime-compose | `2.10.0` | `2.11.0` | | [io.ktor:ktor-server-core](https://github.com/ktorio/ktor) | `3.5.0` | `3.5.1` | | [io.ktor:ktor-server-cio](https://github.com/ktorio/ktor) | `3.5.0` | `3.5.1` | | [io.ktor:ktor-server-html-builder](https://github.com/ktorio/ktor) | `3.5.0` | `3.5.1` | | [io.ktor:ktor-server-content-negotiation](https://github.com/ktorio/ktor) | `3.5.0` | `3.5.1` | | [io.ktor:ktor-serialization-kotlinx-json](https://github.com/ktorio/ktor) | `3.5.0` | `3.5.1` | | [io.ktor:ktor-server-test-host](https://github.com/ktorio/ktor) | `3.5.0` | `3.5.1` | Updates `gradle-wrapper` from 9.6.0 to 9.6.1 - [Release notes](https://github.com/gradle/gradle/releases) - [Commits](https://github.com/gradle/gradle/compare/v9.6.0...v9.6.1) Updates `androidx.lifecycle:lifecycle-runtime-ktx` from 2.10.0 to 2.11.0 Updates `androidx.lifecycle:lifecycle-process` from 2.10.0 to 2.11.0 Updates `androidx.lifecycle:lifecycle-process` from 2.10.0 to 2.11.0 Updates `androidx.lifecycle:lifecycle-viewmodel-compose` from 2.10.0 to 2.11.0 Updates `androidx.lifecycle:lifecycle-runtime-compose` from 2.10.0 to 2.11.0 Updates `androidx.lifecycle:lifecycle-runtime-compose` from 2.10.0 to 2.11.0 Updates `io.ktor:ktor-server-core` from 3.5.0 to 3.5.1 - [Release notes](https://github.com/ktorio/ktor/releases) - [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md) - [Commits](https://github.com/ktorio/ktor/compare/3.5.0...3.5.1) Updates `io.ktor:ktor-server-cio` from 3.5.0 to 3.5.1 - [Release notes](https://github.com/ktorio/ktor/releases) - [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md) - [Commits](https://github.com/ktorio/ktor/compare/3.5.0...3.5.1) Updates `io.ktor:ktor-server-html-builder` from 3.5.0 to 3.5.1 - [Release notes](https://github.com/ktorio/ktor/releases) - [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md) - [Commits](https://github.com/ktorio/ktor/compare/3.5.0...3.5.1) Updates `io.ktor:ktor-server-content-negotiation` from 3.5.0 to 3.5.1 - [Release notes](https://github.com/ktorio/ktor/releases) - [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md) - [Commits](https://github.com/ktorio/ktor/compare/3.5.0...3.5.1) Updates `io.ktor:ktor-serialization-kotlinx-json` from 3.5.0 to 3.5.1 - [Release notes](https://github.com/ktorio/ktor/releases) - [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md) - [Commits](https://github.com/ktorio/ktor/compare/3.5.0...3.5.1) Updates `io.ktor:ktor-server-test-host` from 3.5.0 to 3.5.1 - [Release notes](https://github.com/ktorio/ktor/releases) - [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md) - [Commits](https://github.com/ktorio/ktor/compare/3.5.0...3.5.1) Updates `io.ktor:ktor-server-cio` from 3.5.0 to 3.5.1 - [Release notes](https://github.com/ktorio/ktor/releases) - [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md) - [Commits](https://github.com/ktorio/ktor/compare/3.5.0...3.5.1) Updates `io.ktor:ktor-server-html-builder` from 3.5.0 to 3.5.1 - [Release notes](https://github.com/ktorio/ktor/releases) - [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md) - [Commits](https://github.com/ktorio/ktor/compare/3.5.0...3.5.1) Updates `io.ktor:ktor-server-content-negotiation` from 3.5.0 to 3.5.1 - [Release notes](https://github.com/ktorio/ktor/releases) - [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md) - [Commits](https://github.com/ktorio/ktor/compare/3.5.0...3.5.1) Updates `io.ktor:ktor-serialization-kotlinx-json` from 3.5.0 to 3.5.1 - [Release notes](https://github.com/ktorio/ktor/releases) - [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md) - [Commits](https://github.com/ktorio/ktor/compare/3.5.0...3.5.1) Updates `io.ktor:ktor-server-test-host` from 3.5.0 to 3.5.1 - [Release notes](https://github.com/ktorio/ktor/releases) - [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md) - [Commits](https://github.com/ktorio/ktor/compare/3.5.0...3.5.1) --- updated-dependencies: - dependency-name: gradle-wrapper dependency-version: 9.6.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: gradle-minor-patch - dependency-name: androidx.lifecycle:lifecycle-runtime-ktx dependency-version: 2.11.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: gradle-minor-patch - dependency-name: androidx.lifecycle:lifecycle-process dependency-version: 2.11.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: gradle-minor-patch - dependency-name: androidx.lifecycle:lifecycle-process dependency-version: 2.11.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: gradle-minor-patch - dependency-name: androidx.lifecycle:lifecycle-viewmodel-compose dependency-version: 2.11.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: gradle-minor-patch - dependency-name: androidx.lifecycle:lifecycle-runtime-compose dependency-version: 2.11.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: gradle-minor-patch - dependency-name: androidx.lifecycle:lifecycle-runtime-compose dependency-version: 2.11.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: gradle-minor-patch - dependency-name: io.ktor:ktor-server-core dependency-version: 3.5.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: gradle-minor-patch - dependency-name: io.ktor:ktor-server-cio dependency-version: 3.5.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: gradle-minor-patch - dependency-name: io.ktor:ktor-server-html-builder dependency-version: 3.5.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: gradle-minor-patch - dependency-name: io.ktor:ktor-server-content-negotiation dependency-version: 3.5.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: gradle-minor-patch - dependency-name: io.ktor:ktor-serialization-kotlinx-json dependency-version: 3.5.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: gradle-minor-patch - dependency-name: io.ktor:ktor-server-test-host dependency-version: 3.5.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: gradle-minor-patch - dependency-name: io.ktor:ktor-server-cio dependency-version: 3.5.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: gradle-minor-patch - dependency-name: io.ktor:ktor-server-html-builder dependency-version: 3.5.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: gradle-minor-patch - dependency-name: io.ktor:ktor-server-content-negotiation dependency-version: 3.5.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: gradle-minor-patch - dependency-name: io.ktor:ktor-serialization-kotlinx-json dependency-version: 3.5.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: gradle-minor-patch - dependency-name: io.ktor:ktor-server-test-host dependency-version: 3.5.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: gradle-minor-patch ... Signed-off-by: dependabot[bot] --- gradle/libs.versions.toml | 6 +++--- gradle/wrapper/gradle-wrapper.properties | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2110e34..61a128d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -3,16 +3,16 @@ agp = "9.2.1" kotlin = "2.4.0" coreKtx = "1.19.0" activityCompose = "1.13.0" -lifecycleRuntimeKtx = "2.10.0" +lifecycleRuntimeKtx = "2.11.0" composeBom = "2024.12.01" navigationCompose = "2.9.8" -lifecycleViewmodelCompose = "2.10.0" +lifecycleViewmodelCompose = "2.11.0" junit = "4.13.2" junitExt = "1.3.0" espressoCore = "3.7.0" ktlintPlugin = "12.3.0" coroutines = "1.11.0" -ktor = "3.5.0" +ktor = "3.5.1" okhttp = "4.12.0" jsoup = "1.22.2" coil = "2.7.0" diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 65d8749..dbe66e1 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionSha256Sum=bbaeb2fef8710818cf0e261201dab964c572f92b942812df0c3620d62a529a01 -distributionUrl=https\://services.gradle.org/distributions/gradle-9.6.0-bin.zip +distributionSha256Sum=9c0f7faeeb306cb14e4279a3e084ca6b596894089a0638e68a07c945a32c9e14 +distributionUrl=https\://services.gradle.org/distributions/gradle-9.6.1-bin.zip networkTimeout=10000 retries=0 retryBackOffMs=500 From 755cc18d42069568ef06a5fea8a995d028ad8742 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 2 Jul 2026 10:00:28 +0000 Subject: [PATCH 2/3] fix(ui): satisfy the new Compose lint on resource reads in composition The lifecycle 2.11 bump pulls a newer androidx.compose.ui whose LocalContextGetResourceValueCall lint check (correctly) errors on querying string resources through LocalContext.current, which does not recompose on locale/configuration change. Route composition-time reads through stringResource() (the per-screen str() helpers, the engine status row, and the update banner) and the one event-time read (the history-import toast) through resources captured from LocalResources.current in composition. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_016AYAgNYmBkxsEYcgzSAjgT --- app/src/main/java/org/searchmob/MainActivity.kt | 10 +++++----- .../main/java/org/searchmob/ui/about/AboutScreen.kt | 5 +++-- .../java/org/searchmob/ui/history/HistoryScreen.kt | 9 +++++++-- app/src/main/java/org/searchmob/ui/home/HomeScreen.kt | 3 ++- .../org/searchmob/ui/onboarding/OnboardingWizard.kt | 3 ++- .../main/java/org/searchmob/ui/search/SearchScreen.kt | 9 +++------ .../java/org/searchmob/ui/settings/SettingsScreen.kt | 5 +++-- .../java/org/searchmob/ui/setup/BrowserSetupScreen.kt | 3 ++- 8 files changed, 27 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/org/searchmob/MainActivity.kt b/app/src/main/java/org/searchmob/MainActivity.kt index 3797535..c979aef 100644 --- a/app/src/main/java/org/searchmob/MainActivity.kt +++ b/app/src/main/java/org/searchmob/MainActivity.kt @@ -34,6 +34,7 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.core.content.ContextCompat import androidx.lifecycle.compose.collectAsStateWithLifecycle @@ -347,22 +348,21 @@ private fun UpdateBanner( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp), ) { - val context = LocalContext.current Text( text = if (inProgress) { - context.getString(R.string.update_banner_downloading, version) + stringResource(R.string.update_banner_downloading, version) } else { - context.getString(R.string.update_banner_available, version) + stringResource(R.string.update_banner_available, version) }, style = MaterialTheme.typography.bodyMedium, modifier = Modifier.weight(1f), ) Button(onClick = onUpdate, enabled = !inProgress) { - Text(context.getString(R.string.update_banner_action)) + Text(stringResource(R.string.update_banner_action)) } TextButton(onClick = onDismiss, enabled = !inProgress) { - Text(context.getString(R.string.update_banner_dismiss)) + Text(stringResource(R.string.update_banner_dismiss)) } } } diff --git a/app/src/main/java/org/searchmob/ui/about/AboutScreen.kt b/app/src/main/java/org/searchmob/ui/about/AboutScreen.kt index 3701bb0..39d1445 100644 --- a/app/src/main/java/org/searchmob/ui/about/AboutScreen.kt +++ b/app/src/main/java/org/searchmob/ui/about/AboutScreen.kt @@ -26,6 +26,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.testTag +import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.heading import androidx.compose.ui.semantics.semantics import androidx.compose.ui.unit.dp @@ -267,10 +268,10 @@ private fun Footer( } @Composable -private fun str(id: Int): String = LocalContext.current.getString(id) +private fun str(id: Int): String = stringResource(id) @Composable private fun str( id: Int, vararg formatArgs: Any, -): String = LocalContext.current.getString(id, *formatArgs) +): String = stringResource(id, *formatArgs) diff --git a/app/src/main/java/org/searchmob/ui/history/HistoryScreen.kt b/app/src/main/java/org/searchmob/ui/history/HistoryScreen.kt index 403f6da..f1ce39d 100644 --- a/app/src/main/java/org/searchmob/ui/history/HistoryScreen.kt +++ b/app/src/main/java/org/searchmob/ui/history/HistoryScreen.kt @@ -28,6 +28,8 @@ import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalResources +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle @@ -46,6 +48,9 @@ fun HistoryScreen( ) { val state by viewModel.state.collectAsStateWithLifecycle() val context = LocalContext.current + // Captured in composition so the toast below (an event-time callback, where composable reads are + // not allowed) formats with configuration-aware resources instead of querying LocalContext. + val resources = LocalResources.current val scope = androidx.compose.runtime.rememberCoroutineScope() val exportLauncher = @@ -76,7 +81,7 @@ fun HistoryScreen( viewModel.import(text) { count -> Toast.makeText( context, - context.getString(R.string.history_imported, count), + resources.getString(R.string.history_imported, count), Toast.LENGTH_SHORT, ).show() } @@ -178,4 +183,4 @@ private fun CenteredText(text: String) { } @Composable -private fun str(id: Int): String = LocalContext.current.getString(id) +private fun str(id: Int): String = stringResource(id) diff --git a/app/src/main/java/org/searchmob/ui/home/HomeScreen.kt b/app/src/main/java/org/searchmob/ui/home/HomeScreen.kt index 72a0963..b575013 100644 --- a/app/src/main/java/org/searchmob/ui/home/HomeScreen.kt +++ b/app/src/main/java/org/searchmob/ui/home/HomeScreen.kt @@ -30,6 +30,7 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import org.searchmob.R @@ -160,4 +161,4 @@ private fun OemGuidanceCard() { } @Composable -private fun str(id: Int): String = LocalContext.current.getString(id) +private fun str(id: Int): String = stringResource(id) diff --git a/app/src/main/java/org/searchmob/ui/onboarding/OnboardingWizard.kt b/app/src/main/java/org/searchmob/ui/onboarding/OnboardingWizard.kt index 5c3e5fb..14dd185 100644 --- a/app/src/main/java/org/searchmob/ui/onboarding/OnboardingWizard.kt +++ b/app/src/main/java/org/searchmob/ui/onboarding/OnboardingWizard.kt @@ -39,6 +39,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalClipboardManager import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.testTag +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.unit.dp import androidx.core.content.ContextCompat @@ -311,4 +312,4 @@ private fun hasNotificationsPermission(context: android.content.Context): Boolea } @Composable -private fun str(id: Int): String = LocalContext.current.getString(id) +private fun str(id: Int): String = stringResource(id) diff --git a/app/src/main/java/org/searchmob/ui/search/SearchScreen.kt b/app/src/main/java/org/searchmob/ui/search/SearchScreen.kt index cedfe86..b88920a 100644 --- a/app/src/main/java/org/searchmob/ui/search/SearchScreen.kt +++ b/app/src/main/java/org/searchmob/ui/search/SearchScreen.kt @@ -51,6 +51,7 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.testTag +import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.Role import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.semantics @@ -400,7 +401,6 @@ private fun MediaActionsRow( */ @Composable private fun EngineStatusRow(engineStatus: List) { - val context = LocalContext.current var expanded by remember(engineStatus) { mutableStateOf(false) } val responded = engineStatus.count { it.status != EngineStatus.FAILED } Column( @@ -412,7 +412,7 @@ private fun EngineStatusRow(engineStatus: List) { .padding(vertical = 4.dp), ) { Text( - text = context.getString(R.string.search_engines_responded, responded, engineStatus.size), + text = stringResource(R.string.search_engines_responded, responded, engineStatus.size), style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant, ) @@ -421,7 +421,7 @@ private fun EngineStatusRow(engineStatus: List) { val detail = when (outcome.status) { EngineStatus.CONTRIBUTED -> - context.getString(R.string.search_engine_result_count, outcome.count) + stringResource(R.string.search_engine_result_count, outcome.count) EngineStatus.EMPTY -> stringResource(R.string.engine_status_no_results) EngineStatus.FAILED -> stringResource(R.string.engine_status_failed) } @@ -648,6 +648,3 @@ private fun RankMenu(onSelect: (RankRule) -> Unit) { } } } - -@Composable -private fun stringResource(id: Int): String = LocalContext.current.getString(id) diff --git a/app/src/main/java/org/searchmob/ui/settings/SettingsScreen.kt b/app/src/main/java/org/searchmob/ui/settings/SettingsScreen.kt index ab6c8a6..ce706a9 100644 --- a/app/src/main/java/org/searchmob/ui/settings/SettingsScreen.kt +++ b/app/src/main/java/org/searchmob/ui/settings/SettingsScreen.kt @@ -49,6 +49,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalClipboardManager import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.testTag +import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.Role import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.semantics @@ -1000,10 +1001,10 @@ private fun PasteTextDialog( } @Composable -private fun str(id: Int): String = LocalContext.current.getString(id) +private fun str(id: Int): String = stringResource(id) @Composable private fun str( id: Int, vararg formatArgs: Any, -): String = LocalContext.current.getString(id, *formatArgs) +): String = stringResource(id, *formatArgs) diff --git a/app/src/main/java/org/searchmob/ui/setup/BrowserSetupScreen.kt b/app/src/main/java/org/searchmob/ui/setup/BrowserSetupScreen.kt index f833bdd..404da84 100644 --- a/app/src/main/java/org/searchmob/ui/setup/BrowserSetupScreen.kt +++ b/app/src/main/java/org/searchmob/ui/setup/BrowserSetupScreen.kt @@ -35,6 +35,7 @@ import androidx.compose.ui.platform.ClipboardManager import androidx.compose.ui.platform.LocalClipboardManager import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.testTag +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle @@ -279,4 +280,4 @@ private fun InstructionCard( } @Composable -private fun str(id: Int): String = LocalContext.current.getString(id) +private fun str(id: Int): String = stringResource(id) From a8d79aadeacfa0ea812dd32a90bee3159314f701 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 2 Jul 2026 10:06:33 +0000 Subject: [PATCH 3/3] fix(ui): hoist the history-import toast string; LocalResources is not in this Compose The resolved androidx.compose.ui ships the LocalContextGetResourceValueCall lint check but not yet the LocalResources composition local, so read the localized pattern with stringResource() in composition and format it with the count when the import completes. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_016AYAgNYmBkxsEYcgzSAjgT --- .../java/org/searchmob/ui/history/HistoryScreen.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/searchmob/ui/history/HistoryScreen.kt b/app/src/main/java/org/searchmob/ui/history/HistoryScreen.kt index f1ce39d..eeb0221 100644 --- a/app/src/main/java/org/searchmob/ui/history/HistoryScreen.kt +++ b/app/src/main/java/org/searchmob/ui/history/HistoryScreen.kt @@ -28,7 +28,6 @@ import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalResources import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp @@ -48,9 +47,10 @@ fun HistoryScreen( ) { val state by viewModel.state.collectAsStateWithLifecycle() val context = LocalContext.current - // Captured in composition so the toast below (an event-time callback, where composable reads are - // not allowed) formats with configuration-aware resources instead of querying LocalContext. - val resources = LocalResources.current + // The import toast fires in an event-time callback, where composable reads are not allowed, so + // the localized pattern is read here in composition and formatted with the count on completion + // (String.format applies the same positional %1$d substitution getString would). + val importedTemplate = stringResource(R.string.history_imported) val scope = androidx.compose.runtime.rememberCoroutineScope() val exportLauncher = @@ -81,7 +81,7 @@ fun HistoryScreen( viewModel.import(text) { count -> Toast.makeText( context, - resources.getString(R.string.history_imported, count), + importedTemplate.format(count), Toast.LENGTH_SHORT, ).show() }