@lobehub/chat 1.119.2 → 1.120.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/.vscode/settings.json +2 -3
  2. package/CHANGELOG.md +58 -0
  3. package/changelog/v1.json +21 -0
  4. package/locales/ar/models.json +24 -3
  5. package/locales/bg-BG/models.json +24 -3
  6. package/locales/de-DE/models.json +24 -3
  7. package/locales/en-US/models.json +24 -3
  8. package/locales/es-ES/models.json +24 -3
  9. package/locales/fa-IR/models.json +24 -3
  10. package/locales/fr-FR/models.json +24 -3
  11. package/locales/it-IT/models.json +24 -3
  12. package/locales/ja-JP/models.json +24 -3
  13. package/locales/ko-KR/models.json +24 -3
  14. package/locales/nl-NL/models.json +24 -3
  15. package/locales/pl-PL/models.json +24 -3
  16. package/locales/pt-BR/models.json +24 -3
  17. package/locales/ru-RU/models.json +24 -3
  18. package/locales/tr-TR/models.json +24 -3
  19. package/locales/vi-VN/models.json +24 -3
  20. package/locales/zh-CN/models.json +24 -3
  21. package/locales/zh-TW/models.json +24 -3
  22. package/package.json +2 -5
  23. package/packages/database/src/models/__tests__/generationBatch.test.ts +47 -1
  24. package/packages/database/src/models/generationBatch.ts +8 -1
  25. package/packages/model-bank/src/aiModels/aihubmix.ts +1 -1
  26. package/packages/model-bank/src/aiModels/google.ts +4 -4
  27. package/packages/model-bank/src/aiModels/openrouter.ts +2 -2
  28. package/packages/model-bank/src/aiModels/qwen.ts +3 -1
  29. package/packages/model-bank/src/aiModels/siliconcloud.ts +6 -0
  30. package/packages/model-bank/src/aiModels/vertexai.ts +2 -2
  31. package/packages/model-runtime/src/google/createImage.ts +52 -24
  32. package/packages/model-runtime/src/qwen/index.ts +1 -1
  33. package/packages/model-runtime/src/siliconcloud/index.ts +1 -1
  34. package/src/app/[variants]/(main)/(mobile)/me/settings/features/useCategory.tsx +2 -16
  35. package/src/app/[variants]/(main)/chat/@session/_layout/Desktop/SessionHeader.tsx +1 -3
  36. package/src/app/[variants]/(main)/chat/@session/_layout/Mobile/SessionHeader.tsx +1 -3
  37. package/src/app/[variants]/(main)/settings/hooks/useCategory.tsx +3 -21
  38. package/src/config/featureFlags/schema.test.ts +1 -2
  39. package/src/config/featureFlags/schema.ts +0 -6
  40. package/src/config/featureFlags/utils/parser.test.ts +7 -7
  41. package/src/database/_deprecated/core/index.ts +0 -1
  42. package/src/database/_deprecated/core/model.ts +4 -38
  43. package/src/database/_deprecated/models/message.ts +1 -1
  44. package/src/layout/GlobalProvider/StoreInitialization.tsx +0 -3
  45. package/src/store/serverConfig/selectors.test.ts +0 -1
  46. package/src/store/user/initialState.ts +1 -4
  47. package/src/store/user/selectors.ts +0 -1
  48. package/src/store/user/store.ts +1 -4
  49. package/docs/self-hosting/advanced/webrtc.mdx +0 -86
  50. package/docs/self-hosting/advanced/webrtc.zh-CN.mdx +0 -80
  51. package/src/app/[variants]/(main)/settings/sync/features/Alert.tsx +0 -53
  52. package/src/app/[variants]/(main)/settings/sync/features/DeviceInfo/Card.tsx +0 -42
  53. package/src/app/[variants]/(main)/settings/sync/features/DeviceInfo/DeviceName.tsx +0 -62
  54. package/src/app/[variants]/(main)/settings/sync/features/DeviceInfo/SystemIcon.tsx +0 -31
  55. package/src/app/[variants]/(main)/settings/sync/features/DeviceInfo/index.tsx +0 -103
  56. package/src/app/[variants]/(main)/settings/sync/features/WebRTC/ChannelNameInput.tsx +0 -45
  57. package/src/app/[variants]/(main)/settings/sync/features/WebRTC/SyncSwitch/index.css +0 -238
  58. package/src/app/[variants]/(main)/settings/sync/features/WebRTC/SyncSwitch/index.tsx +0 -79
  59. package/src/app/[variants]/(main)/settings/sync/features/WebRTC/generateRandomRoomName.ts +0 -4
  60. package/src/app/[variants]/(main)/settings/sync/features/WebRTC/index.tsx +0 -103
  61. package/src/app/[variants]/(main)/settings/sync/index.tsx +0 -17
  62. package/src/app/[variants]/(main)/settings/sync/page.tsx +0 -29
  63. package/src/database/_deprecated/core/sync.ts +0 -321
  64. package/src/features/SyncStatusInspector/DisableSync.tsx +0 -79
  65. package/src/features/SyncStatusInspector/EnableSync.tsx +0 -132
  66. package/src/features/SyncStatusInspector/EnableTag.tsx +0 -66
  67. package/src/features/SyncStatusInspector/index.tsx +0 -27
  68. package/src/hooks/useSyncData.ts +0 -50
  69. package/src/services/__tests__/sync.test.ts +0 -56
  70. package/src/services/sync.ts +0 -19
  71. package/src/store/user/slices/sync/action.test.ts +0 -164
  72. package/src/store/user/slices/sync/action.ts +0 -101
  73. package/src/store/user/slices/sync/initialState.ts +0 -13
  74. package/src/store/user/slices/sync/selectors.ts +0 -20
@@ -1,321 +0,0 @@
1
- import Debug from 'debug';
2
- import { throttle, uniqBy } from 'lodash-es';
3
- import type { WebrtcProvider } from 'y-webrtc';
4
- import type { Doc, Transaction } from 'yjs';
5
-
6
- import {
7
- OnAwarenessChange,
8
- OnSyncEvent,
9
- OnSyncStatusChange,
10
- PeerSyncStatus,
11
- StartDataSyncParams,
12
- } from '@/types/sync';
13
-
14
- import { LobeDBSchemaMap, browserDB } from './db';
15
-
16
- const LOG_NAME_SPACE = 'DataSync';
17
-
18
- class DataSync {
19
- private _ydoc: Doc | null = null;
20
- private provider: WebrtcProvider | null = null;
21
-
22
- private syncParams!: StartDataSyncParams;
23
- private onAwarenessChange!: OnAwarenessChange;
24
-
25
- private waitForConnecting: any;
26
-
27
- logger = Debug(LOG_NAME_SPACE);
28
-
29
- transact(fn: (transaction: Transaction) => unknown) {
30
- this._ydoc?.transact(fn);
31
- }
32
-
33
- getYMap = (tableKey: keyof LobeDBSchemaMap) => {
34
- return this._ydoc?.getMap(tableKey);
35
- };
36
-
37
- startDataSync = async (params: StartDataSyncParams) => {
38
- this.syncParams = params;
39
- this.onAwarenessChange = params.onAwarenessChange;
40
-
41
- // 开发时由于存在 fast refresh 全局实例会缓存在运行时中
42
- // 因此需要在每次重新连接时清理上一次的实例
43
- if (window.__ONLY_USE_FOR_CLEANUP_IN_DEV) {
44
- await this.cleanConnection(window.__ONLY_USE_FOR_CLEANUP_IN_DEV);
45
- }
46
-
47
- await this.connect(params);
48
- };
49
-
50
- connect = async (params: StartDataSyncParams) => {
51
- const { channel, onSyncEvent, onSyncStatusChange, user, onAwarenessChange, signaling } = params;
52
- // ====== 1. init yjs doc ====== //
53
-
54
- await this.initYDoc();
55
-
56
- this.logger('[YJS] start to listen sync event...');
57
- this.initYjsObserve(onSyncEvent, onSyncStatusChange);
58
-
59
- // ====== 2. init webrtc provider ====== //
60
- this.logger(`[WebRTC] init provider... room: ${channel.name}`);
61
- const { WebrtcProvider } = await import('y-webrtc');
62
-
63
- // clients connected to the same room-name share document updates
64
- this.provider = new WebrtcProvider(channel.name, this._ydoc!, {
65
- password: channel.password,
66
- signaling: [signaling],
67
- });
68
-
69
- // when fast refresh in dev, the provider will be cached in window
70
- // so we need to clean it in destory
71
- if (process.env.NODE_ENV === 'development') {
72
- window.__ONLY_USE_FOR_CLEANUP_IN_DEV = this.provider;
73
- }
74
-
75
- this.logger(`[WebRTC] provider init success`);
76
-
77
- // ====== 3. check signaling server connection ====== //
78
-
79
- // 当本地设备正确连接到 WebRTC Provider 后,触发 status 事件
80
- // 当开始连接,则开始监听事件
81
- this.provider.on('status', async ({ connected }) => {
82
- this.logger('[WebRTC] peer status:', connected);
83
- if (connected) {
84
- // this.initObserve(onSyncEvent, onSyncStatusChange);
85
- onSyncStatusChange?.(PeerSyncStatus.Connecting);
86
- }
87
- });
88
-
89
- // check the connection with signaling server
90
- let connectionCheckCount = 0;
91
-
92
- this.waitForConnecting = setInterval(() => {
93
- const signalingConnection: IWebsocketClient = this.provider!.signalingConns[0];
94
-
95
- if (signalingConnection.connected) {
96
- onSyncStatusChange?.(PeerSyncStatus.Ready);
97
- clearInterval(this.waitForConnecting);
98
- return;
99
- }
100
-
101
- connectionCheckCount += 1;
102
-
103
- // check for 5 times, or make it failed
104
- if (connectionCheckCount > 5) {
105
- onSyncStatusChange?.(PeerSyncStatus.Unconnected);
106
- clearInterval(this.waitForConnecting);
107
- }
108
- }, 2000);
109
-
110
- // ====== 4. handle data sync ====== //
111
-
112
- // 当各方的数据均完成同步后,YJS 对象之间的数据已经一致时,触发 synced 事件
113
- this.provider.on('synced', async ({ synced }) => {
114
- this.logger('[WebRTC] peer sync status:', synced);
115
- if (synced) {
116
- this.logger('[WebRTC] start to init yjs data...');
117
- onSyncStatusChange?.(PeerSyncStatus.Syncing);
118
- await this.initSync();
119
- onSyncStatusChange?.(PeerSyncStatus.Synced);
120
- this.logger('[WebRTC] yjs data init success');
121
- } else {
122
- this.logger('[WebRTC] data not sync, try to reconnect in 1s...');
123
- // await this.reconnect(params);
124
- setTimeout(() => {
125
- onSyncStatusChange?.(PeerSyncStatus.Syncing);
126
- this.reconnect(params);
127
- }, 1000);
128
- }
129
- });
130
-
131
- // ====== 5. handle awareness ====== //
132
-
133
- this.initAwareness({ onAwarenessChange, user });
134
-
135
- return this.provider;
136
- };
137
-
138
- reconnect = async (params: StartDataSyncParams) => {
139
- await this.cleanConnection(this.provider);
140
-
141
- await this.connect(params);
142
- };
143
-
144
- async disconnect() {
145
- await this.cleanConnection(this.provider);
146
- }
147
-
148
- private initYDoc = async () => {
149
- if (typeof window === 'undefined') return;
150
-
151
- this.logger('[YJS] init YDoc...');
152
- const { Doc } = await import('yjs');
153
- this._ydoc = new Doc();
154
- };
155
-
156
- private async cleanConnection(provider: WebrtcProvider | null) {
157
- if (provider) {
158
- this.logger(`[WebRTC] clean Connection...`);
159
- this.logger(`[WebRTC] clean awareness...`);
160
- provider.awareness.destroy();
161
-
162
- this.logger(`[WebRTC] clean room...`);
163
- provider.room?.disconnect();
164
- provider.room?.destroy();
165
-
166
- this.logger(`[WebRTC] clean provider...`);
167
- provider.disconnect();
168
- provider.destroy();
169
-
170
- this.logger(`[WebRTC] clean yjs doc...`);
171
- this._ydoc?.destroy();
172
-
173
- this.logger(`[WebRTC] -------------------`);
174
- }
175
- }
176
-
177
- private initSync = async () => {
178
- await Promise.all(
179
- ['sessions', 'sessionGroups', 'topics', 'messages', 'plugins'].map(async (tableKey) =>
180
- this.loadDataFromDBtoYjs(tableKey as keyof LobeDBSchemaMap),
181
- ),
182
- );
183
- };
184
-
185
- private initYjsObserve = (onEvent: OnSyncEvent, onSyncStatusChange: OnSyncStatusChange) => {
186
- ['sessions', 'sessionGroups', 'topics', 'messages', 'plugins'].forEach((tableKey) => {
187
- // listen yjs change
188
- this.observeYMapChange(tableKey as keyof LobeDBSchemaMap, onEvent, onSyncStatusChange);
189
- });
190
- };
191
-
192
- private observeYMapChange = (
193
- tableKey: keyof LobeDBSchemaMap,
194
- onEvent: OnSyncEvent,
195
- onSyncStatusChange: OnSyncStatusChange,
196
- ) => {
197
- const table = browserDB[tableKey];
198
- const yItemMap = this.getYMap(tableKey);
199
- const updateSyncEvent = throttle(onEvent, 1000);
200
-
201
- // 定义一个变量来保存定时器的ID
202
- // eslint-disable-next-line no-undef
203
- let debounceTimer: NodeJS.Timeout;
204
-
205
- yItemMap?.observe(async (event) => {
206
- // abort local change
207
- if (event.transaction.local) return;
208
-
209
- // 每次有变更时,都先清除之前的定时器(如果有的话),然后设置新的定时器
210
- clearTimeout(debounceTimer);
211
-
212
- onSyncStatusChange(PeerSyncStatus.Syncing);
213
-
214
- this.logger(`[YJS] observe ${tableKey} changes:`, event.keysChanged.size);
215
- const pools = Array.from(event.keys).map(async ([id, payload]) => {
216
- const item: any = yItemMap.get(id);
217
-
218
- switch (payload.action) {
219
- case 'add':
220
- case 'update': {
221
- await table.put(item, id);
222
-
223
- break;
224
- }
225
-
226
- case 'delete': {
227
- await table.delete(id);
228
- break;
229
- }
230
- }
231
- });
232
-
233
- await Promise.all(pools);
234
-
235
- updateSyncEvent(tableKey);
236
-
237
- // 设置定时器,2000ms 后更新状态为'synced'
238
- debounceTimer = setTimeout(() => {
239
- onSyncStatusChange(PeerSyncStatus.Synced);
240
- }, 2000);
241
- });
242
- };
243
-
244
- private loadDataFromDBtoYjs = async (tableKey: keyof LobeDBSchemaMap) => {
245
- const table = browserDB[tableKey];
246
- const items = await table.toArray();
247
- const yItemMap = this.getYMap(tableKey);
248
-
249
- // 定义每批次最多包含的数据条数
250
- const batchSize = 50;
251
-
252
- // 计算总批次数
253
- const totalBatches = Math.ceil(items.length / batchSize);
254
-
255
- for (let i = 0; i < totalBatches; i++) {
256
- // 计算当前批次的起始和结束索引
257
- const start = i * batchSize;
258
- const end = start + batchSize;
259
-
260
- // 获取当前批次的数据
261
- const batchItems = items.slice(start, end);
262
-
263
- // 将当前批次的数据推送到 Yjs 中
264
- this._ydoc?.transact(() => {
265
- batchItems.forEach((item) => {
266
- yItemMap!.set(item.id, item);
267
- });
268
- });
269
- }
270
-
271
- this.logger('[DB]:', tableKey, yItemMap?.size);
272
- };
273
-
274
- private initAwareness = ({ user }: Pick<StartDataSyncParams, 'user' | 'onAwarenessChange'>) => {
275
- if (!this.provider) return;
276
-
277
- const awareness = this.provider.awareness;
278
-
279
- awareness.setLocalState({ clientID: awareness.clientID, user });
280
- this.onAwarenessChange?.([{ ...user, clientID: awareness.clientID, current: true }]);
281
-
282
- awareness.on('change', () => this.syncAwarenessToUI());
283
- };
284
-
285
- private syncAwarenessToUI = async () => {
286
- const awareness = this.provider?.awareness;
287
-
288
- if (!awareness) return;
289
-
290
- const state = Array.from(awareness.getStates().values()).map((s) => ({
291
- ...s.user,
292
- clientID: s.clientID,
293
- current: s.clientID === awareness.clientID,
294
- }));
295
-
296
- this.onAwarenessChange?.(uniqBy(state, 'id'));
297
- };
298
- }
299
-
300
- export const dataSync = new DataSync();
301
-
302
- interface IWebsocketClient {
303
- binaryType: 'arraybuffer' | 'blob' | null;
304
- connect(): void;
305
- connected: boolean;
306
- connecting: boolean;
307
- destroy(): void;
308
- disconnect(): void;
309
- lastMessageReceived: number;
310
- send(message: any): void;
311
- shouldConnect: boolean;
312
- unsuccessfulReconnects: number;
313
- url: string;
314
- ws: WebSocket;
315
- }
316
-
317
- declare global {
318
- interface Window {
319
- __ONLY_USE_FOR_CLEANUP_IN_DEV?: WebrtcProvider | null;
320
- }
321
- }
@@ -1,79 +0,0 @@
1
- import { Button, Icon, Tag } from '@lobehub/ui';
2
- import { Badge, Popover } from 'antd';
3
- import { TooltipPlacement } from 'antd/es/tooltip';
4
- import { LucideCloudCog, LucideCloudy } from 'lucide-react';
5
- import Link from 'next/link';
6
- import { memo } from 'react';
7
- import { useTranslation } from 'react-i18next';
8
- import { Flexbox } from 'react-layout-kit';
9
-
10
- import { useUserStore } from '@/store/user';
11
- import { syncSettingsSelectors } from '@/store/user/selectors';
12
-
13
- interface DisableSyncProps {
14
- noPopover?: boolean;
15
- placement?: TooltipPlacement;
16
- }
17
-
18
- const DisableSync = memo<DisableSyncProps>(({ noPopover, placement = 'bottomLeft' }) => {
19
- const { t } = useTranslation('common');
20
- const [haveConfig, setSettings] = useUserStore((s) => [
21
- !!syncSettingsSelectors.webrtcConfig(s).channelName,
22
- s.setSettings,
23
- ]);
24
-
25
- const enableSync = () => {
26
- setSettings({ sync: { webrtc: { enabled: true } } });
27
- };
28
-
29
- const tag = (
30
- <div>
31
- <Tag>
32
- <Badge status="default" />
33
- {t('sync.status.disabled')}
34
- </Tag>
35
- </div>
36
- );
37
-
38
- return noPopover ? (
39
- tag
40
- ) : (
41
- <Popover
42
- arrow={false}
43
- content={
44
- <Flexbox gap={12} width={320}>
45
- {t('sync.disabled.desc')}
46
- {haveConfig ? (
47
- <Flexbox gap={8} horizontal>
48
- <Link href={'/settings/sync'}>
49
- <Button block icon={<Icon icon={LucideCloudCog} />}>
50
- {t('sync.disabled.actions.settings')}
51
- </Button>
52
- </Link>
53
- <Button block onClick={enableSync} type={'primary'}>
54
- {t('sync.disabled.actions.enable')}
55
- </Button>
56
- </Flexbox>
57
- ) : (
58
- <Link href={'/settings/sync'}>
59
- <Button block icon={<Icon icon={LucideCloudCog} />} type={'primary'}>
60
- {t('sync.disabled.actions.settings')}
61
- </Button>
62
- </Link>
63
- )}
64
- </Flexbox>
65
- }
66
- placement={placement}
67
- title={
68
- <Flexbox gap={8} horizontal>
69
- <Icon icon={LucideCloudy} />
70
- {t('sync.disabled.title')}
71
- </Flexbox>
72
- }
73
- >
74
- {tag}
75
- </Popover>
76
- );
77
- });
78
-
79
- export default DisableSync;
@@ -1,132 +0,0 @@
1
- import { ActionIcon, Avatar, Icon, Tag, Text } from '@lobehub/ui';
2
- import { Divider, Popover, Switch } from 'antd';
3
- import { createStyles } from 'antd-style';
4
- import { TooltipPlacement } from 'antd/es/tooltip';
5
- import isEqual from 'fast-deep-equal';
6
- import { LucideCloudy, LucideLaptop, LucideSmartphone, SettingsIcon } from 'lucide-react';
7
- import Link from 'next/link';
8
- import { memo } from 'react';
9
- import { useTranslation } from 'react-i18next';
10
- import { Flexbox } from 'react-layout-kit';
11
-
12
- import { useUserStore } from '@/store/user';
13
- import { syncSettingsSelectors } from '@/store/user/selectors';
14
- import { pathString } from '@/utils/url';
15
-
16
- import EnableTag from './EnableTag';
17
-
18
- const useStyles = createStyles(({ css, token, prefixCls }) => ({
19
- text: css`
20
- max-width: 100%;
21
- color: ${token.colorTextTertiary};
22
- .${prefixCls}-typography-copy {
23
- color: ${token.colorTextTertiary};
24
- }
25
- `,
26
- title: css`
27
- color: ${token.colorTextTertiary};
28
- `,
29
- }));
30
-
31
- interface EnableSyncProps {
32
- hiddenActions?: boolean;
33
- placement?: TooltipPlacement;
34
- }
35
-
36
- const EnableSync = memo<EnableSyncProps>(({ hiddenActions, placement = 'bottomLeft' }) => {
37
- const { t } = useTranslation('common');
38
-
39
- const { styles, theme } = useStyles();
40
- const [syncStatus, isSyncing, channelName, enableWebRTC, setSettings] = useUserStore((s) => [
41
- s.syncStatus,
42
- s.syncStatus === 'syncing',
43
- syncSettingsSelectors.webrtcChannelName(s),
44
- syncSettingsSelectors.enableWebRTC(s),
45
- s.setSettings,
46
- ]);
47
-
48
- const users = useUserStore((s) => s.syncAwareness, isEqual);
49
-
50
- const switchSync = (enabled: boolean) => {
51
- setSettings({ sync: { webrtc: { enabled } } });
52
- };
53
-
54
- return (
55
- <Popover
56
- arrow={false}
57
- content={
58
- <Flexbox gap={16}>
59
- <Flexbox align={'center'} gap={24} horizontal>
60
- <Flexbox
61
- align={'center'}
62
- className={styles.title}
63
- gap={4}
64
- horizontal
65
- style={{ paddingInlineEnd: 12 }}
66
- >
67
- {t('sync.channel')}
68
- <Text className={styles.text}>{channelName}</Text>
69
- </Flexbox>
70
- </Flexbox>
71
- <Divider dashed style={{ margin: 0 }} />
72
- <Flexbox gap={12}>
73
- {users.map((user) => (
74
- <Flexbox gap={12} horizontal key={user.clientID}>
75
- <Avatar
76
- avatar={
77
- <Icon
78
- color={theme.purple}
79
- icon={user.isMobile ? LucideSmartphone : LucideLaptop}
80
- size={24}
81
- />
82
- }
83
- background={theme.purple1}
84
- shape={'square'}
85
- />
86
-
87
- <Flexbox>
88
- <Flexbox gap={8} horizontal>
89
- {user.name || user.id}
90
- {user.current && (
91
- <Flexbox horizontal>
92
- <Tag bordered={false} color={'blue'}>
93
- {t('sync.awareness.current')}
94
- </Tag>
95
- </Flexbox>
96
- )}
97
- </Flexbox>
98
- <Text type={'secondary'}>
99
- {user.os} · {user.browser}
100
- </Text>
101
- </Flexbox>
102
- </Flexbox>
103
- ))}
104
- </Flexbox>
105
- </Flexbox>
106
- }
107
- placement={placement}
108
- title={
109
- <Flexbox distribution={'space-between'} horizontal>
110
- <Flexbox align={'center'} gap={8} horizontal>
111
- <Icon icon={LucideCloudy} />
112
- {t('sync.title')}
113
- {!hiddenActions && (
114
- <Switch checked={enableWebRTC} onChange={switchSync} size={'small'} />
115
- )}
116
- </Flexbox>
117
- {!hiddenActions && (
118
- <Link href={pathString('/settings/sync')}>
119
- <ActionIcon icon={SettingsIcon} title={t('sync.actions.settings')} />
120
- </Link>
121
- )}
122
- </Flexbox>
123
- }
124
- >
125
- <div>
126
- <EnableTag isSyncing={isSyncing} status={syncStatus} />
127
- </div>
128
- </Popover>
129
- );
130
- });
131
-
132
- export default EnableSync;
@@ -1,66 +0,0 @@
1
- import { Icon, Tag, Tooltip } from '@lobehub/ui';
2
- import { Badge } from 'antd';
3
- import { LucideCloudy, LucideRefreshCw, LucideRouter, LucideWifiOff } from 'lucide-react';
4
- import { memo } from 'react';
5
- import { useTranslation } from 'react-i18next';
6
-
7
- import { PeerSyncStatus } from '@/types/sync';
8
-
9
- const EnableTag = memo<{ isSyncing: boolean; status: PeerSyncStatus }>(({ status, isSyncing }) => {
10
- const { t } = useTranslation('common');
11
-
12
- switch (status) {
13
- case PeerSyncStatus.Connecting: {
14
- return (
15
- <Tag
16
- bordered={false}
17
- color={'blue'}
18
- icon={<Badge color={'blue'} status="processing" />}
19
- style={{ display: 'flex', gap: 4 }}
20
- >
21
- {t('sync.status.connecting')}
22
- </Tag>
23
- );
24
- }
25
-
26
- case PeerSyncStatus.Synced: {
27
- return (
28
- <Tag bordered={false} color={'green'} icon={<Icon icon={LucideCloudy} />}>
29
- {t('sync.status.synced')}
30
- </Tag>
31
- );
32
- }
33
-
34
- case PeerSyncStatus.Ready: {
35
- return (
36
- <Tag bordered={false} color={'blue'} icon={<Icon icon={LucideRouter} />}>
37
- {t('sync.status.ready')}
38
- </Tag>
39
- );
40
- }
41
-
42
- case PeerSyncStatus.Syncing: {
43
- return (
44
- <Tag
45
- bordered={false}
46
- color={'blue'}
47
- icon={<Icon icon={LucideRefreshCw} spin={isSyncing} />}
48
- >
49
- {t('sync.status.syncing')}
50
- </Tag>
51
- );
52
- }
53
-
54
- case PeerSyncStatus.Unconnected: {
55
- return (
56
- <Tooltip title={t('sync.unconnected.tip')}>
57
- <Tag bordered={false} color={'red'} icon={<Icon icon={LucideWifiOff} />}>
58
- {t('sync.status.unconnected')}
59
- </Tag>
60
- </Tooltip>
61
- );
62
- }
63
- }
64
- });
65
-
66
- export default EnableTag;
@@ -1,27 +0,0 @@
1
- import { TooltipPlacement } from 'antd/es/tooltip';
2
- import { memo } from 'react';
3
-
4
- import { useUserStore } from '@/store/user';
5
-
6
- import DisableSync from './DisableSync';
7
- import EnableSync from './EnableSync';
8
-
9
- interface SyncStatusTagProps {
10
- hiddenActions?: boolean;
11
- hiddenEnableGuide?: boolean;
12
- placement?: TooltipPlacement;
13
- }
14
-
15
- const SyncStatusTag = memo<SyncStatusTagProps>(
16
- ({ hiddenActions, placement, hiddenEnableGuide }) => {
17
- const [enableSync] = useUserStore((s) => [s.syncEnabled]);
18
-
19
- return enableSync ? (
20
- <EnableSync hiddenActions={hiddenActions} placement={placement} />
21
- ) : (
22
- <DisableSync noPopover={hiddenEnableGuide} placement={placement} />
23
- );
24
- },
25
- );
26
-
27
- export default SyncStatusTag;
@@ -1,50 +0,0 @@
1
- import { useCallback } from 'react';
2
-
3
- import { useChatStore } from '@/store/chat';
4
- import { featureFlagsSelectors, useServerConfigStore } from '@/store/serverConfig';
5
- import { useSessionStore } from '@/store/session';
6
- import { useUserStore } from '@/store/user';
7
- import { syncSettingsSelectors, userProfileSelectors } from '@/store/user/selectors';
8
-
9
- export const useSyncEvent = () => {
10
- const [refreshMessages, refreshTopic] = useChatStore((s) => [s.refreshMessages, s.refreshTopic]);
11
- const [refreshSessions] = useSessionStore((s) => [s.refreshSessions]);
12
-
13
- return useCallback((tableKey: string) => {
14
- // console.log('triggerSync Event:', tableKey);
15
-
16
- switch (tableKey) {
17
- case 'messages': {
18
- refreshMessages();
19
- break;
20
- }
21
-
22
- case 'topics': {
23
- refreshTopic();
24
- break;
25
- }
26
-
27
- case 'sessions': {
28
- refreshSessions();
29
- break;
30
- }
31
-
32
- default: {
33
- break;
34
- }
35
- }
36
- }, []);
37
- };
38
-
39
- export const useEnabledDataSync = () => {
40
- const [userId, userEnableSync, useEnabledSync] = useUserStore((s) => [
41
- userProfileSelectors.userId(s),
42
- syncSettingsSelectors.enableWebRTC(s),
43
- s.useEnabledSync,
44
- ]);
45
-
46
- const { enableWebrtc } = useServerConfigStore(featureFlagsSelectors);
47
- const syncEvent = useSyncEvent();
48
-
49
- useEnabledSync(enableWebrtc, { onEvent: syncEvent, userEnableSync, userId });
50
- };