import { Temporal } from '@js-temporal/polyfill' import { components } from '../../api/schema.ts' import { immerable } from 'immer' export interface EmojiReaction { emoji: string count: number didReact: boolean } export class Post { [immerable] = true 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[] public readonly possibleReactions: string[] constructor( postId: string, content: string, media: PostMedia[], createdAt: string | Temporal.Instant, authorName: string, reactions: EmojiReaction[] = [], possibleReactions: string[] = [], ) { this.postId = postId this.content = content this.media = media this.createdAt = Temporal.Instant.from(createdAt) this.authorName = authorName this.reactions = reactions this.possibleReactions = possibleReactions } public static fromDto(dto: components['schemas']['PostDto']): Post { return new Post( dto.postId, dto.content, dto.media.map((m) => new PostMediaImpl(new URL(m.url), m.width, m.height)), Temporal.Instant.from(dto.createdAt), dto.author.username, dto.reactions.map((r) => ({ emoji: r.emoji, count: r.count, didReact: r.didReact, })), dto.possibleReactions, ) } } export interface PostMedia { readonly url: URL readonly width: number | null readonly height: number | null } class PostMediaImpl implements PostMedia { constructor( readonly url: URL, readonly width: number | null, readonly height: number | null, ) {} }