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 {
|
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
|
/// Get a localized text from the given key
|
||||||
///
|
///
|
||||||
/// First lookup is done in the active language, second in
|
/// 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>> {
|
pub fn try_msg(&self, key: &str) -> Option<Cow<str>> {
|
||||||
self.active
|
self.active
|
||||||
.try_msg(key, None)
|
.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
|
/// 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.
|
/// Tries its best to localize compound message.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
@ -383,55 +436,7 @@ impl LocalizationGuard {
|
|||||||
//
|
//
|
||||||
// TODO: return Cow<str>?
|
// TODO: return Cow<str>?
|
||||||
pub fn get_content(&self, content: &Content) -> String {
|
pub fn get_content(&self, content: &Content) -> String {
|
||||||
// Function to localize content for given language.
|
match Self::get_content_for_lang(&self.active, content) {
|
||||||
//
|
|
||||||
// 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) {
|
|
||||||
Ok(text) => text,
|
Ok(text) => text,
|
||||||
// If localisation or some part of it failed, repeat with fallback.
|
// If localisation or some part of it failed, repeat with fallback.
|
||||||
// If it did fail as well, it's probably because fallback was disabled,
|
// If it did fail as well, it's probably because fallback was disabled,
|
||||||
@ -440,11 +445,20 @@ impl LocalizationGuard {
|
|||||||
Err(broken_text) => self
|
Err(broken_text) => self
|
||||||
.fallback
|
.fallback
|
||||||
.as_ref()
|
.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),
|
.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.
|
/// NOTE: Exists for legacy reasons, avoid.
|
||||||
///
|
///
|
||||||
/// Get a localized text from the variation of given key with given
|
/// 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
|
// then unavailable ones, each sorted by quality and then alphabetically
|
||||||
// In the tuple, "name" is the recipe book key, and "recipe.output.0.name()"
|
// In the tuple, "name" is the recipe book key, and "recipe.output.0.name()"
|
||||||
// is the display name (as stored in the item descriptors)
|
// 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
|
let mut ordered_recipes: Vec<_> = self
|
||||||
.client
|
.client
|
||||||
.recipe_book()
|
.recipe_book()
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|(_, recipe)| match search_filter {
|
.filter(|(_, recipe)| match search_filter {
|
||||||
SearchFilter::None => {
|
SearchFilter::None => {
|
||||||
#[allow(deprecated)]
|
search(&recipe.output.0)
|
||||||
let output_name = recipe.output.0.name().to_lowercase();
|
|
||||||
search_keys
|
|
||||||
.iter()
|
|
||||||
.all(|&substring| output_name.contains(substring))
|
|
||||||
},
|
},
|
||||||
SearchFilter::Input => recipe.inputs().any(|(input, _, _)| {
|
SearchFilter::Input => recipe.inputs().any(|(input, _, _)| {
|
||||||
let search = |input_name: &str| {
|
let search_tag = |name: &str| {
|
||||||
let input_name = input_name.to_lowercase();
|
|
||||||
search_keys
|
search_keys
|
||||||
.iter()
|
.iter()
|
||||||
.all(|&substring| input_name.contains(substring))
|
.all(|&substring| name.contains(substring))
|
||||||
};
|
};
|
||||||
|
|
||||||
match input {
|
match input {
|
||||||
#[allow(deprecated)]
|
RecipeInput::Item(def) => search(def),
|
||||||
RecipeInput::Item(def) => search(&def.name()),
|
RecipeInput::Tag(tag) => search_tag(tag.name()),
|
||||||
RecipeInput::Tag(tag) => search(tag.name()),
|
RecipeInput::TagSameItem(tag) => search_tag(tag.name()),
|
||||||
RecipeInput::TagSameItem(tag) => search(tag.name()),
|
|
||||||
#[allow(deprecated)]
|
|
||||||
RecipeInput::ListSameItem(defs) => {
|
RecipeInput::ListSameItem(defs) => {
|
||||||
defs.iter().any(|def| search(&def.name()))
|
defs.iter().any(search)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
Loading…
Reference in New Issue
Block a user