feat: add conversation image previews and sharing

This commit is contained in:
jjbrunton committed 2026-08-09 22:28:41 +01:00
1 parent 488145340d
commit b573b88b08
20 files changed
+634 -26

No files matched your search

@@ -2,15 +2,18 @@ import type { ZodType } from 'zod';
import {
ConversationsResponseSchema,
ConversationDetailResponseSchema,
ConversationMediaShareOptionsResponseSchema,
ErrorResponseSchema,
ProcessedPostsResponseSchema,
SendReplyRequestSchema,
ShareConversationMediaRequestSchema,
StartConversationRequestSchema,
StartConversationResponseSchema,
SuccessResponseSchema,
SuggestedReplyResponseSchema,
type ActiveChat,
type ConversationDetailResponse,
type ConversationMediaShareOptions,
type ProcessedPost,
type SuccessResponse,
} from '../../../../../packages/api-contracts/src/index.js';
@@ -34,8 +37,10 @@ export interface ConversationApi {
detail(id: string): Promise<ConversationDetailResponse>;
suggestReply(id: string): Promise<string>;
suggestMediaAsk(id: string): Promise<string>;
mediaShareOptions(id: string): Promise<ConversationMediaShareOptions>;
processedPosts(username: string): Promise<ProcessedPost[]>;
sendReply(id: string, message: string): Promise<SuccessResponse>;
shareMedia(id: string, assetId: string): Promise<SuccessResponse>;
startConversation(accountId: string, username: string, message: string): Promise<ActiveChat>;
}
@@ -66,6 +71,12 @@ export function createConversationApi(fetchImplementation?: typeof fetch): Conve
);
return response.suggestedReply;
},
async mediaShareOptions(id) {
return parseResponse(
await request(`${conversationPath(id)}/shareable-media`),
ConversationMediaShareOptionsResponseSchema,
);
},
async processedPosts(username) {
return parseResponse(
await request(`/api/posts/by-author/${encodeURIComponent(username.trim().replace(/^u\//i, ''))}`),
@@ -83,6 +94,17 @@ export function createConversationApi(fetchImplementation?: typeof fetch): Conve
SuccessResponseSchema,
);
},
async shareMedia(id, assetId) {
const body = ShareConversationMediaRequestSchema.parse({ assetId });
return parseResponse(
await request(`${conversationPath(id)}/share-media`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
}),
SuccessResponseSchema,
);
},
async startConversation(accountId, username, message) {
const body = StartConversationRequestSchema.parse({
accountId,