aboutsummaryrefslogtreecommitdiff
path: root/ui
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2026-01-23 17:41:45 +0100
committermetamuffin <metamuffin@disroot.org>2026-01-23 17:41:45 +0100
commit774f64c0789529884dd7a5232f190e347ad29532 (patch)
tree6eb85388837c993a054fba5ca59fdd329f5b5840 /ui
parent3671a4e07565c86f8071fb2309f463aeaf684ba3 (diff)
downloadjellything-774f64c0789529884dd7a5232f190e347ad29532.tar
jellything-774f64c0789529884dd7a5232f190e347ad29532.tar.bz2
jellything-774f64c0789529884dd7a5232f190e347ad29532.tar.zst
move locale code to own crate
Diffstat (limited to 'ui')
-rw-r--r--ui/Cargo.toml5
-rw-r--r--ui/locale/Cargo.toml7
-rw-r--r--ui/locale/src/lib.rs73
-rw-r--r--ui/src/components/mod.rs10
-rw-r--r--ui/src/components/node_page.rs3
-rw-r--r--ui/src/components/props.rs2
-rw-r--r--ui/src/components/stats.rs2
-rw-r--r--ui/src/format.rs19
-rw-r--r--ui/src/lib.rs13
-rw-r--r--ui/src/locale.rs52
-rw-r--r--ui/src/scaffold.rs6
11 files changed, 112 insertions, 80 deletions
diff --git a/ui/Cargo.toml b/ui/Cargo.toml
index 8752938..9bf5082 100644
--- a/ui/Cargo.toml
+++ b/ui/Cargo.toml
@@ -4,10 +4,13 @@ version = "0.1.0"
edition = "2024"
[dependencies]
-markup = "0.15.0"
+markup = { git = "https://github.com/metamuffin/markup.rs", rev = "2ee9aee" }
jellycommon = { path = "../common" }
humansize = "2.1.3"
serde = { version = "1.0.228", features = ["derive", "rc"] }
serde_json = "1.0.145"
vte = "0.15.0"
chrono = "0.4.43"
+jellyui-client-scripts = { path = "client-scripts" }
+jellyui-client-style = { path = "client-style" }
+jellyui-locale = { path = "locale" }
diff --git a/ui/locale/Cargo.toml b/ui/locale/Cargo.toml
new file mode 100644
index 0000000..5e2b14d
--- /dev/null
+++ b/ui/locale/Cargo.toml
@@ -0,0 +1,7 @@
+[package]
+name = "jellyui-locale"
+version = "0.1.0"
+edition = "2024"
+
+[features]
+reload = []
diff --git a/ui/locale/src/lib.rs b/ui/locale/src/lib.rs
new file mode 100644
index 0000000..2028418
--- /dev/null
+++ b/ui/locale/src/lib.rs
@@ -0,0 +1,73 @@
+/*
+ This file is part of jellything (https://codeberg.org/metamuffin/jellything)
+ which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
+ Copyright (C) 2026 metamuffin <metamuffin.org>
+*/
+use std::{borrow::Cow, collections::HashMap, sync::LazyLock};
+
+macro_rules! languages {
+ ($($lang:literal),*) => {
+ #[cfg(feature = "reload")]
+ const LANGUAGES: &[&str] = &[$($lang),*];
+ #[cfg(not(feature = "reload"))]
+ const LANGUAGES: &[(&str, &str)] = &[$(($lang, include_str!(concat!("../../../locale/", $lang, ".ini")))),*];
+ };
+}
+languages!("en", "de");
+
+pub static LANG_TABLES: LazyLock<HashMap<&'static str, HashMap<&'static str, &'static str>>> =
+ LazyLock::new(|| {
+ let mut langs = LANGUAGES
+ .iter()
+ .map(|(k, v)| (*k, parse_ini(v)))
+ .collect::<HashMap<_, _>>();
+
+ let fallback = langs["en"].clone();
+ for l in langs.values_mut() {
+ for (k, fv) in &fallback {
+ if !l.contains_key(k) {
+ l.insert(k, fv);
+ }
+ }
+ }
+ langs
+ });
+
+fn parse_ini<'a>(source: &'a str) -> HashMap<&'a str, &'a str> {
+ source
+ .lines()
+ .filter_map(|line| {
+ let (key, value) = line.split_once("=")?;
+ Some((key.trim(), value.trim()))
+ })
+ .collect()
+}
+
+pub fn tr(lang: &str, key: &str) -> Cow<'static, str> {
+ let tr_map = LANG_TABLES.get(&lang).unwrap();
+ tr_map
+ .get(key)
+ .copied()
+ .unwrap_or("MISSING TRANSLATION")
+ .into()
+}
+
+pub fn escape(str: &str) -> String {
+ let mut o = String::with_capacity(str.len());
+ let mut last = 0;
+ for (index, byte) in str.bytes().enumerate() {
+ if let Some(esc) = match byte {
+ b'<' => Some("&lt;"),
+ b'>' => Some("&gt;"),
+ b'&' => Some("&amp;"),
+ b'"' => Some("&quot;"),
+ _ => None,
+ } {
+ o += &str[last..index];
+ o += esc;
+ last = index + 1;
+ }
+ }
+ o += &str[last..];
+ o
+}
diff --git a/ui/src/components/mod.rs b/ui/src/components/mod.rs
index 4d2dd62..07b050b 100644
--- a/ui/src/components/mod.rs
+++ b/ui/src/components/mod.rs
@@ -9,8 +9,11 @@ pub mod node_page;
pub mod props;
pub mod stats;
-use crate::{RenderInfo, components::message::Message};
-use jellycommon::{VIEW_MESSAGE, jellyobject::Object};
+use crate::{
+ RenderInfo,
+ components::{message::Message, node_page::NodePage},
+};
+use jellycommon::{jellyobject::Object, *};
use markup::define;
define! {
@@ -18,5 +21,8 @@ define! {
@if let Some(message) = view.get(VIEW_MESSAGE) {
@Message { ri, message }
}
+ @if let Some(nku) = view.get(VIEW_NODE_PAGE) {
+ @NodePage { ri, nku }
+ }
}
}
diff --git a/ui/src/components/node_page.rs b/ui/src/components/node_page.rs
index 4a594d6..405f50a 100644
--- a/ui/src/components/node_page.rs
+++ b/ui/src/components/node_page.rs
@@ -4,12 +4,13 @@
Copyright (C) 2026 metamuffin <metamuffin.org>
*/
-use crate::{RenderInfo, components::props::Props, locale::tr};
+use crate::{RenderInfo, components::props::Props};
use jellycommon::{
jellyobject::{Object, Tag, TypedTag},
routes::{u_image, u_node_slug_player},
*,
};
+use jellyui_locale::tr;
use std::marker::PhantomData;
markup::define! {
diff --git a/ui/src/components/props.rs b/ui/src/components/props.rs
index f23d72e..fa078e7 100644
--- a/ui/src/components/props.rs
+++ b/ui/src/components/props.rs
@@ -7,13 +7,13 @@
use crate::{
RenderInfo,
format::{format_count, format_duration},
- locale::tr,
};
use chrono::DateTime;
use jellycommon::{
jellyobject::{Object, TypedTag},
*,
};
+use jellyui_locale::tr;
use std::marker::PhantomData;
markup::define! {
diff --git a/ui/src/components/stats.rs b/ui/src/components/stats.rs
index 8dfb304..698430b 100644
--- a/ui/src/components/stats.rs
+++ b/ui/src/components/stats.rs
@@ -7,9 +7,9 @@
use crate::{
RenderInfo,
format::{format_duration, format_duration_long, format_size},
- locale::tr,
};
use jellycommon::{jellyobject::Object, *};
+use jellyui_locale::tr;
use markup::raw;
markup::define! {
diff --git a/ui/src/format.rs b/ui/src/format.rs
index 01982af..4eb8f84 100644
--- a/ui/src/format.rs
+++ b/ui/src/format.rs
@@ -8,17 +8,16 @@ use jellycommon::{
jellyobject::{Object, Tag},
*,
};
-
-use crate::locale::tr;
-use std::fmt::Write;
+use jellyui_locale::tr;
+use std::{borrow::Cow, fmt::Write};
pub fn format_duration(d: f64) -> String {
- format_duration_mode(LANG_ENG.0, d, false)
+ format_duration_mode("en", d, false)
}
-pub fn format_duration_long(lang: Language, d: f64) -> String {
+pub fn format_duration_long(lang: &str, d: f64) -> String {
format_duration_mode(lang, d, true)
}
-fn format_duration_mode(lang: Language, mut d: f64, long_units: bool) -> String {
+fn format_duration_mode(lang: &str, mut d: f64, long_units: bool) -> String {
let mut s = String::new();
let sign = if d > 0. { "" } else { "-" };
d = d.abs();
@@ -58,15 +57,15 @@ fn test_duration_short() {
#[test]
fn test_duration_long() {
assert_eq!(
- format_duration_long(LANG_ENG.0, 61.).as_str(),
+ format_duration_long("en", 61.).as_str(),
"1 minute and 1 second"
);
assert_eq!(
- format_duration_long(LANG_ENG.0, 121.).as_str(),
+ format_duration_long("en", 121.).as_str(),
"2 minutes and 1 second"
);
assert_eq!(
- format_duration_long(LANG_ENG.0, 3661.).as_str(),
+ format_duration_long("en", 3661.).as_str(),
"1 hour, 1 minute and 1 second"
);
}
@@ -74,7 +73,7 @@ fn test_duration_long() {
pub fn format_size(size: u64) -> String {
humansize::format_size(size, humansize::DECIMAL)
}
-pub fn format_kind(lang: Language, kind: Tag) -> &'static str {
+pub fn format_kind(lang: &str, kind: Tag) -> Cow<'static, str> {
tr(
lang,
match kind {
diff --git a/ui/src/lib.rs b/ui/src/lib.rs
index 72109d4..3b04b40 100644
--- a/ui/src/lib.rs
+++ b/ui/src/lib.rs
@@ -5,18 +5,15 @@
*/
mod components;
pub(crate) mod format;
-pub(crate) mod locale;
mod scaffold;
+pub use jellyui_client_scripts::*;
+pub use jellyui_client_style::*;
+
use crate::{components::View, scaffold::Scaffold};
-use jellycommon::{
- jellyobject::{Object, Tag},
- *,
-};
+use jellycommon::{jellyobject::Object, *};
use serde::{Deserialize, Serialize};
-pub type FlashM = Option<(String, String)>;
-
#[rustfmt::skip]
#[derive(Debug, Deserialize, Serialize, Default)]
pub struct Config {
@@ -27,7 +24,7 @@ pub struct Config {
pub struct RenderInfo<'a> {
pub user: Option<Object<'a>>,
- pub lang: Tag,
+ pub lang: &'a str,
pub status_message: Option<&'a str>,
pub config: &'a Config,
}
diff --git a/ui/src/locale.rs b/ui/src/locale.rs
deleted file mode 100644
index 08c73c2..0000000
--- a/ui/src/locale.rs
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- This file is part of jellything (https://codeberg.org/metamuffin/jellything)
- which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
- Copyright (C) 2026 metamuffin <metamuffin.org>
-*/
-use jellycommon::*;
-use std::{collections::HashMap, sync::LazyLock};
-
-pub static LANG_TABLES: LazyLock<HashMap<Language, HashMap<&'static str, &'static str>>> =
- LazyLock::new(|| {
- let mut k = HashMap::new();
- for (lang, source) in [
- (LANG_ENG.0, include_str!("../../locale/en.ini")),
- (LANG_DEU.0, include_str!("../../locale/de.ini")),
- ] {
- // TODO fallback to english
- let tr_map = source
- .lines()
- .filter_map(|line| {
- let (key, value) = line.split_once("=")?;
- Some((key.trim(), value.trim()))
- })
- .collect::<HashMap<&'static str, &'static str>>();
- k.insert(lang, tr_map);
- }
- k
- });
-
-pub fn tr(lang: Language, key: &str) -> &'static str {
- let tr_map = LANG_TABLES.get(&lang).unwrap();
- tr_map.get(key).copied().unwrap_or("MISSING TRANSLATION")
-}
-
-pub fn escape(str: &str) -> String {
- let mut o = String::with_capacity(str.len());
- let mut last = 0;
- for (index, byte) in str.bytes().enumerate() {
- if let Some(esc) = match byte {
- b'<' => Some("&lt;"),
- b'>' => Some("&gt;"),
- b'&' => Some("&amp;"),
- b'"' => Some("&quot;"),
- _ => None,
- } {
- o += &str[last..index];
- o += esc;
- last = index + 1;
- }
- }
- o += &str[last..];
- o
-}
diff --git a/ui/src/scaffold.rs b/ui/src/scaffold.rs
index fee311a..8cfb432 100644
--- a/ui/src/scaffold.rs
+++ b/ui/src/scaffold.rs
@@ -4,10 +4,7 @@
Copyright (C) 2026 metamuffin <metamuffin.org>
*/
-use crate::{
- RenderInfo,
- locale::{escape, tr},
-};
+use crate::RenderInfo;
use jellycommon::{
routes::{
u_account_login, u_account_logout, u_account_register, u_account_settings,
@@ -15,6 +12,7 @@ use jellycommon::{
},
user::{USER_ADMIN, USER_NAME},
};
+use jellyui_locale::{escape, tr};
use markup::{Render, raw};
markup::define! {