use leptos::*; use leptos_router::*; use crate::prelude::*; use leptos_use::{storage::use_local_storage, use_cookie, utils::{FromToStringCodec, JsonCodec}}; #[derive(Clone, Copy)] pub struct Feeds { // object feeds pub home: Timeline, pub global: Timeline, // notification feeds pub private: Timeline, pub public: Timeline, // exploration feeds pub user: Timeline, pub server: Timeline, pub context: Timeline, } impl Feeds { pub fn new(username: &str) -> Self { Feeds { home: Timeline::new(format!("{URL_BASE}/actors/{username}/feed/page")), global: Timeline::new(format!("{URL_BASE}/feed/page")), private: Timeline::new(format!("{URL_BASE}/actors/{username}/inbox/page")), public: Timeline::new(format!("{URL_BASE}/inbox/page")), user: Timeline::new(format!("{URL_BASE}/actors/{username}/outbox/page")), server: Timeline::new(format!("{URL_BASE}/outbox/page")), context: Timeline::new(format!("{URL_BASE}/outbox/page")), // TODO ehhh } } pub fn reset(&self) { self.home.reset(None); self.global.reset(None); self.private.reset(None); self.public.reset(None); self.user.reset(None); self.server.reset(None); self.context.reset(None); } } #[component] pub fn App() -> impl IntoView { let (token, set_token) = use_cookie::("token"); let (userid, set_userid) = use_cookie::("user_id"); let (config, set_config, _) = use_local_storage::("config"); let auth = Auth { token, userid }; let username = auth.userid.get_untracked() .map(|x| x.split('/').last().unwrap_or_default().to_string()) .unwrap_or_default(); let feeds = Feeds::new(&username); provide_context(auth); provide_context(config); provide_context(feeds); let reply_controls = ReplyControls::default(); provide_context(reply_controls); let screen_width = window().screen().map(|x| x.avail_width().unwrap_or_default()).unwrap_or_default(); let (menu, set_menu) = create_signal(screen_width <= 786); let (advanced, set_advanced) = create_signal(false); let title_target = move || if auth.present() { "/web/home" } else { "/web/server" }; spawn_local(async move { // refresh token first, or verify that we're still authed if Auth::refresh(auth.token, set_token, set_userid).await { feeds.home.more(auth); // home inbox requires auth to be read feeds.private.more(auth); } feeds.global.more(auth); feeds.public.more(auth); // server inbox may contain private posts }); // refresh token every hour set_interval( move || spawn_local(async move { Auth::refresh(auth.token, set_token, set_userid).await; }), std::time::Duration::from_secs(3600) ); view! {


{move || if advanced.get() { view! { }} else { view! { }}}
} >
} /> } } else { view! { } } /> } /> } /> } /> } /> } /> // TODO can we avoid this? } /> } /> // } />
} } #[component] fn Navigable() -> impl IntoView { let location = use_location(); let breadcrumb = Signal::derive(move || { let path = location.pathname.get(); let mut path_iter = path.split('/').skip(1); // TODO wow this breadcrumb logic really isnt nice can we make it better?? match path_iter.next() { Some("actors") => match path_iter.next() { None => "actors :: all".to_string(), Some(id) => { let mut out = "actors :: ".to_string(); if id.starts_with('+') { out.push_str("proxy"); } else { out.push_str(id); } if let Some(x) = path_iter.next() { out.push_str(" :: "); out.push_str(x); } out }, }, Some(p) => p.to_string(), None => "?".to_string(), } }); view! {
"<<" {crate::NAME}" :: "{breadcrumb}
} } #[component] pub fn NotFound() -> impl IntoView { view! {

nothing to see here!

} } #[component] pub fn Loader(#[prop(optional)] margin: bool) -> impl IntoView { view! {
} }