femto-webapp/src/app/feed/posts/postsService.ts
2025-06-11 23:12:03 +02:00

76 lines
1.8 KiB
TypeScript

import { Post } from './posts.ts'
import { ApiClient } from '../../api/client.ts'
export class PostsService {
constructor(private readonly client: ApiClient) {}
async createNew(
authorId: string,
content: string,
media: CreatePostMedia[],
isPublic: boolean,
): Promise<Post> {
const response = await this.client.POST('/posts', {
body: {
authorId,
content,
media: media.map((m) => {
return { ...m, type: null, url: m.url.toString() }
}),
isPublic,
},
credentials: 'include',
})
if (!response.data) {
throw new Error('Failed to create post')
}
return Post.fromDto(response.data.post)
}
async loadPublicFeed(
cursor: string | null,
amount: number | null,
): Promise<{ posts: Post[]; next: string | null }> {
const response = await this.client.GET('/posts', {
params: {
query: { From: cursor ?? undefined, Amount: amount ?? undefined },
},
credentials: 'include',
})
if (!response.data) {
return { posts: [], next: null }
}
return { posts: response.data.posts.map(Post.fromDto), next: response.data.next }
}
async addReaction(postId: string, emoji: string): Promise<void> {
await this.client.POST('/posts/{postId}/reactions', {
params: {
path: { postId },
},
body: { emoji },
credentials: 'include',
})
}
async removeReaction(postId: string, emoji: string): Promise<void> {
await this.client.DELETE('/posts/{postId}/reactions', {
params: {
path: { postId },
},
body: { emoji },
credentials: 'include',
})
}
}
interface CreatePostMedia {
mediaId: string
url: string | URL
width: number | null
height: number | null
}