From 72389136a7cf44087bf16886c0036037030f365e Mon Sep 17 00:00:00 2001 From: john Date: Mon, 26 May 2025 22:49:15 +0200 Subject: [PATCH] wip emoji reactions --- src/app/feed/components/PostItem.tsx | 53 ++++++++++++++++++++++++++++ src/app/feed/posts/posts.ts | 45 +++++++++++++++++++++++ 2 files changed, 98 insertions(+) diff --git a/src/app/feed/components/PostItem.tsx b/src/app/feed/components/PostItem.tsx index 582e05b..99a1dd6 100644 --- a/src/app/feed/components/PostItem.tsx +++ b/src/app/feed/components/PostItem.tsx @@ -44,10 +44,63 @@ export default function PostItem({ post }: PostItemProps) { ))} )} + + ) } +interface PostReactionsProps { + post: Post +} + +function PostReactions({ post }: PostReactionsProps) { + // State to track user's reactions + const [userReactions, setUserReactions] = useState>(new Set()) + + // Function to format reaction count + const formatCount = (count: number): string => { + if (count < 1000) return count.toString() + if (count < 10000) return `${(count / 1000).toFixed(1)}K` + return `${Math.floor(count / 1000)}K` + } + + // Function to handle reaction click + const handleReactionClick = (emoji: string) => { + setUserReactions((prev) => { + const newReactions = new Set(prev) + if (newReactions.has(emoji)) { + newReactions.delete(emoji) + } else { + newReactions.add(emoji) + } + return newReactions + }) + } + + return ( +
+ {post.reactions.map((reaction) => { + const isSelected = userReactions.has(reaction.emoji) + return ( + + ) + })} +
+ ) +} + interface PostMediaProps { media: PostMedia } diff --git a/src/app/feed/posts/posts.ts b/src/app/feed/posts/posts.ts index 77d0a5f..dee5c7b 100644 --- a/src/app/feed/posts/posts.ts +++ b/src/app/feed/posts/posts.ts @@ -1,12 +1,18 @@ import { Temporal } from '@js-temporal/polyfill' import { components } from '../../api/schema.ts' +export interface EmojiReaction { + emoji: string + count: number +} + export class Post { public readonly postId: string public readonly content: string public readonly media: PostMedia[] public readonly createdAt: Temporal.Instant public readonly authorName: string + public readonly reactions: EmojiReaction[] constructor( postId: string, @@ -14,12 +20,51 @@ export class Post { media: PostMedia[], createdAt: string | Temporal.Instant, authorName: string, + reactions: EmojiReaction[] = [], ) { this.postId = postId this.content = content this.media = media this.createdAt = Temporal.Instant.from(createdAt) this.authorName = authorName + this.reactions = reactions.length > 0 ? reactions : this.generateRandomReactions() + } + + private generateRandomReactions(): EmojiReaction[] { + // List of popular emojis + const emojis = [ + '👍', + '❤️', + '😂', + '🎉', + '🔥', + '👏', + '🙏', + '💯', + '🤔', + '😍', + '🥰', + '😮', + '😢', + '😡', + '🤩', + ] + + // Randomly select 5 unique emojis + const selectedEmojis: string[] = [] + while (selectedEmojis.length < 5) { + const randomIndex = Math.floor(Math.random() * emojis.length) + const emoji = emojis[randomIndex] + if (!selectedEmojis.includes(emoji!)) { + selectedEmojis.push(emoji!) + } + } + + // Create reaction objects with random counts + return selectedEmojis.map((emoji) => ({ + emoji, + count: Math.floor(Math.random() * 50), // Random count between 0 and 49 + })) } public static fromDto(dto: components['schemas']['PostDto']): Post {