@lobehub/chat 0.162.7 → 0.162.9

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 (67) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/README.md +8 -8
  3. package/README.zh-CN.md +8 -8
  4. package/locales/ar/error.json +5 -1
  5. package/locales/bg-BG/error.json +4 -0
  6. package/locales/de-DE/error.json +4 -0
  7. package/locales/en-US/error.json +4 -0
  8. package/locales/es-ES/error.json +4 -0
  9. package/locales/fr-FR/error.json +4 -0
  10. package/locales/it-IT/error.json +4 -0
  11. package/locales/ja-JP/error.json +4 -0
  12. package/locales/ko-KR/error.json +4 -0
  13. package/locales/nl-NL/error.json +4 -0
  14. package/locales/pl-PL/error.json +4 -0
  15. package/locales/pt-BR/error.json +4 -0
  16. package/locales/ru-RU/error.json +4 -0
  17. package/locales/tr-TR/error.json +4 -0
  18. package/locales/vi-VN/error.json +4 -0
  19. package/locales/zh-CN/error.json +4 -0
  20. package/locales/zh-TW/error.json +5 -1
  21. package/package.json +1 -1
  22. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/Footer/LocalFiles.tsx +1 -1
  23. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/Footer/SendMore.tsx +6 -1
  24. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/Footer/index.tsx +6 -3
  25. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Mobile/Files.tsx +1 -1
  26. package/src/app/(main)/settings/common/features/Theme/index.tsx +1 -1
  27. package/src/components/FileList/EditableFileList.tsx +17 -5
  28. package/src/components/FileList/FileListViewer.tsx +19 -0
  29. package/src/components/FileList/index.ts +2 -0
  30. package/src/components/FileList/type.tsx +7 -0
  31. package/src/components/ImageItem/index.tsx +75 -0
  32. package/src/features/Conversation/Error/AccessCodeForm.tsx +2 -2
  33. package/src/features/Conversation/Messages/User.tsx +2 -2
  34. package/src/features/FileList/EditableFileList.tsx +31 -0
  35. package/src/features/FileList/FileListPreviewer.tsx +17 -0
  36. package/src/features/FileList/index.tsx +2 -0
  37. package/src/hooks/_header.ts +6 -6
  38. package/src/libs/swr/index.ts +33 -2
  39. package/src/locales/default/error.ts +1 -0
  40. package/src/services/__tests__/chat.test.ts +4 -1
  41. package/src/services/_auth.ts +2 -6
  42. package/src/services/_header.ts +2 -5
  43. package/src/services/file/client.test.ts +2 -0
  44. package/src/services/file/client.ts +2 -0
  45. package/src/services/user/client.ts +2 -1
  46. package/src/store/agent/slices/chat/action.ts +3 -4
  47. package/src/store/file/slices/images/action.test.ts +10 -5
  48. package/src/store/file/slices/images/action.ts +87 -22
  49. package/src/store/file/slices/images/initialState.ts +2 -0
  50. package/src/store/file/{selectors.test.ts → slices/images/selectors.test.ts} +4 -1
  51. package/src/store/file/slices/images/selectors.ts +7 -1
  52. package/src/store/global/action.ts +2 -2
  53. package/src/store/tool/slices/plugin/action.ts +1 -1
  54. package/src/store/user/slices/common/action.ts +2 -2
  55. package/src/store/user/slices/modelList/action.test.ts +31 -31
  56. package/src/store/user/slices/modelList/selectors/keyVaults.ts +10 -2
  57. package/src/store/user/slices/settings/action.test.ts +20 -9
  58. package/src/store/user/slices/settings/action.ts +18 -1
  59. package/src/store/user/slices/settings/initialState.ts +1 -0
  60. package/src/store/user/slices/settings/selectors/settings.ts +4 -7
  61. package/src/store/user/slices/sync/selectors.ts +8 -2
  62. package/src/tools/dalle/Render/Item/Image.tsx +1 -1
  63. package/src/{components/FileList → tools/dalle/Render/Item}/ImageFileItem.tsx +1 -1
  64. package/src/types/files.ts +1 -0
  65. package/src/types/user/settings/index.ts +1 -1
  66. package/src/components/FileList/index.tsx +0 -22
  67. /package/src/components/{FileList → ImageItem}/style.ts +0 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,56 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ### [Version 0.162.9](https://github.com/lobehub/lobe-chat/compare/v0.162.8...v0.162.9)
6
+
7
+ <sup>Released on **2024-05-29**</sup>
8
+
9
+ #### ♻ Code Refactoring
10
+
11
+ - **misc**: Refactor the settings to add optimistic updating.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### Code refactoring
19
+
20
+ - **misc**: Refactor the settings to add optimistic updating, closes [#2709](https://github.com/lobehub/lobe-chat/issues/2709) ([fade53e](https://github.com/lobehub/lobe-chat/commit/fade53e))
21
+
22
+ </details>
23
+
24
+ <div align="right">
25
+
26
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
27
+
28
+ </div>
29
+
30
+ ### [Version 0.162.8](https://github.com/lobehub/lobe-chat/compare/v0.162.7...v0.162.8)
31
+
32
+ <sup>Released on **2024-05-28**</sup>
33
+
34
+ #### 💄 Styles
35
+
36
+ - **misc**: Add optimistic loading for image uploading.
37
+
38
+ <br/>
39
+
40
+ <details>
41
+ <summary><kbd>Improvements and Fixes</kbd></summary>
42
+
43
+ #### Styles
44
+
45
+ - **misc**: Add optimistic loading for image uploading, closes [#2700](https://github.com/lobehub/lobe-chat/issues/2700) ([f99c9ce](https://github.com/lobehub/lobe-chat/commit/f99c9ce))
46
+
47
+ </details>
48
+
49
+ <div align="right">
50
+
51
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
52
+
53
+ </div>
54
+
5
55
  ### [Version 0.162.7](https://github.com/lobehub/lobe-chat/compare/v0.162.6...v0.162.7)
6
56
 
7
57
  <sup>Released on **2024-05-28**</sup>
package/README.md CHANGED
@@ -262,14 +262,14 @@ Our marketplace is not just a showcase platform but also a collaborative space.
262
262
 
263
263
  <!-- AGENT LIST -->
264
264
 
265
- | Recent Submits | Description |
266
- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
267
- | [C# .NET Technology Expert](https://chat-preview.lobehub.com/market?agent=dotnet-expert)<br/><sup>By **[johnnyqian](https://github.com/johnnyqian)** on **2024-05-28**</sup> | C# .NET Technology Expert<br/>`net` `developer` `net-core` `azure` `c` `microsoft` `sql-server` `entity-framework` `ef` `ef-core` |
268
- | [Daily Assistant](https://chat-preview.lobehub.com/market?agent=junior-helper)<br/><sup>By **[Qinks6](https://github.com/Qinks6)** on **2024-05-28**</sup> | A cute little helper that can search and draw<br/>`assistant` `search` `drawing` `information-retrieval` `user-interaction` |
269
- | [Node.js Optimizer](https://chat-preview.lobehub.com/market?agent=node-js-devoloper)<br/><sup>By **[chrisuhg](https://github.com/chrisuhg)** on **2024-05-28**</sup> | Specializes in Node.js code review, performance optimization, asynchronous programming, error handling, code refactoring, dependency management, security enhancement, test coverage, and documentation writing.<br/>`node-js` `code-optimization` `performance-optimization` `asynchronous-programming` `error-handling` |
270
- | [Foreign Colleague Evaluation Assistant](https://chat-preview.lobehub.com/market?agent=praise-assistant)<br/><sup>By **[johnnyqian](https://github.com/johnnyqian)** on **2024-05-27**</sup> | Give positive feedback to your colleagues<br/>`foreign-company` `evaluate` `review` `software-engineer` `praise` |
271
-
272
- > 📊 Total agents: [<kbd>**278**</kbd> ](https://github.com/lobehub/lobe-chat-agents)
265
+ | Recent Submits | Description |
266
+ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
267
+ | [Dart/Flutter Dev](https://chat-preview.lobehub.com/market?agent=dart-flutter)<br/><sup>By **[rezmeplxrf](https://github.com/rezmeplxrf)** on **2024-05-28**</sup> | Dart/Flutter Expert. Never nest more than 3 levels deep. Use riverpod, flutter_riverpod, riverpod_hook, flutter_hook for state management.<br/>`dart` `flutter` `development` `state-management` `riverpod` |
268
+ | [C# .NET Technology Expert](https://chat-preview.lobehub.com/market?agent=dotnet-expert)<br/><sup>By **[johnnyqian](https://github.com/johnnyqian)** on **2024-05-28**</sup> | C# .NET Technology Expert<br/>`net` `developer` `net-core` `azure` `c` `microsoft` `sql-server` `entity-framework` `ef` `ef-core` |
269
+ | [Christian Missionary](https://chat-preview.lobehub.com/market?agent=jesus-missionary)<br/><sup>By **[epochaudio](https://github.com/epochaudio)** on **2024-05-28**</sup> | As a missionary of Jesus, I will enlighten your understanding and practical application of God's word based on the teachings of the Bible. Whether in times of confusion or seeking spiritual growth, I am here to serve you by this source of wisdom.<br/>`bible-teaching` `christian-mission` `theology-preaching` |
270
+ | [Daily Assistant](https://chat-preview.lobehub.com/market?agent=junior-helper)<br/><sup>By **[Qinks6](https://github.com/Qinks6)** on **2024-05-28**</sup> | A cute little helper that can search and draw<br/>`assistant` `search` `drawing` `information-retrieval` `user-interaction` |
271
+
272
+ > 📊 Total agents: [<kbd>**280**</kbd> ](https://github.com/lobehub/lobe-chat-agents)
273
273
 
274
274
  <!-- AGENT LIST -->
275
275
 
package/README.zh-CN.md CHANGED
@@ -250,14 +250,14 @@ LobeChat 的插件生态系统是其核心功能的重要扩展,它极大地
250
250
 
251
251
  <!-- AGENT LIST -->
252
252
 
253
- | 最近新增 | 助手说明 |
254
- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
255
- | [C# .NET 技术专家](https://chat-preview.lobehub.com/market?agent=dotnet-expert)<br/><sup>By **[johnnyqian](https://github.com/johnnyqian)** on **2024-05-28**</sup> | C# .NET 技术专家<br/>`net` `developer` `net-core` `azure` `c` `microsoft` `sql-server` `entity-framework` `ef` `ef-core` |
256
- | [日常小助手](https://chat-preview.lobehub.com/market?agent=junior-helper)<br/><sup>By **[Qinks6](https://github.com/Qinks6)** on **2024-05-28**</sup> | 一个能搜索、能画图的小可爱<br/>`助手` `搜索` `绘图` `信息查询` `用户交互` |
257
- | [Node.js 优化师](https://chat-preview.lobehub.com/market?agent=node-js-devoloper)<br/><sup>By **[chrisuhg](https://github.com/chrisuhg)** on **2024-05-28**</sup> | 擅长 Node.js 代码审查、性能优化、异步编程、错误处理、代码重构、依赖管理、安全增强、测试覆盖率和文档编写。<br/>`node-js` `代码优化` `性能优化` `异步编程` `错误处理` |
258
- | [外企同事评价助手](https://chat-preview.lobehub.com/market?agent=praise-assistant)<br/><sup>By **[johnnyqian](https://github.com/johnnyqian)** on **2024-05-27**</sup> | 给你的同事好评<br/>`foreign-company` `evaluate` `review` `software-engineer` `praise` |
259
-
260
- > 📊 Total agents: [<kbd>**278**</kbd> ](https://github.com/lobehub/lobe-chat-agents)
253
+ | 最近新增 | 助手说明 |
254
+ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
255
+ | [Dart/Flutter Dev](https://chat-preview.lobehub.com/market?agent=dart-flutter)<br/><sup>By **[rezmeplxrf](https://github.com/rezmeplxrf)** on **2024-05-28**</sup> | Dart/Flutter 전문가. 3단계 이상 중첩하지 않음. 상태 관리에 riverpod, flutter_riverpod, riverpod_hook, flutter_hook 사용.<br/>`dart` `flutter` `개발` `상태-관리` `riverpod` |
256
+ | [C# .NET 技术专家](https://chat-preview.lobehub.com/market?agent=dotnet-expert)<br/><sup>By **[johnnyqian](https://github.com/johnnyqian)** on **2024-05-28**</sup> | C# .NET 技术专家<br/>`net` `developer` `net-core` `azure` `c` `microsoft` `sql-server` `entity-framework` `ef` `ef-core` |
257
+ | [基督传教士](https://chat-preview.lobehub.com/market?agent=jesus-missionary)<br/><sup>By **[epochaudio](https://github.com/epochaudio)** on **2024-05-28**</sup> | 作为一名耶稣传教士,我将依据圣经教导以启迪你对神的话语的理解和实际运用。无论是在困惑还是寻求灵性成长的过程中,我都在这智慧的源泉旁为你服务<br/>`圣经教学` `基督传教` `神学布道` |
258
+ | [日常小助手](https://chat-preview.lobehub.com/market?agent=junior-helper)<br/><sup>By **[Qinks6](https://github.com/Qinks6)** on **2024-05-28**</sup> | 一个能搜索、能画图的小可爱<br/>`助手` `搜索` `绘图` `信息查询` `用户交互` |
259
+
260
+ > 📊 Total agents: [<kbd>**280**</kbd> ](https://github.com/lobehub/lobe-chat-agents)
261
261
 
262
262
  <!-- AGENT LIST -->
263
263
 
@@ -136,5 +136,9 @@
136
136
  "apiKey": "مفتاح واجهة برمجة التطبيقات المخصص",
137
137
  "password": "كلمة المرور"
138
138
  }
139
+ },
140
+ "upload": {
141
+ "desc": "التفاصيل: {{detail}}",
142
+ "title": "فشل تحميل الملف، يرجى التحقق من الاتصال بالشبكة أو المحاولة لاحقًا"
139
143
  }
140
- }
144
+ }
@@ -136,5 +136,9 @@
136
136
  "apiKey": "Персонализиран API ключ",
137
137
  "password": "Парола"
138
138
  }
139
+ },
140
+ "upload": {
141
+ "desc": "Подробности: {{detail}}",
142
+ "title": "Неуспешно качване на файл, моля проверете интернет връзката или опитайте по-късно"
139
143
  }
140
144
  }
@@ -136,5 +136,9 @@
136
136
  "apiKey": "Benutzerdefinierter API-Schlüssel",
137
137
  "password": "Passwort"
138
138
  }
139
+ },
140
+ "upload": {
141
+ "desc": "Details: {{detail}}",
142
+ "title": "Dateiupload fehlgeschlagen. Bitte überprüfen Sie Ihre Netzwerkverbindung und versuchen Sie es später erneut."
139
143
  }
140
144
  }
@@ -136,5 +136,9 @@
136
136
  "apiKey": "Custom API Key",
137
137
  "password": "Password"
138
138
  }
139
+ },
140
+ "upload": {
141
+ "desc": "Details: {{detail}}",
142
+ "title": "File upload failed. Please check your network connection or try again later"
139
143
  }
140
144
  }
@@ -136,5 +136,9 @@
136
136
  "apiKey": "Clave de API personalizada",
137
137
  "password": "Contraseña"
138
138
  }
139
+ },
140
+ "upload": {
141
+ "desc": "Detalles: {{detail}}",
142
+ "title": "Error al subir el archivo, por favor verifica la conexión a internet o inténtalo de nuevo más tarde"
139
143
  }
140
144
  }
@@ -136,5 +136,9 @@
136
136
  "apiKey": "Clé API personnalisée",
137
137
  "password": "Mot de passe"
138
138
  }
139
+ },
140
+ "upload": {
141
+ "desc": "Détails : {{detail}}",
142
+ "title": "Échec de l'envoi du fichier, veuillez vérifier votre connexion réseau ou réessayer plus tard"
139
143
  }
140
144
  }
@@ -136,5 +136,9 @@
136
136
  "apiKey": "Chiave API personalizzata",
137
137
  "password": "Password"
138
138
  }
139
+ },
140
+ "upload": {
141
+ "desc": "Dettagli: {{detail}}",
142
+ "title": "Caricamento del file fallito, controlla la connessione di rete o riprova più tardi"
139
143
  }
140
144
  }
@@ -136,5 +136,9 @@
136
136
  "apiKey": "カスタムAPIキー",
137
137
  "password": "パスワード"
138
138
  }
139
+ },
140
+ "upload": {
141
+ "desc": "詳細: {{detail}}",
142
+ "title": "ファイルのアップロードに失敗しました。ネットワーク接続を確認するか、後でもう一度お試しください"
139
143
  }
140
144
  }
@@ -136,5 +136,9 @@
136
136
  "apiKey": "사용자 정의 API Key",
137
137
  "password": "비밀번호"
138
138
  }
139
+ },
140
+ "upload": {
141
+ "desc": "상세 내용: {{detail}}",
142
+ "title": "파일 업로드 실패, 네트워크 연결을 확인하거나 나중에 다시 시도해주세요"
139
143
  }
140
144
  }
@@ -136,5 +136,9 @@
136
136
  "apiKey": "Custom API Key",
137
137
  "password": "Password"
138
138
  }
139
+ },
140
+ "upload": {
141
+ "desc": "Details: {{detail}}",
142
+ "title": "Bestand uploaden mislukt, controleer uw internetverbinding of probeer het later opnieuw"
139
143
  }
140
144
  }
@@ -136,5 +136,9 @@
136
136
  "apiKey": "Niestandardowy klucz API",
137
137
  "password": "Hasło"
138
138
  }
139
+ },
140
+ "upload": {
141
+ "desc": "Szczegóły: {{detail}}",
142
+ "title": "Nie udało się przesłać pliku. Sprawdź połączenie sieciowe lub spróbuj ponownie później"
139
143
  }
140
144
  }
@@ -136,5 +136,9 @@
136
136
  "apiKey": "Chave de API personalizada",
137
137
  "password": "Senha"
138
138
  }
139
+ },
140
+ "upload": {
141
+ "desc": "Detalhes: {{detail}}",
142
+ "title": "Falha ao enviar o arquivo, verifique a conexão de rede ou tente novamente mais tarde"
139
143
  }
140
144
  }
@@ -136,5 +136,9 @@
136
136
  "apiKey": "Пользовательский ключ API",
137
137
  "password": "Пароль"
138
138
  }
139
+ },
140
+ "upload": {
141
+ "desc": "Подробности: {{detail}}",
142
+ "title": "Ошибка загрузки файла. Проверьте подключение к сети или попробуйте позже"
139
143
  }
140
144
  }
@@ -136,5 +136,9 @@
136
136
  "apiKey": "Özel API Anahtarı",
137
137
  "password": "Şifre"
138
138
  }
139
+ },
140
+ "upload": {
141
+ "desc": "Detay: {{detail}}",
142
+ "title": "Dosya yükleme başarısız, lütfen ağ bağlantınızı kontrol edin veya daha sonra tekrar deneyin"
139
143
  }
140
144
  }
@@ -136,5 +136,9 @@
136
136
  "apiKey": "Khóa API tùy chỉnh",
137
137
  "password": "Mật khẩu"
138
138
  }
139
+ },
140
+ "upload": {
141
+ "desc": "Chi tiết: {{detail}}",
142
+ "title": "Tải lên tệp thất bại, vui lòng kiểm tra kết nối mạng hoặc thử lại sau"
139
143
  }
140
144
  }
@@ -136,5 +136,9 @@
136
136
  "apiKey": "自定义 API Key",
137
137
  "password": "密码"
138
138
  }
139
+ },
140
+ "upload": {
141
+ "desc": "详情: {{detail}}",
142
+ "title": "文件上传失败,请检查网络连接或稍后再试"
139
143
  }
140
144
  }
@@ -136,5 +136,9 @@
136
136
  "apiKey": "自定義 API Key",
137
137
  "password": "密碼"
138
138
  }
139
+ },
140
+ "upload": {
141
+ "desc": "詳情: {{detail}}",
142
+ "title": "檔案上傳失敗,請檢查網路連線或稍後再試"
139
143
  }
140
- }
144
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "0.162.7",
3
+ "version": "0.162.9",
4
4
  "description": "Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
5
5
  "keywords": [
6
6
  "framework",
@@ -1,6 +1,6 @@
1
1
  import { memo } from 'react';
2
2
 
3
- import EditableFileList from '@/components/FileList/EditableFileList';
3
+ import { EditableFileList } from '@/features/FileList';
4
4
  import { useFileStore } from '@/store/file';
5
5
 
6
6
  export const LocalFiles = memo(() => {
@@ -27,7 +27,11 @@ const useStyles = createStyles(({ css, prefixCls }) => {
27
27
 
28
28
  const isMac = isMacOS();
29
29
 
30
- const SendMore = memo(() => {
30
+ interface SendMoreProps {
31
+ disabled?: boolean;
32
+ }
33
+
34
+ const SendMore = memo<SendMoreProps>(({ disabled }) => {
31
35
  const { t } = useTranslation('chat');
32
36
 
33
37
  const { styles } = useStyles();
@@ -55,6 +59,7 @@ const SendMore = memo(() => {
55
59
 
56
60
  return (
57
61
  <Dropdown
62
+ disabled={disabled}
58
63
  menu={{
59
64
  items: [
60
65
  {
@@ -14,6 +14,7 @@ import { useAgentStore } from '@/store/agent';
14
14
  import { agentSelectors } from '@/store/agent/slices/chat';
15
15
  import { useChatStore } from '@/store/chat';
16
16
  import { chatSelectors } from '@/store/chat/selectors';
17
+ import { filesSelectors, useFileStore } from '@/store/file';
17
18
  import { useUserStore } from '@/store/user';
18
19
  import { modelProviderSelectors, preferenceSelectors } from '@/store/user/selectors';
19
20
  import { isMacOS } from '@/utils/platform';
@@ -60,10 +61,11 @@ const Footer = memo<FooterProps>(({ setExpand }) => {
60
61
 
61
62
  const { theme, styles } = useStyles();
62
63
 
63
- const [loading, stopGenerateMessage] = useChatStore((s) => [
64
+ const [isAIGenerating, stopGenerateMessage] = useChatStore((s) => [
64
65
  chatSelectors.isAIGenerating(s),
65
66
  s.stopGenerateMessage,
66
67
  ]);
68
+ const isImageUploading = useFileStore(filesSelectors.isImageUploading);
67
69
 
68
70
  const model = useAgentStore(agentSelectors.currentAgentModel);
69
71
 
@@ -123,7 +125,7 @@ const Footer = memo<FooterProps>(({ setExpand }) => {
123
125
  </Flexbox>
124
126
  <SaveTopic />
125
127
  <Flexbox style={{ minWidth: 92 }}>
126
- {loading ? (
128
+ {isAIGenerating ? (
127
129
  <Button
128
130
  className={styles.loadingButton}
129
131
  icon={<StopLoadingIcon />}
@@ -134,6 +136,7 @@ const Footer = memo<FooterProps>(({ setExpand }) => {
134
136
  ) : (
135
137
  <Space.Compact>
136
138
  <Button
139
+ disabled={isImageUploading}
137
140
  onClick={() => {
138
141
  sendMessage();
139
142
  setExpand?.(false);
@@ -142,7 +145,7 @@ const Footer = memo<FooterProps>(({ setExpand }) => {
142
145
  >
143
146
  {t('input.send')}
144
147
  </Button>
145
- <SendMore />
148
+ <SendMore disabled={isImageUploading} />
146
149
  </Space.Compact>
147
150
  )}
148
151
  </Flexbox>
@@ -1,7 +1,7 @@
1
1
  import { memo } from 'react';
2
2
  import { Flexbox } from 'react-layout-kit';
3
3
 
4
- import EditableFileList from '@/components/FileList/EditableFileList';
4
+ import { EditableFileList } from '@/features/FileList';
5
5
  import { useFileStore } from '@/store/file';
6
6
 
7
7
  const Files = memo(() => {
@@ -41,7 +41,6 @@ const Theme = memo(() => {
41
41
  {
42
42
  children: (
43
43
  <SelectWithImg
44
- defaultValue={themeMode}
45
44
  height={60}
46
45
  onChange={setThemeMode}
47
46
  options={[
@@ -65,6 +64,7 @@ const Theme = memo(() => {
65
64
  },
66
65
  ]}
67
66
  unoptimized={false}
67
+ value={themeMode}
68
68
  width={100}
69
69
  />
70
70
  ),
@@ -3,18 +3,22 @@ import { useResponsive } from 'antd-style';
3
3
  import { memo } from 'react';
4
4
  import { Flexbox } from 'react-layout-kit';
5
5
 
6
- import ImageFileItem from './ImageFileItem';
6
+ import ImageItem from '@/components/ImageItem';
7
+
8
+ import { ImageFileItem } from './type';
7
9
 
8
10
  interface EditableFileListProps {
9
11
  alwaysShowClose?: boolean;
10
12
  editable?: boolean;
11
- items: string[];
13
+ items: ImageFileItem[];
14
+ onRemove?: (id: string) => void;
12
15
  padding?: number | string;
13
16
  }
14
17
 
15
- const EditableFileList = memo<EditableFileListProps>(
16
- ({ items, editable = true, alwaysShowClose, padding = 12 }) => {
18
+ export const EditableFileList = memo<EditableFileListProps>(
19
+ ({ items, editable = true, alwaysShowClose, onRemove, padding = 12 }) => {
17
20
  const { mobile } = useResponsive();
21
+
18
22
  return (
19
23
  <Flexbox
20
24
  gap={mobile ? 4 : 6}
@@ -24,7 +28,15 @@ const EditableFileList = memo<EditableFileListProps>(
24
28
  >
25
29
  <ImageGallery>
26
30
  {items.map((i) => (
27
- <ImageFileItem alwaysShowClose={alwaysShowClose} editable={editable} id={i} key={i} />
31
+ <ImageItem
32
+ alt={i.alt}
33
+ alwaysShowClose={alwaysShowClose}
34
+ editable={editable}
35
+ key={i.id}
36
+ loading={i.loading}
37
+ onRemove={() => onRemove?.(i.id)}
38
+ url={i.url}
39
+ />
28
40
  ))}
29
41
  </ImageGallery>
30
42
  </Flexbox>
@@ -0,0 +1,19 @@
1
+ import { ImageGallery } from '@lobehub/ui';
2
+ import { memo } from 'react';
3
+
4
+ import GalleyGrid from '@/components/GalleyGrid';
5
+ import ImageItem from '@/components/ImageItem';
6
+
7
+ import { ImageFileItem } from './type';
8
+
9
+ interface FileListProps {
10
+ items: ImageFileItem[];
11
+ }
12
+
13
+ export const ImageFileListViewer = memo<FileListProps>(({ items }) => {
14
+ return (
15
+ <ImageGallery>
16
+ <GalleyGrid items={items} renderItem={ImageItem} />
17
+ </ImageGallery>
18
+ );
19
+ });
@@ -0,0 +1,2 @@
1
+ export { EditableFileList } from './EditableFileList';
2
+ export { ImageFileListViewer } from './FileListViewer';
@@ -0,0 +1,7 @@
1
+ export interface ImageFileItem {
2
+ alt?: string;
3
+ id: string;
4
+ loading?: boolean;
5
+ onRemove?: (id: string) => void;
6
+ url: string;
7
+ }
@@ -0,0 +1,75 @@
1
+ import { ActionIcon, Image } from '@lobehub/ui';
2
+ import { createStyles } from 'antd-style';
3
+ import { Trash } from 'lucide-react';
4
+ import { CSSProperties, memo } from 'react';
5
+
6
+ import { usePlatform } from '@/hooks/usePlatform';
7
+
8
+ import { MIN_IMAGE_SIZE } from './style';
9
+
10
+ const useStyles = createStyles(({ css, token }) => ({
11
+ deleteButton: css`
12
+ color: #fff;
13
+ background: ${token.colorBgMask};
14
+
15
+ &:hover {
16
+ background: ${token.colorError};
17
+ }
18
+ `,
19
+ editableImage: css`
20
+ background: ${token.colorBgContainer};
21
+ box-shadow: 0 0 0 1px ${token.colorFill} inset;
22
+ `,
23
+ image: css`
24
+ margin-block: 0 !important;
25
+ `,
26
+ }));
27
+
28
+ interface FileItemProps {
29
+ alt?: string;
30
+ alwaysShowClose?: boolean;
31
+ className?: string;
32
+ editable?: boolean;
33
+ loading?: boolean;
34
+ onClick?: () => void;
35
+ onRemove?: () => void;
36
+ style?: CSSProperties;
37
+ url?: string;
38
+ }
39
+
40
+ const ImageItem = memo<FileItemProps>(
41
+ ({ editable, alt, onRemove, url, loading, alwaysShowClose }) => {
42
+ const IMAGE_SIZE = editable ? MIN_IMAGE_SIZE : '100%';
43
+ const { styles, cx } = useStyles();
44
+ const { isSafari } = usePlatform();
45
+
46
+ return (
47
+ <Image
48
+ actions={
49
+ editable && (
50
+ <ActionIcon
51
+ className={styles.deleteButton}
52
+ glass
53
+ icon={Trash}
54
+ onClick={(e) => {
55
+ e.stopPropagation();
56
+ onRemove?.();
57
+ }}
58
+ size={'small'}
59
+ />
60
+ )
61
+ }
62
+ alt={alt || ''}
63
+ alwaysShowActions={alwaysShowClose}
64
+ height={isSafari ? 'auto' : '100%'}
65
+ isLoading={loading}
66
+ size={IMAGE_SIZE as any}
67
+ src={url}
68
+ style={{ height: isSafari ? 'auto' : '100%' }}
69
+ wrapperClassName={cx(styles.image, editable && styles.editableImage)}
70
+ />
71
+ );
72
+ },
73
+ );
74
+
75
+ export default ImageItem;
@@ -5,7 +5,7 @@ import { Flexbox } from 'react-layout-kit';
5
5
 
6
6
  import { useChatStore } from '@/store/chat';
7
7
  import { useUserStore } from '@/store/user';
8
- import { settingsSelectors } from '@/store/user/selectors';
8
+ import { keyVaultsConfigSelectors } from '@/store/user/selectors';
9
9
 
10
10
  import { FormAction } from './style';
11
11
 
@@ -16,7 +16,7 @@ interface AccessCodeFormProps {
16
16
  const AccessCodeForm = memo<AccessCodeFormProps>(({ id }) => {
17
17
  const { t } = useTranslation('error');
18
18
  const [password, updateKeyVaults] = useUserStore((s) => [
19
- settingsSelectors.password(s),
19
+ keyVaultsConfigSelectors.password(s),
20
20
  s.updateKeyVaults,
21
21
  ]);
22
22
  const [resend, deleteMessage] = useChatStore((s) => [s.regenerateMessage, s.deleteMessage]);
@@ -1,8 +1,8 @@
1
1
  import { ReactNode, memo } from 'react';
2
2
  import { Flexbox } from 'react-layout-kit';
3
3
 
4
- import FileList from '@/components/FileList';
5
4
  import { LOADING_FLAT } from '@/const/message';
5
+ import { FileListPreviewer } from '@/features/FileList';
6
6
  import { ChatMessage } from '@/types/message';
7
7
 
8
8
  import BubblesLoading from '../components/BubblesLoading';
@@ -17,7 +17,7 @@ export const UserMessage = memo<
17
17
  return (
18
18
  <Flexbox gap={8} id={id}>
19
19
  {editableContent}
20
- {res.files && res.files?.length > 0 && <FileList items={res.files} />}
20
+ {res.files && res.files?.length > 0 && <FileListPreviewer items={res.files} />}
21
21
  </Flexbox>
22
22
  );
23
23
  });