From 0fba4d6838e85fc2d6d7b9c408b77f14bb6a0f07 Mon Sep 17 00:00:00 2001
From: alemi <me@alemi.dev>
Date: Wed, 15 Jan 2025 01:47:58 +0100
Subject: [PATCH] feat(web): botched object likes

---
 web/src/actors/header.rs   |  2 +-
 web/src/app.rs             | 27 ++++++++++++++++++---------
 web/src/objects/replies.rs | 20 ++++++++++++++++++++
 web/src/objects/view.rs    |  1 +
 web/src/prelude.rs         |  2 +-
 5 files changed, 41 insertions(+), 11 deletions(-)

diff --git a/web/src/actors/header.rs b/web/src/actors/header.rs
index 180d17b..f23f655 100644
--- a/web/src/actors/header.rs
+++ b/web/src/actors/header.rs
@@ -126,7 +126,7 @@ pub fn ActorHeader() -> impl IntoView {
 					<span class:tab-active=move || matches!(matched_route.get(), FeedRoute::User)>
 						<a class="clean" href=web_path.clone()><span class="emoji">"πŸ–‚ "</span>"outbox"</a>
 					</span>
-					<span class="ml-1" class:tab-active=move || matches!(matched_route.get(), FeedRoute::Likes)>
+					<span class="ml-1" class:tab-active=move || matches!(matched_route.get(), FeedRoute::ActorLikes)>
 						<a class="clean" href=format!("{web_path}/likes")><span class="emoji">"⭐ "</span>"likes"</a>
 					</span>
 					<span class="ml-1" style="float: right" class:tab-active=move || matches!(matched_route.get(), FeedRoute::Followers)>
diff --git a/web/src/app.rs b/web/src/app.rs
index 5dfed91..7ccffea 100644
--- a/web/src/app.rs
+++ b/web/src/app.rs
@@ -26,6 +26,7 @@ pub struct Feeds {
 	pub server: Timeline,
 	pub context: Timeline,
 	pub replies: Timeline,
+	pub object_likes: Timeline,
 	pub tag: Timeline,
 }
 
@@ -41,6 +42,7 @@ impl Feeds {
 			tag: Timeline::new(format!("{URL_BASE}/tags/upub/page")),
 			context: Timeline::new(format!("{URL_BASE}/outbox/page")), // TODO ehhh
 			replies: Timeline::new(format!("{URL_BASE}/outbox/page")), // TODO ehhh
+			object_likes: Timeline::new(format!("{URL_BASE}/outbox/page")), // TODO ehhh
 		}
 	}
 
@@ -205,7 +207,7 @@ pub fn App() -> impl IntoView {
 										<Route path="objects/:id" view=ObjectView >
 											<Route path="" view=ObjectContext />
 											<Route path="replies" view=ObjectReplies />
-											// <Route path="liked" view=ObjectLiked />
+											<Route path="likes" view=ObjectLikes />
 											// <Route path="announced" view=ObjectAnnounced />
 										</Route>
 
@@ -230,7 +232,7 @@ pub fn App() -> impl IntoView {
 
 #[derive(Debug, Clone, Copy)]
 pub(crate) enum FeedRoute {
-	Home, Global, Server, Notifications, User, Following, Followers, Likes, Replies, Context
+	Home, Global, Server, Notifications, User, Following, Followers, ActorLikes, ObjectLikes, Replies, Context
 }
 
 #[component]
@@ -268,7 +270,7 @@ fn Scrollable() -> impl IntoView {
 					None
 				},
 				Some("likes") => {
-					set_route.set(FeedRoute::Likes);
+					set_route.set(FeedRoute::ActorLikes);
 					Some(feeds.user_likes)
 				},
 				_ => {
@@ -277,12 +279,19 @@ fn Scrollable() -> impl IntoView {
 				},
 			}
 		} else if path.starts_with("/web/objects") {
-			if matches!(path.split('/').nth(4), Some("replies")) {
-				set_route.set(FeedRoute::Replies);
-				Some(feeds.replies)
-			} else {
-				set_route.set(FeedRoute::Context);
-				Some(feeds.context)
+			match path.split('/').nth(4) {
+				Some("likes") => {
+					set_route.set(FeedRoute::ObjectLikes);
+					Some(feeds.object_likes)
+				},
+				Some("replies") => {
+					set_route.set(FeedRoute::Replies);
+					Some(feeds.replies)
+				},
+				_ => {
+					set_route.set(FeedRoute::Context);
+					Some(feeds.context)
+				},
 			}
 		} else {
 			None
diff --git a/web/src/objects/replies.rs b/web/src/objects/replies.rs
index 4cdb6bf..b963ae8 100644
--- a/web/src/objects/replies.rs
+++ b/web/src/objects/replies.rs
@@ -22,3 +22,23 @@ pub fn ObjectReplies() -> impl IntoView {
 		</div>
 	}
 }
+
+#[component]
+pub fn ObjectLikes() -> impl IntoView {
+	let feeds = use_context::<Feeds>().expect("missing feeds context");
+	let params = use_params::<IdParam>();
+	let id = Signal::derive(move ||
+		params.with(|p| p.as_ref().ok().and_then(|x| x.id.as_ref()).cloned()).unwrap_or_default()
+	);
+	create_effect(move |_| {
+		let tl_url = format!("{}/likes/page", Uri::api(U::Object, &id.get(), false));
+		if !feeds.object_likes.next.get_untracked().starts_with(&tl_url) {
+			feeds.object_likes.reset(Some(tl_url));
+		}
+	});
+	view! {
+		<div class="mr-1-r ml-1-r">
+			<Feed tl=feeds.object_likes />
+		</div>
+	}
+}
diff --git a/web/src/objects/view.rs b/web/src/objects/view.rs
index 8a9412a..195daa5 100644
--- a/web/src/objects/view.rs
+++ b/web/src/objects/view.rs
@@ -56,6 +56,7 @@ pub fn ObjectView() -> impl IntoView {
 		<p>
 			<span class:tab-active=move || matches!(matched_route.get(), FeedRoute::Context)><a class="clean" href=move || format!("/web/objects/{}", id.get())><span class="emoji ml-2">"πŸ•ΈοΈ "</span>"context"</a></span>
 			<span class:tab-active=move || matches!(matched_route.get(), FeedRoute::Replies)><a class="clean" href=move || format!("/web/objects/{}/replies", id.get())><span class="emoji ml-2">"πŸ“« "</span>"replies"</a></span>
+			<span class:tab-active=move || matches!(matched_route.get(), FeedRoute::ObjectLikes)><a class="clean" href=move || format!("/web/objects/{}/likes", id.get())><span class="emoji ml-2">"⭐ "</span>"likes"</a></span>
 			{move || if auth.present() {
 				if loading.get() {
 					Some(view! {
diff --git a/web/src/prelude.rs b/web/src/prelude.rs
index a481b55..eccfc4c 100644
--- a/web/src/prelude.rs
+++ b/web/src/prelude.rs
@@ -20,7 +20,7 @@ pub use crate::{
 		attachment::Attachment,
 		item::{Object, Summary, LikeButton, RepostButton, ReplyButton},
 		context::ObjectContext,
-		replies::ObjectReplies,
+		replies::{ObjectReplies, ObjectLikes},
 	},
 	timeline::{
 		Timeline,