WIP proof of concept to add localization using fluent-rs

This commit is contained in:
2024-12-05 11:47:54 -05:00
parent 900d13ad4d
commit 0e87c22e55
5 changed files with 227 additions and 5 deletions

189
Cargo.lock generated
View File

@@ -313,6 +313,17 @@ dependencies = [
"syn 2.0.89", "syn 2.0.89",
] ]
[[package]]
name = "async-trait"
version = "0.1.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.89",
]
[[package]] [[package]]
name = "atomic-waker" name = "atomic-waker"
version = "1.1.2" version = "1.1.2"
@@ -757,6 +768,12 @@ dependencies = [
"zeroize", "zeroize",
] ]
[[package]]
name = "chunky-vec"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb7bdea464ae038f09197b82430b921c53619fc8d2bcaf7b151013b3ca008017"
[[package]] [[package]]
name = "cipher" name = "cipher"
version = "0.4.4" version = "0.4.4"
@@ -1038,6 +1055,17 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b"
[[package]]
name = "displaydoc"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.89",
]
[[package]] [[package]]
name = "dlib" name = "dlib"
version = "0.5.2" version = "0.5.2"
@@ -1250,6 +1278,15 @@ version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
[[package]]
name = "elsa"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d98e71ae4df57d214182a2e5cb90230c0192c6ddfcaa05c36453d46a54713e10"
dependencies = [
"stable_deref_trait",
]
[[package]] [[package]]
name = "emath" name = "emath"
version = "0.27.2" version = "0.27.2"
@@ -1458,6 +1495,81 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4"
[[package]]
name = "fluent"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb74634707bebd0ce645a981148e8fb8c7bccd4c33c652aeffd28bf2f96d555a"
dependencies = [
"fluent-bundle",
"unic-langid",
]
[[package]]
name = "fluent-bundle"
version = "0.15.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fe0a21ee80050c678013f82edf4b705fe2f26f1f9877593d13198612503f493"
dependencies = [
"fluent-langneg",
"fluent-syntax",
"intl-memoizer",
"intl_pluralrules",
"rustc-hash 1.1.0",
"self_cell 0.10.3",
"smallvec",
"unic-langid",
]
[[package]]
name = "fluent-fallback"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1010c29cde3a7eeb231c59d95411dcea1c1d91ad00dd733b076dbd885815024a"
dependencies = [
"async-trait",
"chunky-vec",
"fluent-bundle",
"futures",
"once_cell",
"pin-cell",
"rustc-hash 1.1.0",
"unic-langid",
]
[[package]]
name = "fluent-langneg"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c4ad0989667548f06ccd0e306ed56b61bd4d35458d54df5ec7587c0e8ed5e94"
dependencies = [
"unic-langid",
]
[[package]]
name = "fluent-resmgr"
version = "0.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2a2360469fd304ea6560a6dfb8f843328d3a6498f1c867f187e57993609af7e"
dependencies = [
"elsa",
"fluent-bundle",
"fluent-fallback",
"futures",
"rustc-hash 1.1.0",
"thiserror 1.0.63",
"unic-langid",
]
[[package]]
name = "fluent-syntax"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a530c4694a6a8d528794ee9bbd8ba0122e779629ac908d15ad5a7ae7763a33d"
dependencies = [
"thiserror 1.0.63",
]
[[package]] [[package]]
name = "flume" name = "flume"
version = "0.11.0" version = "0.11.0"
@@ -2063,6 +2175,25 @@ dependencies = [
"syn 2.0.89", "syn 2.0.89",
] ]
[[package]]
name = "intl-memoizer"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe22e020fce238ae18a6d5d8c502ee76a52a6e880d99477657e6acc30ec57bda"
dependencies = [
"type-map",
"unic-langid",
]
[[package]]
name = "intl_pluralrules"
version = "7.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "078ea7b7c29a2b4df841a7f6ac8775ff6074020c6776d48491ce2268e068f972"
dependencies = [
"unic-langid",
]
[[package]] [[package]]
name = "ipnet" name = "ipnet"
version = "2.10.0" version = "2.10.0"
@@ -2617,6 +2748,9 @@ dependencies = [
"ehttp 0.2.0", "ehttp 0.2.0",
"enostr", "enostr",
"env_logger 0.10.2", "env_logger 0.10.2",
"fluent",
"fluent-fallback",
"fluent-resmgr",
"hex", "hex",
"image", "image",
"indexmap", "indexmap",
@@ -2639,6 +2773,7 @@ dependencies = [
"tracing-appender", "tracing-appender",
"tracing-subscriber", "tracing-subscriber",
"tracing-wasm", "tracing-wasm",
"unic-langid",
"url", "url",
"urlencoding", "urlencoding",
"uuid", "uuid",
@@ -3035,6 +3170,12 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315"
[[package]]
name = "pin-cell"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1f4c4ebd3c5f82080164b7d9cc8e505cd9536fda8c750b779daceb4b7180a7b"
[[package]] [[package]]
name = "pin-project" name = "pin-project"
version = "1.1.5" version = "1.1.5"
@@ -3871,6 +4012,21 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "self_cell"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e14e4d63b804dc0c7ec4a1e52bcb63f02c7ac94476755aa579edac21e01f915d"
dependencies = [
"self_cell 1.0.4",
]
[[package]]
name = "self_cell"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d369a96f978623eb3dc28807c4852d6cc617fed53da5d3c400feff1ef34a714a"
[[package]] [[package]]
name = "semver" name = "semver"
version = "1.0.23" version = "1.0.23"
@@ -4126,6 +4282,12 @@ dependencies = [
"bitflags 2.6.0", "bitflags 2.6.0",
] ]
[[package]]
name = "stable_deref_trait"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]] [[package]]
name = "static_assertions" name = "static_assertions"
version = "1.1.0" version = "1.1.0"
@@ -4366,6 +4528,15 @@ dependencies = [
"strict-num", "strict-num",
] ]
[[package]]
name = "tinystr"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f"
dependencies = [
"displaydoc",
]
[[package]] [[package]]
name = "tinyvec" name = "tinyvec"
version = "1.8.0" version = "1.8.0"
@@ -4662,6 +4833,24 @@ version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
[[package]]
name = "unic-langid"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23dd9d1e72a73b25e07123a80776aae3e7b0ec461ef94f9151eed6ec88005a44"
dependencies = [
"unic-langid-impl",
]
[[package]]
name = "unic-langid-impl"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a5422c1f65949306c99240b81de9f3f15929f5a8bfe05bb44b034cc8bf593e5"
dependencies = [
"tinystr",
]
[[package]] [[package]]
name = "unicase" name = "unicase"
version = "2.7.0" version = "2.7.0"

View File

@@ -56,6 +56,10 @@ tracing-appender = "0.2.3"
urlencoding = "2.1.3" urlencoding = "2.1.3"
open = "5.3.0" open = "5.3.0"
url = "2.5" url = "2.5"
fluent-resmgr = "0.0.7"
fluent-fallback = "0.7.1"
fluent = "0.16.1"
unic-langid = "0.9.5"
[dev-dependencies] [dev-dependencies]
tempfile = "3.13.0" tempfile = "3.13.0"

View File

@@ -0,0 +1 @@
universe-title = Universe with Fluent Translation

View File

@@ -37,6 +37,8 @@ use std::path::Path;
use std::time::Duration; use std::time::Duration;
use tracing::{error, info, trace, warn}; use tracing::{error, info, trace, warn};
use fluent_resmgr::resource_manager::ResourceManager;
#[derive(Debug, Eq, PartialEq, Clone)] #[derive(Debug, Eq, PartialEq, Clone)]
pub enum DamusState { pub enum DamusState {
Initializing, Initializing,
@@ -69,6 +71,8 @@ pub struct Damus {
pub debug: bool, pub debug: bool,
pub since_optimize: bool, pub since_optimize: bool,
pub textmode: bool, pub textmode: bool,
pub res_mgr: ResourceManager,
} }
fn handle_key_events(input: &egui::InputState, _pixels_per_point: f32, columns: &mut Columns) { fn handle_key_events(input: &egui::InputState, _pixels_per_point: f32, columns: &mut Columns) {
@@ -471,6 +475,8 @@ impl Damus {
let app_rect_handler = AppSizeHandler::new(&path); let app_rect_handler = AppSizeHandler::new(&path);
let support = Support::new(&path); let support = Support::new(&path);
let res_mgr = ResourceManager::new("./assets/translations/{locale}/{res_id}".into());
Self { Self {
pool, pool,
debug, debug,
@@ -492,6 +498,7 @@ impl Damus {
path, path,
app_rect_handler, app_rect_handler,
support, support,
res_mgr,
} }
} }
@@ -557,6 +564,8 @@ impl Damus {
let config = Config::new().set_ingester_threads(2); let config = Config::new().set_ingester_threads(2);
let res_mgr = ResourceManager::new("../assets/translations/{locale}/{res_id}".into());
Self { Self {
debug, debug,
unknown_ids: UnknownIds::default(), unknown_ids: UnknownIds::default(),
@@ -585,6 +594,7 @@ impl Damus {
path, path,
app_rect_handler, app_rect_handler,
support, support,
res_mgr,
} }
} }

View File

@@ -2,10 +2,7 @@ use core::f32;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::collections::HashMap; use std::collections::HashMap;
use egui::{ use egui::{pos2, vec2, Align, Button, Color32, FontId, Id, ImageSource, Margin, Pos2, Rect, RichText, Separator, TextBuffer, Ui, Vec2};
pos2, vec2, Align, Button, Color32, FontId, Id, ImageSource, Margin, Pos2, Rect, RichText,
Separator, Ui, Vec2,
};
use nostrdb::Ndb; use nostrdb::Ndb;
use tracing::error; use tracing::error;
@@ -18,6 +15,9 @@ use crate::{
Damus, Damus,
}; };
use fluent_resmgr::resource_manager::ResourceManager;
use unic_langid::LanguageIdentifier;
use super::{anim::AnimationHelper, padding}; use super::{anim::AnimationHelper, padding};
pub enum AddColumnResponse { pub enum AddColumnResponse {
@@ -85,6 +85,7 @@ pub struct AddColumnView<'a> {
key_state_map: &'a mut HashMap<Id, AcquireKeyState>, key_state_map: &'a mut HashMap<Id, AcquireKeyState>,
ndb: &'a Ndb, ndb: &'a Ndb,
cur_account: Option<&'a UserAccount>, cur_account: Option<&'a UserAccount>,
res_mgr: &'a ResourceManager,
} }
impl<'a> AddColumnView<'a> { impl<'a> AddColumnView<'a> {
@@ -92,11 +93,13 @@ impl<'a> AddColumnView<'a> {
key_state_map: &'a mut HashMap<Id, AcquireKeyState>, key_state_map: &'a mut HashMap<Id, AcquireKeyState>,
ndb: &'a Ndb, ndb: &'a Ndb,
cur_account: Option<&'a UserAccount>, cur_account: Option<&'a UserAccount>,
res_mgr: &'a ResourceManager,
) -> Self { ) -> Self {
Self { Self {
key_state_map, key_state_map,
ndb, ndb,
cur_account, cur_account,
res_mgr,
} }
} }
@@ -276,9 +279,22 @@ impl<'a> AddColumnView<'a> {
} }
fn get_base_options(&self) -> Vec<ColumnOptionData> { fn get_base_options(&self) -> Vec<ColumnOptionData> {
let default_locale: LanguageIdentifier = "en-US".parse().expect("Parsing failed.");
let resources = vec!["notedeck.ftl".into()];
let bundle = self.res_mgr
.get_bundle(
vec![default_locale],
resources,
)
.expect("Could not get bundle");
let mut errors = vec![];
let msg = bundle.get_message("universe-title").expect("Message exists");
let pattern = msg.value().expect("Message has a value");
let value: &'static mut str = bundle.format_pattern(pattern, None, &mut errors).to_string().leak();
let mut vec = Vec::new(); let mut vec = Vec::new();
vec.push(ColumnOptionData { vec.push(ColumnOptionData {
title: "Universe", title: value,
description: "See the whole nostr universe", description: "See the whole nostr universe",
icon: egui::include_image!("../../assets/icons/universe_icon_dark_4x.png"), icon: egui::include_image!("../../assets/icons/universe_icon_dark_4x.png"),
option: AddColumnOption::Universe, option: AddColumnOption::Universe,
@@ -356,6 +372,7 @@ pub fn render_add_column_routes(
&mut app.view_state.id_state_map, &mut app.view_state.id_state_map,
&app.ndb, &app.ndb,
app.accounts.get_selected_account(), app.accounts.get_selected_account(),
&app.res_mgr,
); );
let resp = match route { let resp = match route {
AddColumnRoute::Base => add_column_view.ui(ui), AddColumnRoute::Base => add_column_view.ui(ui),
@@ -463,6 +480,7 @@ mod preview {
&mut self.app.view_state.id_state_map, &mut self.app.view_state.id_state_map,
&self.app.ndb, &self.app.ndb,
self.app.accounts.get_selected_account(), self.app.accounts.get_selected_account(),
&self.app.res_mgr,
) )
.ui(ui); .ui(ui);
} }