diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 0d26c07..3dcf73d 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -18,7 +18,7 @@ android { minSdk = 26 targetSdk = 36 versionCode = 1 - versionName = "0.0.75" + versionName = "0.0.8" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } diff --git a/app/src/main/java/com/baidaidai/rootless_store/components/executeScreen/executeScreenNecessaryComponents.kt b/app/src/main/java/com/baidaidai/rootless_store/components/executeScreen/executeScreenNecessaryComponents.kt index 7d0c870..e6e80a4 100644 --- a/app/src/main/java/com/baidaidai/rootless_store/components/executeScreen/executeScreenNecessaryComponents.kt +++ b/app/src/main/java/com/baidaidai/rootless_store/components/executeScreen/executeScreenNecessaryComponents.kt @@ -10,6 +10,7 @@ import androidx.compose.material3.Text import androidx.compose.material3.TopAppBarScrollBehavior import androidx.compose.runtime.Composable import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.PreviewLightDark import com.baidaidai.rootless_store.R @@ -21,7 +22,7 @@ object executeScreenNecessaryComponents { scrollBehavior: TopAppBarScrollBehavior ){ MediumFlexibleTopAppBar( - title = { Text("Executing Plugin") }, + title = { Text(stringResource(R.string.execute_screen_top_app_bar_title)) }, scrollBehavior = scrollBehavior, actions = { ExecuteScreenStopButton() @@ -40,7 +41,7 @@ object executeScreenNecessaryComponents { ) { Icon( painter = painterResource(R.drawable.material_symbols_ios_share), - contentDescription = "Share" + contentDescription = stringResource(R.string.execute_screen_top_app_bar_share_content_description) ) } } @@ -52,7 +53,7 @@ object executeScreenNecessaryComponents { ) { Icon( painter = painterResource(R.drawable.material_symbols_disabled), - contentDescription = "Stop" + contentDescription = stringResource(R.string.execute_screen_top_app_bar_stop_content_description) ) } } @@ -64,7 +65,7 @@ object executeScreenNecessaryComponents { ) { Icon( painter = painterResource(R.drawable.material_symbols_arrow_back), - contentDescription = "Back" + contentDescription = stringResource(R.string.execute_screen_top_app_bar_back_content_description) ) } } diff --git a/app/src/main/java/com/baidaidai/rootless_store/components/homeScreen/HowToDevelopRootlessStorePlugin.kt b/app/src/main/java/com/baidaidai/rootless_store/components/homeScreen/HowToDevelopRootlessStorePlugin.kt index 8b545b2..974177c 100644 --- a/app/src/main/java/com/baidaidai/rootless_store/components/homeScreen/HowToDevelopRootlessStorePlugin.kt +++ b/app/src/main/java/com/baidaidai/rootless_store/components/homeScreen/HowToDevelopRootlessStorePlugin.kt @@ -23,6 +23,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.core.content.ContextCompat.startActivity import com.baidaidai.rootless_store.R @@ -61,7 +62,7 @@ fun HowToDevelopRootlessStorePlugin(){ ){ Icon( painter = painterResource(R.drawable.outline_construction_24), - contentDescription = "Develop Icon", + contentDescription = stringResource(R.string.home_screen_how_to_develop_rootless_store_plugin_icon_content_description), modifier = Modifier .clip(CircleShape) .background(color = MaterialTheme.colorScheme.secondaryFixed) @@ -75,11 +76,11 @@ fun HowToDevelopRootlessStorePlugin(){ ) Column{ Text( - text = "Learn Rootless Store", + text = stringResource(R.string.home_screen_how_to_develop_rootless_store_plugin_headline), style = MaterialTheme.typography.titleMedium ) Text( - text = "Learn how to develop RootlessStore plugins", + text = stringResource(R.string.home_screen_how_to_develop_rootless_store_plugin_supporting), style = MaterialTheme.typography.labelSmall ) } diff --git a/app/src/main/java/com/baidaidai/rootless_store/components/homeScreen/RootLessStoreVersionCheckerContainer.kt b/app/src/main/java/com/baidaidai/rootless_store/components/homeScreen/RootLessStoreVersionCheckerContainer.kt index 329b97d..0b9f849 100644 --- a/app/src/main/java/com/baidaidai/rootless_store/components/homeScreen/RootLessStoreVersionCheckerContainer.kt +++ b/app/src/main/java/com/baidaidai/rootless_store/components/homeScreen/RootLessStoreVersionCheckerContainer.kt @@ -20,6 +20,7 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.baidaidai.rootless_store.R +import com.baidaidai.rootless_store.core.i18n.icuString @Composable fun RootLessStoreVersionCheckerContainer(){ @@ -47,7 +48,7 @@ fun RootLessStoreVersionCheckerContainer(){ ){ Icon( painter = painterResource(R.drawable.terminal_24px), - contentDescription = "Terminal Icon", + contentDescription = stringResource(R.string.home_screen_version_checker_container_icon_content_description), modifier = Modifier .size(30.dp) ) @@ -57,11 +58,14 @@ fun RootLessStoreVersionCheckerContainer(){ ) Column{ Text( - text = "RootLessStore is Running", + text = stringResource(R.string.home_screen_version_checker_container_headline), style = MaterialTheme.typography.titleMedium ) Text( - text = "Version: $versionNumber", + text = icuString( + R.string.home_screen_version_checker_container_supporting, + mapOf("version" to versionNumber) + ), style = MaterialTheme.typography.titleSmall ) } diff --git a/app/src/main/java/com/baidaidai/rootless_store/components/homeScreen/RootlessStoreHosterStatusBoard.kt b/app/src/main/java/com/baidaidai/rootless_store/components/homeScreen/RootlessStoreHosterStatusBoard.kt index f1bba01..14deaea 100644 --- a/app/src/main/java/com/baidaidai/rootless_store/components/homeScreen/RootlessStoreHosterStatusBoard.kt +++ b/app/src/main/java/com/baidaidai/rootless_store/components/homeScreen/RootlessStoreHosterStatusBoard.kt @@ -24,6 +24,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.scale import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.baidaidai.rootless_store.R import com.baidaidai.rootless_store.domain.status.model.RootlessStoreHosterStatus @@ -63,7 +64,7 @@ fun RootlessStoreHosterStatusBoard( ) { Icon( painter = painterResource(R.drawable.monitor_heart_24px), - contentDescription = "Hoster Status", + contentDescription = stringResource(R.string.home_screen_hoster_status_board_icon_content_description), tint = MaterialTheme.colorScheme.onSurfaceVariant, modifier = Modifier .size(24.dp) @@ -73,7 +74,7 @@ fun RootlessStoreHosterStatusBoard( .width(10.dp) ) Text( - text = "Hoster Status", + text = stringResource(R.string.home_screen_hoster_status_board_title), style = MaterialTheme.typography.titleMedium ) } @@ -115,12 +116,12 @@ fun RootlessStoreHosterStatusBoard( horizontalArrangement = Arrangement.SpaceAround ) { HosterStatusCircularProgressRow( - label = "Memory", + label = stringResource(R.string.home_screen_hoster_status_board_memory_label), currentValue = hosterStatus.memoryStatus.usedMemory, maxValue = hosterStatus.memoryStatus.totalMemory ) HosterStatusCircularProgressRow( - label = "Storage", + label = stringResource(R.string.home_screen_hoster_status_board_storage_label), currentValue = hosterStatus.storageStatus.usedStorage, maxValue = hosterStatus.storageStatus.totalStorage ) @@ -140,30 +141,42 @@ fun RootlessStoreHosterStatusBoard( modifier = Modifier .padding(horizontal = 30.dp, vertical = 20.dp) ) { - HosterStatusRow("Version", "${hosterStatus.osAndAPIVersion?.androidVersion} (${hosterStatus.osAndAPIVersion?.apiVersion})") + HosterStatusRow( + stringResource(R.string.home_screen_hoster_status_board_version_label), + "${hosterStatus.osAndAPIVersion?.androidVersion} (${hosterStatus.osAndAPIVersion?.apiVersion})" + ) Spacer( modifier = Modifier .height(8.dp) ) - HosterStatusRow("Kernel", hosterStatus.kernelVersion ?: "null") + HosterStatusRow( + stringResource(R.string.home_screen_hoster_status_board_kernel_label), + hosterStatus.kernelVersion ?: "null" + ) Spacer( modifier = Modifier .height(8.dp) ) - HosterStatusRow("SELinux", hosterStatus.selinuxStatus.toString()) + HosterStatusRow( + stringResource(R.string.home_screen_hoster_status_board_selinux_label), + hosterStatus.selinuxStatus.toString() + ) Spacer( modifier = Modifier .height(8.dp) ) HosterStatusRow( - "Plugins", + stringResource(R.string.home_screen_hoster_status_board_plugins_label), "${hosterStatus.pluginStatus.enabledCount}/${hosterStatus.pluginStatus.totalCount}" ) Spacer( modifier = Modifier .height(8.dp) ) - HosterStatusRow("Temp", hosterStatus.tempStatus?.toString() ?: "null") + HosterStatusRow( + stringResource(R.string.home_screen_hoster_status_board_temp_label), + hosterStatus.tempStatus?.toString() ?: "null" + ) } } } diff --git a/app/src/main/java/com/baidaidai/rootless_store/components/pluginsScreen/PluginInfoContainerLocal.kt b/app/src/main/java/com/baidaidai/rootless_store/components/pluginsScreen/PluginInfoContainerLocal.kt index 9039440..7a97291 100644 --- a/app/src/main/java/com/baidaidai/rootless_store/components/pluginsScreen/PluginInfoContainerLocal.kt +++ b/app/src/main/java/com/baidaidai/rootless_store/components/pluginsScreen/PluginInfoContainerLocal.kt @@ -24,9 +24,11 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.unit.dp import com.baidaidai.rootless_store.R +import com.baidaidai.rootless_store.core.i18n.icuString import com.baidaidai.rootless_store.domain.plugin.manifest.PluginManifestRoom @Composable @@ -49,7 +51,7 @@ fun PluginInfoContainerLocal( ) { Icon( painter = painterResource(R.drawable.outline_close_24), - contentDescription = "delete button", + contentDescription = stringResource(R.string.plugin_screen_info_container_local_delete_button_content_description), modifier = Modifier .fillMaxSize() ) @@ -78,7 +80,7 @@ fun PluginInfoContainerLocal( ){ Icon( painter = painterResource(R.drawable.outline_extension_24), - contentDescription = "Plugin Icon", + contentDescription = stringResource(R.string.plugin_screen_info_container_local_icon_content_description), modifier = Modifier .size(24.dp) ) @@ -95,7 +97,10 @@ fun PluginInfoContainerLocal( style = MaterialTheme.typography.titleMedium ) Text( - text = "Version: ${pluginManifest.installedVersion}", + text = icuString( + R.string.plugin_screen_info_container_local_version, + mapOf("version" to pluginManifest.installedVersion) + ), style = MaterialTheme.typography.labelMedium ) } @@ -119,11 +124,20 @@ fun PluginInfoContainerLocal( modifier = Modifier .padding(24.dp) ) { - PluginInfoRow(label = "Author", value = pluginManifest.author) - PluginInfoRow(label = "Source", value = pluginManifest.source.toString()) - PluginInfoRow(label = "State", value = pluginManifest.state.toString()) PluginInfoRow( - label = "Required", + label = stringResource(R.string.plugin_screen_info_container_local_author_label), + value = pluginManifest.author + ) + PluginInfoRow( + label = stringResource(R.string.plugin_screen_info_container_local_source_label), + value = pluginManifest.source.toString() + ) + PluginInfoRow( + label = stringResource(R.string.plugin_screen_info_container_local_state_label), + value = pluginManifest.state.toString() + ) + PluginInfoRow( + label = stringResource(R.string.plugin_screen_info_container_local_required_label), value = pluginManifest.requiredEnvironment.toString() ) } diff --git a/app/src/main/java/com/baidaidai/rootless_store/components/pluginsScreen/PluginScreenNecessaryComponents.kt b/app/src/main/java/com/baidaidai/rootless_store/components/pluginsScreen/PluginScreenNecessaryComponents.kt index 53cc3f2..2207f25 100644 --- a/app/src/main/java/com/baidaidai/rootless_store/components/pluginsScreen/PluginScreenNecessaryComponents.kt +++ b/app/src/main/java/com/baidaidai/rootless_store/components/pluginsScreen/PluginScreenNecessaryComponents.kt @@ -11,7 +11,9 @@ import androidx.compose.material3.TextButton import androidx.compose.material3.TopAppBarScrollBehavior import androidx.compose.runtime.Composable import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import com.baidaidai.rootless_store.R +import com.baidaidai.rootless_store.core.i18n.icuString object PluginScreenNecessaryComponents { @OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class) @@ -24,16 +26,21 @@ object PluginScreenNecessaryComponents { ){ LargeFlexibleTopAppBar( title = { - Text("Plugin") + Text(stringResource(R.string.plugin_screen_top_app_bar_title)) }, subtitle = { - Text(text = "Instead $pluginInfoCount plugin") + Text( + text = icuString( + R.string.plugin_screen_top_app_bar_subtitle, + mapOf("pluginCount" to pluginInfoCount) + ) + ) }, navigationIcon = { TextButton( onClick = textButtonOnClick ) { - Text("Edit") + Text(stringResource(R.string.plugin_screen_top_app_bar_edit_button)) } }, actions = { @@ -42,7 +49,7 @@ object PluginScreenNecessaryComponents { ) { Icon( painter = painterResource(R.drawable.material_symbols_filter_list), - contentDescription = "Filter" + contentDescription = stringResource(R.string.plugin_screen_top_app_bar_filter_content_description) ) } }, @@ -59,7 +66,7 @@ object PluginScreenNecessaryComponents { ) { Icon( painter = painterResource(R.drawable.outline_box_add_24), - contentDescription = "Install" + contentDescription = stringResource(R.string.plugin_screen_floating_button_install_content_description) ) } } diff --git a/app/src/main/java/com/baidaidai/rootless_store/components/shizukuAdbScreen/ShizukuAdbScreenNecessaryComponents.kt b/app/src/main/java/com/baidaidai/rootless_store/components/shizukuAdbScreen/ShizukuAdbScreenNecessaryComponents.kt index b04ef58..6c04af6 100644 --- a/app/src/main/java/com/baidaidai/rootless_store/components/shizukuAdbScreen/ShizukuAdbScreenNecessaryComponents.kt +++ b/app/src/main/java/com/baidaidai/rootless_store/components/shizukuAdbScreen/ShizukuAdbScreenNecessaryComponents.kt @@ -30,9 +30,11 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import com.baidaidai.rootless_store.R +import com.baidaidai.rootless_store.core.i18n.icuString object ShizukuAdbScreenNecessaryComponents { @@ -73,7 +75,7 @@ object ShizukuAdbScreenNecessaryComponents { Spacer(Modifier.height(16.dp)) Text( - text = "All done", + text = stringResource(R.string.shizuku_adb_screen_bottom_sheet_title), style = MaterialTheme.typography.headlineSmall, color = MaterialTheme.colorScheme.onSurface, textAlign = TextAlign.Center @@ -82,7 +84,7 @@ object ShizukuAdbScreenNecessaryComponents { Spacer(Modifier.height(8.dp)) Text( - text = "Returning to Home in $remainderTime s", + text = icuString(R.string.shizuku_adb_screen_bottom_sheet_countdown_context,mapOf("second" to remainderTime)), style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onSurfaceVariant, textAlign = TextAlign.Center @@ -98,13 +100,13 @@ object ShizukuAdbScreenNecessaryComponents { onClick = onCloseButtonClick, modifier = Modifier.weight(1f) ) { - Text("Close") + Text(stringResource(R.string.shizuku_adb_screen_bottom_sheet_close_button)) } Button( onClick = onReturnButtonClick, modifier = Modifier.weight(1f) ) { - Text("Return now") + Text(stringResource(R.string.shizuku_adb_screen_bottom_sheet_return_button)) } } } @@ -163,7 +165,7 @@ object ShizukuAdbScreenNecessaryComponents { }else{ painterResource(R.drawable.material_symbols_play_arrow) }, - contentDescription = "Start", + contentDescription = stringResource(R.string.shizuku_adb_screen_action_card_start_content_description), modifier = Modifier.size(24.dp) ) } @@ -201,17 +203,17 @@ object ShizukuAdbScreenNecessaryComponents { verticalAlignment = Alignment.CenterVertically, ){ Text( - text = "Shizuku Access", + text = stringResource(R.string.shizuku_adb_screen_overview_card_title), style = MaterialTheme.typography.titleLargeEmphasized ) Icon( painterResource(R.drawable.material_shizuku_icon), - contentDescription = "Shizuku Icon", + contentDescription = stringResource(R.string.shizuku_adb_screen_overview_card_icon_content_description), tint = MaterialTheme.colorScheme.primary, ) } Text( - text = "Rootless Store uses Shizuku’s ADB shell for some features so please request ADB authorization.\nFirst then connect to Shizuku.", + text = stringResource(R.string.shizuku_adb_screen_overview_card_description), style = MaterialTheme.typography.bodyMedium ) } diff --git a/app/src/main/java/com/baidaidai/rootless_store/components/sourcesScreen/SourceScreenLeadingDeleteButton.kt b/app/src/main/java/com/baidaidai/rootless_store/components/sourcesScreen/SourceScreenLeadingDeleteButton.kt index b6fef52..5d3258b 100644 --- a/app/src/main/java/com/baidaidai/rootless_store/components/sourcesScreen/SourceScreenLeadingDeleteButton.kt +++ b/app/src/main/java/com/baidaidai/rootless_store/components/sourcesScreen/SourceScreenLeadingDeleteButton.kt @@ -12,6 +12,7 @@ import androidx.compose.material3.contentColorFor import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.baidaidai.rootless_store.R import com.baidaidai.rootless_store.domain.source.model.PluginSourceLocal @@ -36,7 +37,7 @@ fun SourceScreenLeadingDeleteButton( ) { Icon( painter = painterResource(R.drawable.outline_close_small_24), - contentDescription = "Delete", + contentDescription = stringResource(R.string.sources_screen_list_item_delete_content_description), ) } Spacer(modifier = Modifier.width(12.dp)) diff --git a/app/src/main/java/com/baidaidai/rootless_store/components/sourcesScreen/SourceScreenListItem.kt b/app/src/main/java/com/baidaidai/rootless_store/components/sourcesScreen/SourceScreenListItem.kt index a3c030d..530d7f0 100644 --- a/app/src/main/java/com/baidaidai/rootless_store/components/sourcesScreen/SourceScreenListItem.kt +++ b/app/src/main/java/com/baidaidai/rootless_store/components/sourcesScreen/SourceScreenListItem.kt @@ -14,6 +14,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.baidaidai.rootless_store.R import com.baidaidai.rootless_store.domain.source.model.PluginSourceLocal @@ -38,7 +39,7 @@ fun SourceScreenListItem( trailingContent = { Icon( painter = painterResource(R.drawable.outline_arrow_forward_ios_24), - contentDescription = "go to" + contentDescription = stringResource(R.string.sources_screen_list_item_go_to_content_description) ) }, colors = SourceListItemColor(), @@ -53,7 +54,7 @@ fun SourceScreenListItem( // Should Change Intro Compatible Source Image( painter = painterResource(R.drawable.ic_launcher_background), - contentDescription = "2", + contentDescription = stringResource(R.string.sources_screen_list_item_icon_content_description), modifier = Modifier .size(40.dp) .clip(CircleShape) diff --git a/app/src/main/java/com/baidaidai/rootless_store/components/sourcesScreen/SourcesScreenNecessaryComponents.kt b/app/src/main/java/com/baidaidai/rootless_store/components/sourcesScreen/SourcesScreenNecessaryComponents.kt index 02066de..a856d2c 100644 --- a/app/src/main/java/com/baidaidai/rootless_store/components/sourcesScreen/SourcesScreenNecessaryComponents.kt +++ b/app/src/main/java/com/baidaidai/rootless_store/components/sourcesScreen/SourcesScreenNecessaryComponents.kt @@ -9,7 +9,9 @@ import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import com.baidaidai.rootless_store.R +import com.baidaidai.rootless_store.core.i18n.icuString object SourcesScreenNecessaryComponents { @OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class) @@ -21,16 +23,21 @@ object SourcesScreenNecessaryComponents { ){ LargeFlexibleTopAppBar( title = { - Text("Sources") + Text(stringResource(R.string.sources_screen_top_app_bar_title)) }, subtitle = { - Text(text = "Append $sourceCount Source") + Text( + text = icuString( + R.string.sources_screen_top_app_bar_subtitle, + mapOf("sourceCount" to sourceCount) + ) + ) }, navigationIcon = { TextButton( onClick = textButtonOnClick ) { - Text("Edit") + Text(stringResource(R.string.sources_screen_top_app_bar_edit_button)) } }, actions = { @@ -39,7 +46,7 @@ object SourcesScreenNecessaryComponents { ) { Icon( painter = painterResource(R.drawable.material_symbols_24px), - contentDescription = "Add" + contentDescription = stringResource(R.string.sources_screen_top_app_bar_add_content_description) ) } } diff --git a/app/src/main/java/com/baidaidai/rootless_store/components/startScreen/StartScreenNecessaryComponents.kt b/app/src/main/java/com/baidaidai/rootless_store/components/startScreen/StartScreenNecessaryComponents.kt index ff1391e..6e99c2a 100644 --- a/app/src/main/java/com/baidaidai/rootless_store/components/startScreen/StartScreenNecessaryComponents.kt +++ b/app/src/main/java/com/baidaidai/rootless_store/components/startScreen/StartScreenNecessaryComponents.kt @@ -11,6 +11,7 @@ import androidx.compose.material3.TopAppBarScrollBehavior import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import androidx.navigation.NavController import androidx.navigation.compose.currentBackStackEntryAsState import com.baidaidai.rootless_store.R @@ -38,7 +39,7 @@ object StartScreenNecessaryComponents { NavBarItemSpec( number = 0, pattern = painterResource(R.drawable.outline_home_24), - contentDeprecated = "Home", + contentDeprecated = stringResource(R.string.start_screen_navigation_bar_home_label), compatibleDestinationList = listOf( "HomeScreen", "ShellScreen" @@ -47,7 +48,7 @@ object StartScreenNecessaryComponents { NavBarItemSpec( number = 1, pattern = painterResource(R.drawable.outline_extension_24), - contentDeprecated = "Plugin", + contentDeprecated = stringResource(R.string.start_screen_navigation_bar_plugin_label), compatibleDestinationList = listOf( "PluginScreen", "ExecuteScreen" @@ -56,7 +57,7 @@ object StartScreenNecessaryComponents { NavBarItemSpec( number = 2, pattern = painterResource(R.drawable.outline_list_alt_24), - contentDeprecated = "Sources", + contentDeprecated = stringResource(R.string.start_screen_navigation_bar_sources_label), compatibleDestinationList = listOf( "SourcesScreen", "MarketScreen" diff --git a/app/src/main/java/com/baidaidai/rootless_store/components/startScreen/StartScreenRepositoryDialog.kt b/app/src/main/java/com/baidaidai/rootless_store/components/startScreen/StartScreenRepositoryDialog.kt index 7441bce..79af7be 100644 --- a/app/src/main/java/com/baidaidai/rootless_store/components/startScreen/StartScreenRepositoryDialog.kt +++ b/app/src/main/java/com/baidaidai/rootless_store/components/startScreen/StartScreenRepositoryDialog.kt @@ -18,6 +18,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.baidaidai.rootless_store.R @@ -35,14 +36,14 @@ fun StartScreenRepositoryDialog( Button( onClick = onConfirmButtonClick ) { - Text("Add") + Text(stringResource(R.string.sources_screen_repository_dialog_confirm_button)) } }, dismissButton = { TextButton( onClick = onDismissButtonClick ) { - Text("Cancel") + Text(stringResource(R.string.sources_screen_repository_dialog_dismiss_button)) } }, title = { @@ -58,12 +59,12 @@ fun StartScreenRepositoryDialog( ) Spacer(modifier = Modifier.width(8.dp)) Text( - text = "Add Source", + text = stringResource(R.string.sources_screen_repository_dialog_title), style = MaterialTheme.typography.titleLarge ) } Text( - text = "Add a repository to update and discover plugins.", + text = stringResource(R.string.sources_screen_repository_dialog_description), style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant ) @@ -77,8 +78,8 @@ fun StartScreenRepositoryDialog( OutlinedTextField( value = sourceDomainContent, onValueChange = { newValue -> onTextFieldValueChange(newValue)}, - label = { Text("Source URL") }, - placeholder = { Text("https://endpoint/api/v1") }, + label = { Text(stringResource(R.string.sources_screen_repository_dialog_input_label)) }, + placeholder = { Text(stringResource(R.string.sources_screen_repository_dialog_input_placeholder)) }, singleLine = true, modifier = Modifier.fillMaxWidth() ) diff --git a/app/src/main/java/com/baidaidai/rootless_store/core/i18n/IcuString.kt b/app/src/main/java/com/baidaidai/rootless_store/core/i18n/IcuString.kt new file mode 100644 index 0000000..e4b3097 --- /dev/null +++ b/app/src/main/java/com/baidaidai/rootless_store/core/i18n/IcuString.kt @@ -0,0 +1,32 @@ +package com.baidaidai.rootless_store.core.i18n + +import android.icu.text.MessageFormat +import androidx.annotation.StringRes +import androidx.compose.runtime.Composable +import androidx.compose.ui.platform.LocalConfiguration +import androidx.compose.ui.res.stringResource +import java.util.Locale + +fun formatIcu( + pattern: String, + locale: Locale, + args: Map = emptyMap() +): String { + return MessageFormat(pattern, locale).format(args) +} + +@Composable +fun icuString( + @StringRes id: Int, + args: Map = emptyMap() +): String { + val pattern = stringResource(id) + val locales = LocalConfiguration.current.locales + val locale = if (locales.size() > 0) locales[0] else Locale.getDefault() + + return formatIcu( + pattern = pattern, + locale = locale, + args = args + ) +} diff --git a/app/src/main/java/com/baidaidai/rootless_store/ui/screens/ShellScreen.kt b/app/src/main/java/com/baidaidai/rootless_store/ui/screens/ShellScreen.kt index 7f8266c..6c02adb 100644 --- a/app/src/main/java/com/baidaidai/rootless_store/ui/screens/ShellScreen.kt +++ b/app/src/main/java/com/baidaidai/rootless_store/ui/screens/ShellScreen.kt @@ -53,6 +53,7 @@ import com.baidaidai.rootless_store.domain.shell.model.ShellCommandContainer import com.baidaidai.rootless_store.domain.shell.model.ShellEnvironment import com.baidaidai.rootless_store.ui.model.RootLessStoreShellScreenViewModel import androidx.compose.ui.graphics.* +import androidx.compose.ui.res.stringResource import com.topjohnwu.superuser.Shell @OptIn(ExperimentalMaterial3ExpressiveApi::class) @@ -141,7 +142,7 @@ fun ShellScreen( }, maxLines = 1, label = { - Text("Shell Command") + Text(stringResource(R.string.shell_screen_command_input_label)) }, modifier = Modifier .fillMaxWidth() diff --git a/app/src/main/java/com/baidaidai/rootless_store/ui/screens/ShizukuAdbScreen.kt b/app/src/main/java/com/baidaidai/rootless_store/ui/screens/ShizukuAdbScreen.kt index 9818a89..926074a 100644 --- a/app/src/main/java/com/baidaidai/rootless_store/ui/screens/ShizukuAdbScreen.kt +++ b/app/src/main/java/com/baidaidai/rootless_store/ui/screens/ShizukuAdbScreen.kt @@ -22,7 +22,9 @@ 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 com.baidaidai.rootless_store.R import com.baidaidai.rootless_store.components.shizukuAdbScreen.ShizukuAdbScreenNecessaryComponents.ShizukuAdbScreenActionCard import com.baidaidai.rootless_store.components.shizukuAdbScreen.ShizukuAdbScreenNecessaryComponents.ShizukuAdbScreenModelSheet import com.baidaidai.rootless_store.components.shizukuAdbScreen.ShizukuAdbScreenNecessaryComponents.ShizukuAdbScreenOverviewCard @@ -100,9 +102,9 @@ fun ShizukuAdbScreen( } item { ShizukuAdbScreenActionCard( - step = "Step 1", - title = "Request Shizuku Auth", - description = "Grant ADB authorization so Rootless Store can start the shell workflow and unlock the next step", + step = stringResource(R.string.shizuku_adb_screen_action_card_step_1_label), + title = stringResource(R.string.shizuku_adb_screen_action_card_step_1_title), + description = stringResource(R.string.shizuku_adb_screen_action_card_step_1_description), targetStatus = shizukuActived, onClick = { shizukuAdbScreenViewModel.activeShizuku() @@ -111,9 +113,9 @@ fun ShizukuAdbScreen( } item { ShizukuAdbScreenActionCard( - step = "Step 2", - title = "Connect to Shizuku", - description = "After authorization is ready open Shizuku and enter the ADB shell session to finish setup and continue", + step = stringResource(R.string.shizuku_adb_screen_action_card_step_2_label), + title = stringResource(R.string.shizuku_adb_screen_action_card_step_2_title), + description = stringResource(R.string.shizuku_adb_screen_action_card_step_2_description), targetStatus = endpointActived, onClick = { shizukuAdbScreenViewModel.activeShizukuEndpoint() diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml new file mode 100644 index 0000000..2442d36 --- /dev/null +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -0,0 +1,93 @@ + + + 终端图标 + Rootless Store 正运行 + 版本 {version} + + 宿主状态 + 宿主状态 + 总体状态:%1$s + 内存 + 存储 + 版本 + 内核 + SELinux + 插件 + 温度 + + 开发图标 + 了解 Rootless Store + 了解如何开发 Rootless Store 插件 + + + Shizuku 授权 + Shizuku 图标 + Rootless Store 的部分功能依赖 Shizuku 提供的 ADB 能力,请先授予 Shizuku 授权,然后再连接到 UserService + + + 开始 + 步骤 1 + 请求 Shizuku 授权 + 授予 ADB 授权,让 Rootless Store 可以启动 Shell 流程并解锁下一步。 + 步骤 2 + 连接到 Shizuku UserService + 请连接到 Shizuku UserService 以完成最后准备 + + + 已完成 + + 返回首页倒计时 {second} 秒 + 关闭 + 立即返回 + + + Shell 命令 + + + 插件页 + 已安装了 {pluginCount} 个插件 + 编辑 + 筛选 + + + 安装 + + + 删除按钮 + 插件图标 + 版本:{version} + 作者 + 来源 + 状态 + 最低权限 + + + 插件源 + 已添加了 {sourceCount} 个插件源 + 编辑 + 添加 + + + 前往 + 删除 + 源图标 + + + 添加 + 取消 + 添加插件源 + 添加一个仓库源,用于更新和发现更多插件 + 插件源 URL + https://endpoint/api/v1 + + + 正执行插件 + 分享 + 停止 + 返回 + + + 主页 + 插件页 + 插件源 + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4e73e51..d8a8585 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,4 +1,96 @@ Rootless Store - v0.0.75 - \ No newline at end of file + v0.0.8 + + + Terminal Icon + Rootless Store is Running + Version {version} + + Hoster Status + Hoster Status + Overall: %1$s + Memory + Storage + Version + Kernel + SELinux + Plugins + Temp + + Develop Icon + Learn Rootless Store + Learn how to develop Rootless Store plugins + + + Shizuku Authorization + Shizuku Icon + Some Rootless Store features rely on Shizuku’s ADB capabilities. Please grant Shizuku authorization first, then connect to the UserService. + + + Start + Step 1 + Request Shizuku Auth + Grant ADB authorization so Rootless Store can start the shell workflow and unlock the next step + Step 2 + Connect to Shizuku UserService + Connect to the Shizuku UserService to complete the final setup + + + All done + + Returning to Home in {second} s + Close + Return now + + + Shell Command + + + Plugin + Installed {pluginCount} plugins + Edit + Filter + + + Install + + + Delete button + Plugin Icon + Version: {version} + Author + Source + State + Required + + + Sources + Added {sourceCount} sources + Edit + Add + + + Go to + Delete + Source Icon + + + Add + Cancel + Add Source + Add a repository to update and discover plugins. + Source URL + https://endpoint/api/v1 + + + Executing Plugin + Share + Stop + Back + + + Home + Plugin + Sources + diff --git a/asset/markdown/readme/README_zh-CN.md b/asset/markdown/readme/README_zh-CN.md index 0a8120b..5f80de5 100644 --- a/asset/markdown/readme/README_zh-CN.md +++ b/asset/markdown/readme/README_zh-CN.md @@ -6,12 +6,12 @@ ## 项目预览

- - - - - - + + + + + +

## 项目简介 diff --git a/asset/markdown/release/v0.0.8.md b/asset/markdown/release/v0.0.8.md new file mode 100644 index 0000000..9ed48a0 --- /dev/null +++ b/asset/markdown/release/v0.0.8.md @@ -0,0 +1,77 @@ +# 多语言支持初步落地版 + +Welcome to Rootless Store v0.0.8! + +This update focuses on bringing initial internationalization support into Rootless Store. In v0.0.8, the app introduces localized string resources, adds ICU-based dynamic text formatting, and starts aligning key screens and documentation previews with a more language-aware experience. + +欢迎来到 Rootless Store v0.0.8! + +这个版本的重点,是让 Rootless Store 的多语言能力正式开始落地。v0.0.8 引入了本地化字符串资源、基于 ICU 的动态文本格式化能力,并开始把核心页面和文档预览同步到更完整的语言适配体验上。 + +--- + +### What's New in v0.0.8 + +* **Initial App Internationalization Support**: + * **Localized UI Strings**: Added localized string resources so core app text can now be presented in supported languages more consistently. + * **Language-aware Screen Text**: Replaced hard-coded UI text across multiple screens and components with resource-based strings. +* **Dynamic ICU Text Formatting**: + * **Formatted Runtime Text**: Added ICU-based string formatting to handle dynamic text such as versions, counts, and countdown-style content in a localization-friendly way. +* **Localized Core Experience**: + * **Broader Screen Coverage**: Localization support now covers important parts of the Home, Plugin, Source, Execute, Shell, Shizuku, and navigation flows. + * **Content Description Localization**: Accessibility-facing content descriptions were also brought into the string resource system for better consistency. +* **Localized Documentation & Preview Assets**: + * **Simplified Chinese Preview Images**: Added localized preview screenshots for Chinese documentation. + * **README_zh-CN Preview Alignment**: Updated the Chinese README preview section to use the new localized image assets. + +### v0.0.8 更新内容 + +* **应用多语言支持初步接入**: + * **本地化 UI 文本**: 新增了本地化字符串资源,让核心界面的文本内容可以更一致地适配已支持的语言。 + * **页面文案资源化**: 将多个页面与组件中的硬编码文案逐步替换为资源字符串,为后续多语言扩展打下基础。 +* **ICU 动态文本格式化能力**: + * **运行时文本格式化**: 新增了基于 ICU 的字符串格式化能力,用于处理版本号、数量统计、倒计时等需要动态插值的内容,让这些文案更适合做本地化。 +* **核心使用体验本地化**: + * **更多页面接入多语言**: Home、Plugin、Source、Execute、Shell、Shizuku 以及底部导航等关键流程,已经开始接入本地化支持。 + * **可访问性文案同步本地化**: 一些面向可访问性的 content description 也被纳入字符串资源体系,整体一致性更好。 +* **文档与预览资源同步本地化**: + * **简体中文预览图**: 新增了用于中文文档的本地化页面预览图。 + * **README_zh-CN 预览更新**: 中文 README 的项目预览区已切换到对应的中文预览资源。 + +--- + +### Key Features + +* **Resource-based UI Language Support**: Rootless Store is moving away from hard-coded interface text and toward a more maintainable localization-ready architecture. +* **Dynamic Text That Translates Better**: ICU-based formatting makes dynamic content such as version labels, counts, and status text easier to localize correctly. +* **Wider Language Coverage Across Core Screens**: The app’s main flows are starting to feel more coherent across supported languages. +* **Documentation That Matches the App Experience**: Localized screenshots and README previews help the project presentation stay aligned with the in-app language direction. + +### 主要功能 + +* **基于资源的界面语言支持**: Rootless Store 正在逐步摆脱硬编码界面文案,转向更适合维护和扩展的本地化架构。 +* **更适合翻译的动态文本能力**: 基于 ICU 的格式化方式,让版本号、数量、状态等动态内容更容易被正确本地化。 +* **核心页面更广泛的语言覆盖**: 应用的主要流程正在不同支持语言下变得更统一、更连贯。 +* **与应用体验一致的文档展示**: 本地化截图和 README 预览让项目文档与应用本身的语言方向保持一致。 + +--- + +### Known Issues & Future Plans + +* This is an initial i18n release, so some screens, strings, and terminology may still need further normalization. +* Language coverage is still in an early stage, and more components may be migrated to resource-based text in future versions. +* Future updates may continue expanding supported locales, refining translated wording, and improving app-wide language consistency. + +### 已知问题与未来计划 + +* 这是一个初步的 i18n 版本,因此部分页面、文案和术语仍可能需要继续统一和打磨。 +* 目前的语言覆盖还处于早期阶段,后续版本仍会继续把更多组件迁移到资源化文案体系中。 +* 未来更新预计会继续扩展支持语言、优化翻译措辞,并进一步提升全应用范围内的语言一致性。 + +--- + +### Thanks + +Thank you for continuing to follow Rootless Store as it grows. This step toward localization is not only about translation, but also about making the project more approachable to a wider range of users and contributors. + +感谢你持续关注 Rootless Store 的演进。多语言这一步,不只是“翻译文案”,也是让项目对更多用户和贡献者更容易接近的重要一步。 diff --git a/asset/picture/zh-rCN/AdbShizukuScreen.png b/asset/picture/zh-rCN/AdbShizukuScreen.png new file mode 100644 index 0000000..e85ebd8 Binary files /dev/null and b/asset/picture/zh-rCN/AdbShizukuScreen.png differ diff --git a/asset/picture/zh-rCN/ExecuteScreen.png b/asset/picture/zh-rCN/ExecuteScreen.png new file mode 100644 index 0000000..860841a Binary files /dev/null and b/asset/picture/zh-rCN/ExecuteScreen.png differ diff --git a/asset/picture/zh-rCN/HomeScreen.png b/asset/picture/zh-rCN/HomeScreen.png new file mode 100644 index 0000000..6c7d7d2 Binary files /dev/null and b/asset/picture/zh-rCN/HomeScreen.png differ diff --git a/asset/picture/zh-rCN/PluginScreen.png b/asset/picture/zh-rCN/PluginScreen.png new file mode 100644 index 0000000..ed70d42 Binary files /dev/null and b/asset/picture/zh-rCN/PluginScreen.png differ diff --git a/asset/picture/zh-rCN/ShellScreen.png b/asset/picture/zh-rCN/ShellScreen.png new file mode 100644 index 0000000..55e74a4 Binary files /dev/null and b/asset/picture/zh-rCN/ShellScreen.png differ diff --git a/asset/picture/zh-rCN/SourceScreen.png b/asset/picture/zh-rCN/SourceScreen.png new file mode 100644 index 0000000..aba46a6 Binary files /dev/null and b/asset/picture/zh-rCN/SourceScreen.png differ