feat: add post like

This commit is contained in:
gosangam
2026-06-09 16:34:10 +05:30
parent e36afdd1a5
commit 647a803b96
8 changed files with 441 additions and 266 deletions
+32
View File
@@ -77,6 +77,18 @@ export type Post = {
original_author_name?: string | null;
original_author_handle?: string | null;
original_author_avatar_url?: string | null;
/** Effective like total = denormalized count + pending (un-flushed)
* delta. Always present on hydrated reads (defaults to 0). */
likes_count?: number;
/** Whether the calling viewer has liked this post. Always false / absent
* for anonymous viewers. */
viewer_has_liked?: boolean;
};
/** Result of a like / unlike toggle: the new viewer state + effective total. */
export type LikeResult = {
liked: boolean;
likes_count: number;
};
export type Bookmark = {
@@ -198,6 +210,22 @@ export const posts = {
unreshare(id: string) {
return call<void>(`/posts/${id}/reshare`, { method: "DELETE" });
},
/** Like a post (idempotent). Returns the new viewer state + effective
* total (DB count + pending Redis delta). Auth-required. */
like(id: string) {
return call<LikeResult>(`/posts/${id}/like`, { method: "POST" });
},
/** Unlike a post (idempotent). Same shape as `like`. */
unlike(id: string) {
return call<LikeResult>(`/posts/${id}/like`, { method: "DELETE" });
},
/** One page of users who liked the post (newest first), optional
* name/handle search. `total` is the full matching count. Public. */
likers(id: string, opts: FollowListParams = {}) {
return call<FollowList>(
`/posts/${id}/likes?${followListQuery(opts)}`,
);
},
/** Report a post. category from PostReportCategory; reason optional.
* Auth-required (401 for anonymous callers). Returns nothing (204). */
report(id: string, category: PostReportCategory, reason: string) {
@@ -417,6 +445,10 @@ export type AppNotification = {
actor_name?: string | null;
actor_handle?: string | null;
actor_avatar_url?: string | null;
/** For aggregated `post_like` rows: the liked post + how many likers the
* row represents (renders "X and N-1 others liked your post"). */
post_id?: string | null;
actor_count?: number;
};
export const notifications = {