Skip to content

Commit 34cec35

Browse files
committed
feat: added multi-language support
added jp, fr, ru; kudos to chatgpt for translation
1 parent 0e77e59 commit 34cec35

10 files changed

Lines changed: 795 additions & 126 deletions

File tree

app/build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ android {
1616
applicationId = "tridefender.llama.snapdragon"
1717
minSdk = 24
1818
targetSdk = 34
19-
versionCode = 5
20-
versionName = "1.1.c21b45"
19+
versionCode = 6
20+
versionName = "1.2"
2121

2222
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
2323
vectorDrawables {

app/src/main/java/tridefender/llama/snapdragon/ui/MainScreen.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ import androidx.compose.material.icons.filled.PlayArrow
88
import androidx.compose.material3.*
99
import androidx.compose.runtime.*
1010
import androidx.compose.ui.Modifier
11+
import androidx.compose.ui.res.stringResource
1112
import androidx.navigation.NavHostController
1213
import androidx.navigation.compose.NavHost
1314
import androidx.navigation.compose.composable
1415
import androidx.navigation.compose.currentBackStackEntryAsState
1516
import androidx.navigation.compose.rememberNavController
17+
import tridefender.llama.snapdragon.R
1618
import tridefender.llama.snapdragon.ui.kernel.KernelScreen
1719
import tridefender.llama.snapdragon.ui.launcher.AllConfigScreen
1820
import tridefender.llama.snapdragon.ui.runtime.RuntimeScreen
@@ -32,7 +34,7 @@ fun MainScreen(
3234
NavigationBar {
3335
NavigationBarItem(
3436
icon = { Icon(Icons.Default.Settings, contentDescription = null) },
35-
label = { Text("Config") },
37+
label = { Text(stringResource(R.string.nav_config)) },
3638
selected = currentRoute == "config",
3739
onClick = {
3840
if (currentRoute != "config") {
@@ -44,7 +46,7 @@ fun MainScreen(
4446
)
4547
NavigationBarItem(
4648
icon = { Icon(Icons.Default.Memory, contentDescription = null) },
47-
label = { Text("Kernels") },
49+
label = { Text(stringResource(R.string.nav_kernels)) },
4850
selected = currentRoute == "kernels",
4951
onClick = {
5052
if (currentRoute != "kernels") {
@@ -56,7 +58,7 @@ fun MainScreen(
5658
)
5759
NavigationBarItem(
5860
icon = { Icon(Icons.Default.PlayArrow, contentDescription = null) },
59-
label = { Text("Runtime") },
61+
label = { Text(stringResource(R.string.nav_runtime)) },
6062
selected = currentRoute == "runtime",
6163
onClick = {
6264
if (currentRoute != "runtime") {

app/src/main/java/tridefender/llama/snapdragon/ui/kernel/KernelScreen.kt

Lines changed: 45 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,12 @@ import androidx.compose.material3.*
2323
import androidx.compose.runtime.*
2424
import androidx.compose.ui.Alignment
2525
import androidx.compose.ui.Modifier
26+
import androidx.compose.ui.res.stringResource
2627
import androidx.compose.ui.text.font.FontWeight
2728
import androidx.compose.ui.text.style.TextOverflow
2829
import androidx.compose.ui.unit.dp
2930
import androidx.hilt.navigation.compose.hiltViewModel
31+
import tridefender.llama.snapdragon.R
3032
import tridefender.llama.snapdragon.model.DownloadState
3133
import tridefender.llama.snapdragon.model.GitHubRelease
3234
import tridefender.llama.snapdragon.model.KernelSource
@@ -115,7 +117,7 @@ fun KernelScreen(
115117
) {
116118
Icon(Icons.Default.CloudDownload, contentDescription = null, modifier = Modifier.size(18.dp))
117119
Spacer(modifier = Modifier.width(6.dp))
118-
Text("Download")
120+
Text(stringResource(R.string.download))
119121
}
120122

121123
OutlinedButton(
@@ -133,7 +135,7 @@ fun KernelScreen(
133135
) {
134136
Icon(Icons.Default.Folder, contentDescription = null, modifier = Modifier.size(18.dp))
135137
Spacer(modifier = Modifier.width(6.dp))
136-
Text("Import")
138+
Text(stringResource(R.string.import_label))
137139
}
138140
}
139141

@@ -144,7 +146,7 @@ fun KernelScreen(
144146

145147
// Installed versions header
146148
Text(
147-
text = "Installed Kernels",
149+
text = stringResource(R.string.installed_kernels),
148150
style = MaterialTheme.typography.titleMedium,
149151
fontWeight = FontWeight.SemiBold,
150152
modifier = Modifier.padding(top = 4.dp)
@@ -153,7 +155,7 @@ fun KernelScreen(
153155
// Version list
154156
if (kernelConfig.versions.isEmpty()) {
155157
Text(
156-
"No kernel versions installed",
158+
stringResource(R.string.no_kernel_versions_installed),
157159
style = MaterialTheme.typography.bodyMedium,
158160
color = MaterialTheme.colorScheme.onSurfaceVariant
159161
)
@@ -205,19 +207,19 @@ fun KernelScreen(
205207
showDeleteConfirm?.let { name ->
206208
AlertDialog(
207209
onDismissRequest = { showDeleteConfirm = null },
208-
title = { Text("Delete Kernel") },
209-
text = { Text("Delete '$name'? This cannot be undone.") },
210+
title = { Text(stringResource(R.string.delete_kernel)) },
211+
text = { Text(stringResource(R.string.delete_kernel_message, name)) },
210212
confirmButton = {
211213
TextButton(onClick = {
212214
viewModel.deleteVersion(name)
213215
showDeleteConfirm = null
214216
}) {
215-
Text("Delete", color = MaterialTheme.colorScheme.error)
217+
Text(stringResource(R.string.delete), color = MaterialTheme.colorScheme.error)
216218
}
217219
},
218220
dismissButton = {
219221
TextButton(onClick = { showDeleteConfirm = null }) {
220-
Text("Cancel")
222+
Text(stringResource(R.string.cancel))
221223
}
222224
}
223225
)
@@ -240,9 +242,9 @@ private fun ActiveVersionHeader(
240242
val active = versions.find { it.name == activeVersion }
241243
val sourceLabel = active?.let {
242244
when (it.source) {
243-
KernelSource.BUNDLED -> "Bundled"
244-
KernelSource.GITHUB_RELEASE -> "GitHub Release"
245-
KernelSource.LOCAL_IMPORT -> "Local Import"
245+
KernelSource.BUNDLED -> stringResource(R.string.bundled)
246+
KernelSource.GITHUB_RELEASE -> stringResource(R.string.github_release)
247+
KernelSource.LOCAL_IMPORT -> stringResource(R.string.local_import)
246248
}
247249
} ?: "None"
248250

@@ -255,7 +257,7 @@ private fun ActiveVersionHeader(
255257
) {
256258
Column(modifier = Modifier.padding(16.dp)) {
257259
Text(
258-
text = "Active Kernel",
260+
text = stringResource(R.string.active_kernel),
259261
style = MaterialTheme.typography.labelMedium,
260262
color = MaterialTheme.colorScheme.onPrimaryContainer.copy(alpha = 0.7f)
261263
)
@@ -300,9 +302,9 @@ private fun DownloadProgressCard(
300302
) {
301303
Column(modifier = Modifier.padding(16.dp)) {
302304
val label = when (downloadState) {
303-
DownloadState.DOWNLOADING -> "Downloading kernel..."
304-
DownloadState.EXTRACTING -> "Extracting archive..."
305-
DownloadState.VALIDATING -> "Validating files..."
305+
DownloadState.DOWNLOADING -> stringResource(R.string.downloading_kernel)
306+
DownloadState.EXTRACTING -> stringResource(R.string.extracting_archive)
307+
DownloadState.VALIDATING -> stringResource(R.string.validating_files)
306308
else -> ""
307309
}
308310
Text(
@@ -369,7 +371,7 @@ private fun KernelVersionRow(
369371
Spacer(modifier = Modifier.width(8.dp))
370372
SuggestionChip(
371373
onClick = {},
372-
label = { Text("Active", style = MaterialTheme.typography.labelSmall) },
374+
label = { Text(stringResource(R.string.active), style = MaterialTheme.typography.labelSmall) },
373375
icon = {
374376
Icon(
375377
Icons.Outlined.CheckCircle,
@@ -386,9 +388,9 @@ private fun KernelVersionRow(
386388

387389
Row(verticalAlignment = Alignment.CenterVertically) {
388390
val sourceLabel = when (version.source) {
389-
KernelSource.BUNDLED -> "Bundled"
390-
KernelSource.GITHUB_RELEASE -> "GitHub"
391-
KernelSource.LOCAL_IMPORT -> "Local"
391+
KernelSource.BUNDLED -> stringResource(R.string.bundled)
392+
KernelSource.GITHUB_RELEASE -> stringResource(R.string.github)
393+
KernelSource.LOCAL_IMPORT -> stringResource(R.string.local)
392394
}
393395
AssistChip(
394396
onClick = {},
@@ -400,13 +402,13 @@ private fun KernelVersionRow(
400402
Spacer(modifier = Modifier.width(8.dp))
401403
Icon(
402404
Icons.Default.Warning,
403-
contentDescription = "Missing libraries",
405+
contentDescription = stringResource(R.string.missing_libraries),
404406
tint = MaterialTheme.colorScheme.error,
405407
modifier = Modifier.size(14.dp)
406408
)
407409
Spacer(modifier = Modifier.width(2.dp))
408410
Text(
409-
text = "${version.missingLibraries.size} missing",
411+
text = stringResource(R.string.missing_count, version.missingLibraries.size),
410412
style = MaterialTheme.typography.labelSmall,
411413
color = MaterialTheme.colorScheme.error
412414
)
@@ -432,7 +434,7 @@ private fun KernelVersionRow(
432434
) {
433435
Icon(
434436
Icons.Outlined.SwapHoriz,
435-
contentDescription = "Activate",
437+
contentDescription = stringResource(R.string.activate),
436438
tint = if (serverRunning) MaterialTheme.colorScheme.onSurface.copy(alpha = 0.38f)
437439
else MaterialTheme.colorScheme.primary
438440
)
@@ -443,7 +445,7 @@ private fun KernelVersionRow(
443445
IconButton(onClick = { onDelete(version.name) }) {
444446
Icon(
445447
Icons.Default.Delete,
446-
contentDescription = "Delete",
448+
contentDescription = stringResource(R.string.delete),
447449
tint = MaterialTheme.colorScheme.error.copy(alpha = 0.7f)
448450
)
449451
}
@@ -462,15 +464,15 @@ private fun ImportNameDialog(
462464

463465
AlertDialog(
464466
onDismissRequest = onDismiss,
465-
title = { Text("Import Kernel") },
467+
title = { Text(stringResource(R.string.import_kernel)) },
466468
text = {
467469
Column {
468-
Text("Enter a name for this kernel version:")
470+
Text(stringResource(R.string.enter_kernel_version_name))
469471
Spacer(modifier = Modifier.height(8.dp))
470472
OutlinedTextField(
471473
value = name,
472474
onValueChange = { name = it },
473-
label = { Text("Version name") },
475+
label = { Text(stringResource(R.string.version_name)) },
474476
singleLine = true,
475477
shape = RoundedCornerShape(12.dp),
476478
modifier = Modifier.fillMaxWidth()
@@ -482,12 +484,12 @@ private fun ImportNameDialog(
482484
onClick = { onConfirm(name) },
483485
enabled = name.isNotBlank()
484486
) {
485-
Text("Import")
487+
Text(stringResource(R.string.import_label))
486488
}
487489
},
488490
dismissButton = {
489491
TextButton(onClick = onDismiss) {
490-
Text("Cancel")
492+
Text(stringResource(R.string.cancel))
491493
}
492494
}
493495
)
@@ -513,7 +515,7 @@ private fun DownloadDialog(
513515
onDismiss()
514516
}
515517
},
516-
title = { Text("Download Kernels") },
518+
title = { Text(stringResource(R.string.download_kernels)) },
517519
text = {
518520
Column(
519521
modifier = Modifier
@@ -530,13 +532,13 @@ private fun DownloadDialog(
530532
}
531533
} else if (releases.isEmpty()) {
532534
Text(
533-
"No releases found or network error",
535+
stringResource(R.string.no_releases_found),
534536
style = MaterialTheme.typography.bodyMedium,
535537
color = MaterialTheme.colorScheme.onSurfaceVariant
536538
)
537539
} else {
538540
Text(
539-
"Select a release to download:",
541+
stringResource(R.string.select_release_to_download),
540542
style = MaterialTheme.typography.bodySmall,
541543
color = MaterialTheme.colorScheme.onSurfaceVariant
542544
)
@@ -555,9 +557,9 @@ private fun DownloadDialog(
555557
if (downloadState == DownloadState.DOWNLOADING || downloadState == DownloadState.EXTRACTING || downloadState == DownloadState.VALIDATING) {
556558
Spacer(modifier = Modifier.height(16.dp))
557559
val label = when (downloadState) {
558-
DownloadState.DOWNLOADING -> "Downloading..."
559-
DownloadState.EXTRACTING -> "Extracting..."
560-
DownloadState.VALIDATING -> "Validating..."
560+
DownloadState.DOWNLOADING -> stringResource(R.string.downloading)
561+
DownloadState.EXTRACTING -> stringResource(R.string.extracting)
562+
DownloadState.VALIDATING -> stringResource(R.string.validating)
561563
else -> ""
562564
}
563565
Text(label, style = MaterialTheme.typography.bodySmall)
@@ -593,7 +595,7 @@ private fun DownloadDialog(
593595
)
594596
Spacer(modifier = Modifier.width(8.dp))
595597
Text(
596-
"Download complete!",
598+
stringResource(R.string.download_complete),
597599
style = MaterialTheme.typography.bodyMedium,
598600
fontWeight = FontWeight.Medium,
599601
color = MaterialTheme.colorScheme.primary
@@ -621,7 +623,7 @@ private fun DownloadDialog(
621623
)
622624
Spacer(modifier = Modifier.width(8.dp))
623625
Text(
624-
"Download failed. Please try again.",
626+
stringResource(R.string.download_failed),
625627
style = MaterialTheme.typography.bodyMedium,
626628
color = MaterialTheme.colorScheme.error
627629
)
@@ -632,7 +634,7 @@ private fun DownloadDialog(
632634
},
633635
confirmButton = {
634636
TextButton(onClick = onDismiss) {
635-
Text("Close")
637+
Text(stringResource(R.string.close))
636638
}
637639
}
638640
)
@@ -683,15 +685,15 @@ private fun ImportResultDialog(
683685
onDismissRequest = onDismiss,
684686
title = {
685687
Text(when (result) {
686-
is ImportResult.Success -> "Import Successful"
687-
is ImportResult.Error -> "Import Failed"
688+
is ImportResult.Success -> stringResource(R.string.import_successful)
689+
is ImportResult.Error -> stringResource(R.string.import_failed)
688690
})
689691
},
690692
text = {
691693
Column {
692694
when (result) {
693695
is ImportResult.Success -> {
694-
Text("Kernel imported successfully.")
696+
Text(stringResource(R.string.kernel_imported_successfully))
695697
if (result.missingLibraries.isNotEmpty()) {
696698
Spacer(modifier = Modifier.height(8.dp))
697699
Row(verticalAlignment = Alignment.Top) {
@@ -704,7 +706,7 @@ private fun ImportResultDialog(
704706
Spacer(modifier = Modifier.width(6.dp))
705707
Column {
706708
Text(
707-
"Missing libraries:",
709+
stringResource(R.string.missing_libraries),
708710
style = MaterialTheme.typography.bodyMedium,
709711
fontWeight = FontWeight.Medium,
710712
color = MaterialTheme.colorScheme.error
@@ -718,7 +720,7 @@ private fun ImportResultDialog(
718720
}
719721
Spacer(modifier = Modifier.height(4.dp))
720722
Text(
721-
"Some features may not work correctly.",
723+
stringResource(R.string.some_features_may_not_work),
722724
style = MaterialTheme.typography.bodySmall,
723725
color = MaterialTheme.colorScheme.error
724726
)
@@ -734,7 +736,7 @@ private fun ImportResultDialog(
734736
},
735737
confirmButton = {
736738
TextButton(onClick = onDismiss) {
737-
Text("OK")
739+
Text(stringResource(R.string.ok))
738740
}
739741
}
740742
)

0 commit comments

Comments
 (0)