From 2c302b4fbf815531b9c8a9721c543d3529b4a99c Mon Sep 17 00:00:00 2001 From: alemi Date: Tue, 30 Apr 2024 02:09:23 +0200 Subject: [PATCH] feat(web): like button (without undo) --- web/index.html | 4 ++ web/src/components/object.rs | 103 +++++++++++++++++++++++++++++------ 2 files changed, 90 insertions(+), 17 deletions(-) diff --git a/web/index.html b/web/index.html index 0c3565e..9aafeab 100644 --- a/web/index.html +++ b/web/index.html @@ -250,6 +250,10 @@ color: transparent; text-shadow: 0 0 0 var(--secondary); } + span.emoji-btn:hover { + color: unset; + text-shadow: unset; + } diff --git a/web/src/components/object.rs b/web/src/components/object.rs index 82d8c45..8968de4 100644 --- a/web/src/components/object.rs +++ b/web/src/components/object.rs @@ -1,7 +1,7 @@ use leptos::*; use crate::{prelude::*, URL_SENSITIVE}; -use apb::{target::Addressed, Base, Collection, Object}; +use apb::{target::Addressed, ActivityMut, Base, Collection, Object, ObjectMut}; #[component] pub fn Attachment( @@ -78,26 +78,25 @@ pub fn Attachment( #[component] pub fn Object(object: serde_json::Value) -> impl IntoView { - let uid = object.id().unwrap_or_default().to_string(); + let oid = object.id().unwrap_or_default().to_string(); let content = dissolve::strip_html_tags(object.content().unwrap_or_default()); let author_id = object.attributed_to().id().unwrap_or_default(); let author = CACHE.get_or(&author_id, serde_json::Value::String(author_id.clone())); let sensitive = object.sensitive().unwrap_or_default(); + let addressed = object.addressed(); + let public = addressed.iter().any(|x| x.as_str() == apb::target::PUBLIC); let attachments = object.attachment() .map(|x| view! { }) .collect_view(); let comments = object.replies().get() - .map(|x| x.total_items().unwrap_or(0)) - .filter(|x| *x > 0) - .map(|x| view! { {x} }); - let likes = object.audience().get() - .map(|x| x.total_items().unwrap_or(0)) - .filter(|x| *x > 0) - .map(|x| view! { {x} }); + .map_or(0, |x| x.total_items().unwrap_or(0)); let shares = object.generator().get() - .map(|x| x.total_items().unwrap_or(0)) - .filter(|x| *x > 0) - .map(|x| view! { {x} }); + .map_or(0, |x| x.total_items().unwrap_or(0)); + let likes = object.audience().get() + .map_or(0, |x| x.total_items().unwrap_or(0)); + let already_liked = object.audience().get() + .map_or(false, |x| !x.ordered_items().is_empty()); + let like_target = if public { None } else { Some(author_id) }; let attachments_padding = if object.attachment().is_empty() { None } else { @@ -111,11 +110,11 @@ pub fn Object(object: serde_json::Value) -> impl IntoView { {object.in_reply_to().id().map(|reply| view! { reply })} - + - "↗" + "↗" @@ -127,9 +126,9 @@ pub fn Object(object: serde_json::Value) -> impl IntoView {
- {comments}" 📨" - {likes}" ⭐" - {shares}" 🚀" + + +
} } @@ -149,3 +148,73 @@ pub fn Summary(summary: Option, open: bool, children: Children) -> impl } } +#[component] +pub fn LikeButton( + n: u64, + target: String, + liked: bool, + #[prop(default=None)] + author: Option, +) -> impl IntoView { + let (count, set_count) = create_signal(n); + let (clicked, set_clicked) = create_signal(!liked); + let auth = use_context::().expect("missing auth context"); + view! { + { + set_clicked.set(false); + set_count.set(count.get() + 1); + }, + Err(e) => tracing::error!("failed sending like: {e}"), + } + }); + } + > + {move || if count.get() > 0 { Some(view! { {count} })} else { None }} + " ⭐" + + } +} + +#[component] +pub fn ReplyButton(n: u64) -> impl IntoView { + let comments = if n > 0 { + Some(view! { {n} }) + } else { + None + }; + view! { + {comments}" 📨" + } +} + +#[component] +pub fn RepostButton(n: u64) -> impl IntoView { + let shares = if n > 0 { + Some(view! { {n} }) + } else { + None + }; + view! { + {shares}" 🚀" + } +}