mirror of
https://github.com/an-anime-team/sleepy-launcher.git
synced 2024-11-22 04:40:06 +03:00
feat(i18n): multiple localization changes
Improved `tr!` macro to use enhanced arguments syntax; Updated Indonesian; Fixed formatting error for `close` string
This commit is contained in:
parent
cab5a1f6f7
commit
7614561213
11 changed files with 88 additions and 59 deletions
|
@ -13,7 +13,7 @@ failed-get-selected-wine = Gagal mendapatkan versi wine yang dipilih
|
|||
downloading-failed = Gagal mengunduh
|
||||
unpacking-failed = Gagal mengekstrak berkas
|
||||
|
||||
kill-game-process-failed = Failed to kill the game's process
|
||||
kill-game-process-failed = Gagal menghentikan paksa proses game
|
||||
|
||||
game-file-repairing-error = Gagal memperbaiki file game
|
||||
integrity-files-getting-error = Gagal mendapatkan integritas file
|
||||
|
|
|
@ -58,8 +58,8 @@ disable-mhypbase-description = Masih dalam pengujicobaan. Jika diaktifkan, launc
|
|||
ask-superuser-permissions = Minta izin dari admin
|
||||
ask-superuser-permissions-description = Launcher akan otomatis memperbarui file hosts Anda. Opsi ini tidak diperlukan jika Anda memakai edisi flatpak
|
||||
|
||||
launcher-behavior = Launcher behavior
|
||||
launcher-behavior-description = What should launcher window do when it starts the game
|
||||
launcher-behavior = Kelakuan launcher
|
||||
launcher-behavior-description = Apa yang terjadi pada jendela launcher ketika memulai game
|
||||
|
||||
wine-tools = Peralatan wine
|
||||
command-line = Command line
|
||||
|
|
|
@ -16,10 +16,17 @@ debug-file = File debug
|
|||
wish-url = Buka wishes
|
||||
about = Tentang
|
||||
|
||||
close = { $form ->
|
||||
[verb] Menutup
|
||||
*[noun] Tutup
|
||||
}
|
||||
|
||||
close = Tutup
|
||||
hide = Hide
|
||||
nothing = Nothing
|
||||
hide = { $form ->
|
||||
[verb] Sembunyikan
|
||||
*[noun] Sembunyi
|
||||
}
|
||||
|
||||
nothing = Tidak berubah
|
||||
save = Simpan
|
||||
continue = Lanjutkan
|
||||
resume = Lanjutkan
|
||||
|
@ -64,7 +71,7 @@ update = Perbarui
|
|||
download = Unduh
|
||||
predownload-update = Pra-unduh pembaruan versi {$version} ({$size})
|
||||
|
||||
kill-game-process = Kill game process
|
||||
kill-game-process = Hentikan paksa proses game
|
||||
|
||||
main-window--patch-unavailable-tooltip = Server patch tidak tersedia dan launcher tidak bisa memverifikasi status patch game. Anda bisa menjalankan game dengan resiko sendiri
|
||||
main-window--patch-outdated-tooltip = Patch kadaluarsa atau sedang dalam persiapan sehingga tidak tersedia. Kembali lagi nanti untuk melihat status patch
|
||||
|
|
25
src/i18n.rs
25
src/i18n.rs
|
@ -88,10 +88,10 @@ pub fn format_lang(lang: &LanguageIdentifier) -> String {
|
|||
/// With parameters:
|
||||
///
|
||||
/// ```no_run
|
||||
/// println!("Translated message: {}", tr!("game-outdated", [
|
||||
/// ("latest", "3.3.0")
|
||||
/// ]));
|
||||
/// ```
|
||||
/// println!("Translated message: {}", tr!("game-outdated", {
|
||||
/// "latest" = "3.3.0"
|
||||
/// }));
|
||||
/// ```
|
||||
macro_rules! tr {
|
||||
($id:expr) => {
|
||||
{
|
||||
|
@ -104,19 +104,22 @@ macro_rules! tr {
|
|||
}
|
||||
};
|
||||
|
||||
($id:expr, $args:expr) => {
|
||||
($id:expr, { $($key:literal = $value:expr),* }) => {
|
||||
{
|
||||
use std::collections::HashMap;
|
||||
|
||||
use fluent_templates::Loader;
|
||||
use fluent_templates::fluent_bundle::FluentValue;
|
||||
|
||||
let mut args = HashMap::new();
|
||||
|
||||
$(
|
||||
args.insert($key, FluentValue::from($value));
|
||||
)*
|
||||
|
||||
#[allow(unused_unsafe)]
|
||||
$crate::i18n::LOCALES
|
||||
.lookup_with_args(
|
||||
unsafe { &$crate::i18n::LANG },
|
||||
$id,
|
||||
&std::collections::HashMap::from_iter($args.into_iter()
|
||||
.map(|(key, value)| (key, FluentValue::from(value))))
|
||||
)
|
||||
.lookup_complete(unsafe { &$crate::i18n::LANG }, $id, Some(&args))
|
||||
.expect(&format!("Failed to find a message with given id: {}", stringify!($id)))
|
||||
}
|
||||
};
|
||||
|
|
|
@ -98,6 +98,9 @@ fn main() {
|
|||
// Forcely run the game
|
||||
let just_run_game = std::env::args().any(|arg| &arg == "--just-run-game");
|
||||
|
||||
// Forcely disable verbode tracing output in stdout
|
||||
let no_verbose_tracing = std::env::args().any(|arg| &arg == "--no-verbose-tracing");
|
||||
|
||||
// Prepare stdout logger
|
||||
let stdout = tracing_subscriber::fmt::layer()
|
||||
.pretty()
|
||||
|
@ -108,8 +111,8 @@ fn main() {
|
|||
LevelFilter::WARN
|
||||
}
|
||||
})
|
||||
.with_filter(filter_fn(|metadata| {
|
||||
!metadata.target().contains("rustls")
|
||||
.with_filter(filter_fn(move |metadata| {
|
||||
!metadata.target().contains("rustls") && !no_verbose_tracing
|
||||
}));
|
||||
|
||||
// Prepare debug file logger
|
||||
|
|
|
@ -243,7 +243,7 @@ impl SimpleAsyncComponent for DefaultPathsApp {
|
|||
|
||||
gtk::Button {
|
||||
set_label: &if model.migrate_installation {
|
||||
tr!("close")
|
||||
tr!("close", { "form" = "noun" })
|
||||
} else {
|
||||
tr!("exit")
|
||||
},
|
||||
|
|
|
@ -175,7 +175,9 @@ impl SimpleAsyncComponent for DependenciesApp {
|
|||
for package in packages {
|
||||
if !is_available(package) {
|
||||
sender.output(Self::Output::Toast {
|
||||
title: tr!("package-not-available", [("package", package)]),
|
||||
title: tr!("package-not-available", {
|
||||
"package" = package
|
||||
}),
|
||||
description: None
|
||||
});
|
||||
|
||||
|
|
|
@ -285,7 +285,7 @@ impl SimpleComponent for FirstRunApp {
|
|||
|
||||
let dialog = adw::MessageDialog::new(MAIN_WINDOW.as_ref(), Some(&title), Some(&description));
|
||||
|
||||
dialog.add_response("close", &tr!("close"));
|
||||
dialog.add_response("close", &tr!("close", { "form" = "noun" }));
|
||||
dialog.add_response("save", &tr!("save"));
|
||||
|
||||
dialog.set_response_appearance("save", adw::ResponseAppearance::Suggested);
|
||||
|
|
|
@ -308,13 +308,13 @@ impl SimpleComponent for App {
|
|||
set_width_request: 44,
|
||||
|
||||
#[watch]
|
||||
set_tooltip_text: Some(&tr!("predownload-update", [
|
||||
("version", match model.state.as_ref() {
|
||||
set_tooltip_text: Some(&tr!("predownload-update", {
|
||||
"version" = match model.state.as_ref() {
|
||||
Some(LauncherState::PredownloadAvailable { game, .. }) => game.latest().to_string(),
|
||||
_ => String::from("?")
|
||||
}),
|
||||
},
|
||||
|
||||
("size", match model.state.as_ref() {
|
||||
"size" = match model.state.as_ref() {
|
||||
Some(LauncherState::PredownloadAvailable { game, voices }) => {
|
||||
let mut size = game.downloaded_size().unwrap_or(0);
|
||||
|
||||
|
@ -326,8 +326,8 @@ impl SimpleComponent for App {
|
|||
}
|
||||
|
||||
_ => String::from("?")
|
||||
})
|
||||
])),
|
||||
}
|
||||
})),
|
||||
|
||||
#[watch]
|
||||
set_visible: matches!(model.state.as_ref(), Some(LauncherState::PredownloadAvailable { .. })),
|
||||
|
@ -1002,9 +1002,9 @@ impl SimpleComponent for App {
|
|||
}
|
||||
|
||||
StateUpdating::Voice(locale) => {
|
||||
sender.input(AppMsg::SetLoadingStatus(Some(Some(tr!("loading-launcher-state--voice", [
|
||||
("locale", locale.to_name())
|
||||
])))));
|
||||
sender.input(AppMsg::SetLoadingStatus(Some(Some(tr!("loading-launcher-state--voice", {
|
||||
"locale" = locale.to_name()
|
||||
})))));
|
||||
}
|
||||
|
||||
StateUpdating::Patch => {
|
||||
|
@ -1189,7 +1189,7 @@ impl App {
|
|||
Some(description.as_ref())
|
||||
);
|
||||
|
||||
dialog.add_response("close", &tr!("close"));
|
||||
dialog.add_response("close", &tr!("close", { "form" = "noun" }));
|
||||
dialog.add_response("save", &tr!("save"));
|
||||
|
||||
dialog.set_response_appearance("save", adw::ResponseAppearance::Suggested);
|
||||
|
|
|
@ -397,10 +397,10 @@ impl SimpleAsyncComponent for GeneralApp {
|
|||
#[watch]
|
||||
set_css_classes: match model.game_diff.as_ref() {
|
||||
Some(diff) => match diff {
|
||||
VersionDiff::Latest { .. } => &["success"],
|
||||
VersionDiff::Predownload { .. } => &["accent"],
|
||||
VersionDiff::Diff { .. } => &["warning"],
|
||||
VersionDiff::Outdated { .. } => &["error"],
|
||||
VersionDiff::Latest { .. } => &["success"],
|
||||
VersionDiff::Predownload { .. } => &["accent"],
|
||||
VersionDiff::Diff { .. } => &["warning"],
|
||||
VersionDiff::Outdated { .. } => &["error"],
|
||||
VersionDiff::NotInstalled { .. } => &[]
|
||||
}
|
||||
|
||||
|
@ -411,17 +411,21 @@ impl SimpleAsyncComponent for GeneralApp {
|
|||
set_tooltip_text: Some(&match model.game_diff.as_ref() {
|
||||
Some(diff) => match diff {
|
||||
VersionDiff::Latest { .. } => String::new(),
|
||||
VersionDiff::Predownload { current, latest, .. } => tr!("game-predownload-available", [
|
||||
("old", current.to_string()),
|
||||
("new", latest.to_string())
|
||||
]),
|
||||
VersionDiff::Diff { current, latest, .. } => tr!("game-update-available", [
|
||||
("old", current.to_string()),
|
||||
("new", latest.to_string())
|
||||
]),
|
||||
VersionDiff::Outdated { latest, ..} => tr!("game-outdated", [
|
||||
("latest", latest.to_string())
|
||||
]),
|
||||
|
||||
VersionDiff::Predownload { current, latest, .. } => tr!("game-predownload-available", {
|
||||
"old" = current.to_string(),
|
||||
"new" = latest.to_string()
|
||||
}),
|
||||
|
||||
VersionDiff::Diff { current, latest, .. } => tr!("game-update-available", {
|
||||
"old" = current.to_string(),
|
||||
"new" = latest.to_string()
|
||||
}),
|
||||
|
||||
VersionDiff::Outdated { latest, ..} => tr!("game-outdated", {
|
||||
"latest" = latest.to_string()
|
||||
}),
|
||||
|
||||
VersionDiff::NotInstalled { .. } => String::new()
|
||||
}
|
||||
|
||||
|
@ -439,8 +443,13 @@ impl SimpleAsyncComponent for GeneralApp {
|
|||
set_text: &match model.player_patch.as_ref() {
|
||||
Some(patch) => match patch.status() {
|
||||
PatchStatus::NotAvailable => tr!("patch-not-available"),
|
||||
PatchStatus::Outdated { current, .. } => tr!("patch-outdated", [("current", current.to_string())]),
|
||||
|
||||
PatchStatus::Outdated { current, .. } => tr!("patch-outdated", {
|
||||
"current" = current.to_string()
|
||||
}),
|
||||
|
||||
PatchStatus::Preparation { .. } => tr!("patch-preparation"),
|
||||
|
||||
PatchStatus::Testing { version, .. } |
|
||||
PatchStatus::Available { version, .. } => version.to_string()
|
||||
}
|
||||
|
@ -452,9 +461,11 @@ impl SimpleAsyncComponent for GeneralApp {
|
|||
set_css_classes: match model.player_patch.as_ref() {
|
||||
Some(patch) => match patch.status() {
|
||||
PatchStatus::NotAvailable => &["error"],
|
||||
|
||||
PatchStatus::Outdated { .. } |
|
||||
PatchStatus::Preparation { .. } |
|
||||
PatchStatus::Testing { .. } => &["warning"],
|
||||
|
||||
PatchStatus::Available { .. } => unsafe {
|
||||
let path = match Config::get() {
|
||||
Ok(config) => config.game.path.for_edition(config.launcher.edition).to_path_buf(),
|
||||
|
@ -476,12 +487,15 @@ impl SimpleAsyncComponent for GeneralApp {
|
|||
set_tooltip_text: Some(&match model.player_patch.as_ref() {
|
||||
Some(patch) => match patch.status() {
|
||||
PatchStatus::NotAvailable => tr!("patch-not-available-tooltip"),
|
||||
PatchStatus::Outdated { current, latest, .. } => tr!("patch-outdated-tooltip", [
|
||||
("current", current.to_string()),
|
||||
("latest", latest.to_string())
|
||||
]),
|
||||
|
||||
PatchStatus::Outdated { current, latest, .. } => tr!("patch-outdated-tooltip", {
|
||||
"current" = current.to_string(),
|
||||
"latest" = latest.to_string()
|
||||
}),
|
||||
|
||||
PatchStatus::Preparation { .. } => tr!("patch-preparation-tooltip"),
|
||||
PatchStatus::Testing { .. } => tr!("patch-testing-tooltip"),
|
||||
|
||||
PatchStatus::Available { .. } => unsafe {
|
||||
let path = match Config::get() {
|
||||
Ok(config) => config.game.path.for_edition(config.launcher.edition).to_path_buf(),
|
||||
|
@ -582,8 +596,8 @@ impl SimpleAsyncComponent for GeneralApp {
|
|||
|
||||
set_model: Some(>k::StringList::new(&[
|
||||
&tr!("nothing"),
|
||||
&tr!("hide", [("form", "verb")]),
|
||||
&tr!("close", [("form", "verb")]),
|
||||
&tr!("hide", { "form" = "verb" }),
|
||||
&tr!("close", { "form" = "verb" }),
|
||||
])),
|
||||
|
||||
set_selected: match CONFIG.launcher.behavior {
|
||||
|
@ -873,9 +887,9 @@ impl SimpleAsyncComponent for GeneralApp {
|
|||
|
||||
if let Err(err) = result {
|
||||
sender.input(GeneralAppMsg::Toast {
|
||||
title: tr!("wine-run-error", [
|
||||
("executable", executable.join(" "))
|
||||
]),
|
||||
title: tr!("wine-run-error", {
|
||||
"executable" = executable.join(" ")
|
||||
}),
|
||||
description: Some(err.to_string())
|
||||
});
|
||||
|
||||
|
|
|
@ -154,7 +154,7 @@ impl SimpleAsyncComponent for PreferencesApp {
|
|||
|
||||
let dialog = adw::MessageDialog::new(PREFERENCES_WINDOW.as_ref(), Some(&title), Some(&description));
|
||||
|
||||
dialog.add_response("close", &tr!("close"));
|
||||
dialog.add_response("close", &tr!("close", { "form" = "noun" }));
|
||||
dialog.add_response("save", &tr!("save"));
|
||||
|
||||
dialog.set_response_appearance("save", adw::ResponseAppearance::Suggested);
|
||||
|
|
Loading…
Reference in a new issue