@lobehub/chat 0.107.12 → 0.107.14

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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,85 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ### [Version 0.107.14](https://github.com/lobehub/lobe-chat/compare/v0.107.13...v0.107.14)
6
+
7
+ <sup>Released on **2023-12-03**</sup>
8
+
9
+ #### 🐛 Bug Fixes
10
+
11
+ - **misc**: Fix opt+delete fail in inputing (resolve.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### What's fixed
19
+
20
+ - **misc**: Fix opt+delete fail in inputing (resolve, closes [#556](https://github.com/lobehub/lobe-chat/issues/556) ([4d5d93d](https://github.com/lobehub/lobe-chat/commit/4d5d93d))
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.107.13](https://github.com/lobehub/lobe-chat/compare/v0.107.12...v0.107.13)
31
+
32
+ <sup>Released on **2023-12-03**</sup>
33
+
34
+ #### ♻ Code Refactoring
35
+
36
+ - **misc**: Refactor Image components.
37
+
38
+ #### 🐛 Bug Fixes
39
+
40
+ - **misc**: Fix a bug that can't send only images with empty content, Fix image gallery sort index, Fix image gallery sort index, Fix image sort index, Fix image upload error, Fix import.
41
+
42
+ #### 💄 Styles
43
+
44
+ - **misc**: Change image fit to cover mode, Fix empty files style, Move file inside chat input in mobile mode, Update editable image style, Update image default background color, Update image editable style, Update image grid, Update Image grid, Update image remove button hover style.
45
+
46
+ <br/>
47
+
48
+ <details>
49
+ <summary><kbd>Improvements and Fixes</kbd></summary>
50
+
51
+ #### Code refactoring
52
+
53
+ - **misc**: Refactor Image components ([72dcd18](https://github.com/lobehub/lobe-chat/commit/72dcd18))
54
+
55
+ #### What's fixed
56
+
57
+ - **misc**: Fix a bug that can't send only images with empty content ([9601520](https://github.com/lobehub/lobe-chat/commit/9601520))
58
+ - **misc**: Fix image gallery sort index ([16548d3](https://github.com/lobehub/lobe-chat/commit/16548d3))
59
+ - **misc**: Fix image gallery sort index ([5636599](https://github.com/lobehub/lobe-chat/commit/5636599))
60
+ - **misc**: Fix image sort index ([29cf223](https://github.com/lobehub/lobe-chat/commit/29cf223))
61
+ - **misc**: Fix image upload error ([c7745c7](https://github.com/lobehub/lobe-chat/commit/c7745c7))
62
+ - **misc**: Fix import ([af797d6](https://github.com/lobehub/lobe-chat/commit/af797d6))
63
+
64
+ #### Styles
65
+
66
+ - **misc**: Change image fit to cover mode ([9fdc459](https://github.com/lobehub/lobe-chat/commit/9fdc459))
67
+ - **misc**: Fix empty files style ([bbe14c4](https://github.com/lobehub/lobe-chat/commit/bbe14c4))
68
+ - **misc**: Move file inside chat input in mobile mode ([b6401c1](https://github.com/lobehub/lobe-chat/commit/b6401c1))
69
+ - **misc**: Update editable image style ([a96ca4c](https://github.com/lobehub/lobe-chat/commit/a96ca4c))
70
+ - **misc**: Update image default background color ([fadc024](https://github.com/lobehub/lobe-chat/commit/fadc024))
71
+ - **misc**: Update image editable style ([8dea792](https://github.com/lobehub/lobe-chat/commit/8dea792))
72
+ - **misc**: Update image grid ([901d10c](https://github.com/lobehub/lobe-chat/commit/901d10c))
73
+ - **misc**: Update Image grid ([c68788d](https://github.com/lobehub/lobe-chat/commit/c68788d))
74
+ - **misc**: Update image remove button hover style ([5bc916c](https://github.com/lobehub/lobe-chat/commit/5bc916c))
75
+
76
+ </details>
77
+
78
+ <div align="right">
79
+
80
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
81
+
82
+ </div>
83
+
5
84
  ### [Version 0.107.12](https://github.com/lobehub/lobe-chat/compare/v0.107.11...v0.107.12)
6
85
 
7
86
  <sup>Released on **2023-12-02**</sup>
package/README.md CHANGED
@@ -203,12 +203,12 @@ Our marketplace is not just a showcase platform but also a collaborative space.
203
203
 
204
204
  | Recent Submits | Description |
205
205
  | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
206
+ | [Organic Chemistry Researcher](https://chat-preview.lobehub.com/market?agent=organic-chemistry-researcher)<br/><sup>By **[y22emc2](https://github.com/y22emc2)** on **2023-12-02**</sup> | Specializes in academic translation and writing in the field of organic chemistry<br/>`organic-chemistry` `research` `translation` `writing` `academic-articles` |
206
207
  | [JS Code Quality Optimization](https://chat-preview.lobehub.com/market?agent=js-code-quality)<br/><sup>By **[canisminor1990](https://github.com/canisminor1990)** on **2023-11-22**</sup> | Dedicated to clean and elegant code refactoring<br/>`refactoring` `code-optimization` `code-quality` |
207
208
  | [LobeChat Test Engineer](https://chat-preview.lobehub.com/market?agent=lobe-chat-unit-test-dev)<br/><sup>By **[arvinxx](https://github.com/arvinxx)** on **2023-11-22**</sup> | Proficient in writing frontend automation tests, especially comprehensive test coverage for TypeScript applications. Skilled in using the Vitest testing framework with a deep understanding of testing principles and strategies.<br/>`automation-testing` `testing` `lobe-chat` `frontend` |
208
209
  | [Q\&A Document Conversion Expert](https://chat-preview.lobehub.com/market?agent=q-a-helper)<br/><sup>By **[barryWang12138](https://github.com/barryWang12138)** on **2023-11-22**</sup> | Please provide your document content, and I will segment and clean it according to your requirements, and provide answers in a standardized format.<br/>`q-a` `document` |
209
- | [True Friend](https://chat-preview.lobehub.com/market?agent=ai-0x0-old-friends)<br/><sup>By **[mushan0x0](https://github.com/mushan0x0)** on **2023-11-21**</sup> | You can talk to me about anything. I can give you some thoughts and advice as a friend. Relax.<br/>`friendship` `humor` `authentic` `simulation` |
210
210
 
211
- > 📊 Total agents: [<kbd>**52**</kbd> ](https://github.com/lobehub/lobe-chat-agents)
211
+ > 📊 Total agents: [<kbd>**53**</kbd> ](https://github.com/lobehub/lobe-chat-agents)
212
212
 
213
213
  <!-- AGENT LIST -->
214
214
 
@@ -395,6 +395,8 @@ If you want to deploy this service yourself on Zeabur, you can follow these step
395
395
 
396
396
  </div>
397
397
 
398
+ <br/>
399
+
398
400
  ### Environment Variable
399
401
 
400
402
  This project provides some additional configuration items set with environment variables:
@@ -485,7 +487,37 @@ Contributions of all types are more than welcome; if you are interested in contr
485
487
  [![][submit-agents-shield]][submit-agents-link]
486
488
  [![][submit-plugin-shield]][submit-plugin-link]
487
489
 
488
- [![][contributors-contrib]][contributors-link]
490
+ <a href="https://github.com/lobehub/lobe-chat/graphs/contributors" target="_blank">
491
+ <table>
492
+ <tr>
493
+ <th colspan="2">
494
+ <br><img src="https://contrib.rocks/image?repo=lobehub/lobe-chat"><br><br>
495
+ </th>
496
+ </tr>
497
+ <tr>
498
+ <td>
499
+ <picture>
500
+ <source media="(prefers-color-scheme: dark)" srcset="https://next.ossinsight.io/widgets/official/compose-org-active-contributors/thumbnail.png?activity=active&period=past_28_days&owner_id=131470832&repo_ids=643445235&image_size=2x3&color_scheme=dark">
501
+ <img src="https://next.ossinsight.io/widgets/official/compose-org-active-contributors/thumbnail.png?activity=active&period=past_28_days&owner_id=131470832&repo_ids=643445235&image_size=2x3&color_scheme=light">
502
+ </picture>
503
+ </td>
504
+ <td rowspan="2">
505
+ <picture>
506
+ <source media="(prefers-color-scheme: dark)" srcset="https://next.ossinsight.io/widgets/official/compose-org-participants-growth/thumbnail.png?activity=active&period=past_28_days&owner_id=131470832&repo_ids=643445235&image_size=4x7&color_scheme=dark">
507
+ <img src="https://next.ossinsight.io/widgets/official/compose-org-participants-growth/thumbnail.png?activity=active&period=past_28_days&owner_id=131470832&repo_ids=643445235&image_size=4x7&color_scheme=light">
508
+ </picture>
509
+ </td>
510
+ </tr>
511
+ <tr>
512
+ <td>
513
+ <picture>
514
+ <source media="(prefers-color-scheme: dark)" srcset="https://next.ossinsight.io/widgets/official/compose-org-active-contributors/thumbnail.png?activity=new&period=past_28_days&owner_id=131470832&repo_ids=643445235&image_size=2x3&color_scheme=dark">
515
+ <img src="https://next.ossinsight.io/widgets/official/compose-org-active-contributors/thumbnail.png?activity=new&period=past_28_days&owner_id=131470832&repo_ids=643445235&image_size=2x3&color_scheme=light">
516
+ </picture>
517
+ </td>
518
+ </tr>
519
+ </table>
520
+ </a>
489
521
 
490
522
  <div align="right">
491
523
 
@@ -530,8 +562,6 @@ This project is [MIT](./LICENSE) licensed.
530
562
  [chat-plugins-gateway]: https://github.com/lobehub/chat-plugins-gateway
531
563
  [codespaces-link]: https://codespaces.new/lobehub/lobe-chat
532
564
  [codespaces-shield]: https://github.com/codespaces/badge.svg
533
- [contributors-contrib]: https://contrib.rocks/image?repo=lobehub/lobe-chat
534
- [contributors-link]: https://github.com/lobehub/lobe-chat/graphs/contributors
535
565
  [deploy-button-image]: https://vercel.com/button
536
566
  [deploy-link]: https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Flobehub%2Flobe-chat&env=OPENAI_API_KEY&envDescription=Find%20your%20OpenAI%20API%20Key%20by%20click%20the%20right%20Learn%20More%20button.&envLink=https%3A%2F%2Fplatform.openai.com%2Faccount%2Fapi-keys&project-name=lobe-chat&repository-name=lobe-chat
537
567
  [deploy-on-zeabur-button-image]: https://zeabur.com/button.svg
package/README.zh-CN.md CHANGED
@@ -182,12 +182,12 @@ LobeChat 的插件生态系统是其核心功能的重要扩展,它极大地
182
182
 
183
183
  | 最近新增 | 助手说明 |
184
184
  | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
185
+ | [有机化学研究员](https://chat-preview.lobehub.com/market?agent=organic-chemistry-researcher)<br/><sup>By **[y22emc2](https://github.com/y22emc2)** on **2023-12-02**</sup> | 擅长有机化学领域的学术翻译和写作<br/>`有机化学` `科研` `翻译` `写作` `学术文章` |
185
186
  | [JS 代码质量优化](https://chat-preview.lobehub.com/market?agent=js-code-quality)<br/><sup>By **[canisminor1990](https://github.com/canisminor1990)** on **2023-11-22**</sup> | 致力于干净和优雅的代码重构<br/>`重构` `代码优化` `代码质量` |
186
187
  | [LobeChat 测试工程师](https://chat-preview.lobehub.com/market?agent=lobe-chat-unit-test-dev)<br/><sup>By **[arvinxx](https://github.com/arvinxx)** on **2023-11-22**</sup> | 擅长编写前端自动化测试,特别是 TypeScript 应用的全面测试覆盖。熟练使用 Vitest 测试框架,具备深入的测试原理和策略理解。<br/>`自动化测试` `测试` `lobe-chat` `前端` |
187
188
  | [问答文档转换专家](https://chat-preview.lobehub.com/market?agent=q-a-helper)<br/><sup>By **[barryWang12138](https://github.com/barryWang12138)** on **2023-11-22**</sup> | 请提供您的文档内容,我将根据您的要求进行分段和清洗,并按照规范的格式回答。<br/>`q-a` `文档` |
188
- | [真实的老友](https://chat-preview.lobehub.com/market?agent=ai-0x0-old-friends)<br/><sup>By **[mushan0x0](https://github.com/mushan0x0)** on **2023-11-21**</sup> | 可以跟我谈论一切,我可以给你作为老友的一些想法和建议,放轻松<br/>`友情` `幽默` `真实` `模拟` |
189
189
 
190
- > 📊 Total agents: [<kbd>**52**</kbd> ](https://github.com/lobehub/lobe-chat-agents)
190
+ > 📊 Total agents: [<kbd>**53**</kbd> ](https://github.com/lobehub/lobe-chat-agents)
191
191
 
192
192
  <!-- AGENT LIST -->
193
193
 
@@ -369,6 +369,8 @@ $ docker run -d -p 3210:3210 \
369
369
 
370
370
  </div>
371
371
 
372
+ <br/>
373
+
372
374
  ### 环境变量
373
375
 
374
376
  本项目提供了一些额外的配置项,使用环境变量进行设置:
@@ -459,7 +461,37 @@ $ bun run dev
459
461
  [![][submit-agents-shield]][submit-agents-link]
460
462
  [![][submit-plugin-shield]][submit-plugin-link]
461
463
 
462
- [![][contributors-contrib]][contributors-link]
464
+ <a href="https://github.com/lobehub/lobe-chat/graphs/contributors" target="_blank">
465
+ <table>
466
+ <tr>
467
+ <th colspan="2">
468
+ <br><img src="https://contrib.rocks/image?repo=lobehub/lobe-chat"><br><br>
469
+ </th>
470
+ </tr>
471
+ <tr>
472
+ <td>
473
+ <picture>
474
+ <source media="(prefers-color-scheme: dark)" srcset="https://next.ossinsight.io/widgets/official/compose-org-active-contributors/thumbnail.png?activity=active&period=past_28_days&owner_id=131470832&repo_ids=643445235&image_size=2x3&color_scheme=dark">
475
+ <img src="https://next.ossinsight.io/widgets/official/compose-org-active-contributors/thumbnail.png?activity=active&period=past_28_days&owner_id=131470832&repo_ids=643445235&image_size=2x3&color_scheme=light">
476
+ </picture>
477
+ </td>
478
+ <td rowspan="2">
479
+ <picture>
480
+ <source media="(prefers-color-scheme: dark)" srcset="https://next.ossinsight.io/widgets/official/compose-org-participants-growth/thumbnail.png?activity=active&period=past_28_days&owner_id=131470832&repo_ids=643445235&image_size=4x7&color_scheme=dark">
481
+ <img src="https://next.ossinsight.io/widgets/official/compose-org-participants-growth/thumbnail.png?activity=active&period=past_28_days&owner_id=131470832&repo_ids=643445235&image_size=4x7&color_scheme=light">
482
+ </picture>
483
+ </td>
484
+ </tr>
485
+ <tr>
486
+ <td>
487
+ <picture>
488
+ <source media="(prefers-color-scheme: dark)" srcset="https://next.ossinsight.io/widgets/official/compose-org-active-contributors/thumbnail.png?activity=new&period=past_28_days&owner_id=131470832&repo_ids=643445235&image_size=2x3&color_scheme=dark">
489
+ <img src="https://next.ossinsight.io/widgets/official/compose-org-active-contributors/thumbnail.png?activity=new&period=past_28_days&owner_id=131470832&repo_ids=643445235&image_size=2x3&color_scheme=light">
490
+ </picture>
491
+ </td>
492
+ </tr>
493
+ </table>
494
+ </a>
463
495
 
464
496
  <div align="right">
465
497
 
@@ -504,8 +536,6 @@ This project is [MIT](./LICENSE) licensed.
504
536
  [chat-plugins-gateway]: https://github.com/lobehub/chat-plugins-gateway
505
537
  [codespaces-link]: https://codespaces.new/lobehub/lobe-chat
506
538
  [codespaces-shield]: https://github.com/codespaces/badge.svg
507
- [contributors-contrib]: https://contrib.rocks/image?repo=lobehub/lobe-chat
508
- [contributors-link]: https://github.com/lobehub/lobe-chat/graphs/contributors
509
539
  [deploy-button-image]: https://vercel.com/button
510
540
  [deploy-link]: https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Flobehub%2Flobe-chat&env=OPENAI_API_KEY&envDescription=Find%20your%20OpenAI%20API%20Key%20by%20click%20the%20right%20Learn%20More%20button.&envLink=https%3A%2F%2Fplatform.openai.com%2Faccount%2Fapi-keys&project-name=lobe-chat&repository-name=lobe-chat
511
541
  [deploy-on-zeabur-button-image]: https://zeabur.com/button.svg
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "0.107.12",
3
+ "version": "0.107.14",
4
4
  "description": "An open-source, extensible (Function Calling), high-performance chatbot framework. It supports one-click free deployment of your private ChatGPT/LLM web application",
5
5
  "keywords": [
6
6
  "chatbot",
@@ -106,7 +106,6 @@
106
106
  "react-intersection-observer": "^9",
107
107
  "react-layout-kit": "^1",
108
108
  "react-lazy-load": "^4",
109
- "react-spring-lightbox": "^1",
110
109
  "react-wrap-balancer": "^1.1.0",
111
110
  "remark": "^14",
112
111
  "remark-gfm": "^3",
@@ -1,10 +1,10 @@
1
1
  import { memo } from 'react';
2
2
 
3
- import FileList from '@/app/chat/components/FileList';
3
+ import EditableFileList from '@/components/FileList/EditableFileList';
4
4
  import { useFileStore } from '@/store/file';
5
5
 
6
6
  export const LocalFiles = memo(() => {
7
7
  const inputFilesList = useFileStore((s) => s.inputFilesList);
8
8
 
9
- return <FileList items={inputFilesList} />;
9
+ return <EditableFileList items={inputFilesList} padding={0} />;
10
10
  });
@@ -1,16 +1,17 @@
1
1
  import { memo } from 'react';
2
- import { Flexbox } from 'react-layout-kit';
3
2
 
4
- import FileList from '@/app/chat/components/FileList';
3
+ import EditableFileList from '@/components/FileList/EditableFileList';
5
4
  import { useFileStore } from '@/store/file';
6
5
 
7
6
  const Files = memo(() => {
8
7
  const inputFilesList = useFileStore((s) => s.inputFilesList);
9
8
 
9
+ if (!inputFilesList || inputFilesList?.length === 0) return null;
10
+
10
11
  return (
11
- <Flexbox padding={12}>
12
- <FileList alwaysShowClose items={inputFilesList} />
13
- </Flexbox>
12
+ <div style={{ position: 'relative', width: '100vw' }}>
13
+ <EditableFileList alwaysShowClose items={inputFilesList} padding={'0 8px'} />
14
+ </div>
14
15
  );
15
16
  });
16
17
 
@@ -3,6 +3,7 @@ import { rgba } from 'polished';
3
3
  import { memo } from 'react';
4
4
  import { Flexbox } from 'react-layout-kit';
5
5
 
6
+ import Files from '@/app/chat/(mobile)/features/ChatInput/Files';
6
7
  import ActionBar from '@/app/chat/features/ChatInput/ActionBar';
7
8
  import InputAreaInner from '@/app/chat/features/ChatInput/InputAreaInner';
8
9
  import STT from '@/app/chat/features/ChatInput/STT';
@@ -28,6 +29,7 @@ const ChatInputArea = memo(() => {
28
29
 
29
30
  return (
30
31
  <Flexbox className={styles.container} gap={12}>
32
+ <Files />
31
33
  <ActionBar mobile padding={'0 8px'} rightAreaStartRender={<SaveTopic mobile />} />
32
34
  <Flexbox className={styles.inner} gap={8} horizontal>
33
35
  <STT mobile />
@@ -4,7 +4,6 @@ import { memo } from 'react';
4
4
  import SafeSpacing from '@/components/SafeSpacing';
5
5
  import { CHAT_TEXTAREA_HEIGHT_MOBILE } from '@/const/layoutTokens';
6
6
 
7
- import Files from './Files';
8
7
  import ChatInputArea from './Mobile';
9
8
 
10
9
  const useStyles = createStyles(
@@ -25,7 +24,6 @@ const ChatInputMobileLayout = memo(() => {
25
24
 
26
25
  return (
27
26
  <>
28
- <Files />
29
27
  <SafeSpacing height={CHAT_TEXTAREA_HEIGHT_MOBILE} mobile position={'bottom'} />
30
28
  <div className={styles}>
31
29
  <ChatInputArea />
@@ -6,9 +6,9 @@ import { domToJpeg, domToPng, domToSvg, domToWebp } from 'modern-screenshot';
6
6
  import { memo, useCallback, useState } from 'react';
7
7
  import { useTranslation } from 'react-i18next';
8
8
  import { Flexbox } from 'react-layout-kit';
9
- import ChatList from 'src/app/chat/features/Conversation/ChatList';
10
9
 
11
10
  import pkg from '@/../package.json';
11
+ import ChatList from '@/app/chat/features/Conversation/ChatList';
12
12
  import { useSessionStore } from '@/store/session';
13
13
  import { agentSelectors, sessionSelectors } from '@/store/session/selectors';
14
14
 
@@ -22,6 +22,7 @@ const Clear = memo(() => {
22
22
  }, []);
23
23
 
24
24
  useHotkeys(hotkeys, resetConversation, {
25
+ enableOnFormTags: true,
25
26
  preventDefault: true,
26
27
  });
27
28
 
@@ -1,7 +1,7 @@
1
1
  import { ReactNode, memo } from 'react';
2
2
  import { Flexbox } from 'react-layout-kit';
3
3
 
4
- import FileList from '@/app/chat/components/FileList';
4
+ import FileList from '@/components/FileList';
5
5
  import { LOADING_FLAT } from '@/const/message';
6
6
  import { ChatMessage } from '@/types/chatMessage';
7
7
 
@@ -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 editable={false} items={res.files} />}
20
+ {res.files && res.files?.length > 0 && <FileList items={res.files} />}
21
21
  </Flexbox>
22
22
  );
23
23
  });
@@ -45,6 +45,7 @@ const List = memo(() => {
45
45
  resendMessage(lastMessage.id);
46
46
  },
47
47
  {
48
+ enableOnFormTags: true,
48
49
  preventDefault: true,
49
50
  },
50
51
  );
@@ -0,0 +1,35 @@
1
+ import { ImageGallery } from '@lobehub/ui';
2
+ import { useResponsive } from 'antd-style';
3
+ import { memo } from 'react';
4
+ import { Flexbox } from 'react-layout-kit';
5
+
6
+ import FileItem from '@/components/FileList/FileItem';
7
+
8
+ interface EditableFileListProps {
9
+ alwaysShowClose?: boolean;
10
+ editable?: boolean;
11
+ items: string[];
12
+ padding?: number | string;
13
+ }
14
+
15
+ const EditableFileList = memo<EditableFileListProps>(
16
+ ({ items, editable = true, alwaysShowClose, padding = 12 }) => {
17
+ const { mobile } = useResponsive();
18
+ return (
19
+ <Flexbox
20
+ gap={mobile ? 4 : 6}
21
+ horizontal
22
+ padding={padding}
23
+ style={{ overflow: 'auto', width: '100%' }}
24
+ >
25
+ <ImageGallery>
26
+ {items.map((i) => (
27
+ <FileItem alwaysShowClose={alwaysShowClose} editable={editable} id={i} key={i} />
28
+ ))}
29
+ </ImageGallery>
30
+ </Flexbox>
31
+ );
32
+ },
33
+ );
34
+
35
+ export default EditableFileList;
@@ -0,0 +1,36 @@
1
+ import { CSSProperties, ReactNode, memo } from 'react';
2
+ import { Flexbox } from 'react-layout-kit';
3
+
4
+ import { MAX_SIZE_DESKTOP, MIN_IMAGE_SIZE, useStyles } from '@/components/FileList/style';
5
+
6
+ interface FileGridProps {
7
+ children: ReactNode;
8
+ className?: string;
9
+ col?: number;
10
+ gap?: number;
11
+ max?: number;
12
+ min?: number;
13
+ style?: CSSProperties;
14
+ }
15
+
16
+ const FileGrid = memo<FileGridProps>(
17
+ ({
18
+ gap = 4,
19
+ col = 3,
20
+ max = MAX_SIZE_DESKTOP,
21
+ min = MIN_IMAGE_SIZE,
22
+ children,
23
+ className,
24
+ style,
25
+ }) => {
26
+ const { styles, cx } = useStyles({ col, gap, max, min });
27
+
28
+ return (
29
+ <Flexbox className={cx(styles.container, className)} gap={gap} horizontal style={style}>
30
+ {children}
31
+ </Flexbox>
32
+ );
33
+ },
34
+ );
35
+
36
+ export default FileGrid;
@@ -0,0 +1,73 @@
1
+ import { ActionIcon, Image } from '@lobehub/ui';
2
+ import { createStyles } from 'antd-style';
3
+ import { Trash } from 'lucide-react';
4
+ import { CSSProperties, memo, useCallback } from 'react';
5
+
6
+ import { useFileStore } from '@/store/file';
7
+
8
+ import { MIN_IMAGE_SIZE } from './style';
9
+
10
+ export 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
+ border: 1px solid ${token.colorBorderSecondary};
22
+ `,
23
+ image: css`
24
+ margin-block: 0 !important;
25
+ `,
26
+ }));
27
+
28
+ interface FileItemProps {
29
+ alwaysShowClose?: boolean;
30
+ className?: string;
31
+ editable?: boolean;
32
+ id: string;
33
+ onClick?: () => void;
34
+ style?: CSSProperties;
35
+ }
36
+ const FileItem = memo<FileItemProps>(({ editable, id, alwaysShowClose }) => {
37
+ const [useFetchFile, removeFile] = useFileStore((s) => [s.useFetchFile, s.removeFile]);
38
+ const IMAGE_SIZE = editable ? MIN_IMAGE_SIZE : '100%';
39
+ const { data, isLoading } = useFetchFile(id);
40
+ const { styles, cx } = useStyles();
41
+
42
+ const handleRemoveFile = useCallback(
43
+ (e: any) => {
44
+ e.stopPropagation();
45
+ removeFile(id);
46
+ },
47
+ [id],
48
+ );
49
+
50
+ return (
51
+ <Image
52
+ actions={
53
+ editable && (
54
+ <ActionIcon
55
+ className={styles.deleteButton}
56
+ glass
57
+ icon={Trash}
58
+ onClick={handleRemoveFile}
59
+ size={'small'}
60
+ />
61
+ )
62
+ }
63
+ alt={data?.name || id || ''}
64
+ alwaysShowActions={alwaysShowClose}
65
+ isLoading={isLoading}
66
+ size={IMAGE_SIZE as any}
67
+ src={data?.url}
68
+ wrapperClassName={cx(styles.image, editable && styles.editableImage)}
69
+ />
70
+ );
71
+ });
72
+
73
+ export default FileItem;
@@ -0,0 +1,62 @@
1
+ import { ImageGallery } from '@lobehub/ui';
2
+ import { useResponsive } from 'antd-style';
3
+ import { memo, useMemo } from 'react';
4
+ import { Flexbox } from 'react-layout-kit';
5
+
6
+ import { MAX_SIZE_DESKTOP, MAX_SIZE_MOBILE } from '@/components/FileList/style';
7
+
8
+ import FileGrid from './FileGrid';
9
+ import FileItem from './FileItem';
10
+
11
+ interface FileListProps {
12
+ items: string[];
13
+ }
14
+
15
+ const FileList = memo<FileListProps>(({ items }) => {
16
+ const { mobile } = useResponsive();
17
+
18
+ const { firstRow, lastRow } = useMemo(() => {
19
+ if (items.length === 4) {
20
+ return {
21
+ firstRow: items.slice(0, 2),
22
+ lastRow: items.slice(2, 4),
23
+ };
24
+ }
25
+
26
+ const firstCol = items.length % 3 === 0 ? 3 : items.length % 3;
27
+
28
+ return {
29
+ firstRow: items.slice(0, firstCol),
30
+ lastRow: items.slice(firstCol, items.length),
31
+ };
32
+ }, [items]);
33
+
34
+ const { gap, max } = useMemo(
35
+ () => ({
36
+ gap: mobile ? 4 : 6,
37
+ max: mobile ? MAX_SIZE_MOBILE : MAX_SIZE_DESKTOP,
38
+ }),
39
+ [mobile],
40
+ );
41
+
42
+ return (
43
+ <ImageGallery>
44
+ <Flexbox gap={gap}>
45
+ <FileGrid col={firstRow.length} gap={gap} max={max}>
46
+ {firstRow.map((i) => (
47
+ <FileItem id={i} key={i} />
48
+ ))}
49
+ </FileGrid>
50
+ {lastRow.length > 0 && (
51
+ <FileGrid col={lastRow.length > 2 ? 3 : lastRow.length} gap={gap} max={max}>
52
+ {lastRow.map((i) => (
53
+ <FileItem id={i} key={i} />
54
+ ))}
55
+ </FileGrid>
56
+ )}
57
+ </Flexbox>
58
+ </ImageGallery>
59
+ );
60
+ });
61
+
62
+ export default FileList;
@@ -0,0 +1,24 @@
1
+ import { createStyles } from 'antd-style';
2
+
3
+ export const MIN_IMAGE_SIZE = 64;
4
+ export const MAX_SIZE_DESKTOP = 640;
5
+ export const MAX_SIZE_MOBILE = 280;
6
+ export const useStyles = createStyles(
7
+ ({ css }, { col, gap, max, min }: { col: number; gap: number; max: number; min: number }) => ({
8
+ container: css`
9
+ display: grid;
10
+ grid-gap: ${gap}px;
11
+ grid-template-columns: repeat(${col}, 1fr);
12
+
13
+ width: 100%;
14
+ max-width: ${max}px;
15
+
16
+ & > div {
17
+ width: 100%;
18
+ min-width: ${min}px;
19
+ min-height: ${min}px;
20
+ max-height: ${(max - gap * (col - 1)) / col}px;
21
+ }
22
+ `,
23
+ }),
24
+ );
@@ -6,9 +6,9 @@ import { LucideBlocks, LucideSettings, LucideStore, LucideTrash2 } from 'lucide-
6
6
  import { memo, useState } from 'react';
7
7
  import { useTranslation } from 'react-i18next';
8
8
  import { Flexbox } from 'react-layout-kit';
9
- import DevModal from 'src/features/PluginDevModal';
10
9
 
11
10
  import { FORM_STYLE } from '@/const/layoutTokens';
11
+ import DevModal from '@/features/PluginDevModal';
12
12
  import { pluginHelpers, usePluginStore } from '@/store/plugin';
13
13
  import { pluginSelectors } from '@/store/plugin/selectors';
14
14
 
@@ -8,6 +8,7 @@ import { useIsPWA } from '@/hooks/useIsPWA';
8
8
  const AppLayoutDesktop = memo<PropsWithChildren>(({ children }) => {
9
9
  const isPWA = useIsPWA();
10
10
  const theme = useTheme();
11
+
11
12
  return (
12
13
  <Flexbox
13
14
  height={'100%'}
@@ -16,6 +16,7 @@ const InnerLocale = memo<LocaleLayoutProps>(({ children, lang }) => {
16
16
  lang,
17
17
  async () =>
18
18
  await import(`antd/locale/${lang?.includes('-') ? lang?.replace('-', '_') : 'en-US'}.js`),
19
+ { revalidateOnFocus: false },
19
20
  );
20
21
  const [i18n] = useState(createI18nNext(lang));
21
22