mirror of
https://github.com/an-anime-team/sleepy-launcher.git
synced 2025-02-16 17:59:46 +03:00
feat(i18n): added automatic default launcher language selection
Improved `i18n` mod to list supported languages and some other stuff As well was added `get_default_lang` function which will return language key based on current system language. This function is called at the first launcher start to update default `launcher.language` config property, so user will immediately have proper language in initial setup window
This commit is contained in:
parent
b7e85b7a8f
commit
cbd91c42aa
3 changed files with 88 additions and 23 deletions
|
@ -8,20 +8,9 @@ pub struct Background {
|
|||
}
|
||||
|
||||
pub fn get_uri() -> String {
|
||||
let mut lang;
|
||||
|
||||
unsafe {
|
||||
lang = crate::i18n::LANG.language.as_str().to_string();
|
||||
|
||||
if let Some(region) = crate::i18n::LANG.region {
|
||||
lang += "-";
|
||||
lang += ®ion.as_str().to_ascii_lowercase();
|
||||
}
|
||||
}
|
||||
|
||||
let uri = concat!("https://sdk-os-static.", "ho", "yo", "verse", ".com/hk4e_global/mdk/launcher/api/content?filter_adv=true&key=gcStgarh&launcher_id=10&language=");
|
||||
|
||||
uri.to_owned() + &lang
|
||||
uri.to_owned() + crate::i18n::get_lang()
|
||||
}
|
||||
|
||||
#[cached::proc_macro::cached(result)]
|
||||
|
|
77
src/i18n.rs
77
src/i18n.rs
|
@ -8,17 +8,88 @@ fluent_templates::static_loader! {
|
|||
};
|
||||
}
|
||||
|
||||
pub static mut LANG: LanguageIdentifier = langid!("en");
|
||||
/// Map of supported languages
|
||||
pub const SUPPORTED_LANGUAGES: &[(&str, LanguageIdentifier)] = &[
|
||||
("en-us", langid!("en")),
|
||||
("ru-ru", langid!("ru"))
|
||||
];
|
||||
|
||||
static mut LANG: LanguageIdentifier = langid!("en");
|
||||
|
||||
/// Set launcher language
|
||||
pub fn set_lang<T: AsRef<str>>(lang: T) -> anyhow::Result<()> {
|
||||
for (key, id) in SUPPORTED_LANGUAGES {
|
||||
if key == &lang.as_ref() {
|
||||
unsafe {
|
||||
LANG = id.to_owned()
|
||||
}
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
anyhow::bail!("Language {} is not supported", lang.as_ref())
|
||||
}
|
||||
|
||||
/// Get launcher language
|
||||
pub fn get_lang() -> &'static str {
|
||||
for (key, lang) in SUPPORTED_LANGUAGES {
|
||||
if lang == unsafe { &LANG } {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
/// Get system language or default language if system one is not supported
|
||||
///
|
||||
/// Checks env variables in following order:
|
||||
/// - `LC_ALL`
|
||||
/// - `LC_MESSAGES`
|
||||
/// - `LANG`
|
||||
pub fn get_default_lang() -> String {
|
||||
let lang = std::env::var("LC_ALL")
|
||||
.unwrap_or_else(|_| std::env::var("LC_MESSAGES")
|
||||
.unwrap_or_else(|_| std::env::var("LANG")
|
||||
.unwrap_or_else(|_| String::from("en_US.UTF-8"))));
|
||||
|
||||
let lang = lang.split('.')
|
||||
.next()
|
||||
.unwrap_or("en_US")
|
||||
.replace('_', "-")
|
||||
.to_ascii_lowercase();
|
||||
|
||||
for (key, _) in SUPPORTED_LANGUAGES {
|
||||
if key == &lang {
|
||||
return lang;
|
||||
}
|
||||
}
|
||||
|
||||
String::from("en-us")
|
||||
}
|
||||
|
||||
/// Get translated message by key
|
||||
///
|
||||
/// ```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 a given id: {id}"))
|
||||
.expect(&format!("Failed to find message with given id: {id}"))
|
||||
}
|
||||
}
|
||||
|
||||
/// Get translated message by key with filled arguments
|
||||
///
|
||||
/// ```no_run
|
||||
/// println!("Translated message: {}", tr_args("game-outdated", [
|
||||
/// ("latest", "3.3.0".into())
|
||||
/// ]));
|
||||
/// ```
|
||||
#[allow(clippy::expect_fun_call)]
|
||||
pub fn tr_args<I, T>(id: &str, args: I) -> String
|
||||
where
|
||||
|
@ -28,6 +99,6 @@ where
|
|||
unsafe {
|
||||
LOCALES
|
||||
.lookup_with_args(&LANG, id, &std::collections::HashMap::from_iter(args.into_iter()))
|
||||
.expect(&format!("Failed to find message with a given id: {id}"))
|
||||
.expect(&format!("Failed to find message with given id: {id}"))
|
||||
}
|
||||
}
|
||||
|
|
21
src/main.rs
21
src/main.rs
|
@ -65,6 +65,13 @@ fn main() {
|
|||
|
||||
// This one is kinda critical buy well, I can't do something with it
|
||||
std::fs::write(FIRST_RUN_FILE.as_path(), "").expect("Failed to create .first-run file");
|
||||
|
||||
// Set initial launcher language based on system language
|
||||
let mut config = config::get().expect("Failed to get config");
|
||||
|
||||
config.launcher.language = i18n::get_default_lang();
|
||||
|
||||
config::update_raw(config).expect("Failed to update config");
|
||||
}
|
||||
|
||||
// Force debug output
|
||||
|
@ -130,7 +137,12 @@ fn main() {
|
|||
background-size: cover;
|
||||
}}
|
||||
", BACKGROUND_FILE.to_string_lossy()));
|
||||
|
||||
|
||||
// Set UI language
|
||||
i18n::set_lang(config::get().unwrap().launcher.language).expect("Failed to set launcher language");
|
||||
|
||||
tracing::info!("Set UI language to {}", i18n::get_lang());
|
||||
|
||||
// Run FirstRun window if .first-run file persist
|
||||
if FIRST_RUN_FILE.exists() {
|
||||
app.run::<ui::first_run::main::FirstRunApp>(());
|
||||
|
@ -138,13 +150,6 @@ fn main() {
|
|||
|
||||
// Run the app if everything's ready
|
||||
else {
|
||||
// Set UI language
|
||||
unsafe {
|
||||
i18n::LANG = config::get().unwrap().launcher.language.parse().unwrap();
|
||||
|
||||
tracing::info!("Set UI language to {}", i18n::LANG);
|
||||
}
|
||||
|
||||
app.run::<ui::main::App>(());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue