Skip to content

Commit

Permalink
Added russian localization
Browse files Browse the repository at this point in the history
  • Loading branch information
sirekanian committed Jan 14, 2024
1 parent 2402068 commit 9aaeb22
Show file tree
Hide file tree
Showing 23 changed files with 240 additions and 61 deletions.
4 changes: 2 additions & 2 deletions app/src/fdroid/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<resources>
<string name="outln_source_code_title">GitLab</string>
<string name="outln_source_code_link">"https://gitlab.com/sirekanyan.org/outline"</string>
<string name="outln_source_code_title" translatable="false">GitLab</string>
<string name="outln_source_code_link" translatable="false">"https://gitlab.com/sirekanyan.org/outline"</string>
</resources>
16 changes: 10 additions & 6 deletions app/src/main/java/org/sirekanyan/outline/MainContent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ fun MainContent(state: MainState) {
TextButton(onClick = { state.dialog = AddServerDialog }) {
Icon(Icons.Default.Add, null)
Spacer(Modifier.size(8.dp))
Text("Add server")
Text(stringResource(R.string.outln_text_add_server))
}
}
}
Expand All @@ -98,8 +98,12 @@ fun MainContent(state: MainState) {
listOf()
} else {
listOf(
MenuItem("Sort by…", IconSort) { isSortingVisible = true },
MenuItem("Search", Icons.Default.Search) { search.openSearch() },
MenuItem(R.string.outln_menu_sort, IconSort) {
isSortingVisible = true
},
MenuItem(R.string.outln_menu_search, Icons.Default.Search) {
search.openSearch()
},
)
}
MainTopAppBar(
Expand Down Expand Up @@ -173,15 +177,15 @@ fun MainContent(state: MainState) {
},
onMenuClick = state::openDrawer,
visibleItems = listOf(
MenuItem("Sort by…", IconSort) {
MenuItem(R.string.outln_menu_sort, IconSort) {
isSortingVisible = true
},
),
overflowItems = listOf(
MenuItem("Edit", Icons.Default.Edit) {
MenuItem(R.string.outln_menu_edit, Icons.Default.Edit) {
state.dialog = RenameServerDialog(page.server)
},
MenuItem("Delete", Icons.Default.Delete) {
MenuItem(R.string.outln_menu_delete, Icons.Default.Delete) {
state.dialog = DeleteServerDialog(page.server)
},
),
Expand Down
6 changes: 4 additions & 2 deletions app/src/main/java/org/sirekanyan/outline/MainTopAppBar.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.sirekanyan.outline

import androidx.annotation.StringRes
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Menu
import androidx.compose.material.icons.filled.MoreVert
Expand All @@ -19,9 +20,10 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp

data class MenuItem(val text: String, val icon: ImageVector, val onClick: () -> Unit)
data class MenuItem(@StringRes val text: Int, val icon: ImageVector, val onClick: () -> Unit)

@Composable
@OptIn(ExperimentalMaterial3Api::class)
Expand Down Expand Up @@ -57,7 +59,7 @@ private fun MainMenu(visibleItems: List<MenuItem>, overflowItems: List<MenuItem>
DropdownMenu(isMenuVisible, { isMenuVisible = false }) {
overflowItems.forEach { (text, icon, onClick) ->
DropdownMenuItem(
text = { Text(text) },
text = { Text(stringResource(text)) },
leadingIcon = { Icon(icon, null) },
onClick = {
isMenuVisible = false
Expand Down
17 changes: 11 additions & 6 deletions app/src/main/java/org/sirekanyan/outline/NotSupportedContent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,32 @@ fun NotSupportedContent(onDismissRequest: () -> Unit) {
val isInstalled = remember { isOutlineInstalled(context) }
AlertDialog(
icon = { Icon(Icons.Default.Info, null) },
title = { Text("Not supported") },
title = { Text(stringResource(R.string.outln_title_not_supported)) },
text = {
Text(
text = stringResource(R.string.outln_app_name) + " does not support ss:// links. " +
"Would you like to ${if (isInstalled) "open" else "install"} Outline?",
text = stringResource(
if (isInstalled) {
R.string.outln_text_not_supported_open
} else {
R.string.outln_text_not_supported_install
}
),
)
},
onDismissRequest = onDismissRequest,
dismissButton = {
TextButton(onClick = onDismissRequest) {
Text("Cancel")
Text(stringResource(R.string.outln_btn_cancel))
}
},
confirmButton = {
if (isInstalled) {
TextButton(onClick = { onDismissRequest(); openOutline(context) }) {
Text("Open Outline")
Text(stringResource(R.string.outln_btn_not_supported_open))
}
} else {
TextButton(onClick = { onDismissRequest(); installOutline(context) }) {
Text("Install Outline")
Text(stringResource(R.string.outln_btn_not_supported_install))
}
}
},
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/java/org/sirekanyan/outline/ext/Context.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ package org.sirekanyan.outline.ext
import android.content.Context
import android.content.Intent
import android.net.Uri
import org.sirekanyan.outline.R

fun Context.openGooglePlay(uri: String) {
try {
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(uri)))
} catch (exception: Exception) {
logDebug("Cannot open Google Play", exception)
showToast("Cannot open Google Play")
showToast(R.string.outln_toast_cannot_open_play)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.job
import kotlinx.coroutines.plus
import org.sirekanyan.outline.R
import java.net.ConnectException
import java.net.UnknownHostException

Expand All @@ -24,10 +25,10 @@ fun rememberStateScope(): CoroutineScope {
}
when (throwable) {
is UnknownHostException, is ConnectException -> {
context.showToast("Check network connection")
context.showToast(R.string.outln_toast_check_network)
}
else -> {
context.showToast("Something went wrong")
context.showToast(R.string.outln_toast_something_wrong)
}
}
}
Expand Down
4 changes: 0 additions & 4 deletions app/src/main/java/org/sirekanyan/outline/ext/Toast.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ import android.content.Context
import android.widget.Toast
import androidx.annotation.StringRes

fun Context.showToast(text: String) {
Toast.makeText(this, text, Toast.LENGTH_SHORT).show()
}

fun Context.showToast(@StringRes text: Int) {
Toast.makeText(this, text, Toast.LENGTH_SHORT).show()
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ fun KeysErrorContent(insets: PaddingValues, onRetry: () -> Unit) {
textAlign = TextAlign.Center,
)
Button(onClick = onRetry) {
Text(text = "Try again")
Text(text = stringResource(R.string.outln_btn_try_again))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import kotlinx.coroutines.launch
import org.sirekanyan.outline.R
import org.sirekanyan.outline.ui.SimpleBottomSheet

@Composable
Expand All @@ -25,7 +26,7 @@ fun SortBottomSheet(
) {
val coroutineScope = rememberCoroutineScope()
SimpleBottomSheet(
title = "Sort by…",
title = stringResource(R.string.outln_sorting_by),
onDismissRequest = onDismissRequest,
items = { sheetState ->
Sorting.entries.forEach { option ->
Expand Down
11 changes: 6 additions & 5 deletions app/src/main/java/org/sirekanyan/outline/ui/AboutDialog.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package org.sirekanyan.outline.ui
import android.content.Intent
import android.content.Intent.ACTION_SENDTO
import android.net.Uri
import androidx.annotation.StringRes
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.heightIn
Expand Down Expand Up @@ -77,7 +78,7 @@ fun AboutDialogContent(onDismiss: () -> Unit) {
confirmButton = {
val context = LocalContext.current
val clipboard = LocalClipboardManager.current
AboutItem(Icons.Default.Email, "Send feedback") {
AboutItem(Icons.Default.Email, R.string.outln_btn_send_feedback) {
val email = "[email protected]"
val subject = Uri.encode("Feedback: $appName $appVersion")
val intent = Intent(ACTION_SENDTO, Uri.parse("mailto:$email?subject=$subject"))
Expand All @@ -86,13 +87,13 @@ fun AboutDialogContent(onDismiss: () -> Unit) {
} catch (exception: Exception) {
logDebug("Cannot find email app", exception)
clipboard.setText(AnnotatedString(email))
context.showToast("Email is copied")
context.showToast(R.string.outln_toast_email_copied)
}
}
if (isPlayFlavor() || isDebugBuild()) {
val packageName = "org.sirekanyan.outline"
val playUri = "https://play.google.com/store/apps/details?id=$packageName"
AboutItem(IconPlayStore, "Rate on Play Store") {
AboutItem(IconPlayStore, R.string.outln_btn_rate_on_play_store) {
context.openGooglePlay(playUri)
onDismiss()
}
Expand All @@ -102,15 +103,15 @@ fun AboutDialogContent(onDismiss: () -> Unit) {
}

@Composable
private fun AboutItem(icon: ImageVector, text: String, onClick: () -> Unit) {
private fun AboutItem(icon: ImageVector, @StringRes text: Int, onClick: () -> Unit) {
TextButton(
onClick = onClick,
modifier = Modifier.fillMaxWidth().heightIn(min = 56.dp),
border = BorderStroke(1.dp, MaterialTheme.colorScheme.primary),
) {
Icon(icon, null, Modifier.padding(horizontal = 4.dp))
Text(
text = text,
text = stringResource(text),
modifier = Modifier.weight(1f).padding(horizontal = 8.dp),
maxLines = 1,
overflow = TextOverflow.Ellipsis,
Expand Down
4 changes: 3 additions & 1 deletion app/src/main/java/org/sirekanyan/outline/ui/AddKeyButton.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import org.sirekanyan.outline.R

@Composable
fun AddKeyButton(isVisible: Boolean, isLoading: Boolean, onClick: () -> Unit) {
Expand All @@ -43,7 +45,7 @@ fun AddKeyButton(isVisible: Boolean, isLoading: Boolean, onClick: () -> Unit) {
} else {
Icon(Icons.Default.Add, null)
Spacer(Modifier.width(12.dp))
Text("Add key")
Text(stringResource(R.string.outln_btn_add_key))
Spacer(Modifier.width(4.dp))
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import androidx.compose.ui.draw.alpha
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.CoroutineScope
Expand Down Expand Up @@ -103,9 +104,9 @@ fun AddServerContent(router: Router) {
val state = rememberAddServerState(router)
Column {
DialogToolbar(
title = "Add server",
title = R.string.outln_title_add_server,
onCloseClick = { router.dialog = null },
action = "Add" to { state.onAddClicked() },
action = R.string.outln_action_add to { state.onAddClicked() },
isLoading = state.isLoading,
)
val focusRequester = remember { FocusRequester() }
Expand All @@ -119,7 +120,7 @@ fun AddServerContent(router: Router) {
.fillMaxWidth()
.padding(16.dp, 24.dp, 16.dp, 8.dp)
.focusRequester(focusRequester),
label = { Text("Management API URL") },
label = { Text(stringResource(R.string.outln_label_server_url)) },
placeholder = { Text("https://xx.xx.xx.xx:xxx/xxxxx", Modifier.alpha(0.38f)) },
isError = state.error.isNotEmpty(),
supportingText = { Text(state.error) },
Expand All @@ -136,7 +137,7 @@ fun AddServerContent(router: Router) {
onCheckedChange = { state.insecure = it },
)
Text(
text = "Allow insecure connection",
text = stringResource(R.string.outln_label_allow_insecure),
modifier = Modifier.padding(end = 16.dp),
style = MaterialTheme.typography.bodySmall,
color = LocalContentColor.current.copy(alpha = 0.66f),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import org.sirekanyan.outline.R
import org.sirekanyan.outline.api.model.Key

@Composable
fun DeleteKeyContent(key: Key, onDismiss: () -> Unit, onConfirm: () -> Unit) {
ConfirmationAlertDialog(
text = "Are you sure you want to delete the key named \"${key.nameOrDefault}\"?",
text = stringResource(R.string.outln_text_confirm_key, key.nameOrDefault),
onDismiss = onDismiss,
onConfirm = onConfirm,
)
Expand All @@ -22,7 +24,7 @@ fun DeleteKeyContent(key: Key, onDismiss: () -> Unit, onConfirm: () -> Unit) {
@Composable
fun DeleteServerContent(serverName: String, onDismiss: () -> Unit, onConfirm: () -> Unit) {
ConfirmationAlertDialog(
text = "Are you sure you want to delete the server named \"$serverName\"?",
text = stringResource(R.string.outln_text_confirm_server, serverName),
onDismiss = onDismiss,
onConfirm = onConfirm,
)
Expand All @@ -32,13 +34,22 @@ fun DeleteServerContent(serverName: String, onDismiss: () -> Unit, onConfirm: ()
private fun ConfirmationAlertDialog(text: String, onDismiss: () -> Unit, onConfirm: () -> Unit) {
AlertDialog(
icon = { Icon(Icons.Default.Delete, null) },
title = { Text("Confirmation") },
title = { Text(stringResource(R.string.outln_title_confirm)) },
text = { Text(text) },
onDismissRequest = onDismiss,
dismissButton = { TextButton(onDismiss) { Text("Cancel") } },
dismissButton = {
TextButton(onClick = onDismiss) {
Text(
text = stringResource(R.string.outln_btn_cancel),
)
}
},
confirmButton = {
TextButton(onClick = { onConfirm(); onDismiss() }) {
Text("Delete", color = MaterialTheme.colorScheme.error)
Text(
text = stringResource(R.string.outln_btn_confirm_delete),
color = MaterialTheme.colorScheme.error,
)
}
},
)
Expand Down
10 changes: 6 additions & 4 deletions app/src/main/java/org/sirekanyan/outline/ui/DialogToolbar.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.sirekanyan.outline.ui

import androidx.annotation.StringRes
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
Expand All @@ -16,19 +17,20 @@ import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.surfaceColorAtElevation
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp

@Composable
@OptIn(ExperimentalMaterial3Api::class)
fun DialogToolbar(
title: String,
@StringRes title: Int,
onCloseClick: () -> Unit,
action: Pair<String, () -> Unit>,
action: Pair<Int, () -> Unit>,
isLoading: Boolean,
) {
TopAppBar(
title = { Text(title, maxLines = 1, overflow = TextOverflow.Ellipsis) },
title = { Text(stringResource(title), maxLines = 1, overflow = TextOverflow.Ellipsis) },
navigationIcon = {
IconButton({ onCloseClick() }) { Icon(Icons.Default.Close, null) }
},
Expand All @@ -37,7 +39,7 @@ fun DialogToolbar(
CircularProgressIndicator(Modifier.size(56.dp).padding(16.dp), strokeWidth = 2.dp)
} else {
val (actionName, onActionClick) = action
TextButton({ onActionClick() }) { Text(actionName) }
TextButton({ onActionClick() }) { Text(stringResource(actionName)) }
}
},
colors = TopAppBarDefaults.topAppBarColors(
Expand Down
Loading

0 comments on commit 9aaeb22

Please sign in to comment.