Skip to main content

upub_web/lists/
mod.rs

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}