feat(core): replaced tr and tr_args functions by tr! macro

This commit is contained in:
Observer KRypt0n_ 2023-07-31 20:20:23 +02:00
parent d04bb3e5e0
commit 7492aad669
No known key found for this signature in database
GPG key ID: 844DA47BA25FE1E2
28 changed files with 429 additions and 430 deletions

View file

@ -148,9 +148,9 @@ for filename in os.listdir("assets/locales/en"):
# FIXME: it only indexes the first match
for line in script.read().split("\n"):
if ("tr(\"" in line) and ("#" not in line):
index = line.find('tr("')
index = line.find('tr!("')
indexLast = line.find('")',index)
var_name = re.sub('[^\\w-]+', '', line[index:indexLast].replace('tr("', '').replace("Some", ""))
var_name = re.sub('[^\\w-]+', '', line[index:indexLast].replace('tr!("', '').replace("Some", ""))
script_entries[var_name] = [script.name, get_line_num(script, var_name)]

View file

@ -1,8 +1,7 @@
use fluent_templates::Loader;
use unic_langid::{langid, LanguageIdentifier};
fluent_templates::static_loader! {
static LOCALES = {
pub static LOCALES = {
locales: "./assets/locales",
core_locales: "./assets/locales/common.ftl",
fallback_language: "en"
@ -24,7 +23,7 @@ pub const SUPPORTED_LANGUAGES: &[LanguageIdentifier] = &[
langid!("hu-hu")
];
static mut LANG: LanguageIdentifier = langid!("en-us");
pub static mut LANG: LanguageIdentifier = langid!("en-us");
/// Set launcher language
pub fn set_lang(lang: LanguageIdentifier) -> anyhow::Result<()> {
@ -75,36 +74,51 @@ pub fn format_lang(lang: &LanguageIdentifier) -> String {
})
}
/// Get translated message by key
#[macro_export]
/// Get translated message by key, with optional translation parameters
///
/// # Examples:
///
/// Without parameters:
///
/// ```no_run
/// println!("Translated message: {}", tr("launch"));
/// ```
#[allow(clippy::expect_fun_call)]
pub fn tr(id: &str) -> String {
unsafe {
LOCALES
.lookup(&LANG, id)
.expect(&format!("Failed to find message with given id: {id}"))
}
}
/// Get translated message by key with filled arguments
/// println!("Translated message: {}", tr!("launch"));
/// ```
///
/// With parameters:
///
/// ```no_run
/// println!("Translated message: {}", tr_args("game-outdated", [
/// ("latest", "3.3.0".into())
/// println!("Translated message: {}", tr!("game-outdated", [
/// ("latest", "3.3.0")
/// ]));
/// ```
#[allow(clippy::expect_fun_call)]
pub fn tr_args<I, T>(id: &str, args: I) -> String
where
I: IntoIterator<Item = (T, fluent_templates::fluent_bundle::FluentValue<'static>)>,
T: AsRef<str> + std::hash::Hash + Eq
{
unsafe {
LOCALES
.lookup_with_args(&LANG, id, &std::collections::HashMap::from_iter(args.into_iter()))
.expect(&format!("Failed to find message with given id: {id}"))
}
macro_rules! tr {
($id:expr) => {
{
use fluent_templates::Loader;
#[allow(unused_unsafe)]
$crate::i18n::LOCALES
.lookup(unsafe { &$crate::i18n::LANG }, $id)
.expect(&format!("Failed to find a message with given id: {}", stringify!($id)))
}
};
($id:expr, $args:expr) => {
{
use fluent_templates::Loader;
use fluent_templates::fluent_bundle::FluentValue;
let mut args = std::collections::HashMap::new();
for (key, value) in $args {
args.insert(key, FluentValue::from(value));
}
#[allow(unused_unsafe)]
$crate::i18n::LOCALES
.lookup_with_args(unsafe { &$crate::i18n::LANG }, $id, &args)
.expect(&format!("Failed to find a message with given id: {}", stringify!($id)))
}
};
}

View file

@ -6,7 +6,7 @@ use adw::prelude::*;
use anime_launcher_sdk::anime_game_core::prelude::*;
use anime_launcher_sdk::anime_game_core::genshin::prelude::*;
use crate::i18n::*;
use crate::*;
pub struct ProgressBarInit {
pub caption: Option<String>,
@ -133,19 +133,19 @@ impl SimpleAsyncComponent for ProgressBar {
ProgressBarMsg::UpdateFromState(state) => {
match state {
DiffUpdate::CheckingFreeSpace(_) |
DiffUpdate::InstallerUpdate(InstallerUpdate::CheckingFreeSpace(_)) => self.caption = Some(tr("checking-free-space")),
DiffUpdate::InstallerUpdate(InstallerUpdate::CheckingFreeSpace(_)) => self.caption = Some(tr!("checking-free-space")),
DiffUpdate::InstallerUpdate(InstallerUpdate::DownloadingStarted(_)) => self.caption = Some(tr("downloading")),
DiffUpdate::InstallerUpdate(InstallerUpdate::UnpackingStarted(_)) => self.caption = Some(tr("unpacking")),
DiffUpdate::InstallerUpdate(InstallerUpdate::DownloadingStarted(_)) => self.caption = Some(tr!("downloading")),
DiffUpdate::InstallerUpdate(InstallerUpdate::UnpackingStarted(_)) => self.caption = Some(tr!("unpacking")),
DiffUpdate::ApplyingHdiffStarted => {
self.caption = Some(tr("applying-hdiff"));
self.caption = Some(tr!("applying-hdiff"));
self.display_fraction = false;
},
DiffUpdate::RemovingOutdatedStarted => {
self.caption = Some(tr("removing-outdated"));
self.caption = Some(tr!("removing-outdated"));
self.display_fraction = false;
},

View file

@ -6,7 +6,6 @@ use relm4::component::*;
use adw::prelude::*;
use crate::*;
use crate::i18n::*;
use crate::ui::components::progress_bar::*;
use super::main::*;
@ -68,7 +67,7 @@ impl SimpleAsyncComponent for DefaultPathsApp {
set_vexpand: true,
gtk::Label {
set_label: &tr("choose-default-paths"),
set_label: &tr!("choose-default-paths"),
add_css_class: "title-1"
}
},
@ -81,7 +80,7 @@ impl SimpleAsyncComponent for DefaultPathsApp {
set_sensitive: !model.show_progress,
adw::ActionRow {
set_title: &tr("launcher-folder"),
set_title: &tr!("launcher-folder"),
set_icon_name: Some("folder-symbolic"),
set_activatable: true,
@ -97,8 +96,8 @@ impl SimpleAsyncComponent for DefaultPathsApp {
set_vexpand: true,
adw::ActionRow {
set_title: &tr("show-all-folders"),
set_subtitle: &tr("show-all-folders-subtitle"),
set_title: &tr!("show-all-folders"),
set_subtitle: &tr!("show-all-folders-subtitle"),
add_suffix = &gtk::Switch {
set_valign: gtk::Align::Center,
@ -119,7 +118,7 @@ impl SimpleAsyncComponent for DefaultPathsApp {
set_sensitive: !model.show_progress,
adw::ActionRow {
set_title: &tr("runners-folder"),
set_title: &tr!("runners-folder"),
set_icon_name: Some("folder-symbolic"),
set_activatable: true,
@ -130,7 +129,7 @@ impl SimpleAsyncComponent for DefaultPathsApp {
},
adw::ActionRow {
set_title: &tr("dxvks-folder"),
set_title: &tr!("dxvks-folder"),
set_icon_name: Some("folder-symbolic"),
set_activatable: true,
@ -141,7 +140,7 @@ impl SimpleAsyncComponent for DefaultPathsApp {
},
adw::ActionRow {
set_title: &tr("wine-prefix-folder"),
set_title: &tr!("wine-prefix-folder"),
set_icon_name: Some("folder-symbolic"),
set_activatable: true,
@ -152,7 +151,7 @@ impl SimpleAsyncComponent for DefaultPathsApp {
},
adw::ActionRow {
set_title: &tr("global-game-installation-folder"),
set_title: &tr!("global-game-installation-folder"),
set_icon_name: Some("folder-symbolic"),
set_activatable: true,
@ -163,7 +162,7 @@ impl SimpleAsyncComponent for DefaultPathsApp {
},
adw::ActionRow {
set_title: &tr("chinese-game-installation-folder"),
set_title: &tr!("chinese-game-installation-folder"),
set_icon_name: Some("folder-symbolic"),
set_activatable: true,
@ -174,7 +173,7 @@ impl SimpleAsyncComponent for DefaultPathsApp {
},
adw::ActionRow {
set_title: &tr("fps-unlocker-folder"),
set_title: &tr!("fps-unlocker-folder"),
set_icon_name: Some("folder-symbolic"),
set_activatable: true,
@ -185,7 +184,7 @@ impl SimpleAsyncComponent for DefaultPathsApp {
},
adw::ActionRow {
set_title: &tr("components-index"),
set_title: &tr!("components-index"),
set_icon_name: Some("folder-symbolic"),
set_activatable: true,
@ -196,7 +195,7 @@ impl SimpleAsyncComponent for DefaultPathsApp {
},
adw::ActionRow {
set_title: &tr("patch-folder"),
set_title: &tr!("patch-folder"),
set_icon_name: Some("folder-symbolic"),
set_activatable: true,
@ -207,7 +206,7 @@ impl SimpleAsyncComponent for DefaultPathsApp {
},
adw::ActionRow {
set_title: &tr("temp-folder"),
set_title: &tr!("temp-folder"),
set_icon_name: Some("folder-symbolic"),
set_activatable: true,
@ -232,9 +231,9 @@ impl SimpleAsyncComponent for DefaultPathsApp {
gtk::Button {
set_label: &if model.migrate_installation {
tr("migrate")
tr!("migrate")
} else {
tr("continue")
tr!("continue")
},
set_css_classes: &["suggested-action", "pill"],
@ -244,9 +243,9 @@ impl SimpleAsyncComponent for DefaultPathsApp {
gtk::Button {
set_label: &if model.migrate_installation {
tr("close")
tr!("close")
} else {
tr("exit")
tr!("exit")
},
add_css_class: "pill",
@ -407,7 +406,7 @@ impl SimpleAsyncComponent for DefaultPathsApp {
Err(err) => {
sender.output(Self::Output::Toast {
title: tr("config-update-error"),
title: tr!("config-update-error"),
description: Some(err.to_string())
});
}

View file

@ -5,7 +5,7 @@ use adw::prelude::*;
use anime_launcher_sdk::is_available;
use crate::i18n::*;
use crate::*;
use super::main::FirstRunAppMsg;
@ -36,12 +36,12 @@ impl SimpleAsyncComponent for DependenciesApp {
set_vexpand: true,
gtk::Label {
set_label: &tr("missing-dependencies-title"),
set_label: &tr!("missing-dependencies-title"),
add_css_class: "title-1"
},
gtk::Label {
set_label: &tr("missing-dependencies-message"),
set_label: &tr!("missing-dependencies-message"),
set_justify: gtk::Justification::Center,
set_wrap: true,
@ -120,14 +120,14 @@ impl SimpleAsyncComponent for DependenciesApp {
set_spacing: 8,
gtk::Button {
set_label: &tr("check"),
set_label: &tr!("check"),
set_css_classes: &["suggested-action", "pill"],
connect_clicked => DependenciesAppMsg::Continue
},
gtk::Button {
set_label: &tr("exit"),
set_label: &tr!("exit"),
add_css_class: "pill",
connect_clicked => DependenciesAppMsg::Exit
@ -175,7 +175,7 @@ impl SimpleAsyncComponent for DependenciesApp {
for package in packages {
if !is_available(package) {
sender.output(Self::Output::Toast {
title: tr_args("package-not-available", [("package", package.into())]),
title: tr!("package-not-available", [("package", package)]),
description: None
});

View file

@ -17,7 +17,6 @@ use anime_launcher_sdk::genshin::config::Config;
use super::main::FirstRunAppMsg;
use crate::ui::components::*;
use crate::i18n::*;
use crate::*;
fn get_installer(uri: &str, temp: Option<PathBuf>) -> anyhow::Result<Installer> {
@ -88,7 +87,7 @@ impl SimpleAsyncComponent for DownloadComponentsApp {
set_vexpand: true,
gtk::Label {
set_label: &tr("download-components"),
set_label: &tr!("download-components"),
add_css_class: "title-1"
}
},
@ -102,7 +101,7 @@ impl SimpleAsyncComponent for DownloadComponentsApp {
#[local_ref]
wine_combo -> adw::ComboRow {
set_title: &tr("wine-version"),
set_title: &tr!("wine-version"),
#[watch]
set_model: Some(&gtk::StringList::new(model.wine_versions.iter()
@ -113,7 +112,7 @@ impl SimpleAsyncComponent for DownloadComponentsApp {
#[local_ref]
dxvk_combo -> adw::ComboRow {
set_title: &tr("dxvk-version"),
set_title: &tr!("dxvk-version"),
#[watch]
set_model: Some(&gtk::StringList::new(model.dxvk_versions.iter()
@ -136,14 +135,14 @@ impl SimpleAsyncComponent for DownloadComponentsApp {
set_spacing: 8,
gtk::Button {
set_label: &tr("download"),
set_label: &tr!("download"),
set_css_classes: &["suggested-action", "pill"],
connect_clicked => DownloadComponentsAppMsg::DownloadWine
},
gtk::Button {
set_label: &tr("exit"),
set_label: &tr!("exit"),
add_css_class: "pill",
connect_clicked => DownloadComponentsAppMsg::Exit
@ -159,7 +158,7 @@ impl SimpleAsyncComponent for DownloadComponentsApp {
set_visible: model.downloading,
adw::ActionRow {
set_title: &tr("download-wine"),
set_title: &tr!("download-wine"),
#[watch]
set_subtitle: &model.downloading_wine_version,
@ -180,7 +179,7 @@ impl SimpleAsyncComponent for DownloadComponentsApp {
},
adw::ActionRow {
set_title: &tr("create-prefix"),
set_title: &tr!("create-prefix"),
#[watch]
set_subtitle: &model.creating_prefix_path,
@ -201,7 +200,7 @@ impl SimpleAsyncComponent for DownloadComponentsApp {
},
adw::ActionRow {
set_title: &tr("download-dxvk"),
set_title: &tr!("download-dxvk"),
#[watch]
set_subtitle: &model.downloading_dxvk_version,
@ -222,7 +221,7 @@ impl SimpleAsyncComponent for DownloadComponentsApp {
},
adw::ActionRow {
set_title: &tr("apply-dxvk"),
set_title: &tr!("apply-dxvk"),
#[watch]
set_icon_name: match model.applying_dxvk {
@ -356,7 +355,7 @@ impl SimpleAsyncComponent for DownloadComponentsApp {
tracing::error!("Failed to update config: {err}");
sender.output(Self::Output::Toast {
title: tr("config-update-error"),
title: tr!("config-update-error"),
description: Some(err.to_string())
});
}
@ -384,7 +383,7 @@ impl SimpleAsyncComponent for DownloadComponentsApp {
tracing::error!("Failed to download wine: {err}");
sender.output(Self::Output::Toast {
title: tr("wine-download-error"),
title: tr!("wine-download-error"),
description: Some(err.to_string())
});
}
@ -393,7 +392,7 @@ impl SimpleAsyncComponent for DownloadComponentsApp {
tracing::error!("Failed to unpack wine: {err}");
sender.output(Self::Output::Toast {
title: tr("wine-unpack-errror"),
title: tr!("wine-unpack-errror"),
description: Some(err.clone())
});
}
@ -408,7 +407,7 @@ impl SimpleAsyncComponent for DownloadComponentsApp {
tracing::error!("Failed to update config: {err}");
sender.output(Self::Output::Toast {
title: tr("config-update-error"),
title: tr!("config-update-error"),
description: Some(err.to_string())
});
}
@ -427,7 +426,7 @@ impl SimpleAsyncComponent for DownloadComponentsApp {
tracing::error!("Failed to initialize wine installer: {err}");
sender.output(Self::Output::Toast {
title: tr("wine-install-failed"),
title: tr!("wine-install-failed"),
description: Some(err.to_string())
});
}
@ -464,7 +463,7 @@ impl SimpleAsyncComponent for DownloadComponentsApp {
tracing::error!("Failed to create prefix: {err}");
sender.output(Self::Output::Toast {
title: tr("wine-prefix-update-failed"),
title: tr!("wine-prefix-update-failed"),
description: Some(err.to_string())
});
}
@ -510,7 +509,7 @@ impl SimpleAsyncComponent for DownloadComponentsApp {
tracing::error!("Failed to download dxvk: {err}");
sender.output(Self::Output::Toast {
title: tr("dxvk-download-error"),
title: tr!("dxvk-download-error"),
description: Some(err.to_string())
});
}
@ -519,7 +518,7 @@ impl SimpleAsyncComponent for DownloadComponentsApp {
tracing::error!("Failed to unpack dxvk: {err}");
sender.output(Self::Output::Toast {
title: tr("dxvk-unpack-error"),
title: tr!("dxvk-unpack-error"),
description: Some(err.clone())
});
}
@ -540,7 +539,7 @@ impl SimpleAsyncComponent for DownloadComponentsApp {
tracing::error!("Failed to initialize dxvk installer: {err}");
sender.output(Self::Output::Toast {
title: tr("dxvk-install-failed"),
title: tr!("dxvk-install-failed"),
description: Some(err.to_string())
});
}
@ -593,7 +592,7 @@ impl SimpleAsyncComponent for DownloadComponentsApp {
tracing::error!("Failed to apply DXVK: {err}");
sender.output(Self::Output::Toast {
title: tr("dxvk-apply-error"),
title: tr!("dxvk-apply-error"),
description: Some(err.to_string())
});
}

View file

@ -3,7 +3,7 @@ use relm4::component::*;
use adw::prelude::*;
use crate::i18n::*;
use crate::*;
use super::main::*;
@ -30,12 +30,12 @@ impl SimpleAsyncComponent for FinishApp {
set_vexpand: true,
gtk::Label {
set_label: &tr("finish-title"),
set_label: &tr!("finish-title"),
add_css_class: "title-1"
},
gtk::Label {
set_label: &tr("finish-message"),
set_label: &tr!("finish-message"),
set_justify: gtk::Justification::Center,
set_wrap: true,
@ -53,14 +53,14 @@ impl SimpleAsyncComponent for FinishApp {
set_spacing: 8,
gtk::Button {
set_label: &tr("restart"),
set_label: &tr!("restart"),
set_css_classes: &["suggested-action", "pill"],
connect_clicked => FinishAppMsg::Restart
},
gtk::Button {
set_label: &tr("exit"),
set_label: &tr!("exit"),
add_css_class: "pill",
connect_clicked => FinishAppMsg::Exit

View file

@ -6,7 +6,6 @@ use adw::prelude::*;
use anime_launcher_sdk::components::loader::ComponentsLoader;
use crate::i18n::tr;
use crate::*;
use super::welcome::*;
@ -77,7 +76,7 @@ impl SimpleComponent for FirstRunApp {
},
adw::StatusPage {
set_title: &tr("loading-data"),
set_title: &tr!("loading-data"),
set_icon_name: Some(APP_ID),
set_vexpand: true,
@ -164,7 +163,7 @@ impl SimpleComponent for FirstRunApp {
carousel,
loading: None,
title: tr("welcome")
title: tr!("welcome")
};
let toast_overlay = &model.toast_overlay;
@ -192,32 +191,32 @@ impl SimpleComponent for FirstRunApp {
}
FirstRunAppMsg::ScrollToTosWarning => {
self.title = tr("tos-violation-warning");
self.title = tr!("tos-violation-warning");
self.carousel.scroll_to(self.tos_warning.widget(), true);
}
FirstRunAppMsg::ScrollToDependencies => {
self.title = tr("dependencies");
self.title = tr!("dependencies");
self.carousel.scroll_to(self.dependencies.widget(), true);
}
FirstRunAppMsg::ScrollToDefaultPaths => {
self.title = tr("default-paths");
self.title = tr!("default-paths");
self.carousel.scroll_to(self.default_paths.widget(), true);
}
FirstRunAppMsg::ScrollToSelectVoiceovers => {
self.title = tr("select-voice-packages");
self.title = tr!("select-voice-packages");
self.carousel.scroll_to(self.select_voiceovers.widget(), true);
}
FirstRunAppMsg::ScrollToDownloadComponents => {
// Update components index
sender.input(FirstRunAppMsg::SetLoadingStatus(Some(Some(tr("updating-components-index")))));
sender.input(FirstRunAppMsg::SetLoadingStatus(Some(Some(tr!("updating-components-index")))));
let config = Config::get().unwrap_or_else(|_| CONFIG.clone());
@ -238,7 +237,7 @@ impl SimpleComponent for FirstRunApp {
tracing::error!("Failed to sync components index");
sender.input(FirstRunAppMsg::Toast {
title: tr("components-index-sync-failed"),
title: tr!("components-index-sync-failed"),
description: Some(err.to_string())
});
}
@ -250,7 +249,7 @@ impl SimpleComponent for FirstRunApp {
tracing::error!("Failed to verify that components index synced");
sender.input(FirstRunAppMsg::Toast {
title: tr("components-index-verify-failed"),
title: tr!("components-index-verify-failed"),
description: Some(err.to_string())
});
}
@ -265,13 +264,13 @@ impl SimpleComponent for FirstRunApp {
// Scroll to download components page
// This will happen in background behind StatusPage
self.title = tr("download-components");
self.title = tr!("download-components");
self.carousel.scroll_to(self.download_components.widget(), true);
}
FirstRunAppMsg::ScrollToFinish => {
self.title = tr("finish");
self.title = tr!("finish");
self.carousel.scroll_to(self.finish.widget(), true);
}
@ -282,12 +281,12 @@ impl SimpleComponent for FirstRunApp {
toast.set_timeout(4);
if let Some(description) = description {
toast.set_button_label(Some(&tr("details")));
toast.set_button_label(Some(&tr!("details")));
let dialog = adw::MessageDialog::new(MAIN_WINDOW.as_ref(), Some(&title), Some(&description));
dialog.add_response("close", &tr("close"));
dialog.add_response("save", &tr("save"));
dialog.add_response("close", &tr!("close"));
dialog.add_response("save", &tr!("save"));
dialog.set_response_appearance("save", adw::ResponseAppearance::Suggested);

View file

@ -6,7 +6,7 @@ use adw::prelude::*;
use anime_launcher_sdk::config::ConfigExt;
use anime_launcher_sdk::genshin::config::Config;
use crate::i18n::*;
use crate::*;
use super::main::*;
@ -38,7 +38,7 @@ impl SimpleAsyncComponent for SelectVoiceoversApp {
set_vexpand: true,
gtk::Label {
set_label: &tr("select-voice-packages"),
set_label: &tr!("select-voice-packages"),
add_css_class: "title-1"
}
},
@ -48,7 +48,7 @@ impl SimpleAsyncComponent for SelectVoiceoversApp {
set_vexpand: true,
adw::ActionRow {
set_title: &tr("english"),
set_title: &tr!("english"),
#[local_ref]
add_suffix = english -> gtk::Switch {
@ -58,7 +58,7 @@ impl SimpleAsyncComponent for SelectVoiceoversApp {
},
adw::ActionRow {
set_title: &tr("japanese"),
set_title: &tr!("japanese"),
#[local_ref]
add_suffix = japanese -> gtk::Switch {
@ -67,7 +67,7 @@ impl SimpleAsyncComponent for SelectVoiceoversApp {
},
adw::ActionRow {
set_title: &tr("korean"),
set_title: &tr!("korean"),
#[local_ref]
add_suffix = korean -> gtk::Switch {
@ -76,7 +76,7 @@ impl SimpleAsyncComponent for SelectVoiceoversApp {
},
adw::ActionRow {
set_title: &tr("chinese"),
set_title: &tr!("chinese"),
#[local_ref]
add_suffix = chinese -> gtk::Switch {
@ -95,14 +95,14 @@ impl SimpleAsyncComponent for SelectVoiceoversApp {
set_spacing: 8,
gtk::Button {
set_label: &tr("continue"),
set_label: &tr!("continue"),
set_css_classes: &["suggested-action", "pill"],
connect_clicked => SelectVoiceoversAppMsg::Continue
},
gtk::Button {
set_label: &tr("exit"),
set_label: &tr!("exit"),
add_css_class: "pill",
connect_clicked => SelectVoiceoversAppMsg::Exit
@ -142,7 +142,7 @@ impl SimpleAsyncComponent for SelectVoiceoversApp {
Ok(_) => sender.output(Self::Output::ScrollToDownloadComponents),
Err(err) => sender.output(Self::Output::Toast {
title: tr("config-update-error"),
title: tr!("config-update-error"),
description: Some(err.to_string())
})
};

View file

@ -5,7 +5,7 @@ use adw::prelude::*;
use anime_launcher_sdk::is_available;
use crate::i18n::*;
use crate::*;
use super::main::FirstRunAppMsg;
@ -34,14 +34,14 @@ impl SimpleAsyncComponent for TosWarningApp {
set_vexpand: true,
gtk::Label {
set_label: &tr("tos-violation-warning"),
set_label: &tr!("tos-violation-warning"),
add_css_class: "title-1"
}
},
add = &adw::PreferencesGroup {
gtk::Label {
set_label: &tr("tos-violation-warning-message"),
set_label: &tr!("tos-violation-warning-message"),
set_wrap: true,
set_selectable: true
}
@ -57,14 +57,14 @@ impl SimpleAsyncComponent for TosWarningApp {
set_spacing: 8,
gtk::Button {
set_label: &tr("continue"),
set_label: &tr!("continue"),
set_css_classes: &["suggested-action", "pill"],
connect_clicked => TosWarningAppMsg::Continue
},
gtk::Button {
set_label: &tr("exit"),
set_label: &tr!("exit"),
add_css_class: "pill",
connect_clicked => TosWarningAppMsg::Exit
@ -91,13 +91,13 @@ impl SimpleAsyncComponent for TosWarningApp {
TosWarningAppMsg::Continue => {
let dialog = adw::MessageDialog::new(
unsafe { MAIN_WINDOW.as_ref() },
Some(&tr("tos-dialog-title")),
Some(&tr("tos-dialog-message"))
Some(&tr!("tos-dialog-title")),
Some(&tr!("tos-dialog-message"))
);
dialog.add_responses(&[
("exit", &tr("exit")),
("continue", &tr("agree"))
("exit", &tr!("exit")),
("continue", &tr!("agree"))
]);
dialog.connect_response(None, move |_, response| {

View file

@ -3,7 +3,7 @@ use relm4::component::*;
use adw::prelude::*;
use crate::i18n::*;
use crate::*;
use super::main::FirstRunAppMsg;
@ -40,7 +40,7 @@ impl SimpleAsyncComponent for WelcomeApp {
},
gtk::Label {
set_label: &tr("welcome-page-message"),
set_label: &tr!("welcome-page-message"),
set_justify: gtk::Justification::Center,
set_wrap: true,
@ -58,7 +58,7 @@ impl SimpleAsyncComponent for WelcomeApp {
set_spacing: 8,
gtk::Button {
set_label: &tr("continue"),
set_label: &tr!("continue"),
set_css_classes: &["suggested-action", "pill"],
connect_clicked => WelcomeAppMsg::Continue

View file

@ -1,7 +1,6 @@
use relm4::prelude::*;
use crate::*;
use crate::i18n::*;
use super::{App, AppMsg};
@ -22,7 +21,7 @@ pub fn apply_patch(sender: ComponentSender<App>, patch: PlayerPatch, rename_mhyp
tracing::error!("Failed to patch the game");
sender.input(AppMsg::Toast {
title: tr("game-patching-error"),
title: tr!("game-patching-error"),
description: Some(err.to_string())
});
}
@ -38,7 +37,7 @@ pub fn apply_patch(sender: ComponentSender<App>, patch: PlayerPatch, rename_mhyp
tracing::error!("Failed to rename mhypbase file");
sender.input(AppMsg::Toast {
title: tr("game-patching-error"),
title: tr!("game-patching-error"),
description: Some(err.to_string())
});
}

View file

@ -5,7 +5,7 @@ use anime_launcher_sdk::wincompatlib::prelude::*;
use anime_launcher_sdk::config::ConfigExt;
use anime_launcher_sdk::genshin::config::Config;
use crate::i18n::*;
use crate::*;
use super::{App, AppMsg};
@ -27,7 +27,7 @@ pub fn create_prefix(sender: ComponentSender<App>) {
tracing::error!("Failed to create wine prefix");
sender.input(AppMsg::Toast {
title: tr("wine-prefix-update-failed"),
title: tr!("wine-prefix-update-failed"),
description: Some(err.to_string())
});
}
@ -44,7 +44,7 @@ pub fn create_prefix(sender: ComponentSender<App>) {
tracing::error!("Failed to get selected wine executable");
sender.input(AppMsg::Toast {
title: tr("failed-get-selected-wine"),
title: tr!("failed-get-selected-wine"),
description: None
});
}
@ -53,7 +53,7 @@ pub fn create_prefix(sender: ComponentSender<App>) {
tracing::error!("Failed to get selected wine executable: {err}");
sender.input(AppMsg::Toast {
title: tr("failed-get-selected-wine"),
title: tr!("failed-get-selected-wine"),
description: Some(err.to_string())
});
}

View file

@ -3,7 +3,6 @@ use std::process::Command;
use relm4::prelude::*;
use crate::*;
use crate::i18n::*;
use super::{App, AppMsg};
@ -40,7 +39,7 @@ pub fn disable_telemetry(sender: ComponentSender<App>) {
tracing::error!("Failed to update /etc/hosts file");
sender.input(AppMsg::Toast {
title: tr("telemetry-servers-disabling-error"),
title: tr!("telemetry-servers-disabling-error"),
description: None // stdout/err is empty
});
}
@ -49,7 +48,7 @@ pub fn disable_telemetry(sender: ComponentSender<App>) {
tracing::error!("Failed to update /etc/hosts file");
sender.input(AppMsg::Toast {
title: tr("telemetry-servers-disabling-error"),
title: tr!("telemetry-servers-disabling-error"),
description: Some(err.to_string())
});
}

View file

@ -6,7 +6,6 @@ use relm4::{
use gtk::glib::clone;
use crate::*;
use crate::i18n::*;
use crate::ui::components::*;
use super::{App, AppMsg};
@ -28,7 +27,7 @@ pub fn download_diff(sender: ComponentSender<App>, progress_bar_input: Sender<Pr
tracing::error!("Downloading failed: {err}");
sender.input(AppMsg::Toast {
title: tr("downloading-failed"),
title: tr!("downloading-failed"),
description: Some(err.to_string())
});
}
@ -37,7 +36,7 @@ pub fn download_diff(sender: ComponentSender<App>, progress_bar_input: Sender<Pr
tracing::error!("Unpacking failed: {err}");
sender.input(AppMsg::Toast {
title: tr("unpacking-failed"),
title: tr!("unpacking-failed"),
description: Some(err.clone())
});
}
@ -56,7 +55,7 @@ pub fn download_diff(sender: ComponentSender<App>, progress_bar_input: Sender<Pr
tracing::error!("Downloading failed: {err}");
sender.input(AppMsg::Toast {
title: tr("downloading-failed"),
title: tr!("downloading-failed"),
description: Some(err.to_string())
});

View file

@ -8,7 +8,6 @@ use gtk::glib::clone;
use anime_launcher_sdk::components::wine;
use crate::*;
use crate::i18n::*;
use crate::ui::components::*;
use super::{App, AppMsg};
@ -60,7 +59,7 @@ pub fn download_wine(sender: ComponentSender<App>, progress_bar_input: Sender<Pr
tracing::error!("Downloading failed: {err}");
sender.input(AppMsg::Toast {
title: tr("downloading-failed"),
title: tr!("downloading-failed"),
description: Some(err.to_string())
});
}
@ -69,7 +68,7 @@ pub fn download_wine(sender: ComponentSender<App>, progress_bar_input: Sender<Pr
tracing::error!("Unpacking failed: {err}");
sender.input(AppMsg::Toast {
title: tr("unpacking-failed"),
title: tr!("unpacking-failed"),
description: Some(err.clone())
});
}
@ -95,7 +94,7 @@ pub fn download_wine(sender: ComponentSender<App>, progress_bar_input: Sender<Pr
}
Err(err) => sender.input(AppMsg::Toast {
title: tr("wine-install-failed"),
title: tr!("wine-install-failed"),
description: Some(err.to_string())
})
}
@ -103,7 +102,7 @@ pub fn download_wine(sender: ComponentSender<App>, progress_bar_input: Sender<Pr
}
Err(err) => sender.input(AppMsg::Toast {
title: tr("downloaded-wine-list-failed"),
title: tr!("downloaded-wine-list-failed"),
description: Some(err.to_string())
})
}

View file

@ -4,7 +4,6 @@ use gtk::prelude::*;
use anime_launcher_sdk::genshin::config::schema::prelude::LauncherBehavior;
use crate::*;
use crate::i18n::*;
use super::{App, AppMsg};
@ -24,7 +23,7 @@ pub fn launch(sender: ComponentSender<App>) {
tracing::error!("Failed to launch game: {err}");
sender.input(AppMsg::Toast {
title: tr("game-launching-failed"),
title: tr!("game-launching-failed"),
description: Some(err.to_string())
});
}

View file

@ -30,7 +30,6 @@ use anime_launcher_sdk::genshin::states::*;
use anime_launcher_sdk::genshin::consts::*;
use crate::*;
use crate::i18n::*;
use crate::ui::components::*;
use super::preferences::main::*;
@ -115,18 +114,18 @@ impl SimpleComponent for App {
menu! {
main_menu: {
section! {
&tr("launcher-folder") => LauncherFolder,
&tr("game-folder") => GameFolder,
&tr("config-file") => ConfigFile,
&tr("debug-file") => DebugFile,
&tr!("launcher-folder") => LauncherFolder,
&tr!("game-folder") => GameFolder,
&tr!("config-file") => ConfigFile,
&tr!("debug-file") => DebugFile,
},
section! {
&tr("wish-url") => WishUrl
&tr!("wish-url") => WishUrl
},
section! {
&tr("about") => About
&tr!("about") => About
}
}
}
@ -195,7 +194,7 @@ impl SimpleComponent for App {
},
adw::StatusPage {
set_title: &tr("loading-data"),
set_title: &tr!("loading-data"),
set_icon_name: Some(APP_ID),
set_vexpand: true,
@ -302,11 +301,11 @@ impl SimpleComponent for App {
set_width_request: 44,
#[watch]
set_tooltip_text: Some(&tr_args("predownload-update", [
set_tooltip_text: Some(&tr!("predownload-update", [
("version", match model.state.as_ref() {
Some(LauncherState::PredownloadAvailable { game, .. }) => game.latest().to_string(),
_ => String::from("?")
}.into()),
}),
("size", match model.state.as_ref() {
Some(LauncherState::PredownloadAvailable { game, voices }) => {
@ -320,7 +319,7 @@ impl SimpleComponent for App {
}
_ => String::from("?")
}.into())
})
])),
#[watch]
@ -431,15 +430,15 @@ impl SimpleComponent for App {
#[watch]
set_label: &match &model.state {
Some(LauncherState::Launch) |
Some(LauncherState::PredownloadAvailable { .. }) => tr("launch"),
Some(LauncherState::PredownloadAvailable { .. }) => tr!("launch"),
Some(LauncherState::FolderMigrationRequired { .. }) => tr("migrate-folders"),
Some(LauncherState::PlayerPatchAvailable { .. }) => tr("apply-patch"),
Some(LauncherState::FolderMigrationRequired { .. }) => tr!("migrate-folders"),
Some(LauncherState::PlayerPatchAvailable { .. }) => tr!("apply-patch"),
Some(LauncherState::TelemetryNotDisabled) => tr("disable-telemetry"),
Some(LauncherState::TelemetryNotDisabled) => tr!("disable-telemetry"),
Some(LauncherState::WineNotInstalled) => tr("download-wine"),
Some(LauncherState::PrefixNotExists) => tr("create-prefix"),
Some(LauncherState::WineNotInstalled) => tr!("download-wine"),
Some(LauncherState::PrefixNotExists) => tr!("create-prefix"),
Some(LauncherState::GameUpdateAvailable(diff)) |
Some(LauncherState::GameOutdated(diff)) |
@ -450,20 +449,20 @@ impl SimpleComponent for App {
let temp = config.launcher.temp.unwrap_or_else(std::env::temp_dir);
if temp.join(filename).exists() {
tr("resume")
tr!("resume")
}
else {
tr("update")
tr!("update")
}
}
_ => tr("update")
_ => tr!("update")
}
},
Some(LauncherState::GameNotInstalled(_)) |
Some(LauncherState::VoiceNotInstalled(_)) => tr("download"),
Some(LauncherState::VoiceNotInstalled(_)) => tr!("download"),
None => String::from("...")
}
@ -510,15 +509,15 @@ impl SimpleComponent for App {
#[watch]
set_tooltip_text: Some(&match &model.state {
Some(LauncherState::GameOutdated { .. }) |
Some(LauncherState::VoiceOutdated(_)) => tr("main-window--version-outdated-tooltip"),
Some(LauncherState::VoiceOutdated(_)) => tr!("main-window--version-outdated-tooltip"),
Some(LauncherState::FolderMigrationRequired { .. }) => tr("migrate-folders-tooltip"),
Some(LauncherState::FolderMigrationRequired { .. }) => tr!("migrate-folders-tooltip"),
Some(LauncherState::PlayerPatchAvailable { patch: PlayerPatch { status, .. }, .. }) => match status {
PatchStatus::NotAvailable => tr("main-window--patch-unavailable-tooltip"),
PatchStatus::NotAvailable => tr!("main-window--patch-unavailable-tooltip"),
PatchStatus::Outdated { .. } |
PatchStatus::Preparation { .. } => tr("main-window--patch-outdated-tooltip"),
PatchStatus::Preparation { .. } => tr!("main-window--patch-outdated-tooltip"),
_ => String::new()
},
@ -557,7 +556,7 @@ impl SimpleComponent for App {
connect_close_request[sender] => move |_| {
if let Err(err) = Config::flush() {
sender.input(AppMsg::Toast {
title: tr("config-update-error"),
title: tr!("config-update-error"),
description: Some(err.to_string())
});
}
@ -623,7 +622,7 @@ impl SimpleComponent for App {
group.add_action::<LauncherFolder>(RelmAction::new_stateless(clone!(@strong sender => move |_| {
if let Err(err) = open::that(LAUNCHER_FOLDER.as_path()) {
sender.input(AppMsg::Toast {
title: tr("launcher-folder-opening-error"),
title: tr!("launcher-folder-opening-error"),
description: Some(err.to_string())
});
@ -639,7 +638,7 @@ impl SimpleComponent for App {
if let Err(err) = open::that(path) {
sender.input(AppMsg::Toast {
title: tr("game-folder-opening-error"),
title: tr!("game-folder-opening-error"),
description: Some(err.to_string())
});
@ -651,7 +650,7 @@ impl SimpleComponent for App {
if let Ok(file) = config_file() {
if let Err(err) = open::that(file) {
sender.input(AppMsg::Toast {
title: tr("config-file-opening-error"),
title: tr!("config-file-opening-error"),
description: Some(err.to_string())
});
@ -663,7 +662,7 @@ impl SimpleComponent for App {
group.add_action::<DebugFile>(RelmAction::new_stateless(clone!(@strong sender => move |_| {
if let Err(err) = open::that(crate::DEBUG_FILE.as_os_str()) {
sender.input(AppMsg::Toast {
title: tr("debug-file-opening-error"),
title: tr!("debug-file-opening-error"),
description: Some(err.to_string())
});
@ -711,7 +710,7 @@ impl SimpleComponent for App {
tracing::error!("Failed to open wishes URL: {err}");
sender.input(AppMsg::Toast {
title: tr("wish-url-opening-error"),
title: tr!("wish-url-opening-error"),
description: Some(err.to_string())
});
}
@ -721,7 +720,7 @@ impl SimpleComponent for App {
tracing::error!("Couldn't find wishes URL: no url found");
sender.input(AppMsg::Toast {
title: tr("wish-url-search-failed"),
title: tr!("wish-url-search-failed"),
description: None
});
}
@ -731,7 +730,7 @@ impl SimpleComponent for App {
tracing::error!("Couldn't find wishes URL: failed to open cache file: {err}");
sender.input(AppMsg::Toast {
title: tr("wish-url-search-failed"),
title: tr!("wish-url-search-failed"),
description: Some(err.to_string())
});
}
@ -742,7 +741,7 @@ impl SimpleComponent for App {
tracing::error!("Couldn't find wishes URL: cache file doesn't exist");
sender.input(AppMsg::Toast {
title: tr("wish-url-search-failed"),
title: tr!("wish-url-search-failed"),
description: None
});
}
@ -773,7 +772,7 @@ impl SimpleComponent for App {
tracing::error!("Failed to download background picture: {err}");
sender.input(AppMsg::Toast {
title: tr("background-downloading-failed"),
title: tr!("background-downloading-failed"),
description: Some(err.to_string())
});
}
@ -793,7 +792,7 @@ impl SimpleComponent for App {
match components.sync(host) {
Ok(changes) => {
sender.input(AppMsg::Toast {
title: tr("components-index-updated"),
title: tr!("components-index-updated"),
description: if changes.is_empty() {
None
} else {
@ -811,7 +810,7 @@ impl SimpleComponent for App {
tracing::error!("Failed to sync components index");
sender.input(AppMsg::Toast {
title: tr("components-index-sync-failed"),
title: tr!("components-index-sync-failed"),
description: Some(err.to_string())
});
}
@ -823,7 +822,7 @@ impl SimpleComponent for App {
tracing::error!("Failed to verify that components index synced");
sender.input(AppMsg::Toast {
title: tr("components-index-verify-failed"),
title: tr!("components-index-verify-failed"),
description: Some(err.to_string())
});
}
@ -848,7 +847,7 @@ impl SimpleComponent for App {
tracing::error!("Failed to sync patch folder with remote: {server}: {err}");
sender.input(AppMsg::Toast {
title: tr("patch-sync-failed"),
title: tr!("patch-sync-failed"),
description: Some(err.to_string())
});
}
@ -860,7 +859,7 @@ impl SimpleComponent for App {
tracing::error!("Failed to compare local patch folder with remote: {err}");
sender.input(AppMsg::Toast {
title: tr("patch-state-check-failed"),
title: tr!("patch-state-check-failed"),
description: Some(err.to_string())
});
}
@ -874,7 +873,7 @@ impl SimpleComponent for App {
tracing::error!("Failed to fetch player patch info: {err}");
sender.input(AppMsg::Toast {
title: tr("patch-info-fetching-error"),
title: tr!("patch-info-fetching-error"),
description: Some(err.to_string())
});
@ -894,7 +893,7 @@ impl SimpleComponent for App {
tracing::error!("Failed to find game diff: {err}");
sender.input(AppMsg::Toast {
title: tr("game-diff-finding-error"),
title: tr!("game-diff-finding-error"),
description: Some(err.to_string())
});
@ -932,7 +931,7 @@ impl SimpleComponent for App {
// TODO: make function from this message like with toast
AppMsg::UpdateLauncherState { perform_on_download_needed, show_status_page } => {
if show_status_page {
sender.input(AppMsg::SetLoadingStatus(Some(Some(tr("loading-launcher-state")))));
sender.input(AppMsg::SetLoadingStatus(Some(Some(tr!("loading-launcher-state")))));
} else {
self.disabled_buttons = true;
}
@ -941,17 +940,17 @@ impl SimpleComponent for App {
if show_status_page {
match state {
StateUpdating::Game => {
sender.input(AppMsg::SetLoadingStatus(Some(Some(tr("loading-launcher-state--game")))));
sender.input(AppMsg::SetLoadingStatus(Some(Some(tr!("loading-launcher-state--game")))));
}
StateUpdating::Voice(locale) => {
sender.input(AppMsg::SetLoadingStatus(Some(Some(tr_args("loading-launcher-state--voice", [
("locale", locale.to_name().to_owned().into())
sender.input(AppMsg::SetLoadingStatus(Some(Some(tr!("loading-launcher-state--voice", [
("locale", locale.to_name())
])))));
}
StateUpdating::Patch => {
sender.input(AppMsg::SetLoadingStatus(Some(Some(tr("loading-launcher-state--patch")))));
sender.input(AppMsg::SetLoadingStatus(Some(Some(tr!("loading-launcher-state--patch")))));
}
}
}
@ -962,7 +961,7 @@ impl SimpleComponent for App {
Err(err) => {
tracing::error!("Failed to update launcher state: {err}");
self.toast(tr("launcher-state-updating-error"), Some(err.to_string()));
self.toast(tr!("launcher-state-updating-error"), Some(err.to_string()));
None
}
@ -1035,7 +1034,7 @@ impl SimpleComponent for App {
let progress_bar_input = self.progress_bar.sender().clone();
progress_bar_input.send(ProgressBarMsg::UpdateCaption(Some(tr("downloading"))));
progress_bar_input.send(ProgressBarMsg::UpdateCaption(Some(tr!("downloading"))));
let mut diffs: Vec<VersionDiff> = vec![game];
@ -1049,7 +1048,7 @@ impl SimpleComponent for App {
if let Err(err) = result {
sender.input(AppMsg::Toast {
title: tr("downloading-failed"),
title: tr!("downloading-failed"),
description: Some(err.to_string())
});
@ -1116,7 +1115,7 @@ impl App {
toast.set_timeout(4);
if let Some(description) = description {
toast.set_button_label(Some(&tr("details")));
toast.set_button_label(Some(&tr!("details")));
let dialog = adw::MessageDialog::new(
Some(unsafe { MAIN_WINDOW.as_ref().unwrap_unchecked() }),
@ -1124,8 +1123,8 @@ impl App {
Some(description.as_ref())
);
dialog.add_response("close", &tr("close"));
dialog.add_response("save", &tr("save"));
dialog.add_response("close", &tr!("close"));
dialog.add_response("save", &tr!("save"));
dialog.set_response_appearance("save", adw::ResponseAppearance::Suggested);

View file

@ -8,7 +8,6 @@ use relm4::{
use gtk::glib::clone;
use crate::*;
use crate::i18n::*;
use crate::ui::components::*;
use super::{App, AppMsg};
@ -17,7 +16,7 @@ use super::{App, AppMsg};
pub fn repair_game(sender: ComponentSender<App>, progress_bar_input: Sender<ProgressBarMsg>) {
let config = Config::get().unwrap();
progress_bar_input.send(ProgressBarMsg::UpdateCaption(Some(tr("verifying-files"))));
progress_bar_input.send(ProgressBarMsg::UpdateCaption(Some(tr!("verifying-files"))));
sender.input(AppMsg::SetDownloading(true));
std::thread::spawn(move || {
@ -100,7 +99,7 @@ pub fn repair_game(sender: ComponentSender<App>, progress_bar_input: Sender<Prog
if !broken.is_empty() {
let total = broken.len() as u64;
progress_bar_input.send(ProgressBarMsg::UpdateCaption(Some(tr("repairing-files"))));
progress_bar_input.send(ProgressBarMsg::UpdateCaption(Some(tr!("repairing-files"))));
progress_bar_input.send(ProgressBarMsg::DisplayFraction(false));
progress_bar_input.send(ProgressBarMsg::UpdateProgress(0, total));
@ -149,7 +148,7 @@ pub fn repair_game(sender: ComponentSender<App>, progress_bar_input: Sender<Prog
if let Err(err) = file.repair(&game_path) {
sender.input(AppMsg::Toast {
title: tr("game-file-repairing-error"),
title: tr!("game-file-repairing-error"),
description: Some(err.to_string())
});
@ -172,7 +171,7 @@ pub fn repair_game(sender: ComponentSender<App>, progress_bar_input: Sender<Prog
tracing::error!("Failed to get inregrity failes: {err}");
sender.input(AppMsg::Toast {
title: tr("integrity-files-getting-error"),
title: tr!("integrity-files-getting-error"),
description: Some(err.to_string())
});
}

View file

@ -3,7 +3,8 @@ use relm4::component::*;
use gtk::prelude::*;
use crate::i18n::*;
use crate::tr;
use super::first_run::default_paths::DefaultPathsApp;
pub struct MigrateInstallationApp {
@ -23,7 +24,7 @@ impl SimpleComponent for MigrateInstallationApp {
set_hide_on_close: true,
#[watch]
set_title: Some(&tr("migrate-installation")),
set_title: Some(&tr!("migrate-installation")),
gtk::Box {
set_orientation: gtk::Orientation::Vertical,

View file

@ -4,11 +4,10 @@ use relm4::factory::*;
use adw::prelude::*;
use super::EnhancementsAppMsg;
use crate::i18n::tr;
use crate::*;
use super::EnhancementsAppMsg;
#[derive(Debug)]
struct Variable {
key: String,
@ -83,7 +82,7 @@ impl SimpleAsyncComponent for EnvironmentPage {
adw::HeaderBar {
#[wrap(Some)]
set_title_widget = &adw::WindowTitle {
set_title: &tr("environment")
set_title: &tr!("environment")
},
pack_start = &gtk::Button {
@ -96,12 +95,12 @@ impl SimpleAsyncComponent for EnvironmentPage {
},
adw::PreferencesPage {
set_title: &tr("environment"),
set_title: &tr!("environment"),
set_icon_name: Some("document-properties-symbolic"),
add = &adw::PreferencesGroup {
set_title: &tr("game-command"),
set_description: Some(&tr("game-command-description")),
set_title: &tr!("game-command"),
set_description: Some(&tr!("game-command-description")),
adw::EntryRow {
set_title: "%command%",
@ -124,7 +123,7 @@ impl SimpleAsyncComponent for EnvironmentPage {
},
add = &adw::PreferencesGroup {
set_title: &tr("new-variable"),
set_title: &tr!("new-variable"),
#[wrap(Some)]
set_header_suffix = &gtk::Button {
@ -134,7 +133,7 @@ impl SimpleAsyncComponent for EnvironmentPage {
adw::ButtonContent {
set_icon_name: "list-add-symbolic",
set_label: &tr("add")
set_label: &tr!("add")
},
connect_clicked => EnvironmentPageMsg::Add
@ -142,12 +141,12 @@ impl SimpleAsyncComponent for EnvironmentPage {
#[local_ref]
name_entry -> adw::EntryRow {
set_title: &tr("name")
set_title: &tr!("name")
},
#[local_ref]
value_entry -> adw::EntryRow {
set_title: &tr("value")
set_title: &tr!("value")
}
},

View file

@ -7,11 +7,10 @@ use adw::prelude::*;
use anime_launcher_sdk::sessions::SessionsExt;
use anime_launcher_sdk::genshin::sessions::Sessions;
use super::EnhancementsAppMsg;
use crate::i18n::tr;
use crate::*;
use super::EnhancementsAppMsg;
#[derive(Debug)]
struct GameSession {
name: String,
@ -44,7 +43,7 @@ impl AsyncFactoryComponent for GameSession {
set_icon_name: "view-refresh-symbolic",
add_css_class: "flat",
set_tooltip_text: Some(&tr("update-session")),
set_tooltip_text: Some(&tr!("update-session")),
set_valign: gtk::Align::Center,
@ -57,7 +56,7 @@ impl AsyncFactoryComponent for GameSession {
set_icon_name: "user-trash-symbolic",
add_css_class: "flat",
set_tooltip_text: Some(&tr("delete-session")),
set_tooltip_text: Some(&tr!("delete-session")),
set_valign: gtk::Align::Center,
@ -115,7 +114,7 @@ impl SimpleAsyncComponent for GamePage {
adw::HeaderBar {
#[wrap(Some)]
set_title_widget = &adw::WindowTitle {
set_title: &tr("game")
set_title: &tr!("game")
},
pack_start = &gtk::Button {
@ -128,15 +127,15 @@ impl SimpleAsyncComponent for GamePage {
},
adw::PreferencesPage {
set_title: &tr("game"),
set_title: &tr!("game"),
set_icon_name: Some("applications-games-symbolic"),
add = &adw::PreferencesGroup {
set_title: &tr("game-sessions"),
set_title: &tr!("game-sessions"),
#[local_ref]
session_name_entry -> adw::EntryRow {
set_title: &tr("name"),
set_title: &tr!("name"),
add_suffix = &gtk::Button {
set_icon_name: "list-add-symbolic",
@ -220,7 +219,7 @@ impl SimpleAsyncComponent for GamePage {
Err(err) => {
sender.output(EnhancementsAppMsg::Toast {
title: tr("game-session-add-failed"),
title: tr!("game-session-add-failed"),
description: Some(err.to_string())
}).unwrap();
}
@ -234,7 +233,7 @@ impl SimpleAsyncComponent for GamePage {
if let Ok(config) = Config::get() {
if let Err(err) = Sessions::update(session.name.clone(), config.get_wine_prefix_path()) {
sender.output(EnhancementsAppMsg::Toast {
title: tr("game-session-update-failed"),
title: tr!("game-session-update-failed"),
description: Some(err.to_string())
}).unwrap();
}
@ -246,7 +245,7 @@ impl SimpleAsyncComponent for GamePage {
if let Some(session) = self.sessions.guard().get(index) {
if let Err(err) = Sessions::remove(&session.name) {
sender.output(EnhancementsAppMsg::Toast {
title: tr("game-session-remove-failed"),
title: tr!("game-session-remove-failed"),
description: Some(err.to_string())
}).unwrap();
@ -266,7 +265,7 @@ impl SimpleAsyncComponent for GamePage {
if let Ok(config) = Config::get() {
if let Err(err) = Sessions::set_current(session.name.clone()) {
sender.output(EnhancementsAppMsg::Toast {
title: tr("game-session-set-current-failed"),
title: tr!("game-session-set-current-failed"),
description: Some(err.to_string())
}).unwrap();
@ -276,7 +275,7 @@ impl SimpleAsyncComponent for GamePage {
if let Err(err) = Sessions::apply(session.name.clone(), config.get_wine_prefix_path()) {
sender.output(EnhancementsAppMsg::Toast {
title: tr("game-session-apply-failed"),
title: tr!("game-session-apply-failed"),
description: Some(err.to_string())
}).unwrap();

View file

@ -21,7 +21,6 @@ use game::*;
use sandbox::*;
use environment::*;
use crate::i18n::tr;
use crate::*;
use super::gamescope::*;
@ -123,15 +122,15 @@ impl SimpleAsyncComponent for EnhancementsApp {
view! {
#[root]
adw::PreferencesPage {
set_title: &tr("enhancements"),
set_title: &tr!("enhancements"),
set_icon_name: Some("applications-graphics-symbolic"),
add = &adw::PreferencesGroup {
set_title: &tr("options"),
set_title: &tr!("options"),
adw::ActionRow {
set_title: &tr("game"),
set_subtitle: &tr("game-settings-description"),
set_title: &tr!("game"),
set_subtitle: &tr!("game-settings-description"),
add_suffix = &gtk::Image {
set_icon_name: Some("go-next-symbolic")
@ -143,8 +142,8 @@ impl SimpleAsyncComponent for EnhancementsApp {
},
adw::ActionRow {
set_title: &tr("sandbox"),
set_subtitle: &tr("sandbox-settings-description"),
set_title: &tr!("sandbox"),
set_subtitle: &tr!("sandbox-settings-description"),
add_suffix = &gtk::Image {
set_icon_name: Some("go-next-symbolic")
@ -156,8 +155,8 @@ impl SimpleAsyncComponent for EnhancementsApp {
},
adw::ActionRow {
set_title: &tr("environment"),
set_subtitle: &tr("environment-settings-description"),
set_title: &tr!("environment"),
set_subtitle: &tr!("environment-settings-description"),
add_suffix = &gtk::Image {
set_icon_name: Some("go-next-symbolic")
@ -170,15 +169,15 @@ impl SimpleAsyncComponent for EnhancementsApp {
},
add = &adw::PreferencesGroup {
set_title: &tr("wine"),
set_title: &tr!("wine"),
adw::ComboRow {
set_title: &tr("synchronization"),
set_subtitle: &tr("wine-sync-description"),
set_title: &tr!("synchronization"),
set_subtitle: &tr!("wine-sync-description"),
#[wrap(Some)]
set_model = &gtk::StringList::new(&[
&tr("none"),
&tr!("none"),
"ESync",
"FSync"
]),
@ -197,12 +196,12 @@ impl SimpleAsyncComponent for EnhancementsApp {
},
adw::ComboRow {
set_title: &tr("language"),
set_subtitle: &tr("wine-lang-description"),
set_title: &tr!("language"),
set_subtitle: &tr!("wine-lang-description"),
#[wrap(Some)]
set_model = &gtk::StringList::new(&[
&tr("system"),
&tr!("system"),
"English",
"Русский",
"Deutsch",
@ -229,7 +228,7 @@ impl SimpleAsyncComponent for EnhancementsApp {
},
adw::ActionRow {
set_title: &tr("borderless-window"),
set_title: &tr!("borderless-window"),
add_suffix = &gtk::Switch {
set_valign: gtk::Align::Center,
@ -249,7 +248,7 @@ impl SimpleAsyncComponent for EnhancementsApp {
},
adw::ComboRow {
set_title: &tr("virtual-desktop"),
set_title: &tr!("virtual-desktop"),
#[wrap(Some)]
set_model = &gtk::StringList::new(&[
@ -258,7 +257,7 @@ impl SimpleAsyncComponent for EnhancementsApp {
"1920x1080",
"2560x1440",
"3840x2160",
&tr("custom")
&tr!("custom")
]),
set_selected: CONFIG.game.wine.virtual_desktop.get_resolution().into(),
@ -295,14 +294,14 @@ impl SimpleAsyncComponent for EnhancementsApp {
},
add = &adw::PreferencesGroup {
set_title: &tr("game"),
set_title: &tr!("game"),
adw::ComboRow {
set_title: &tr("hud"),
set_title: &tr!("hud"),
#[wrap(Some)]
set_model = &gtk::StringList::new(&[
&tr("none"),
&tr!("none"),
"DXVK",
"MangoHud"
]),
@ -321,15 +320,15 @@ impl SimpleAsyncComponent for EnhancementsApp {
},
adw::ComboRow {
set_title: &tr("fsr"),
set_subtitle: &tr("fsr-description"),
set_title: &tr!("fsr"),
set_subtitle: &tr!("fsr-description"),
#[wrap(Some)]
set_model = &gtk::StringList::new(&[
&tr("ultra-quality"),
&tr("quality"),
&tr("balanced"),
&tr("performance")
&tr!("ultra-quality"),
&tr!("quality"),
&tr!("balanced"),
&tr!("performance")
]),
set_selected: CONFIG.game.enhancements.fsr.quality.ordinal() as u32,
@ -362,8 +361,8 @@ impl SimpleAsyncComponent for EnhancementsApp {
},
adw::ActionRow {
set_title: &tr("gamemode"),
set_subtitle: &tr("gamemode-description"),
set_title: &tr!("gamemode"),
set_subtitle: &tr!("gamemode-description"),
set_sensitive: is_available("gamemoderun"),
@ -385,8 +384,8 @@ impl SimpleAsyncComponent for EnhancementsApp {
},
adw::ActionRow {
set_title: &tr("gamescope"),
set_subtitle: &tr("gamescope-description"),
set_title: &tr!("gamescope"),
set_subtitle: &tr!("gamescope-description"),
set_sensitive: is_available("gamescope"),
@ -418,11 +417,11 @@ impl SimpleAsyncComponent for EnhancementsApp {
},
add = &adw::PreferencesGroup {
set_title: &tr("discord-rpc"),
set_title: &tr!("discord-rpc"),
adw::ActionRow {
set_title: &tr("enabled"),
set_subtitle: &tr("discord-rpc-description"),
set_title: &tr!("enabled"),
set_subtitle: &tr!("discord-rpc-description"),
add_suffix = &gtk::Switch {
set_valign: gtk::Align::Center,
@ -442,11 +441,11 @@ impl SimpleAsyncComponent for EnhancementsApp {
#[local_ref]
discord_rpc_icons -> adw::ExpanderRow {
set_title: &tr("icon")
set_title: &tr!("icon")
},
adw::EntryRow {
set_title: &tr("title"),
set_title: &tr!("title"),
set_text: &CONFIG.launcher.discord_rpc.title,
connect_changed: |row| {
@ -461,7 +460,7 @@ impl SimpleAsyncComponent for EnhancementsApp {
},
adw::EntryRow {
set_title: &tr("description"),
set_title: &tr!("description"),
set_text: &CONFIG.launcher.discord_rpc.subtitle,
connect_changed: |row| {
@ -477,11 +476,11 @@ impl SimpleAsyncComponent for EnhancementsApp {
},
add = &adw::PreferencesGroup {
set_title: &tr("fps-unlocker"),
set_title: &tr!("fps-unlocker"),
adw::ComboRow {
set_title: &tr("enabled"),
set_subtitle: &tr("fps-unlocker-description"),
set_title: &tr!("enabled"),
set_subtitle: &tr!("fps-unlocker-description"),
#[wrap(Some)]
set_model = &gtk::StringList::new(&[
@ -492,7 +491,7 @@ impl SimpleAsyncComponent for EnhancementsApp {
"180",
"200",
"240",
&tr("custom")
&tr!("custom")
]),
set_selected: match Fps::from_num(CONFIG.game.enhancements.fps_unlocker.config.fps) {
@ -535,8 +534,8 @@ impl SimpleAsyncComponent for EnhancementsApp {
},
adw::ActionRow {
set_title: &tr("power-saving"),
set_subtitle: &tr("power-saving-description"),
set_title: &tr!("power-saving"),
set_subtitle: &tr!("power-saving-description"),
add_suffix = &gtk::Switch {
set_valign: gtk::Align::Center,
@ -556,8 +555,8 @@ impl SimpleAsyncComponent for EnhancementsApp {
},
adw::ActionRow {
set_title: &tr("monitor"),
set_subtitle: &tr("monitor-description"),
set_title: &tr!("monitor"),
set_subtitle: &tr!("monitor-description"),
add_suffix = &gtk::SpinButton {
set_valign: gtk::Align::Center,
@ -578,13 +577,13 @@ impl SimpleAsyncComponent for EnhancementsApp {
},
adw::ComboRow {
set_title: &tr("window-mode"),
set_title: &tr!("window-mode"),
#[wrap(Some)]
set_model = &gtk::StringList::new(&[
&tr("default"),
&tr("popup"),
&tr("fullscreen")
&tr!("default"),
&tr!("popup"),
&tr!("fullscreen")
]),
set_selected: CONFIG.game.enhancements.fps_unlocker.config.window_mode.ordinal() as u32,
@ -601,17 +600,17 @@ impl SimpleAsyncComponent for EnhancementsApp {
},
adw::ComboRow {
set_title: &tr("priority"),
set_subtitle: &tr("priority-description"),
set_title: &tr!("priority"),
set_subtitle: &tr!("priority-description"),
#[wrap(Some)]
set_model = &gtk::StringList::new(&[
&tr("realtime"),
&tr("high"),
&tr("above-normal"),
&tr("normal"),
&tr("below-normal"),
&tr("low")
&tr!("realtime"),
&tr!("high"),
&tr!("above-normal"),
&tr!("normal"),
&tr!("below-normal"),
&tr!("low")
]),
set_selected: CONFIG.game.enhancements.fps_unlocker.config.priority as u32,
@ -699,7 +698,7 @@ impl SimpleAsyncComponent for EnhancementsApp {
/*if let Err(err) = result {
sender.input(EnhancementsAppMsg::Toast {
title: tr("discord-rpc-icon-download-failed"),
title: tr!("discord-rpc-icon-download-failed"),
description: Some(err.to_string())
});
}*/
@ -726,7 +725,7 @@ impl SimpleAsyncComponent for EnhancementsApp {
}
Err(err) => sender.input(EnhancementsAppMsg::Toast {
title: tr("discord-rpc-icons-fetch-failed"),
title: tr!("discord-rpc-icons-fetch-failed"),
description: Some(err.to_string())
})
}

View file

@ -8,7 +8,6 @@ use anime_launcher_sdk::is_available;
use super::EnhancementsAppMsg;
use crate::i18n::tr;
use crate::*;
macro_rules! impl_directory {
@ -110,7 +109,7 @@ impl SimpleAsyncComponent for SandboxPage {
adw::HeaderBar {
#[wrap(Some)]
set_title_widget = &adw::WindowTitle {
set_title: &tr("sandbox")
set_title: &tr!("sandbox")
},
pack_start = &gtk::Button {
@ -123,18 +122,18 @@ impl SimpleAsyncComponent for SandboxPage {
},
adw::PreferencesPage {
set_title: &tr("sandbox"),
set_title: &tr!("sandbox"),
set_icon_name: Some("folder-symbolic"),
set_sensitive: is_available("bwrap"),
add = &adw::PreferencesGroup {
set_title: &tr("sandbox"),
set_description: Some(&tr("sandbox-description")),
set_title: &tr!("sandbox"),
set_description: Some(&tr!("sandbox-description")),
adw::ActionRow {
set_title: &tr("enable-sandboxing"),
set_subtitle: &tr("enable-sandboxing-description"),
set_title: &tr!("enable-sandboxing"),
set_subtitle: &tr!("enable-sandboxing-description"),
add_suffix = &gtk::Switch {
set_valign: gtk::Align::Center,
@ -154,8 +153,8 @@ impl SimpleAsyncComponent for SandboxPage {
},
adw::ActionRow {
set_title: &tr("hide-home-directory"),
set_subtitle: &tr("hide-home-directory-description"),
set_title: &tr!("hide-home-directory"),
set_subtitle: &tr!("hide-home-directory-description"),
add_suffix = &gtk::Switch {
set_valign: gtk::Align::Center,
@ -175,7 +174,7 @@ impl SimpleAsyncComponent for SandboxPage {
},
adw::EntryRow {
set_title: &tr("hostname"),
set_title: &tr!("hostname"),
set_text: CONFIG.sandbox.hostname.as_ref().unwrap_or(&String::new()).trim(),
connect_changed => |entry| {
@ -194,7 +193,7 @@ impl SimpleAsyncComponent for SandboxPage {
},
adw::EntryRow {
set_title: &tr("additional-arguments"),
set_title: &tr!("additional-arguments"),
set_text: CONFIG.sandbox.args.as_ref().unwrap_or(&String::new()).trim(),
connect_changed => |entry| {
@ -220,7 +219,7 @@ impl SimpleAsyncComponent for SandboxPage {
connect_clicked[sender] => move |_| {
if let Err(err) = open::that("https://man.archlinux.org/man/bwrap.1") {
sender.output(EnhancementsAppMsg::Toast {
title: tr("documentation-url-open-failed"),
title: tr!("documentation-url-open-failed"),
description: Some(err.to_string())
}).unwrap();
}
@ -230,12 +229,12 @@ impl SimpleAsyncComponent for SandboxPage {
},
add = &adw::PreferencesGroup {
set_title: &tr("private-directories"),
set_description: Some(&tr("private-directories-description")),
set_title: &tr!("private-directories"),
set_description: Some(&tr!("private-directories-description")),
#[local_ref]
private_path_entry -> adw::EntryRow {
set_title: &tr("path"),
set_title: &tr!("path"),
add_suffix = &gtk::Button {
set_icon_name: "list-add-symbolic",
@ -252,8 +251,8 @@ impl SimpleAsyncComponent for SandboxPage {
add = private_paths -> adw::PreferencesGroup {},
add = &adw::PreferencesGroup {
set_title: &tr("shared-directories"),
set_description: Some(&tr("shared-directories-description")),
set_title: &tr!("shared-directories"),
set_description: Some(&tr!("shared-directories-description")),
#[wrap(Some)]
set_header_suffix = &gtk::Button {
@ -263,7 +262,7 @@ impl SimpleAsyncComponent for SandboxPage {
adw::ButtonContent {
set_icon_name: "list-add-symbolic",
set_label: &tr("add")
set_label: &tr!("add")
},
connect_clicked => SandboxPageMsg::AddShared
@ -271,17 +270,17 @@ impl SimpleAsyncComponent for SandboxPage {
#[local_ref]
shared_path_from_entry -> adw::EntryRow {
set_title: &tr("original-path")
set_title: &tr!("original-path")
},
#[local_ref]
shared_path_to_entry -> adw::EntryRow {
set_title: &tr("new-path")
set_title: &tr!("new-path")
},
adw::ActionRow {
set_title: &tr("read-only"),
set_subtitle: &tr("read-only-description"),
set_title: &tr!("read-only"),
set_subtitle: &tr!("read-only-description"),
#[local_ref]
add_suffix = read_only_switch -> gtk::Switch {
@ -294,8 +293,8 @@ impl SimpleAsyncComponent for SandboxPage {
add = shared_paths -> adw::PreferencesGroup {},
add = &adw::PreferencesGroup {
set_title: &tr("symlinks"),
set_description: Some(&tr("symlinks-description")),
set_title: &tr!("symlinks"),
set_description: Some(&tr!("symlinks-description")),
#[wrap(Some)]
set_header_suffix = &gtk::Button {
@ -305,7 +304,7 @@ impl SimpleAsyncComponent for SandboxPage {
adw::ButtonContent {
set_icon_name: "list-add-symbolic",
set_label: &tr("add")
set_label: &tr!("add")
},
connect_clicked => SandboxPageMsg::AddSymlink
@ -313,12 +312,12 @@ impl SimpleAsyncComponent for SandboxPage {
#[local_ref]
symlink_path_from_entry -> adw::EntryRow {
set_title: &tr("original-path")
set_title: &tr!("original-path")
},
#[local_ref]
symlink_path_to_entry -> adw::EntryRow {
set_title: &tr("new-path")
set_title: &tr!("new-path")
}
},

View file

@ -8,7 +8,6 @@ use anime_launcher_sdk::genshin::config::Config;
use anime_launcher_sdk::config::schema_blanks::prelude::*;
use crate::i18n::tr;
use crate::*;
pub struct GamescopeApp;
@ -21,7 +20,7 @@ impl SimpleAsyncComponent for GamescopeApp {
view! {
adw::PreferencesWindow {
set_title: Some(&tr("gamescope")),
set_title: Some(&tr!("gamescope")),
set_modal: true,
set_hide_on_close: true,
@ -31,10 +30,10 @@ impl SimpleAsyncComponent for GamescopeApp {
add = &adw::PreferencesPage {
add = &adw::PreferencesGroup {
set_title: &tr("game-resolution"),
set_title: &tr!("game-resolution"),
adw::EntryRow {
set_title: &tr("width"),
set_title: &tr!("width"),
set_input_purpose: gtk::InputPurpose::Digits,
set_text: &if CONFIG.game.enhancements.gamescope.game.width > 0 {
@ -55,7 +54,7 @@ impl SimpleAsyncComponent for GamescopeApp {
},
adw::EntryRow {
set_title: &tr("height"),
set_title: &tr!("height"),
set_input_purpose: gtk::InputPurpose::Digits,
set_text: &if CONFIG.game.enhancements.gamescope.game.height > 0 {
@ -77,10 +76,10 @@ impl SimpleAsyncComponent for GamescopeApp {
},
add = &adw::PreferencesGroup {
set_title: &tr("gamescope-resolution"),
set_title: &tr!("gamescope-resolution"),
adw::EntryRow {
set_title: &tr("width"),
set_title: &tr!("width"),
set_input_purpose: gtk::InputPurpose::Digits,
set_text: &if CONFIG.game.enhancements.gamescope.gamescope.width > 0 {
@ -101,7 +100,7 @@ impl SimpleAsyncComponent for GamescopeApp {
},
adw::EntryRow {
set_title: &tr("height"),
set_title: &tr!("height"),
set_input_purpose: gtk::InputPurpose::Digits,
set_text: &if CONFIG.game.enhancements.gamescope.gamescope.height > 0 {
@ -123,11 +122,11 @@ impl SimpleAsyncComponent for GamescopeApp {
},
add = &adw::PreferencesGroup {
set_title: &tr("upscaling"),
set_title: &tr!("upscaling"),
adw::ActionRow {
set_title: &tr("integer-scaling"),
set_subtitle: &tr("integer-scaling-description"),
set_title: &tr!("integer-scaling"),
set_subtitle: &tr!("integer-scaling-description"),
add_suffix = &gtk::Switch {
set_valign: gtk::Align::Center,
@ -147,7 +146,7 @@ impl SimpleAsyncComponent for GamescopeApp {
adw::ActionRow {
set_title: "FSR",
set_subtitle: &tr("gamescope-fsr-description"),
set_subtitle: &tr!("gamescope-fsr-description"),
add_suffix = &gtk::Switch {
set_valign: gtk::Align::Center,
@ -167,7 +166,7 @@ impl SimpleAsyncComponent for GamescopeApp {
adw::ActionRow {
set_title: "Nvidia Image Scaling",
set_subtitle: &tr("nis-description"),
set_subtitle: &tr!("nis-description"),
add_suffix = &gtk::Switch {
set_valign: gtk::Align::Center,
@ -187,12 +186,12 @@ impl SimpleAsyncComponent for GamescopeApp {
},
add = &adw::PreferencesGroup {
set_title: &tr("other-settings"),
set_title: &tr!("other-settings"),
// TODO: maybe use Fps enum like in fps unlocker settings
adw::EntryRow {
set_title: &tr("framerate-limit"),
set_title: &tr!("framerate-limit"),
set_input_purpose: gtk::InputPurpose::Digits,
set_text: &if CONFIG.game.enhancements.gamescope.framerate.focused > 0 {
@ -213,7 +212,7 @@ impl SimpleAsyncComponent for GamescopeApp {
},
adw::EntryRow {
set_title: &tr("unfocused-framerate-limit"),
set_title: &tr!("unfocused-framerate-limit"),
set_input_purpose: gtk::InputPurpose::Digits,
set_text: &if CONFIG.game.enhancements.gamescope.framerate.unfocused > 0 {
@ -234,12 +233,12 @@ impl SimpleAsyncComponent for GamescopeApp {
},
adw::ComboRow {
set_title: &tr("window-mode"),
set_title: &tr!("window-mode"),
#[wrap(Some)]
set_model = &gtk::StringList::new(&[
&tr("borderless"),
&tr("fullscreen")
&tr!("borderless"),
&tr!("fullscreen")
]),
set_selected: CONFIG.game.enhancements.gamescope.window_type.ordinal() as u32,

View file

@ -12,7 +12,6 @@ use anime_launcher_sdk::components::wine::UnifiedWine;
use super::GeneralAppMsg;
use crate::ui::components::*;
use crate::i18n::*;
use crate::*;
pub struct ComponentsPage {
@ -58,7 +57,7 @@ impl SimpleAsyncComponent for ComponentsPage {
adw::HeaderBar {
#[wrap(Some)]
set_title_widget = &adw::WindowTitle {
set_title: &tr("components")
set_title: &tr!("components")
},
pack_start = &gtk::Button {
@ -72,10 +71,10 @@ impl SimpleAsyncComponent for ComponentsPage {
adw::PreferencesPage {
add = &adw::PreferencesGroup {
set_title: &tr("wine-version"),
set_title: &tr!("wine-version"),
adw::ComboRow {
set_title: &tr("selected-version"),
set_title: &tr!("selected-version"),
#[watch]
#[block_signal(wine_selected_notify)]
@ -103,8 +102,8 @@ impl SimpleAsyncComponent for ComponentsPage {
},
adw::ActionRow {
set_title: &tr("recommended-only"),
set_subtitle: &tr("wine-recommended-description"),
set_title: &tr!("recommended-only"),
set_subtitle: &tr!("wine-recommended-description"),
add_suffix = &gtk::Switch {
set_valign: gtk::Align::Center,
@ -126,11 +125,11 @@ impl SimpleAsyncComponent for ComponentsPage {
},
add = &adw::PreferencesGroup {
set_title: &tr("wine-options"),
set_title: &tr!("wine-options"),
adw::ActionRow {
set_title: &tr("wine-use-shared-libraries"),
set_subtitle: &tr("wine-use-shared-libraries-description"),
set_title: &tr!("wine-use-shared-libraries"),
set_subtitle: &tr!("wine-use-shared-libraries-description"),
add_suffix = &gtk::Switch {
set_valign: gtk::Align::Center,
@ -151,8 +150,8 @@ impl SimpleAsyncComponent for ComponentsPage {
},
adw::ActionRow {
set_title: &tr("gstreamer-use-shared-libraries"),
set_subtitle: &tr("gstreamer-use-shared-libraries-description"),
set_title: &tr!("gstreamer-use-shared-libraries"),
set_subtitle: &tr!("gstreamer-use-shared-libraries-description"),
add_suffix = &gtk::Switch {
set_valign: gtk::Align::Center,
@ -174,11 +173,11 @@ impl SimpleAsyncComponent for ComponentsPage {
},
add = &adw::PreferencesGroup {
set_title: &tr("dxvk-version"),
set_title: &tr!("dxvk-version"),
#[watch]
set_description: Some(&if !model.allow_dxvk_selection {
tr("dxvk-selection-disabled")
tr!("dxvk-selection-disabled")
} else {
String::new()
}),
@ -187,7 +186,7 @@ impl SimpleAsyncComponent for ComponentsPage {
set_sensitive: model.allow_dxvk_selection,
adw::ComboRow {
set_title: &tr("selected-version"),
set_title: &tr!("selected-version"),
#[watch]
#[block_signal(dxvk_selected_notify)]
@ -215,8 +214,8 @@ impl SimpleAsyncComponent for ComponentsPage {
},
adw::ActionRow {
set_title: &tr("recommended-only"),
set_subtitle: &tr("dxvk-recommended-description"),
set_title: &tr!("recommended-only"),
set_subtitle: &tr!("dxvk-recommended-description"),
add_suffix = &gtk::Switch {
set_valign: gtk::Align::Center,
@ -433,7 +432,7 @@ impl SimpleAsyncComponent for ComponentsPage {
Err(err) => {
sender.output(GeneralAppMsg::Toast {
title: tr("wine-prefix-update-failed"),
title: tr!("wine-prefix-update-failed"),
description: Some(err.to_string())
}).unwrap();
}
@ -476,7 +475,7 @@ impl SimpleAsyncComponent for ComponentsPage {
std::thread::spawn(move || {
if let Err(err) = Dxvk::install(&wine, dxvk_folder, InstallParams::default()) {
sender.output(GeneralAppMsg::Toast {
title: tr("dxvk-install-failed"),
title: tr!("dxvk-install-failed"),
description: Some(err.to_string())
}).unwrap();
}

View file

@ -22,12 +22,12 @@ pub mod components;
use components::*;
use super::main::PreferencesAppMsg;
use crate::ui::migrate_installation::MigrateInstallationApp;
use crate::i18n::*;
use crate::*;
use super::main::PreferencesAppMsg;
#[derive(Debug)]
struct VoicePackageComponent {
locale: VoiceLocale,
@ -46,7 +46,7 @@ impl AsyncFactoryComponent for VoicePackageComponent {
view! {
root = adw::ActionRow {
set_title: &tr(&self.locale.to_name().to_ascii_lowercase()),
set_title: &tr!(&self.locale.to_name().to_ascii_lowercase()),
add_suffix = &gtk::Button {
#[watch]
@ -163,11 +163,11 @@ impl SimpleAsyncComponent for GeneralApp {
view! {
#[root]
adw::PreferencesPage {
set_title: &tr("general"),
set_title: &tr!("general"),
set_icon_name: Some("applications-system-symbolic"),
add = &adw::PreferencesGroup {
set_title: &tr("appearance"),
set_title: &tr!("appearance"),
gtk::Box {
set_orientation: gtk::Orientation::Horizontal,
@ -195,7 +195,7 @@ impl SimpleAsyncComponent for GeneralApp {
},
gtk::Label {
set_text: &tr("modern"),
set_text: &tr!("modern"),
set_margin_top: 16
}
@ -221,7 +221,7 @@ impl SimpleAsyncComponent for GeneralApp {
},
gtk::Label {
set_text: &tr("classic"),
set_text: &tr!("classic"),
set_margin_top: 16
}
@ -234,8 +234,8 @@ impl SimpleAsyncComponent for GeneralApp {
set_visible: model.style == LauncherStyle::Classic,
adw::ActionRow {
set_title: &tr("update-background"),
set_subtitle: &tr("update-background-description"),
set_title: &tr!("update-background"),
set_subtitle: &tr!("update-background-description"),
add_suffix = &gtk::Switch {
set_valign: gtk::Align::Center,
@ -254,11 +254,11 @@ impl SimpleAsyncComponent for GeneralApp {
},
add = &adw::PreferencesGroup {
set_title: &tr("general"),
set_title: &tr!("general"),
adw::ComboRow {
set_title: &tr("launcher-language"),
set_subtitle: &tr("launcher-language-description"),
set_title: &tr!("launcher-language"),
set_subtitle: &tr!("launcher-language-description"),
set_model: Some(&gtk::StringList::new(&model.languages.iter().map(|lang| lang.as_str()).collect::<Vec<&str>>())),
@ -284,11 +284,11 @@ impl SimpleAsyncComponent for GeneralApp {
},
adw::ComboRow {
set_title: &tr("game-edition"),
set_title: &tr!("game-edition"),
set_model: Some(&gtk::StringList::new(&[
&tr("global"),
&tr("china")
&tr!("global"),
&tr!("china")
])),
set_selected: match CONFIG.launcher.edition {
@ -316,8 +316,8 @@ impl SimpleAsyncComponent for GeneralApp {
},
adw::ComboRow {
set_title: &tr("game-environment"),
set_subtitle: &tr("game-environment-description"),
set_title: &tr!("game-environment"),
set_subtitle: &tr!("game-environment-description"),
set_model: Some(&gtk::StringList::new(&[
"PC",
@ -349,8 +349,8 @@ impl SimpleAsyncComponent for GeneralApp {
#[local_ref]
voice_packages -> adw::ExpanderRow {
set_title: &tr("game-voiceovers"),
set_subtitle: &tr("game-voiceovers-description")
set_title: &tr!("game-voiceovers"),
set_subtitle: &tr!("game-voiceovers-description")
},
gtk::Box {
@ -359,14 +359,14 @@ impl SimpleAsyncComponent for GeneralApp {
set_margin_top: 16,
gtk::Button {
set_label: &tr("migrate-installation"),
set_tooltip_text: Some(&tr("migrate-installation-description")),
set_label: &tr!("migrate-installation"),
set_tooltip_text: Some(&tr!("migrate-installation-description")),
connect_clicked => GeneralAppMsg::OpenMigrateInstallation
},
gtk::Button {
set_label: &tr("repair-game"),
set_label: &tr!("repair-game"),
connect_clicked => GeneralAppMsg::RepairGame
}
@ -374,10 +374,10 @@ impl SimpleAsyncComponent for GeneralApp {
},
add = &adw::PreferencesGroup {
set_title: &tr("status"),
set_title: &tr!("status"),
adw::ActionRow {
set_title: &tr("game-version"),
set_title: &tr!("game-version"),
add_suffix = &gtk::Label {
#[watch]
@ -388,7 +388,7 @@ impl SimpleAsyncComponent for GeneralApp {
VersionDiff::Diff { current, .. } |
VersionDiff::Outdated { current, .. } => current.to_string(),
VersionDiff::NotInstalled { .. } => tr("game-not-installed")
VersionDiff::NotInstalled { .. } => tr!("game-not-installed")
}
None => String::from("?")
@ -411,16 +411,16 @@ 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_args("game-predownload-available", [
("old", current.to_string().into()),
("new", latest.to_string().into())
VersionDiff::Predownload { current, latest, .. } => tr!("game-predownload-available", [
("old", current.to_string()),
("new", latest.to_string())
]),
VersionDiff::Diff { current, latest, .. } => tr_args("game-update-available", [
("old", current.to_string().into()),
("new", latest.to_string().into())
VersionDiff::Diff { current, latest, .. } => tr!("game-update-available", [
("old", current.to_string()),
("new", latest.to_string())
]),
VersionDiff::Outdated { latest, ..} => tr_args("game-outdated", [
("latest", latest.to_string().into())
VersionDiff::Outdated { latest, ..} => tr!("game-outdated", [
("latest", latest.to_string())
]),
VersionDiff::NotInstalled { .. } => String::new()
}
@ -431,16 +431,16 @@ impl SimpleAsyncComponent for GeneralApp {
},
adw::ActionRow {
set_title: &tr("player-patch-version"),
set_subtitle: &tr("player-patch-version-description"),
set_title: &tr!("player-patch-version"),
set_subtitle: &tr!("player-patch-version-description"),
add_suffix = &gtk::Label {
#[watch]
set_text: &match model.player_patch.as_ref() {
Some(patch) => match patch.status() {
PatchStatus::NotAvailable => tr("patch-not-available"),
PatchStatus::Outdated { current, .. } => tr_args("patch-outdated", [("current", current.to_string().into())]),
PatchStatus::Preparation { .. } => tr("patch-preparation"),
PatchStatus::NotAvailable => tr!("patch-not-available"),
PatchStatus::Outdated { current, .. } => tr!("patch-outdated", [("current", current.to_string())]),
PatchStatus::Preparation { .. } => tr!("patch-preparation"),
PatchStatus::Testing { version, .. } |
PatchStatus::Available { version, .. } => version.to_string()
}
@ -475,13 +475,13 @@ impl SimpleAsyncComponent for GeneralApp {
#[watch]
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_args("patch-outdated-tooltip", [
("current", current.to_string().into()),
("latest", latest.to_string().into())
PatchStatus::NotAvailable => tr!("patch-not-available-tooltip"),
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::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(),
@ -491,7 +491,7 @@ impl SimpleAsyncComponent for GeneralApp {
if let Ok(true) = model.player_patch.as_ref().unwrap_unchecked().is_applied(path) {
String::new()
} else {
tr("patch-not-applied-tooltip")
tr!("patch-not-applied-tooltip")
}
}
}
@ -504,8 +504,8 @@ impl SimpleAsyncComponent for GeneralApp {
add = &adw::PreferencesGroup {
adw::ActionRow {
set_title: &tr("apply-main-patch"),
set_subtitle: &tr("apply-main-patch-description"),
set_title: &tr!("apply-main-patch"),
set_subtitle: &tr!("apply-main-patch-description"),
add_suffix = &gtk::Switch {
set_valign: gtk::Align::Center,
@ -528,8 +528,8 @@ impl SimpleAsyncComponent for GeneralApp {
},
adw::ActionRow {
set_title: &tr("disable-mhypbase"),
set_subtitle: &tr("disable-mhypbase-description"),
set_title: &tr!("disable-mhypbase"),
set_subtitle: &tr!("disable-mhypbase-description"),
add_suffix = &gtk::Switch {
set_valign: gtk::Align::Center,
@ -552,8 +552,8 @@ impl SimpleAsyncComponent for GeneralApp {
},
adw::ActionRow {
set_title: &tr("ask-superuser-permissions"),
set_subtitle: &tr("ask-superuser-permissions-description"),
set_title: &tr!("ask-superuser-permissions"),
set_subtitle: &tr!("ask-superuser-permissions-description"),
add_suffix = &gtk::Switch {
set_valign: gtk::Align::Center,
@ -574,16 +574,16 @@ impl SimpleAsyncComponent for GeneralApp {
},
add = &adw::PreferencesGroup {
set_title: &tr("options"),
set_title: &tr!("options"),
adw::ComboRow {
set_title: &tr("launcher-behavior"),
set_subtitle: &tr("launcher-behavior-description"),
set_title: &tr!("launcher-behavior"),
set_subtitle: &tr!("launcher-behavior-description"),
set_model: Some(&gtk::StringList::new(&[
&tr("nothing"),
&tr_args("hide", [("form", "verb".into())]),
&tr_args("close", [("form", "verb".into())]),
&tr!("nothing"),
&tr!("hide", [("form", "verb")]),
&tr!("close", [("form", "verb")]),
])),
set_selected: match CONFIG.launcher.behavior {
@ -610,8 +610,8 @@ impl SimpleAsyncComponent for GeneralApp {
add = &adw::PreferencesGroup {
adw::ActionRow {
set_title: &tr("components"),
set_subtitle: &tr("components-description"),
set_title: &tr!("components"),
set_subtitle: &tr!("components-description"),
add_suffix = &gtk::Image {
set_icon_name: Some("go-next-symbolic")
@ -623,10 +623,10 @@ impl SimpleAsyncComponent for GeneralApp {
},
adw::ExpanderRow {
set_title: &tr("wine-tools"),
set_title: &tr!("wine-tools"),
add_row = &adw::ActionRow {
set_title: &tr("command-line"),
set_title: &tr!("command-line"),
set_subtitle: "wineconsole",
set_activatable: true,
@ -635,7 +635,7 @@ impl SimpleAsyncComponent for GeneralApp {
},
add_row = &adw::ActionRow {
set_title: &tr("registry-editor"),
set_title: &tr!("registry-editor"),
set_subtitle: "regedit",
set_activatable: true,
@ -644,7 +644,7 @@ impl SimpleAsyncComponent for GeneralApp {
},
add_row = &adw::ActionRow {
set_title: &tr("explorer"),
set_title: &tr!("explorer"),
set_subtitle: "explorer",
set_activatable: true,
@ -653,7 +653,7 @@ impl SimpleAsyncComponent for GeneralApp {
},
add_row = &adw::ActionRow {
set_title: &tr("task-manager"),
set_title: &tr!("task-manager"),
set_subtitle: "taskmgr",
set_activatable: true,
@ -662,7 +662,7 @@ impl SimpleAsyncComponent for GeneralApp {
},
add_row = &adw::ActionRow {
set_title: &tr("configuration"),
set_title: &tr!("configuration"),
set_subtitle: "winecfg",
set_activatable: true,
@ -671,7 +671,7 @@ impl SimpleAsyncComponent for GeneralApp {
},
add_row = &adw::ActionRow {
set_title: &tr("debugger"),
set_title: &tr!("debugger"),
set_subtitle: "start winedbg",
set_activatable: true,
@ -709,7 +709,7 @@ impl SimpleAsyncComponent for GeneralApp {
style: CONFIG.launcher.style,
languages: SUPPORTED_LANGUAGES.iter().map(|lang| tr(format_lang(lang).as_str())).collect()
languages: SUPPORTED_LANGUAGES.iter().map(|lang| tr!(format_lang(lang).as_str())).collect()
};
for package in VoiceLocale::list() {
@ -773,7 +773,7 @@ impl SimpleAsyncComponent for GeneralApp {
tracing::error!("Failed to delete voice package: {:?}", package.locale());
sender.input(GeneralAppMsg::Toast {
title: tr("voice-package-deletion-error"),
title: tr!("voice-package-deletion-error"),
description: Some(err.to_string())
});
}
@ -841,7 +841,7 @@ impl SimpleAsyncComponent for GeneralApp {
tracing::error!("Failed to download background picture");
sender.input(GeneralAppMsg::Toast {
title: tr("background-downloading-failed"),
title: tr!("background-downloading-failed"),
description: Some(err.to_string())
});
@ -873,8 +873,8 @@ impl SimpleAsyncComponent for GeneralApp {
if let Err(err) = result {
sender.input(GeneralAppMsg::Toast {
title: tr_args("wine-run-error", [
("executable", executable.join(" ").into())
title: tr!("wine-run-error", [
("executable", executable.join(" "))
]),
description: Some(err.to_string())
});

View file

@ -11,7 +11,7 @@ use anime_launcher_sdk::config::ConfigExt;
use anime_launcher_sdk::genshin::config::Config;
use anime_launcher_sdk::genshin::config::schema::launcher::LauncherStyle;
use crate::i18n::tr;
use crate::tr;
use super::general::*;
use super::enhancements::*;
@ -52,7 +52,7 @@ impl SimpleAsyncComponent for PreferencesApp {
view! {
preferences_window = adw::PreferencesWindow {
set_title: Some(&tr("preferences")),
set_title: Some(&tr!("preferences")),
set_default_size: (700, 560),
set_hide_on_close: true,
@ -65,7 +65,7 @@ impl SimpleAsyncComponent for PreferencesApp {
connect_close_request[sender] => move |_| {
if let Err(err) = Config::flush() {
sender.input(PreferencesAppMsg::Toast {
title: tr("config-update-error"),
title: tr!("config-update-error"),
description: Some(err.to_string())
});
}
@ -150,12 +150,12 @@ impl SimpleAsyncComponent for PreferencesApp {
toast.set_timeout(4);
if let Some(description) = description {
toast.set_button_label(Some(&tr("details")));
toast.set_button_label(Some(&tr!("details")));
let dialog = adw::MessageDialog::new(PREFERENCES_WINDOW.as_ref(), Some(&title), Some(&description));
dialog.add_response("close", &tr("close"));
dialog.add_response("save", &tr("save"));
dialog.add_response("close", &tr!("close"));
dialog.add_response("save", &tr!("save"));
dialog.set_response_appearance("save", adw::ResponseAppearance::Suggested);