@lobehub/chat 0.107.11 → 0.107.13

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 (41) hide show
  1. package/.github/FUNDING.yml +13 -0
  2. package/CHANGELOG.md +79 -0
  3. package/README.md +33 -3
  4. package/README.zh-CN.md +33 -3
  5. package/package.json +1 -2
  6. package/src/app/chat/(desktop)/features/ChatInput/DragUpload.tsx +1 -1
  7. package/src/app/chat/(desktop)/features/ChatInput/Footer/LocalFiles.tsx +3 -3
  8. package/src/app/chat/(mobile)/features/ChatInput/Files.tsx +7 -6
  9. package/src/app/chat/(mobile)/features/ChatInput/Mobile.tsx +2 -0
  10. package/src/app/chat/(mobile)/features/ChatInput/index.tsx +0 -2
  11. package/src/app/chat/features/ChatHeader/ShareButton/Preview.tsx +1 -1
  12. package/src/app/chat/features/ChatInput/ActionBar/Clear.tsx +1 -1
  13. package/src/app/chat/features/ChatInput/ActionBar/FileUpload.tsx +1 -1
  14. package/src/app/chat/features/ChatInput/useSend.ts +2 -2
  15. package/src/app/chat/features/Conversation/ChatList/Messages/User.tsx +2 -2
  16. package/src/app/settings/common/Common.tsx +1 -1
  17. package/src/components/FileList/EditableFileList.tsx +35 -0
  18. package/src/components/FileList/FileGrid.tsx +36 -0
  19. package/src/components/FileList/FileItem.tsx +73 -0
  20. package/src/components/FileList/index.tsx +62 -0
  21. package/src/components/FileList/style.ts +24 -0
  22. package/src/features/AgentSetting/AgentPlugin/MarketList.tsx +1 -1
  23. package/src/layout/AppLayout.desktop.tsx +1 -0
  24. package/src/layout/GlobalLayout/Locale.tsx +1 -0
  25. package/src/services/chat.ts +1 -1
  26. package/src/store/chat/actions/message.test.ts +481 -0
  27. package/src/store/chat/actions/message.ts +4 -1
  28. package/src/store/chat/actions/topic.ts +1 -0
  29. package/src/app/chat/components/FileList/FileItem.style.ts +0 -84
  30. package/src/app/chat/components/FileList/FileItem.tsx +0 -73
  31. package/src/app/chat/components/FileList/Lightbox.tsx +0 -46
  32. package/src/app/chat/components/FileList/index.tsx +0 -60
  33. /package/src/store/{files → file}/index.ts +0 -0
  34. /package/src/store/{files → file}/initialState.ts +0 -0
  35. /package/src/store/{files → file}/selectors.test.ts +0 -0
  36. /package/src/store/{files → file}/selectors.ts +0 -0
  37. /package/src/store/{files → file}/slices/images/action.test.ts +0 -0
  38. /package/src/store/{files → file}/slices/images/action.ts +0 -0
  39. /package/src/store/{files → file}/slices/images/index.ts +0 -0
  40. /package/src/store/{files → file}/slices/images/initialState.ts +0 -0
  41. /package/src/store/{files → file}/store.ts +0 -0
@@ -0,0 +1,13 @@
1
+ # These are supported funding model platforms
2
+
3
+ github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4
+ patreon: # Replace with a single Patreon username
5
+ open_collective: lobehub
6
+ ko_fi: # Replace with a single Ko-fi username
7
+ tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8
+ community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9
+ liberapay: # Replace with a single Liberapay username
10
+ issuehunt: lobehub/lobe-chat
11
+ otechie: # Replace with a single Otechie username
12
+ lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
13
+ custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
package/CHANGELOG.md CHANGED
@@ -2,6 +2,85 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ### [Version 0.107.13](https://github.com/lobehub/lobe-chat/compare/v0.107.12...v0.107.13)
6
+
7
+ <sup>Released on **2023-12-03**</sup>
8
+
9
+ #### ♻ Code Refactoring
10
+
11
+ - **misc**: Refactor Image components.
12
+
13
+ #### 🐛 Bug Fixes
14
+
15
+ - **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.
16
+
17
+ #### 💄 Styles
18
+
19
+ - **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.
20
+
21
+ <br/>
22
+
23
+ <details>
24
+ <summary><kbd>Improvements and Fixes</kbd></summary>
25
+
26
+ #### Code refactoring
27
+
28
+ - **misc**: Refactor Image components ([72dcd18](https://github.com/lobehub/lobe-chat/commit/72dcd18))
29
+
30
+ #### What's fixed
31
+
32
+ - **misc**: Fix a bug that can't send only images with empty content ([9601520](https://github.com/lobehub/lobe-chat/commit/9601520))
33
+ - **misc**: Fix image gallery sort index ([16548d3](https://github.com/lobehub/lobe-chat/commit/16548d3))
34
+ - **misc**: Fix image gallery sort index ([5636599](https://github.com/lobehub/lobe-chat/commit/5636599))
35
+ - **misc**: Fix image sort index ([29cf223](https://github.com/lobehub/lobe-chat/commit/29cf223))
36
+ - **misc**: Fix image upload error ([c7745c7](https://github.com/lobehub/lobe-chat/commit/c7745c7))
37
+ - **misc**: Fix import ([af797d6](https://github.com/lobehub/lobe-chat/commit/af797d6))
38
+
39
+ #### Styles
40
+
41
+ - **misc**: Change image fit to cover mode ([9fdc459](https://github.com/lobehub/lobe-chat/commit/9fdc459))
42
+ - **misc**: Fix empty files style ([bbe14c4](https://github.com/lobehub/lobe-chat/commit/bbe14c4))
43
+ - **misc**: Move file inside chat input in mobile mode ([b6401c1](https://github.com/lobehub/lobe-chat/commit/b6401c1))
44
+ - **misc**: Update editable image style ([a96ca4c](https://github.com/lobehub/lobe-chat/commit/a96ca4c))
45
+ - **misc**: Update image default background color ([fadc024](https://github.com/lobehub/lobe-chat/commit/fadc024))
46
+ - **misc**: Update image editable style ([8dea792](https://github.com/lobehub/lobe-chat/commit/8dea792))
47
+ - **misc**: Update image grid ([901d10c](https://github.com/lobehub/lobe-chat/commit/901d10c))
48
+ - **misc**: Update Image grid ([c68788d](https://github.com/lobehub/lobe-chat/commit/c68788d))
49
+ - **misc**: Update image remove button hover style ([5bc916c](https://github.com/lobehub/lobe-chat/commit/5bc916c))
50
+
51
+ </details>
52
+
53
+ <div align="right">
54
+
55
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
56
+
57
+ </div>
58
+
59
+ ### [Version 0.107.12](https://github.com/lobehub/lobe-chat/compare/v0.107.11...v0.107.12)
60
+
61
+ <sup>Released on **2023-12-02**</sup>
62
+
63
+ #### 🐛 Bug Fixes
64
+
65
+ - **misc**: Fix topic not refresh when switching sessions quickly.
66
+
67
+ <br/>
68
+
69
+ <details>
70
+ <summary><kbd>Improvements and Fixes</kbd></summary>
71
+
72
+ #### What's fixed
73
+
74
+ - **misc**: Fix topic not refresh when switching sessions quickly, closes [#555](https://github.com/lobehub/lobe-chat/issues/555) ([1806c05](https://github.com/lobehub/lobe-chat/commit/1806c05))
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.11](https://github.com/lobehub/lobe-chat/compare/v0.107.10...v0.107.11)
6
85
 
7
86
  <sup>Released on **2023-12-01**</sup>
package/README.md CHANGED
@@ -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
@@ -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.11",
3
+ "version": "0.107.13",
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",
@@ -6,7 +6,7 @@ import { memo, useEffect, useRef, useState } from 'react';
6
6
  import { useTranslation } from 'react-i18next';
7
7
  import { Center, Flexbox } from 'react-layout-kit';
8
8
 
9
- import { useFileStore } from '@/store/files';
9
+ import { useFileStore } from '@/store/file';
10
10
 
11
11
  const useStyles = createStyles(({ css, token, stylish }) => {
12
12
  return {
@@ -1,10 +1,10 @@
1
1
  import { memo } from 'react';
2
2
 
3
- import FileList from '@/app/chat/components/FileList';
4
- import { useFileStore } from '@/store/files';
3
+ import EditableFileList from '@/components/FileList/EditableFileList';
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';
5
- import { useFileStore } from '@/store/files';
3
+ import EditableFileList from '@/components/FileList/EditableFileList';
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
 
@@ -8,7 +8,7 @@ import { useTranslation } from 'react-i18next';
8
8
  import HotKeys from '@/components/HotKeys';
9
9
  import { CLEAN_MESSAGE_KEY, PREFIX_KEY } from '@/const/hotkeys';
10
10
  import { useChatStore } from '@/store/chat';
11
- import { useFileStore } from '@/store/files';
11
+ import { useFileStore } from '@/store/file';
12
12
 
13
13
  const Clear = memo(() => {
14
14
  const { t } = useTranslation('setting');
@@ -6,7 +6,7 @@ import { memo, useState } from 'react';
6
6
  import { useTranslation } from 'react-i18next';
7
7
  import { Center } from 'react-layout-kit';
8
8
 
9
- import { useFileStore } from '@/store/files';
9
+ import { useFileStore } from '@/store/file';
10
10
  import { useSessionStore } from '@/store/session';
11
11
  import { agentSelectors } from '@/store/session/selectors';
12
12
 
@@ -1,7 +1,7 @@
1
1
  import { useCallback } from 'react';
2
2
 
3
- import { filesSelectors, useFileStore } from '@/store/files';
4
- import { useChatStore } from 'src/store/chat';
3
+ import { useChatStore } from '@/store/chat';
4
+ import { filesSelectors, useFileStore } from '@/store/file';
5
5
 
6
6
  export const useSendMessage = () => {
7
7
  const [sendMessage, updateInputMessage] = useChatStore((s) => [
@@ -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
  });
@@ -11,7 +11,7 @@ import { DEFAULT_SETTINGS } from '@/const/settings';
11
11
  import AvatarWithUpload from '@/features/AvatarWithUpload';
12
12
  import { localeOptions } from '@/locales/options';
13
13
  import { useChatStore } from '@/store/chat';
14
- import { useFileStore } from '@/store/files';
14
+ import { useFileStore } from '@/store/file';
15
15
  import { settingsSelectors, useGlobalStore } from '@/store/global';
16
16
  import { usePluginStore } from '@/store/plugin';
17
17
  import { useSessionStore } from '@/store/session';
@@ -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