75 lines
1.9 KiB
TypeScript
75 lines
1.9 KiB
TypeScript
import { Temporal } from '@js-temporal/polyfill'
|
|
import { components } from '../../api/schema.ts'
|
|
import { immerable } from 'immer'
|
|
|
|
export interface PostReaction {
|
|
emoji: string
|
|
authorName: string
|
|
reactedOn: Temporal.Instant
|
|
}
|
|
|
|
export interface PostComment {
|
|
author: string
|
|
content: string
|
|
postedOn: Temporal.Instant
|
|
}
|
|
|
|
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: PostReaction[]
|
|
public readonly possibleReactions: string[]
|
|
public readonly comments: PostComment[]
|
|
|
|
constructor(
|
|
postId: string,
|
|
content: string,
|
|
media: PostMedia[],
|
|
createdAt: string | Temporal.Instant,
|
|
authorName: string,
|
|
reactions: PostReaction[],
|
|
possibleReactions: string[],
|
|
comments: PostComment[],
|
|
) {
|
|
this.postId = postId
|
|
this.content = content
|
|
this.media = media
|
|
this.createdAt = Temporal.Instant.from(createdAt)
|
|
this.authorName = authorName
|
|
this.reactions = reactions
|
|
this.possibleReactions = possibleReactions
|
|
this.comments = comments
|
|
}
|
|
|
|
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) => ({ ...r, reactedOn: Temporal.Instant.from(r.reactedOn) })),
|
|
dto.possibleReactions,
|
|
dto.comments.map((c) => ({ ...c, postedOn: Temporal.Instant.from(c.postedOn) })),
|
|
)
|
|
}
|
|
}
|
|
|
|
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,
|
|
) {}
|
|
}
|