diff options
Diffstat (limited to 'server/src/routes/ui/node.rs')
-rw-r--r-- | server/src/routes/ui/node.rs | 81 |
1 files changed, 52 insertions, 29 deletions
diff --git a/server/src/routes/ui/node.rs b/server/src/routes/ui/node.rs index 57e8562..e94547c 100644 --- a/server/src/routes/ui/node.rs +++ b/server/src/routes/ui/node.rs @@ -9,12 +9,14 @@ use super::{ rocket_uri_macro_r_node_thumbnail, }, error::MyResult, + layout::{trs, trsa}, sort::{filter_and_sort_nodes, NodeFilterSort, NodeFilterSortForm, SortOrder, SortProperty}, }; use crate::{ database::Database, routes::{ api::AcceptJson, + locale::AcceptLanguage, ui::{ account::session::Session, assets::rocket_uri_macro_r_person_asset, @@ -30,6 +32,7 @@ use crate::{ }; use anyhow::{anyhow, Result}; use chrono::DateTime; +use jellybase::locale::Language; use jellycommon::{ api::ApiNodeResponse, user::{NodeUserData, WatchedState}, @@ -51,9 +54,11 @@ pub async fn r_library_node_filter<'a>( db: &'a State<Database>, aj: AcceptJson, filter: NodeFilterSort, + lang: AcceptLanguage, parents: bool, children: bool, ) -> MyResult<Either<DynLayoutPage<'a>, Json<ApiNodeResponse>>> { + let AcceptLanguage(lang) = lang; let (node, udata) = db.get_node_with_userdata(id, &session)?; let mut children = if !*aj || children { @@ -100,9 +105,16 @@ pub async fn r_library_node_filter<'a>( } else { Either::Left(LayoutPage { title: node.title.clone().unwrap_or_default(), - content: markup::new! { - @NodePage { node: &node, udata: &udata, children: &children, parents: &parents, filter: &filter, player: false, similar: &similar } - }, + content: markup::new!(@NodePage { + node: &node, + udata: &udata, + children: &children, + parents: &parents, + filter: &filter, + player: false, + similar: &similar, + lang: &lang, + }), ..Default::default() }) }) @@ -134,7 +146,7 @@ pub fn get_similar_media( } markup::define! { - NodeCard<'a>(node: &'a Node, udata: &'a NodeUserData) { + NodeCard<'a>(node: &'a Node, udata: &'a NodeUserData, lang: &'a Language) { @let cls = format!("node card poster {}", aspect_class(node.kind)); div[class=cls] { .poster { @@ -145,7 +157,7 @@ markup::define! { @if node.media.is_some() { a.play.icon[href=&uri!(r_player(&node.slug, PlayerConfig::default()))] { "play_arrow" } } - @Props { node, udata, full: false } + @Props { node, udata, full: false, lang } } } div.title { @@ -160,7 +172,7 @@ markup::define! { } } } - NodeCardWide<'a>(node: &'a Node, udata: &'a NodeUserData) { + NodeCardWide<'a>(node: &'a Node, udata: &'a NodeUserData, lang: &'a Language) { div[class="node card widecard poster"] { div[class=&format!("poster {}", aspect_class(node.kind))] { a[href=uri!(r_library_node(&node.slug))] { @@ -174,12 +186,21 @@ markup::define! { } div.details { a.title[href=uri!(r_library_node(&node.slug))] { @node.title } - @Props { node, udata, full: false } + @Props { node, udata, full: false, lang } span.overview { @node.description } } } } - NodePage<'a>(node: &'a Node, udata: &'a NodeUserData, children: &'a [(Arc<Node>, NodeUserData)], parents: &'a [(Arc<Node>, NodeUserData)], similar: &'a [(Arc<Node>, NodeUserData)], filter: &'a NodeFilterSort, player: bool) { + NodePage<'a>( + node: &'a Node, + udata: &'a NodeUserData, + children: &'a [(Arc<Node>, NodeUserData)], + parents: &'a [(Arc<Node>, NodeUserData)], + similar: &'a [(Arc<Node>, NodeUserData)], + filter: &'a NodeFilterSort, + lang: &'a Language, + player: bool, + ) { @if !matches!(node.kind, NodeKind::Collection) && !player { img.backdrop[src=uri!(r_item_backdrop(&node.slug, Some(2048))), loading="lazy"]; } @@ -193,26 +214,28 @@ markup::define! { ul.parents { @for (node, _) in *parents { li { a.component[href=uri!(r_library_node(&node.slug))] { @node.title } }}} - @if node.media.is_some() { a.play[href=&uri!(r_player(&node.slug, PlayerConfig::default()))] { "Watch now" }} + @if node.media.is_some() { + a.play[href=&uri!(r_player(&node.slug, PlayerConfig::default()))] { @trs(lang, "node.player_link") } + } @if !matches!(node.kind, NodeKind::Collection | NodeKind::Channel) { @if matches!(udata.watched, WatchedState::None | WatchedState::Pending | WatchedState::Progress(_)) { form.mark_watched[method="POST", action=uri!(r_node_userdata_watched(&node.slug, UrlWatchedState::Watched))] { - input[type="submit", value="Mark Watched"]; + input[type="submit", value=trs(lang, "node.watched.set")]; } } @if matches!(udata.watched, WatchedState::Watched) { form.mark_unwatched[method="POST", action=uri!(r_node_userdata_watched(&node.slug, UrlWatchedState::None))] { - input[type="submit", value="Mark Unwatched"]; + input[type="submit", value=trs(lang, "node.watched.unset")]; } } @if matches!(udata.watched, WatchedState::None) { form.mark_unwatched[method="POST", action=uri!(r_node_userdata_watched(&node.slug, UrlWatchedState::Pending))] { - input[type="submit", value="Add to Watchlist"]; + input[type="submit", value=trs(lang, "node.watchlist.set")]; } } @if matches!(udata.watched, WatchedState::Pending) { form.mark_unwatched[method="POST", action=uri!(r_node_userdata_watched(&node.slug, UrlWatchedState::None))] { - input[type="submit", value="Remove from Watchlist"]; + input[type="submit", value=trs(lang, "node.watchlist.unset")]; } } form.rating[method="POST", action=uri!(r_node_userdata_rating(&node.slug))] { @@ -222,14 +245,14 @@ markup::define! { } } .details { - @Props { node, udata, full: true } + @Props { node, udata, full: true, lang } h3 { @node.tagline } @if let Some(description) = &node.description { p { @for line in description.lines() { @line br; } } } @if let Some(media) = &node.media { @if !media.chapters.is_empty() { - h2 { "Chapters" } + h2 { @trs(lang, "node.chapters") } ul.children.hlist { @for chap in &media.chapters { @let (inl, sub) = format_chapter(chap); li { .card."aspect-thumb" { @@ -244,7 +267,7 @@ markup::define! { }} } @if !node.people.is_empty() { - h2 { "Cast & Crew" } + h2 { @trs(lang, "node.people") } @for (group, people) in &node.people { details[open=group==&PeopleGroup::Cast] { summary { h3 { @format!("{}", group) } } @@ -270,7 +293,7 @@ markup::define! { } } details { - summary { "Tracks" } + summary { @trs(lang, "media.tracks") } ol { @for track in &media.tracks { li { @format!("{track}") } }} @@ -278,7 +301,7 @@ markup::define! { } @if !node.tags.is_empty() { details { - summary { "Tags" } + summary { @trs(lang, "node.tags") } ol { @for tag in &node.tags { li { @tag } }} @@ -286,30 +309,30 @@ markup::define! { } } @if matches!(node.kind, NodeKind::Collection | NodeKind::Channel) { - @NodeFilterSortForm { f: filter } + @NodeFilterSortForm { f: filter, lang } } @if !similar.is_empty() { - h2 { "Similar Media" } + h2 { @trs(lang, "node.similar") } ul.children.hlist {@for (node, udata) in similar.iter() { - li { @NodeCard { node, udata } } + li { @NodeCard { node, udata, lang } } }} } @match node.kind { NodeKind::Show | NodeKind::Series | NodeKind::Season => { ol { @for (node, udata) in children.iter() { - li { @NodeCardWide { node, udata } } + li { @NodeCardWide { node, udata, lang } } }} } NodeKind::Collection | NodeKind::Channel | _ => { ul.children {@for (node, udata) in children.iter() { - li { @NodeCard { node, udata } } + li { @NodeCard { node, udata, lang } } }} } } } } - Props<'a>(node: &'a Node, udata: &'a NodeUserData, full: bool) { + Props<'a>(node: &'a Node, udata: &'a NodeUserData, full: bool, lang: &'a Language) { .props { @if let Some(m) = &node.media { p { @format_duration(m.duration) } @@ -324,8 +347,8 @@ markup::define! { } @match node.visibility { Visibility::Visible => {} - Visibility::Reduced => {p.visibility{"Reduced visibility"}} - Visibility::Hidden => {p.visibility{"Hidden"}} + Visibility::Reduced => {p.visibility{@trs(lang, "prop.vis.reduced")}} + Visibility::Hidden => {p.visibility{@trs(lang, "prop.vis.hidden")}} } // TODO // @if !node.children.is_empty() { @@ -349,9 +372,9 @@ markup::define! { } @match udata.watched { WatchedState::None => {} - WatchedState::Pending => { p.pending { "Watchlisted" } } - WatchedState::Progress(x) => { p.progress { "Watched up to " @format_duration(x) } } - WatchedState::Watched => { p.watched { "Watched" } } + WatchedState::Pending => { p.pending { @trs(lang, "prop.watched.pending") } } + WatchedState::Progress(x) => { p.progress { @trsa(lang, "prop.watched.progress", &[("time", &format_duration(x))]) } } + WatchedState::Watched => { p.watched { @trs(lang, "prop.watched.watched") } } } } } |