feat(web): space avatars with GIF support and live space list sync [CI]
ci/woodpecker/push/web-build Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/dev-image Pipeline was successful

This commit is contained in:
justme committed 2026-10-17 13:44:16 +08:00
1 parent 96f92c2ba9
commit ba0b6c258a
14 files changed
+153 -33

No files matched your search

+3
View File
@@ -16,6 +16,8 @@ interface ChannelsState {
join: (link: ParsedChannelLink, password?: string) => Promise<ChannelInfo>;
hydrate: () => Promise<void>;
refresh: () => Promise<void>;
/** 打开着的空间收到最新信息(名称、头像、人数等)时,同步到列表里的那一项 */
patch: (info: ChannelInfo) => void;
forget: (id: string) => Promise<void>;
setPendingLink: (link: ParsedChannelLink | null) => void;
clearJustCreated: () => void;
@@ -47,6 +49,7 @@ export const useChannels = create<ChannelsState>()((set, get) => ({
return hydration;
},
refresh: async () => set({ list: await api.listSaved(), hydrated: true }),
patch: (info) => set((s) => (s.list.some((c) => c.id === info.id) ? { list: s.list.map((c) => (c.id === info.id ? { ...c, ...info, avatar: info.avatar } : c)) } : s)),
forget: async (id) => {
await api.forget(id);
set((s) => ({ list: s.list.filter((c) => c.id !== id) }));
+6 -1
View File
@@ -5,6 +5,7 @@ import type { FileItem, Item } from '@/core-bridge/types';
import { previewKindOf } from '@/lib/fileKind';
import { errorMessage } from '@/core-bridge/errors';
import { useAccount } from './account';
import { useChannels } from './channels';
import { initialData, reduce, withoutItem, type WorkspaceData } from './reduce';
/** 乐观发送:点发送即在本地画出占位项,后台再加密上传;worker 发布真实条目时带回 localId 替换占位项 */
@@ -96,7 +97,11 @@ export const useWorkspace = create<WorkspaceData & Actions>()(() => ({
revokeInvitation: (username) => api.revokeInvitation(username),
open: (channelId) => {
useWorkspace.setState(initialData);
return api.connect(channelId, (e) => useWorkspace.setState((s) => reduce(s, e)));
return api.connect(channelId, (e) => {
useWorkspace.setState((s) => reduce(s, e));
// 空间名称、头像等改了:左侧空间列表是另一份投影,一起更新
if (e.t === 'channel') useChannels.getState().patch(e.info);
});
},
sendText: (text, threadId) => {
const id = newLocalId();