100 lines
2.4 KiB
TypeScript
100 lines
2.4 KiB
TypeScript
import { Post } from './posts.ts'
|
|
import { ApiClient } from '../../api/client.ts'
|
|
import { useUserStore } from '../../user/user.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 load(postId: string): Promise<Post | null> {
|
|
const response = await this.client.GET('/posts/{postId}', {
|
|
params: {
|
|
path: { postId },
|
|
},
|
|
credentials: 'include',
|
|
})
|
|
|
|
if (!response.data?.post) {
|
|
return null
|
|
}
|
|
|
|
return Post.fromDto(response.data.post)
|
|
}
|
|
|
|
async loadPublicFeed(cursor: string | null, amount: number | null): Promise<{ posts: Post[] }> {
|
|
const response = await this.client.GET('/posts', {
|
|
params: {
|
|
query: { After: cursor ?? undefined, Amount: amount ?? undefined },
|
|
},
|
|
credentials: 'include',
|
|
})
|
|
|
|
if (!response.data) {
|
|
return { posts: [] }
|
|
}
|
|
|
|
return { posts: response.data.posts.map(Post.fromDto) }
|
|
}
|
|
|
|
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',
|
|
})
|
|
}
|
|
|
|
async addComment(postId: string, content: string): Promise<void> {
|
|
const authorId = useUserStore.getState().user?.id
|
|
if (!authorId) return
|
|
|
|
await this.client.POST('/posts/{postId}/comments', {
|
|
params: { path: { postId } },
|
|
body: { content, authorId },
|
|
credentials: 'include',
|
|
})
|
|
}
|
|
}
|
|
|
|
interface CreatePostMedia {
|
|
mediaId: string
|
|
url: string | URL
|
|
width: number | null
|
|
height: number | null
|
|
}
|