mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
allow searching in both selected language and fallback langauage in crafting
This commit is contained in:
parent
a0b1f76b9b
commit
6c0da4beeb
@ -236,6 +236,11 @@ pub struct LocalizationGuard {
|
||||
}
|
||||
|
||||
impl LocalizationGuard {
|
||||
/// Get a localized text from the given key in the fallback language.
|
||||
pub fn try_fallback_msg(&self, key: &str) -> Option<Cow<str>> {
|
||||
self.fallback.as_ref().and_then(|fb| fb.try_msg(key, None))
|
||||
}
|
||||
|
||||
/// Get a localized text from the given key
|
||||
///
|
||||
/// First lookup is done in the active language, second in
|
||||
@ -243,7 +248,7 @@ impl LocalizationGuard {
|
||||
pub fn try_msg(&self, key: &str) -> Option<Cow<str>> {
|
||||
self.active
|
||||
.try_msg(key, None)
|
||||
.or_else(|| self.fallback.as_ref().and_then(|fb| fb.try_msg(key, None)))
|
||||
.or_else(|| self.try_fallback_msg(key))
|
||||
}
|
||||
|
||||
/// Get a localized text from the given key
|
||||
@ -344,6 +349,54 @@ impl LocalizationGuard {
|
||||
})
|
||||
}
|
||||
|
||||
// Function to localize content for given language.
|
||||
//
|
||||
// Returns Ok(localized_text) if found no errors.
|
||||
// Returns Err(broken_text) on failure.
|
||||
//
|
||||
// broken_text will have i18n keys in it, just i18n key if it was instant miss
|
||||
// or text with missed keys inlined if it was missed down the chain.
|
||||
fn get_content_for_lang(lang: &Language, content: &Content) -> Result<String, String> {
|
||||
match content {
|
||||
Content::Plain(text) => Ok(text.clone()),
|
||||
Content::Key(key) => lang
|
||||
.try_msg(key, None)
|
||||
.map(Cow::into_owned)
|
||||
.ok_or_else(|| key.to_string()),
|
||||
Content::Attr(key, attr) => lang
|
||||
.try_attr(key, attr, None)
|
||||
.map(Cow::into_owned)
|
||||
.ok_or_else(|| format!("{key}.{attr}")),
|
||||
Content::Localized { key, seed, args } => {
|
||||
// flag to detect failure down the chain
|
||||
let mut is_arg_failure = false;
|
||||
|
||||
let mut fargs = FluentArgs::new();
|
||||
for (k, arg) in args {
|
||||
let arg_val = match arg {
|
||||
LocalizationArg::Content(content) => {
|
||||
let arg_res = Self::get_content_for_lang(lang, content)
|
||||
.unwrap_or_else(|broken_text| {
|
||||
is_arg_failure = true;
|
||||
broken_text
|
||||
})
|
||||
.into();
|
||||
|
||||
FluentValue::String(arg_res)
|
||||
},
|
||||
LocalizationArg::Nat(n) => FluentValue::from(n),
|
||||
};
|
||||
fargs.set(k, arg_val);
|
||||
}
|
||||
|
||||
lang.try_variation(key, *seed, Some(&fargs))
|
||||
.map(Cow::into_owned)
|
||||
.ok_or_else(|| key.clone())
|
||||
.and_then(|text| if is_arg_failure { Err(text) } else { Ok(text) })
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Tries its best to localize compound message.
|
||||
///
|
||||
/// # Example
|
||||
@ -383,55 +436,7 @@ impl LocalizationGuard {
|
||||
//
|
||||
// TODO: return Cow<str>?
|
||||
pub fn get_content(&self, content: &Content) -> String {
|
||||
// Function to localize content for given language.
|
||||
//
|
||||
// Returns Ok(localized_text) if found no errors.
|
||||
// Returns Err(broken_text) on failure.
|
||||
//
|
||||
// broken_text will have i18n keys in it, just i18n key if it was instant miss
|
||||
// or text with missed keys inlined if it was missed down the chain.
|
||||
fn get_content_for_lang(lang: &Language, content: &Content) -> Result<String, String> {
|
||||
match content {
|
||||
Content::Plain(text) => Ok(text.clone()),
|
||||
Content::Key(key) => lang
|
||||
.try_msg(key, None)
|
||||
.map(Cow::into_owned)
|
||||
.ok_or_else(|| key.to_string()),
|
||||
Content::Attr(key, attr) => lang
|
||||
.try_attr(key, attr, None)
|
||||
.map(Cow::into_owned)
|
||||
.ok_or_else(|| format!("{key}.{attr}")),
|
||||
Content::Localized { key, seed, args } => {
|
||||
// flag to detect failure down the chain
|
||||
let mut is_arg_failure = false;
|
||||
|
||||
let mut fargs = FluentArgs::new();
|
||||
for (k, arg) in args {
|
||||
let arg_val = match arg {
|
||||
LocalizationArg::Content(content) => {
|
||||
let arg_res = get_content_for_lang(lang, content)
|
||||
.unwrap_or_else(|broken_text| {
|
||||
is_arg_failure = true;
|
||||
broken_text
|
||||
})
|
||||
.into();
|
||||
|
||||
FluentValue::String(arg_res)
|
||||
},
|
||||
LocalizationArg::Nat(n) => FluentValue::from(n),
|
||||
};
|
||||
fargs.set(k, arg_val);
|
||||
}
|
||||
|
||||
lang.try_variation(key, *seed, Some(&fargs))
|
||||
.map(Cow::into_owned)
|
||||
.ok_or_else(|| key.clone())
|
||||
.and_then(|text| if is_arg_failure { Err(text) } else { Ok(text) })
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
match get_content_for_lang(&self.active, content) {
|
||||
match Self::get_content_for_lang(&self.active, content) {
|
||||
Ok(text) => text,
|
||||
// If localisation or some part of it failed, repeat with fallback.
|
||||
// If it did fail as well, it's probably because fallback was disabled,
|
||||
@ -440,11 +445,20 @@ impl LocalizationGuard {
|
||||
Err(broken_text) => self
|
||||
.fallback
|
||||
.as_ref()
|
||||
.and_then(|fb| get_content_for_lang(fb, content).ok())
|
||||
.and_then(|fb| Self::get_content_for_lang(fb, content).ok())
|
||||
.unwrap_or(broken_text),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_content_fallback(&self, content: &Content) -> String {
|
||||
self.fallback
|
||||
.as_ref()
|
||||
.map(|fb| Self::get_content_for_lang(fb, content))
|
||||
.transpose()
|
||||
.map(|msg| msg.unwrap_or_default())
|
||||
.unwrap_or_else(|e| e)
|
||||
}
|
||||
|
||||
/// NOTE: Exists for legacy reasons, avoid.
|
||||
///
|
||||
/// Get a localized text from the variation of given key with given
|
||||
|
@ -594,34 +594,48 @@ impl<'a> Widget for Crafting<'a> {
|
||||
// then unavailable ones, each sorted by quality and then alphabetically
|
||||
// In the tuple, "name" is the recipe book key, and "recipe.output.0.name()"
|
||||
// is the display name (as stored in the item descriptors)
|
||||
fn content_contains(content: &common::comp::Content, s: &str) -> bool {
|
||||
match content {
|
||||
common::comp::Content::Plain(p) => p.contains(s),
|
||||
common::comp::Content::Key(k) => k.contains(s),
|
||||
common::comp::Content::Attr(k, _) => k.contains(s),
|
||||
common::comp::Content::Localized { key, .. } => key.contains(s),
|
||||
}
|
||||
}
|
||||
let search = |item: &Arc<ItemDef>| {
|
||||
let (name_key, _) = item.i18n(self.item_i18n);
|
||||
let fallback_name = self
|
||||
.localized_strings
|
||||
.get_content_fallback(&name_key)
|
||||
.to_lowercase();
|
||||
let name = self.localized_strings.get_content(&name_key).to_lowercase();
|
||||
|
||||
search_keys.iter().all(|&substring| {
|
||||
name.contains(substring)
|
||||
|| fallback_name.contains(substring)
|
||||
|| content_contains(&name_key, substring)
|
||||
})
|
||||
};
|
||||
let mut ordered_recipes: Vec<_> = self
|
||||
.client
|
||||
.recipe_book()
|
||||
.iter()
|
||||
.filter(|(_, recipe)| match search_filter {
|
||||
SearchFilter::None => {
|
||||
#[allow(deprecated)]
|
||||
let output_name = recipe.output.0.name().to_lowercase();
|
||||
search_keys
|
||||
.iter()
|
||||
.all(|&substring| output_name.contains(substring))
|
||||
search(&recipe.output.0)
|
||||
},
|
||||
SearchFilter::Input => recipe.inputs().any(|(input, _, _)| {
|
||||
let search = |input_name: &str| {
|
||||
let input_name = input_name.to_lowercase();
|
||||
let search_tag = |name: &str| {
|
||||
search_keys
|
||||
.iter()
|
||||
.all(|&substring| input_name.contains(substring))
|
||||
.all(|&substring| name.contains(substring))
|
||||
};
|
||||
|
||||
match input {
|
||||
#[allow(deprecated)]
|
||||
RecipeInput::Item(def) => search(&def.name()),
|
||||
RecipeInput::Tag(tag) => search(tag.name()),
|
||||
RecipeInput::TagSameItem(tag) => search(tag.name()),
|
||||
#[allow(deprecated)]
|
||||
RecipeInput::Item(def) => search(def),
|
||||
RecipeInput::Tag(tag) => search_tag(tag.name()),
|
||||
RecipeInput::TagSameItem(tag) => search_tag(tag.name()),
|
||||
RecipeInput::ListSameItem(defs) => {
|
||||
defs.iter().any(|def| search(&def.name()))
|
||||
defs.iter().any(search)
|
||||
},
|
||||
}
|
||||
}),
|
||||
|
Loading…
Reference in New Issue
Block a user