diff options
| -rw-r--r-- | common/src/node.rs | 1 | ||||
| -rw-r--r-- | import/src/plugins/trakt.rs | 37 | ||||
| -rw-r--r-- | server/src/ui/node.rs | 138 | ||||
| -rw-r--r-- | ui/src/components/node_card.rs | 2 | ||||
| -rw-r--r-- | ui/src/components/node_page.rs | 4 |
5 files changed, 114 insertions, 68 deletions
diff --git a/common/src/node.rs b/common/src/node.rs index b0f9545..612155f 100644 --- a/common/src/node.rs +++ b/common/src/node.rs @@ -108,6 +108,7 @@ enums! { KIND_COLLECTION = b"coll"; KIND_CHANNEL = b"chnl"; KIND_SHOW = b"show"; + KIND_PERSON = b"prsn"; KIND_SERIES = b"seri"; KIND_SEASON = b"sesn"; KIND_EPISODE = b"epsd"; diff --git a/import/src/plugins/trakt.rs b/import/src/plugins/trakt.rs index cc6810c..9b7ed99 100644 --- a/import/src/plugins/trakt.rs +++ b/import/src/plugins/trakt.rs @@ -521,23 +521,28 @@ impl Trakt { sort: Sort::None, })? { Some(r) => r, - None => txn.insert(ObjectBuffer::new(&mut [ - (NO_SLUG.0, &slug.as_str()), - (NO_VISIBILITY.0, &VISI_VISIBLE), - (NO_TITLE.0, &ap.person.name.as_str()), - (NO_IDENTIFIERS.0, &{ - let mut o = ObjectBuffer::empty(); - o = o.as_object().insert(IDENT_TRAKT_PERSON, traktid); - if let Some(tmdbid) = ap.person.ids.tmdb { - o = o.as_object().insert(IDENT_TMDB_PERSON, tmdbid); - } - if let Some(imdbid) = &ap.person.ids.imdb { - o = o.as_object().insert(IDENT_IMDB_PERSON, imdbid); - } - o - }), - ]))?, + None => { + txn.insert(ObjectBuffer::new(&mut [(NO_SLUG.0, &slug.as_str())]))? + } }; + + let mut c = txn.get(row)?.unwrap(); + c = c.as_object().insert(NO_KIND, KIND_PERSON); + c = c.as_object().insert(NO_VISIBILITY, VISI_VISIBLE); + c = c.as_object().insert(NO_TITLE, &ap.person.name); + c = c.as_object().update(NO_IDENTIFIERS, |ids| { + let mut ids = ids.insert(IDENT_TRAKT_PERSON, traktid); + if let Some(tmdbid) = ap.person.ids.tmdb { + ids = ids.as_object().insert(IDENT_TMDB_PERSON, tmdbid); + } + if let Some(imdbid) = &ap.person.ids.imdb { + ids = ids.as_object().insert(IDENT_IMDB_PERSON, imdbid); + } + ids + }); + + txn.update(row, c)?; + credits.push(ObjectBuffer::new(&mut [ (CR_KIND.0, crcat), (CR_ROLE.0, &role.as_str()), diff --git a/server/src/ui/node.rs b/server/src/ui/node.rs index 829a598..0f39213 100644 --- a/server/src/ui/node.rs +++ b/server/src/ui/node.rs @@ -5,89 +5,127 @@ */ use super::error::MyResult; use crate::{request_info::RequestInfo, ui_responder::UiResponse}; -use anyhow::{Result, anyhow}; +use anyhow::Result; use jellycommon::{ - jellyobject::{Object, Path}, + jellyobject::{Object, ObjectBuffer, ObjectBufferBuilder, Path}, *, }; -use jellydb::{Filter, MultiBehaviour, Query, Sort, SortOrder, ValueSort}; +use jellydb::{Filter, MultiBehaviour, Query, Sort, SortOrder, Transaction, ValueSort}; use rocket::get; #[get("/n/<slug>")] pub fn r_node(ri: RequestInfo<'_>, slug: &str) -> MyResult<UiResponse> { ri.require_user()?; - let mut node = None; - let mut children = None; + let mut page_out = ObjectBuffer::empty(); ri.state.database.transaction(&mut |txn| { if let Some(row) = txn.query_single(Query { filter: Filter::Match(Path(vec![NO_SLUG.0]), slug.into()), sort: Sort::None, })? { let n = txn.get(row)?.unwrap(); - node = Some(Object::EMPTY.insert(NKU_NODE, n.as_object())); + let nku = Object::EMPTY.insert(NKU_NODE, n.as_object()); + let nku = nku.as_object(); - let kind = n.as_object().get(NO_KIND).unwrap_or(KIND_COLLECTION); - let (order, path) = match kind { - KIND_CHANNEL => (SortOrder::Descending, Path(vec![NO_RELEASEDATE.0])), - KIND_SEASON | KIND_SHOW => (SortOrder::Ascending, Path(vec![NO_INDEX.0])), - _ => (SortOrder::Ascending, Path(vec![NO_TITLE.0])), - }; + let mut page = ObjectBufferBuilder::default(); - let rows = txn - .query(Query { - sort: Sort::Value(ValueSort { - multi: MultiBehaviour::First, - offset: None, - order, - path, - }), - filter: Filter::All(vec![ - Filter::Match(Path(vec![NO_VISIBILITY.0]), VISI_VISIBLE.into()), - Filter::Match(Path(vec![NO_PARENT.0]), row.into()), - ]), - })? - .collect::<Result<Vec<_>>>()?; + page.push(VIEW_NODE_PAGE, nku); + c_children(&mut page, txn, row, &nku)?; + c_credits(&mut page, txn, &nku)?; - children = Some( - rows.into_iter() - .map(|(row, _)| { - Ok(Object::EMPTY.insert(NKU_NODE, txn.get(row)?.unwrap().as_object())) - }) - .collect::<Result<Vec<_>>>()?, - ); + page_out = page.finish(); } Ok(()) })?; - let (Some(node), Some(children)) = (node, children) else { - Err(anyhow!("not found"))? - }; - - let children = children.iter().map(|c| c.as_object()).collect::<Vec<_>>(); + Ok(ri.respond_ui(page_out)) +} - let kind = node - .as_object() +fn c_children( + page: &mut ObjectBufferBuilder, + txn: &mut dyn Transaction, + row: u64, + nku: &Object, +) -> Result<()> { + let kind = nku .get(NKU_NODE) .unwrap_or_default() .get(NO_KIND) .unwrap_or(KIND_COLLECTION); - let mut children_list = Object::EMPTY.insert( + let (order, path) = match kind { + KIND_CHANNEL => (SortOrder::Descending, Path(vec![NO_RELEASEDATE.0])), + KIND_SEASON | KIND_SHOW => (SortOrder::Ascending, Path(vec![NO_INDEX.0])), + _ => (SortOrder::Ascending, Path(vec![NO_TITLE.0])), + }; + + let children_rows = txn + .query(Query { + sort: Sort::Value(ValueSort { + multi: MultiBehaviour::First, + offset: None, + order, + path, + }), + filter: Filter::All(vec![ + Filter::Match(Path(vec![NO_VISIBILITY.0]), VISI_VISIBLE.into()), + Filter::Match(Path(vec![NO_PARENT.0]), row.into()), + ]), + })? + .collect::<Result<Vec<_>>>()?; + + if children_rows.is_empty() { + return Ok(()); + } + + let mut list = ObjectBufferBuilder::default(); + + list.push( NODELIST_DISPLAYSTYLE, match kind { KIND_SEASON | KIND_SHOW => NLSTYLE_LIST, _ => NLSTYLE_GRID, }, ); - children_list = children_list - .as_object() - .insert_multi(NODELIST_ITEM, &children); - Ok(ri.respond_ui( - Object::EMPTY - .insert(VIEW_NODE_PAGE, node.as_object()) - .as_object() - .insert(VIEW_NODE_LIST, children_list.as_object()), - )) + for (row, _) in children_rows { + list.push( + NODELIST_ITEM, + Object::EMPTY + .insert(NKU_NODE, txn.get(row)?.unwrap().as_object()) + .as_object(), + ); + } + + page.push(VIEW_NODE_LIST, list.finish().as_object()); + Ok(()) +} + +fn c_credits( + page: &mut ObjectBufferBuilder, + txn: &mut dyn Transaction, + nku: &Object, +) -> Result<()> { + let mut list = ObjectBufferBuilder::default(); + list.push(NODELIST_DISPLAYSTYLE, NLSTYLE_INLINE); + list.push(NODELIST_TITLE, "node.people"); + + if !nku.get(NKU_NODE).unwrap_or_default().has(NO_CREDIT.0) { + return Ok(()); + } + + for cred in nku.get(NKU_NODE).unwrap_or_default().iter(NO_CREDIT) { + let mut o = ObjectBuffer::empty(); + if let Some(row) = cred.get(CR_NODE) { + let node = txn.get(row)?.unwrap(); + o = o.as_object().insert(NKU_NODE, node.as_object()); + } + if let Some(role) = cred.get(CR_ROLE) { + o = o.as_object().insert(NKU_ROLE, role) + } + list.push(NODELIST_ITEM, o.as_object()); + } + + page.push(VIEW_NODE_LIST, list.finish().as_object()); + Ok(()) } diff --git a/ui/src/components/node_card.rs b/ui/src/components/node_card.rs index a4ea5e5..1b8fd67 100644 --- a/ui/src/components/node_card.rs +++ b/ui/src/components/node_card.rs @@ -38,7 +38,7 @@ markup::define! { } div.subtitle { span { - @node.get(NO_SUBTITLE) + @nku.get(NKU_ROLE).or(node.get(NO_SUBTITLE)) } } } diff --git a/ui/src/components/node_page.rs b/ui/src/components/node_page.rs index 17e923c..18b1d58 100644 --- a/ui/src/components/node_page.rs +++ b/ui/src/components/node_page.rs @@ -175,7 +175,9 @@ pub fn aspect_class(node: Object<'_>) -> &'static str { match kind { KIND_VIDEO | KIND_EPISODE => "aspect-thumb", KIND_COLLECTION => "aspect-land", - KIND_SEASON | KIND_SHOW | KIND_SERIES | KIND_MOVIE | KIND_SHORTFORMVIDEO => "aspect-port", + KIND_SEASON | KIND_SHOW | KIND_PERSON | KIND_SERIES | KIND_MOVIE | KIND_SHORTFORMVIDEO => { + "aspect-port" + } KIND_CHANNEL | KIND_MUSIC | _ => "aspect-square", } } |