diff --git a/assets/locales/id/errors.ftl b/assets/locales/id/errors.ftl index 50a8939..4c262ef 100644 --- a/assets/locales/id/errors.ftl +++ b/assets/locales/id/errors.ftl @@ -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 diff --git a/assets/locales/id/general.ftl b/assets/locales/id/general.ftl index cfd6bfd..e127a20 100644 --- a/assets/locales/id/general.ftl +++ b/assets/locales/id/general.ftl @@ -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 diff --git a/assets/locales/id/main.ftl b/assets/locales/id/main.ftl index 7ddae31..af68365 100644 --- a/assets/locales/id/main.ftl +++ b/assets/locales/id/main.ftl @@ -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 diff --git a/src/i18n.rs b/src/i18n.rs index db92643..45ca93f 100644 --- a/src/i18n.rs +++ b/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))) } }; diff --git a/src/main.rs b/src/main.rs index 748e8fa..c6399b6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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 diff --git a/src/ui/first_run/default_paths.rs b/src/ui/first_run/default_paths.rs index 4f33ddd..c62e323 100644 --- a/src/ui/first_run/default_paths.rs +++ b/src/ui/first_run/default_paths.rs @@ -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") }, diff --git a/src/ui/first_run/dependencies.rs b/src/ui/first_run/dependencies.rs index d6a2666..c51db17 100644 --- a/src/ui/first_run/dependencies.rs +++ b/src/ui/first_run/dependencies.rs @@ -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 }); diff --git a/src/ui/first_run/main.rs b/src/ui/first_run/main.rs index 3407c3d..e9b1471 100644 --- a/src/ui/first_run/main.rs +++ b/src/ui/first_run/main.rs @@ -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); diff --git a/src/ui/main/mod.rs b/src/ui/main/mod.rs index eb52caf..5c8f441 100644 --- a/src/ui/main/mod.rs +++ b/src/ui/main/mod.rs @@ -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); diff --git a/src/ui/preferences/general/mod.rs b/src/ui/preferences/general/mod.rs index 8ebecc5..00dac0f 100644 --- a/src/ui/preferences/general/mod.rs +++ b/src/ui/preferences/general/mod.rs @@ -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()) }); diff --git a/src/ui/preferences/main.rs b/src/ui/preferences/main.rs index 4276327..23252b8 100644 --- a/src/ui/preferences/main.rs +++ b/src/ui/preferences/main.rs @@ -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);