//! Public share page (milestone 6): renders a shared item without login. use leptos::prelude::*; use wasm_bindgen_futures::spawn_local; use crate::api::{self, Me, Mode, RootInfo, ShareInfo, UserInfo}; use crate::components::toast::{ToastView, provide_toast}; use crate::router::Location; use crate::views::browser::Browser; #[derive(Clone, PartialEq)] enum SharePageState { Loading, NotFound, Expired, Active, } #[component] pub fn ShareView(token: String, loc: ReadSignal) -> impl IntoView { let toast = provide_toast(); let (me, set_me) = signal(Option::::None); let (info, set_info) = signal(Option::::None); let (state, set_state) = signal(SharePageState::Loading); // Resolve the share once per token and scope all file API calls to it. { let tok = token.clone(); let set_me2 = set_me; let set_info2 = set_info; let set_state2 = set_state; spawn_local(async move { api::set_share_token(Some(&tok)); match api::resolve_share(&tok).await { Ok(i) => { let mode = if i.writable { Mode::Rw } else { Mode::Ro }; let me_val = Me { first_boot: false, user: Some(UserInfo { id: i.id, name: "shared".to_string(), is_admin: false, }), roots: vec![RootInfo { id: i.root_id, name: i.name.clone(), path: "/".to_string(), mode, }], allow_writable_shares: false, }; set_me2.set(Some(me_val)); set_info2.set(Some(i)); set_state2.set(SharePageState::Active); } Err(e) => { let expired = e.status() == Some(410); set_state2.set(if expired { SharePageState::Expired } else { SharePageState::NotFound }); } } }); on_cleanup(move || api::set_share_token(None)); } view! { } }