Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use case question - Translating based on a "settings drop-down list" #41

Closed
psionikangel opened this issue Oct 16, 2020 · 9 comments
Closed
Labels
question Further information is requested

Comments

@psionikangel
Copy link

psionikangel commented Oct 16, 2020

Hi @kellpossible !

I have a use case question for you. I am working on adding localization on a rust app based on the very good iced UI framework. You can see the PR here if you are curious, but the extra context shouldn't be necessary to answer my question.

Initially, I had used your library to translate the app based on the system locale (which worked wonderfully on both Mac OS and Windows). Then I tried to make the translation based on a "locale dropdown list" in the settings. (Meaning the fallback language would always be the default when the app loaded, but then the user could go in the settings, select an available language from the dropdown and the app would translate on the fly).

I have tried to achieve that using this example from your documentation

use std::rc::Rc;
use i18n_embed::{
    DesktopLanguageRequester, LanguageRequester,
    DefaultLocalizer, Localizer, fluent::FluentLanguageLoader     
};
use rust_embed::RustEmbed; use lazy_static::lazy_static;
use unic_langid::LanguageIdentifier;

#[derive(RustEmbed)]
#[folder = "i18n/ftl"] // path to localization resources
struct Translations;

const TRANSLATIONS: Translations = Translations {};

lazy_static! {
    static ref LANGUAGE_LOADER: FluentLanguageLoader = {
        // Usually you could use the fluent_language_loader!() macro
        // to pull values from i18n.toml configuration and current
        // module here at compile time, but instantiating the loader
        // manually here instead so the example compiles.
        let fallback: LanguageIdentifier = "en-US".parse().unwrap();
        FluentLanguageLoader::new("test", fallback)
    };
}

fn main() {
    let localizer = DefaultLocalizer::new(&*LANGUAGE_LOADER, &TRANSLATIONS);

    let localizer_rc: Rc<dyn Localizer> = Rc::new(localizer);

    let mut language_requester = DesktopLanguageRequester::new();
    language_requester.add_listener(Rc::downgrade(&localizer_rc));

    // Manually check the currently requested system language,
    // and update the listeners. When the system language changes,
    // this will automatically be triggered.
    language_requester.poll().unwrap();

    // continue on with your application
}

However, when trying it out I can't figure out why the translations aren't applied when I switch language in the settings. (After selecting the new language, the UI view refreshes and the UI elements are recreated, which in theory goes through the tr!() macro again and should produce UI elements with translated text).

The method I tried was to switch the current thread locale with

        let loc = Locale::new(&self.language_state.current_language_name);
        locale_config::Locale::set_current(loc.unwrap());

But when using the debugger I can confirm that it doesn't seem to trigger anything.

The base question that I have I guess would be:

On what system event or other mechanism is the listener bound to in order to determine that the system requested language has changed?

And maybe a follow-up question would be :

Is the use-case that I'm trying to solve is at all supported by using your library? (I'm a complete newbie to Rust, so it would be very possible that I just didn't understand the library well enough before settling on using it).

Sorry for the very long rambling, I hope the question I have make sense.

Regards,

@kellpossible
Copy link
Owner

kellpossible commented Oct 17, 2020

Hi @psionikangel great news, I'm also interested to try out iced when it gets a few more features, and support for older systems!

However, when trying it out I can't figure out why the translations aren't applied when I switch language in the settings. (After selecting the new language, the UI view refreshes and the UI elements are recreated, which in theory goes through the tr!() macro again and should produce UI elements with translated text).

By switching languages in the settings, do you mean in the system settings? I tried to implement support for detecting changes to system selected display language in the past, but closed the issue because it seemed difficult to implement on the desktop platform #30 I can't remember if I finished implementing support for it in the browser, but it was something that I had intended with the design but didn't seem super urgent because the user could just refresh the page to get the same effect. I should probably update the comment in that example to reflect the current state of support for this feature, as it's misleading, and I'm sorry if it caused some headaches! I'll do it soon when I update the library to the latest version of Fluent 🙂

In my applications, I've instead opted to make switching language at runtime an option in the application's settings.

@kellpossible kellpossible added the question Further information is requested label Oct 17, 2020
@kellpossible
Copy link
Owner

I hope I've addressed some of these issues in the new i18-embed release 0.8.6 0083551

@psionikangel
Copy link
Author

psionikangel commented Oct 19, 2020

I was trying at runtime in the application's settings. So based on your comment, that should work?

I guess then if you could point me at some example code to achieve that I would be very grateful, because as I said in my original post, switching the locale of the main thread did not trigger the listener as I was expecting it.

@kellpossible
Copy link
Owner

@psionikangel yes it should work, but you'll have to do the change a different way, using the i18n-embed library directly via select() or the FluentLanguageLoader::load_languages() method (LanguageLoader implementation)

@casperstorm
Copy link

I'll take a stab at this @psionikangel – will use what you have done so far.

@kellpossible
Copy link
Owner

@psionikangel do you think the question is answered here okay? Or is there some more that could be done? I'll certainly make a mental note that when some GUI examples are added for this project to include a change language dropdown list

@psionikangel
Copy link
Author

@kellpossible Yes, thank you for answering. You can close the issue. In the end, it was decided to postpone the translating feature because the UI framework mentionned above (iced) doesn't support all the charactersets that were needed for certain languages.

@kellpossible
Copy link
Owner

Just tried to make an example of this using iced, and ran into the same problem, do you know if there is a tracking issue for it in iced?

@psionikangel
Copy link
Author

Yes, it is iced-rs/iced#103

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants