use leptos::*; use crate::prelude::*; use apb::{target::Addressed, Activity, Actor, Base, Object}; #[component] pub fn InlineActivity(activity: serde_json::Value) -> impl IntoView { let object_id = activity.object().id().unwrap_or_default(); let object = CACHE.get(&object_id).unwrap_or(serde_json::Value::String(object_id.clone())); let addressed = activity.addressed(); let audience = format!("[ {} ]", addressed.join(", ")); let actor_id = activity.actor().id().unwrap_or_default(); let actor = match CACHE.get(&actor_id) { Some(a) => a, None => serde_json::Value::String(actor_id.clone()), }; let privacy = if addressed.iter().any(|x| x == apb::target::PUBLIC) { "🌐" } else if addressed.iter().any(|x| x.ends_with("/followers")) { "🔒" } else { "🔗" }; let date = object.published().or(activity.published()); let kind = activity.activity_type().unwrap_or(apb::ActivityType::Activity); view! {
{kind.as_ref().to_string()} {privacy}
{match kind { // post apb::ActivityType::Create => view! { }.into_view(), _ => view! {}.into_view(), }} } } #[component] pub fn ActorBanner( object: serde_json::Value, #[prop(optional)] tiny: bool ) -> impl IntoView { match object { serde_json::Value::String(id) => view! {
?" "{Uri::pretty(&id)}
}, serde_json::Value::Object(_) => { let uid = object.id().unwrap_or_default().to_string(); let uri = Uri::web("users", &uid); let avatar_url = object.icon().get().map(|x| x.url().id().unwrap_or_default()).unwrap_or_default(); let display_name = object.name().unwrap_or_default().to_string(); let username = object.preferred_username().unwrap_or_default().to_string(); let domain = object.id().unwrap_or_default().replace("https://", "").split('/').next().unwrap_or_default().to_string(); view! {
{display_name}
{username}@{domain}
} }, _ => view! {
invalid actor
} } } #[component] pub fn Object(object: serde_json::Value) -> impl IntoView { let oid = object.id().unwrap_or_default().to_string(); let in_reply_to = object.in_reply_to().id().unwrap_or_default(); let summary = object.summary().unwrap_or_default().to_string(); let content = dissolve::strip_html_tags(object.content().unwrap_or_default()); let date = object.published(); let author_id = object.attributed_to().id().unwrap_or_default(); let author = CACHE.get(&author_id).unwrap_or(serde_json::Value::String(author_id.clone())); view! {
{move || if !in_reply_to.is_empty() { Some(view! { }) } else { None }} {move || if !summary.is_empty() { Some(view! { }) } else { None }}
"in reply to "{Uri::pretty(&in_reply_to)}
{summary.clone()}
{ content.into_iter().map(|x| view! {

{x}

}).collect_view() }
} } #[component] pub fn ObjectInline(object: serde_json::Value) -> impl IntoView { let summary = object.summary().unwrap_or_default().to_string(); let content = dissolve::strip_html_tags(object.content().unwrap_or_default()); view! { {if summary.is_empty() { None } else { Some(view! { {summary} })}}
{content.into_iter().map(|x| view! {

{x}

}).collect_view()}
} } #[component] pub fn DateTime(t: Option>) -> impl IntoView { match t { Some(t) => { let pretty = t.format("%Y/%m/%d %H:%M:%S").to_string(); let rfc = t.to_rfc3339(); Some(view! { {pretty} }) }, None => None, } }