1pub mod view;
2pub mod members;
3pub mod feed;
4pub mod item;
5
6use leptos::prelude::*;
7use apb::{ActivityMut, Collection};
8
9#[derive(Clone, Copy)]
10pub struct ListControls {
11 pub active: ReadSignal<Option<String>>,
12 pub set_active: WriteSignal<Option<String>>,
13
14 pub available: ReadSignal<Vec<String>>,
15 pub set_available: WriteSignal<Vec<String>>,
16}
17
18impl ListControls {
19 pub fn active_name(&self) -> Option<String> {
20 use crate::Cache;
21 use apb::Object;
22
23 let active = self.active.get()?;
24 if let Some(doc) = crate::cache::OBJECTS.get(&active) {
25 if let Ok(name) = doc.name() {
26 return Some(name);
27 }
28 }
29 Some(active)
30 }
31
32 pub fn list_name(&self, id: &str) -> String {
33 use crate::Cache;
34 use apb::Object;
35 if let Some(doc) = crate::cache::OBJECTS.get(id) {
36 if let Ok(name) = doc.name() {
37 return name;
38 }
39 }
40 id.to_string()
41 }
42
43 pub fn fetch(&self, auth: crate::Auth) {
44 use apb::CollectionPage;
45
46 let set_available = self.set_available;
47 if let Some(uid) = auth.userid.get() {
48 leptos::task::spawn_local(async move {
49 let mut lists = Vec::new();
50 let mut next = format!("{uid}/lists/page");
51 loop {
52 match crate::Http::fetch::<serde_json::Value>(&next, auth).await {
53 Ok(page) => {
54 for doc in page.ordered_items().flat() {
55 if let Ok(id) = doc.id() {
56 lists.push(id);
57 }
58 if let Ok(obj) = doc.into_inner() {
59 crate::cache::OBJECTS.include(std::sync::Arc::new(obj));
60 }
61 }
62 if let Ok(next_page) = page.next().id() {
63 next = next_page;
64 continue;
65 }
66 },
67 Err(e) => {
68 tracing::error!("error fetching user lists: {e}");
69 },
70 }
71 break;
72 }
73 set_available.set(lists);
74 });
75 }
76 }
77
78 pub fn add_to_list(&self, lid: String, oid: String, auth: crate::Auth) {
79 let payload = apb::new()
80 .set_activity_type(Some(apb::ActivityType::Add))
81 .set_target(apb::Node::link(lid))
82 .set_object(apb::Node::link(oid));
83
84 leptos::task::spawn_local(async move {
85 if let Err(e) = crate::Http::post(&auth.outbox(), &payload, auth).await {
86 tracing::error!("error adding to list: {e}");
87 }
88 });
89 }
90}
91
92impl Default for ListControls {
93 fn default() -> Self {
94 let (active, set_active) = signal(None);
95 let (available, set_available) = signal(Vec::new());
96 ListControls { active, set_active, available, set_available, }
97 }
98}