sync: phase 1 backend + frontend from server

This commit is contained in:
2026-06-30 09:26:03 -04:00
parent d4cdd89544
commit 30e159cbdb
31 changed files with 4758 additions and 114 deletions
+36 -3
View File
@@ -1,6 +1,15 @@
import { create } from "zustand";
import { api } from "../lib/api.ts";
export interface MessageEmbed {
id?: string;
url: string;
title?: string;
description?: string;
image_url?: string;
site_name?: string;
}
export interface Message {
id: string;
channel_id: string;
@@ -8,16 +17,24 @@ export interface Message {
author_username: string;
author_display_name: string | null;
content: string;
reply_to?: string | null;
embeds?: MessageEmbed[];
created_at: string;
edited_at: string | null;
}
export interface SearchResultMessage extends Message {
channel_name?: string;
}
interface MessageState {
messagesByChannel: Record<string, Message[]>;
searchResultsByChannel: Record<string, SearchResultMessage[]>;
isLoading: boolean;
error: string | null;
fetchMessages: (channelId: string, before?: string) => Promise<void>;
sendMessage: (channelId: string, content: string) => Promise<Message>;
sendMessage: (channelId: string, content: string, replyTo?: string) => Promise<Message>;
searchMessages: (channelId: string, query: string) => Promise<SearchResultMessage[]>;
addMessage: (message: Message) => void;
updateMessage: (message: Message) => void;
removeMessage: (channelId: string, messageId: string) => void;
@@ -25,6 +42,7 @@ interface MessageState {
export const useMessageStore = create<MessageState>((set) => ({
messagesByChannel: {},
searchResultsByChannel: {},
isLoading: false,
error: null,
@@ -53,10 +71,25 @@ export const useMessageStore = create<MessageState>((set) => ({
}
},
sendMessage: async (channelId, content) => {
searchMessages: async (channelId, query) => {
const results = await api.get<SearchResultMessage[]>(
`/channels/${channelId}/messages/search?q=${encodeURIComponent(query)}`,
);
set((state) => ({
searchResultsByChannel: {
...state.searchResultsByChannel,
[channelId]: Array.isArray(results) ? results : [],
},
}));
return Array.isArray(results) ? results : [];
},
sendMessage: async (channelId, content, replyTo) => {
const body: { content: string; reply_to?: string } = { content };
if (replyTo) body.reply_to = replyTo;
const message = await api.post<Message>(
`/channels/${channelId}/messages`,
{ content },
body,
);
set((state) => {
const list = state.messagesByChannel[channelId] || [];