@lobehub/chat 0.152.3 → 0.152.5

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 (211) hide show
  1. package/CHANGELOG.md +4 -29
  2. package/locales/ar/common.json +0 -14
  3. package/locales/ar/setting.json +1 -4
  4. package/locales/bg-BG/common.json +0 -14
  5. package/locales/bg-BG/setting.json +1 -4
  6. package/locales/de-DE/common.json +0 -14
  7. package/locales/de-DE/setting.json +1 -4
  8. package/locales/en-US/common.json +0 -14
  9. package/locales/en-US/setting.json +1 -4
  10. package/locales/es-ES/common.json +0 -14
  11. package/locales/es-ES/setting.json +1 -4
  12. package/locales/fr-FR/common.json +0 -14
  13. package/locales/fr-FR/setting.json +1 -4
  14. package/locales/it-IT/common.json +0 -14
  15. package/locales/it-IT/setting.json +1 -4
  16. package/locales/ja-JP/common.json +0 -14
  17. package/locales/ja-JP/setting.json +1 -4
  18. package/locales/ko-KR/common.json +0 -14
  19. package/locales/ko-KR/setting.json +1 -4
  20. package/locales/nl-NL/common.json +0 -14
  21. package/locales/nl-NL/setting.json +1 -4
  22. package/locales/pl-PL/common.json +0 -14
  23. package/locales/pl-PL/setting.json +1 -4
  24. package/locales/pt-BR/common.json +0 -14
  25. package/locales/pt-BR/setting.json +1 -4
  26. package/locales/ru-RU/common.json +0 -14
  27. package/locales/ru-RU/setting.json +1 -4
  28. package/locales/tr-TR/common.json +0 -14
  29. package/locales/tr-TR/setting.json +1 -4
  30. package/locales/vi-VN/common.json +0 -14
  31. package/locales/vi-VN/setting.json +1 -4
  32. package/locales/zh-CN/common.json +0 -14
  33. package/locales/zh-CN/setting.json +1 -4
  34. package/locales/zh-TW/common.json +0 -14
  35. package/locales/zh-TW/setting.json +1 -4
  36. package/package.json +1 -1
  37. package/src/app/(main)/@nav/_layout/Desktop/Avatar.tsx +11 -0
  38. package/src/app/(main)/@nav/_layout/Desktop/BottomActions.tsx +120 -7
  39. package/src/app/(main)/@nav/_layout/Desktop/index.tsx +2 -7
  40. package/src/app/(main)/@nav/_layout/Mobile.tsx +3 -3
  41. package/src/app/(main)/chat/(mobile)/features/SessionHeader.tsx +1 -1
  42. package/src/app/(main)/chat/_layout/Desktop/index.tsx +8 -6
  43. package/src/app/(main)/chat/_layout/Mobile/index.tsx +3 -5
  44. package/src/app/(main)/chat/features/SettingButton.tsx +5 -4
  45. package/src/app/(main)/chat/layout.ts +2 -5
  46. package/src/app/(main)/chat/settings/{_layout/Desktop → (desktop)}/Header.tsx +0 -2
  47. package/src/app/(main)/chat/settings/(desktop)/index.tsx +23 -0
  48. package/src/app/(main)/chat/settings/{_layout/Mobile → (mobile)}/Header.tsx +2 -3
  49. package/src/app/(main)/chat/settings/(mobile)/index.tsx +16 -0
  50. package/src/app/(main)/chat/settings/features/HeaderContent.tsx +9 -15
  51. package/src/app/(main)/chat/settings/features/SubmitAgentButton/SubmitAgentModal.tsx +0 -2
  52. package/src/app/(main)/chat/settings/features/SubmitAgentButton/index.tsx +8 -16
  53. package/src/app/(main)/chat/settings/layout.tsx +2 -9
  54. package/src/app/(main)/chat/settings/page.tsx +9 -2
  55. package/src/app/(main)/market/{_layout/Desktop/DetailSidebar.tsx → @detail/_layout/Desktop.tsx} +2 -2
  56. package/src/app/(main)/market/{_layout/Mobile/DetailModal.tsx → @detail/_layout/Mobile.tsx} +2 -2
  57. package/src/app/(main)/market/@detail/default.tsx +10 -1
  58. package/src/app/(main)/market/_layout/Desktop/index.tsx +1 -2
  59. package/src/app/(main)/market/_layout/Mobile/index.tsx +1 -3
  60. package/src/app/(main)/settings/(desktop)/index.tsx +23 -0
  61. package/src/app/(main)/settings/(mobile)/features/AvatarBanner.tsx +68 -0
  62. package/src/app/(main)/settings/(mobile)/features/ExtraList.tsx +65 -0
  63. package/src/app/(main)/settings/(mobile)/index.tsx +53 -0
  64. package/src/app/(main)/settings/_layout/Desktop/Header.tsx +23 -78
  65. package/src/app/(main)/settings/_layout/Desktop/SideBar.tsx +27 -39
  66. package/src/app/(main)/settings/_layout/Desktop/index.tsx +17 -41
  67. package/src/app/(main)/settings/_layout/Mobile/{Header.tsx → SubSettingHeader.tsx} +1 -3
  68. package/src/app/(main)/settings/_layout/Mobile/index.tsx +18 -7
  69. package/src/app/(main)/settings/about/AboutList.tsx +53 -0
  70. package/src/app/(main)/settings/about/Analytics.tsx +40 -0
  71. package/src/app/(main)/settings/about/page.tsx +33 -13
  72. package/src/app/(main)/settings/about/style.ts +22 -0
  73. package/src/app/(main)/settings/agent/Agent.tsx +29 -0
  74. package/src/app/(main)/settings/agent/loading.tsx +3 -0
  75. package/src/app/(main)/settings/agent/page.tsx +16 -8
  76. package/src/app/(main)/settings/common/{features/Common.tsx → Common.tsx} +5 -7
  77. package/src/app/(main)/settings/common/{features/Theme/index.tsx → Theme.tsx} +6 -8
  78. package/src/app/(main)/settings/common/index.tsx +16 -11
  79. package/src/app/(main)/settings/common/loading.tsx +3 -0
  80. package/src/app/(main)/settings/common/page.tsx +7 -8
  81. package/src/app/(main)/settings/features/Footer.tsx +0 -2
  82. package/src/app/(main)/settings/features/SettingList/index.tsx +47 -0
  83. package/src/app/(main)/settings/features/UpgradeAlert.tsx +13 -21
  84. package/src/app/(main)/settings/hooks/useSyncSettings.ts +2 -2
  85. package/src/app/(main)/settings/layout.ts +1 -4
  86. package/src/app/(main)/settings/llm/Anthropic/index.tsx +10 -4
  87. package/src/app/(main)/settings/llm/Azure/index.tsx +1 -3
  88. package/src/app/(main)/settings/llm/Bedrock/index.tsx +1 -3
  89. package/src/app/(main)/settings/llm/Google/index.tsx +2 -4
  90. package/src/app/(main)/settings/llm/Groq/index.tsx +1 -3
  91. package/src/app/(main)/settings/llm/Minimax/index.tsx +9 -3
  92. package/src/app/(main)/settings/llm/Mistral/index.tsx +9 -3
  93. package/src/app/(main)/settings/llm/Moonshot/index.tsx +1 -3
  94. package/src/app/(main)/settings/llm/Ollama/index.tsx +1 -3
  95. package/src/app/(main)/settings/llm/OpenAI/index.tsx +0 -2
  96. package/src/app/(main)/settings/llm/OpenRouter/index.tsx +9 -3
  97. package/src/app/(main)/settings/llm/Perplexity/index.tsx +9 -3
  98. package/src/app/(main)/settings/llm/TogetherAI/index.tsx +9 -3
  99. package/src/app/(main)/settings/llm/ZeroOne/index.tsx +9 -3
  100. package/src/app/(main)/settings/llm/Zhipu/index.tsx +10 -3
  101. package/src/app/(main)/settings/llm/components/Checker.tsx +0 -2
  102. package/src/app/(main)/settings/llm/components/ProviderConfig/index.tsx +1 -16
  103. package/src/app/(main)/settings/llm/index.tsx +24 -12
  104. package/src/app/(main)/settings/llm/layout.tsx +11 -0
  105. package/src/app/(main)/settings/llm/loading.tsx +3 -0
  106. package/src/app/(main)/settings/llm/page.tsx +0 -15
  107. package/src/app/(main)/settings/page.tsx +14 -2
  108. package/src/app/(main)/settings/sync/{features/DeviceInfo → DeviceInfo}/Card.tsx +5 -6
  109. package/src/app/(main)/settings/sync/DeviceInfo/DeviceName.tsx +66 -0
  110. package/src/app/(main)/settings/sync/{features/DeviceInfo → DeviceInfo}/index.tsx +36 -22
  111. package/src/app/(main)/settings/sync/PageTitle.tsx +11 -0
  112. package/src/app/(main)/settings/sync/{features/WebRTC → WebRTC}/ChannelNameInput.tsx +3 -3
  113. package/src/app/(main)/settings/sync/{features/WebRTC → WebRTC}/index.tsx +9 -10
  114. package/src/app/(main)/settings/sync/{features/DeviceInfo → components}/SystemIcon.tsx +14 -6
  115. package/src/app/(main)/settings/sync/layout.tsx +12 -0
  116. package/src/app/(main)/settings/sync/loading.tsx +3 -0
  117. package/src/app/(main)/settings/sync/page.tsx +15 -11
  118. package/src/app/(main)/settings/tts/{features/STT.tsx → TTS/index.tsx} +27 -11
  119. package/src/app/(main)/settings/tts/loading.tsx +3 -0
  120. package/src/app/(main)/settings/tts/page.tsx +16 -8
  121. package/src/app/layout.tsx +3 -11
  122. package/src/const/url.ts +0 -1
  123. package/src/features/AgentSetting/AgentConfig/index.tsx +202 -0
  124. package/src/features/AgentSetting/AgentConfig/useSyncConfig.ts +23 -0
  125. package/src/features/AgentSetting/AgentMeta/index.tsx +3 -4
  126. package/src/features/AgentSetting/AgentPlugin/index.tsx +66 -65
  127. package/src/features/AgentSetting/AgentPrompt/index.tsx +47 -101
  128. package/src/features/AgentSetting/AgentTTS/index.tsx +0 -4
  129. package/src/features/AgentSetting/StoreUpdater.tsx +0 -2
  130. package/src/features/AgentSetting/index.tsx +6 -6
  131. package/src/features/AgentSetting/store/index.ts +0 -2
  132. package/src/features/AvatarWithUpload/index.tsx +0 -2
  133. package/src/locales/default/common.ts +0 -14
  134. package/src/locales/default/setting.ts +0 -3
  135. package/src/store/global/initialState.ts +0 -1
  136. package/src/app/(main)/(mobile)/me/features/AvatarBanner.tsx +0 -52
  137. package/src/app/(main)/(mobile)/me/features/Cate.tsx +0 -35
  138. package/src/app/(main)/(mobile)/me/features/ExtraCate.tsx +0 -26
  139. package/src/app/(main)/(mobile)/me/features/useExtraCate.tsx +0 -68
  140. package/src/app/(main)/(mobile)/me/layout.tsx +0 -11
  141. package/src/app/(main)/(mobile)/me/loading.tsx +0 -17
  142. package/src/app/(main)/(mobile)/me/page.tsx +0 -31
  143. package/src/app/(main)/@nav/features/UserAvatar.tsx +0 -24
  144. package/src/app/(main)/@nav/features/UserPanel/LangButton.tsx +0 -55
  145. package/src/app/(main)/@nav/features/UserPanel/Popover.tsx +0 -34
  146. package/src/app/(main)/@nav/features/UserPanel/ThemeButton.tsx +0 -70
  147. package/src/app/(main)/@nav/features/UserPanel/UserInfo.tsx +0 -35
  148. package/src/app/(main)/@nav/features/UserPanel/index.tsx +0 -69
  149. package/src/app/(main)/@nav/features/UserPanel/useMenu.tsx +0 -144
  150. package/src/app/(main)/@nav/features/UserPanel/useNewVersion.tsx +0 -12
  151. package/src/app/(main)/chat/_layout/type.ts +0 -5
  152. package/src/app/(main)/chat/settings/_layout/Desktop/index.tsx +0 -32
  153. package/src/app/(main)/chat/settings/_layout/Mobile/index.tsx +0 -15
  154. package/src/app/(main)/chat/settings/error.tsx +0 -5
  155. package/src/app/(main)/chat/settings/loading.tsx +0 -3
  156. package/src/app/(main)/chat/settings/m/page.tsx +0 -15
  157. package/src/app/(main)/chat/settings/not-found.tsx +0 -3
  158. package/src/app/(main)/market/@detail/loading.tsx +0 -1
  159. package/src/app/(main)/settings/@category/default.tsx +0 -16
  160. package/src/app/(main)/settings/@category/features/CategoryContent.tsx +0 -37
  161. package/src/app/(main)/settings/@category/features/UpgradeAlert.tsx +0 -38
  162. package/src/app/(main)/settings/_layout/type.ts +0 -6
  163. package/src/app/(main)/settings/about/features/AboutList.tsx +0 -122
  164. package/src/app/(main)/settings/about/features/Analytics.tsx +0 -42
  165. package/src/app/(main)/settings/about/index.tsx +0 -35
  166. package/src/app/(main)/settings/agent/index.tsx +0 -48
  167. package/src/app/(main)/settings/error.tsx +0 -5
  168. package/src/app/(main)/settings/hooks/useCategory.tsx +0 -54
  169. package/src/app/(main)/settings/llm/components/Footer.tsx +0 -26
  170. package/src/app/(main)/settings/loading.tsx +0 -9
  171. package/src/app/(main)/settings/m/page.tsx +0 -19
  172. package/src/app/(main)/settings/not-found.tsx +0 -3
  173. package/src/app/(main)/settings/sync/features/DeviceInfo/DeviceName.tsx +0 -63
  174. package/src/app/(main)/settings/sync/index.tsx +0 -17
  175. package/src/app/(main)/settings/tts/features/OpenAI.tsx +0 -54
  176. package/src/app/(main)/settings/tts/index.tsx +0 -15
  177. package/src/app/@modal/(.)settings/m/index.tsx +0 -34
  178. package/src/app/@modal/(.)settings/m/layout.tsx +0 -28
  179. package/src/app/@modal/(.)settings/m/loading.tsx +0 -5
  180. package/src/app/@modal/(.)settings/m/page.tsx +0 -10
  181. package/src/app/@modal/_layout/Desktop.tsx +0 -32
  182. package/src/app/@modal/_layout/Mobile.tsx +0 -1
  183. package/src/app/@modal/_layout/SettingModalLayout.tsx +0 -59
  184. package/src/app/@modal/chat/(.)settings/m/features/CategoryContent.tsx +0 -36
  185. package/src/app/@modal/chat/(.)settings/m/features/useCategory.tsx +0 -62
  186. package/src/app/@modal/chat/(.)settings/m/layout.tsx +0 -55
  187. package/src/app/@modal/chat/(.)settings/m/loading.tsx +0 -5
  188. package/src/app/@modal/chat/(.)settings/m/page.tsx +0 -34
  189. package/src/app/@modal/default.tsx +0 -1
  190. package/src/app/@modal/layout.tsx +0 -30
  191. package/src/app/@modal/loading.tsx +0 -5
  192. package/src/components/BrandWatermark/index.tsx +0 -39
  193. package/src/components/Cell/Divider.tsx +0 -19
  194. package/src/components/Cell/index.tsx +0 -38
  195. package/src/components/Menu/index.tsx +0 -97
  196. package/src/components/SkeletonLoading/index.tsx +0 -21
  197. package/src/features/AgentSetting/AgentChat/index.tsx +0 -135
  198. package/src/features/AgentSetting/AgentModal/index.tsx +0 -95
  199. package/src/hooks/useQuery.ts +0 -7
  200. package/src/hooks/useQueryRoute.ts +0 -16
  201. package/src/server/redirectHard.ts +0 -9
  202. /package/src/app/(main)/settings/{about/features → features/SettingList}/Item.tsx +0 -0
  203. /package/src/app/(main)/settings/{common/features/Theme → features}/ThemeSwatches/ThemeSwatchesNeutral.tsx +0 -0
  204. /package/src/app/(main)/settings/{common/features/Theme → features}/ThemeSwatches/ThemeSwatchesPrimary.tsx +0 -0
  205. /package/src/app/(main)/settings/{common/features/Theme → features}/ThemeSwatches/index.ts +0 -0
  206. /package/src/app/(main)/settings/sync/{features/Alert.tsx → Alert.tsx} +0 -0
  207. /package/src/app/(main)/settings/sync/{features/WebRTC → components}/SyncSwitch/index.css +0 -0
  208. /package/src/app/(main)/settings/sync/{features/WebRTC → components}/SyncSwitch/index.tsx +0 -0
  209. /package/src/app/(main)/settings/sync/{features/WebRTC/generateRandomRoomName.ts → util.ts} +0 -0
  210. /package/src/app/(main)/settings/tts/{features/const.ts → TTS/options.ts} +0 -0
  211. /package/src/features/AgentSetting/{AgentModal → AgentConfig}/ModelSelect.tsx +0 -0
@@ -6,7 +6,7 @@ import { useTranslation } from 'react-i18next';
6
6
 
7
7
  import { agentMarketSelectors, useMarketStore } from '@/store/market';
8
8
 
9
- const DetailModal = memo<PropsWithChildren>(({ children }) => {
9
+ const AgentDetail = memo<PropsWithChildren>(({ children }) => {
10
10
  const [showAgentSidebar, deactivateAgent] = useMarketStore((s) => [
11
11
  agentMarketSelectors.showSideBar(s),
12
12
  s.deactivateAgent,
@@ -29,4 +29,4 @@ const DetailModal = memo<PropsWithChildren>(({ children }) => {
29
29
  );
30
30
  });
31
31
 
32
- export default DetailModal;
32
+ export default AgentDetail;
@@ -1,10 +1,19 @@
1
+ import ServerLayout from '@/components/server/ServerLayout';
1
2
  import { isMobileDevice } from '@/utils/responsive';
2
3
 
4
+ import Desktop from './_layout/Desktop';
5
+ import Mobile from './_layout/Mobile';
3
6
  import AgentDetailContent from './features/AgentDetailContent';
4
7
 
8
+ const Layout = ServerLayout({ Desktop, Mobile });
9
+
5
10
  const Detail = () => {
6
11
  const mobile = isMobileDevice();
7
- return <AgentDetailContent mobile={mobile} />;
12
+ return (
13
+ <Layout>
14
+ <AgentDetailContent mobile={mobile} />
15
+ </Layout>
16
+ );
8
17
  };
9
18
 
10
19
  Detail.displayName = 'AgentDetail';
@@ -4,7 +4,6 @@ import SafeSpacing from '@/components/SafeSpacing';
4
4
  import { MAX_WIDTH } from '@/const/layoutTokens';
5
5
 
6
6
  import { LayoutProps } from '../type';
7
- import DetailSidebar from './DetailSidebar';
8
7
  import Header from './Header';
9
8
  import Hero from './Hero';
10
9
 
@@ -30,7 +29,7 @@ const Layout = ({ children, detail }: LayoutProps) => {
30
29
  {children}
31
30
  </Flexbox>
32
31
  </Flexbox>
33
- <DetailSidebar>{detail}</DetailSidebar>
32
+ {detail}
34
33
  </Flexbox>
35
34
  </Flexbox>
36
35
  );
@@ -1,7 +1,6 @@
1
1
  import MobileContentLayout from '@/components/server/MobileNavLayout';
2
2
 
3
3
  import { LayoutProps } from '../type';
4
- import DetailModal from './DetailModal';
5
4
  import Header from './Header';
6
5
 
7
6
  const Layout = ({ children, detail }: LayoutProps) => {
@@ -11,11 +10,10 @@ const Layout = ({ children, detail }: LayoutProps) => {
11
10
  gap={16}
12
11
  header={<Header />}
13
12
  style={{ paddingInline: 16, paddingTop: 8 }}
14
- withNav
15
13
  >
16
14
  {children}
17
15
  </MobileContentLayout>
18
- <DetailModal>{detail}</DetailModal>
16
+ {detail}
19
17
  </>
20
18
  );
21
19
  };
@@ -0,0 +1,23 @@
1
+ 'use client';
2
+
3
+ import dynamic from 'next/dynamic';
4
+ import { FC, memo } from 'react';
5
+
6
+ import MobileSwitchLoading from '@/features/MobileSwitchLoading';
7
+ import { useIsMobile } from '@/hooks/useIsMobile';
8
+
9
+ import Common from '../common';
10
+ import { SettingsCommonProps } from '../common/Common';
11
+
12
+ const Mobile: FC = dynamic(() => import('../(mobile)'), {
13
+ loading: MobileSwitchLoading,
14
+ ssr: false,
15
+ }) as FC;
16
+
17
+ const Desktop = memo<SettingsCommonProps>((props) => {
18
+ const mobile = useIsMobile();
19
+
20
+ return mobile ? <Mobile /> : <Common {...props} />;
21
+ });
22
+
23
+ export default Desktop;
@@ -0,0 +1,68 @@
1
+ import { DivProps } from '@lobehub/ui';
2
+ import { createStyles } from 'antd-style';
3
+ import Image from 'next/image';
4
+ import { memo } from 'react';
5
+ import { Flexbox } from 'react-layout-kit';
6
+
7
+ import { DEFAULT_USER_AVATAR_URL } from '@/const/meta';
8
+
9
+ export const useStyles = createStyles(({ css, token }) => ({
10
+ banner: css`
11
+ position: relative;
12
+
13
+ overflow: hidden;
14
+
15
+ height: 172px;
16
+ min-height: 172px;
17
+ max-height: 172px;
18
+ `,
19
+ bannerBox: css`
20
+ position: relative;
21
+
22
+ width: 100%;
23
+ height: 100%;
24
+
25
+ background: ${token.colorBgLayout};
26
+
27
+ mask-image: linear-gradient(to bottom, #fff, transparent);
28
+ `,
29
+ bannerImg: css`
30
+ position: absolute;
31
+ top: -50%;
32
+ filter: blur(100px) saturate(2);
33
+ `,
34
+ }));
35
+
36
+ interface AgentCardBannerProps extends DivProps {
37
+ avatar: string;
38
+ size?: number;
39
+ }
40
+
41
+ const AvatarBanner = memo<AgentCardBannerProps>(
42
+ ({ avatar, className, size = 200, children, ...props }) => {
43
+ const { styles, cx } = useStyles();
44
+
45
+ return (
46
+ <Flexbox
47
+ align={'center'}
48
+ className={cx(styles.banner, className)}
49
+ justify={'center'}
50
+ {...props}
51
+ >
52
+ <Flexbox align={'center'} className={styles.bannerBox} justify={'center'}>
53
+ <Image
54
+ alt={'banner'}
55
+ className={styles.bannerImg}
56
+ height={size}
57
+ src={avatar || DEFAULT_USER_AVATAR_URL}
58
+ unoptimized
59
+ width={size}
60
+ />
61
+ </Flexbox>
62
+ {children}
63
+ </Flexbox>
64
+ );
65
+ },
66
+ );
67
+
68
+ export default AvatarBanner;
@@ -0,0 +1,65 @@
1
+ import { Upload } from 'antd';
2
+ import { useResponsive } from 'antd-style';
3
+ import { Feather, FileClock, HardDriveDownload, HardDriveUpload } from 'lucide-react';
4
+ import { memo } from 'react';
5
+ import { useTranslation } from 'react-i18next';
6
+
7
+ import { CHANGELOG, FEEDBACK } from '@/const/url';
8
+ import { useImportConfig } from '@/hooks/useImportConfig';
9
+ import { configService } from '@/services/config';
10
+ import { SettingsTabs } from '@/store/global/initialState';
11
+
12
+ import Item from '../../features/SettingList/Item';
13
+
14
+ interface ExtraListProps {
15
+ activeTab?: SettingsTabs;
16
+ }
17
+ const ExtraList = memo<ExtraListProps>(({ activeTab }) => {
18
+ const { t } = useTranslation('common');
19
+
20
+ const { importConfig } = useImportConfig();
21
+ const { mobile } = useResponsive();
22
+ const items = [
23
+ {
24
+ icon: HardDriveDownload,
25
+ label: t('export'),
26
+ onClick: configService.exportAll,
27
+ value: 'export',
28
+ },
29
+ {
30
+ icon: Feather,
31
+ label: t('feedback'),
32
+ onClick: () => window.open(FEEDBACK, '__blank'),
33
+ value: 'feedback',
34
+ },
35
+ {
36
+ icon: FileClock,
37
+ label: t('changelog'),
38
+ onClick: () => window.open(CHANGELOG, '__blank'),
39
+ value: 'changelog',
40
+ },
41
+ ];
42
+
43
+ return (
44
+ <>
45
+ <Upload
46
+ beforeUpload={(file) => {
47
+ importConfig(file);
48
+
49
+ return false;
50
+ }}
51
+ maxCount={1}
52
+ showUploadList={false}
53
+ >
54
+ <Item icon={HardDriveUpload} label={t('import')} style={{ width: '100vw' }} />
55
+ </Upload>
56
+ {items.map(({ value, icon, label, onClick }) => (
57
+ <div key={value} onClick={onClick}>
58
+ <Item active={mobile ? false : activeTab === value} icon={icon} label={label} />
59
+ </div>
60
+ ))}
61
+ </>
62
+ );
63
+ });
64
+
65
+ export default ExtraList;
@@ -0,0 +1,53 @@
1
+ 'use client';
2
+
3
+ import { Divider } from 'antd';
4
+ import { createStyles } from 'antd-style';
5
+ import { memo } from 'react';
6
+ import { Center, Flexbox } from 'react-layout-kit';
7
+
8
+ import { CURRENT_VERSION } from '@/const/version';
9
+ import AvatarWithUpload from '@/features/AvatarWithUpload';
10
+ import { useUserStore } from '@/store/user';
11
+ import { commonSelectors } from '@/store/user/selectors';
12
+
13
+ import SettingList from '../features/SettingList';
14
+ import AvatarBanner from './features/AvatarBanner';
15
+ import ExtraList from './features/ExtraList';
16
+
17
+ const useStyles = createStyles(({ css, token }) => ({
18
+ divider: css`
19
+ height: 6px;
20
+ background: ${token.colorFillTertiary};
21
+ `,
22
+ footer: css`
23
+ font-size: 12px;
24
+ color: ${token.colorTextQuaternary};
25
+ `,
26
+ }));
27
+
28
+ const Setting = memo(() => {
29
+ const avatar = useUserStore(commonSelectors.userAvatar);
30
+ const { styles } = useStyles();
31
+
32
+ return (
33
+ <Flexbox style={{ overflow: 'scroll' }}>
34
+ <AvatarBanner avatar={avatar}>
35
+ <Center style={{ marginTop: 32, position: 'absolute', zIndex: 2 }}>
36
+ <AvatarWithUpload size={88} />
37
+ </Center>
38
+ </AvatarBanner>
39
+ <div style={{ width: '100%' }}>
40
+ <SettingList />
41
+ <div className={styles.divider} />
42
+ <ExtraList />
43
+ <Center style={{ paddingInline: 64 }}>
44
+ <Divider>
45
+ <span className={styles.footer}>LobeChat v{CURRENT_VERSION}</span>
46
+ </Divider>
47
+ </Center>
48
+ </div>
49
+ </Flexbox>
50
+ );
51
+ });
52
+
53
+ export default Setting;
@@ -1,91 +1,36 @@
1
1
  'use client';
2
2
 
3
- import { ActionIcon, ChatHeader, ChatHeaderTitle } from '@lobehub/ui';
4
- import { Drawer, type DrawerProps, Tag } from 'antd';
5
- import { createStyles } from 'antd-style';
6
- import { Menu } from 'lucide-react';
7
- import { PropsWithChildren, memo, useState } from 'react';
3
+ import { ChatHeader, ChatHeaderTitle } from '@lobehub/ui';
4
+ import { Tag } from 'antd';
5
+ import { memo } from 'react';
8
6
  import { useTranslation } from 'react-i18next';
9
7
  import { Flexbox } from 'react-layout-kit';
10
8
 
11
- import BrandWatermark from '@/components/BrandWatermark';
12
9
  import { useActiveSettingsKey } from '@/hooks/useActiveSettingsKey';
13
10
  import { SettingsTabs } from '@/store/global/initialState';
14
11
 
15
- const useStyles = createStyles(({ token, css }) => ({
16
- container: css`
17
- position: relative;
18
- height: 54px;
19
- background: ${token.colorBgContainer};
20
- `,
21
- title: css`
22
- font-size: 18px;
23
- font-weight: 700;
24
- `,
25
- }));
12
+ const Header = memo(() => {
13
+ const { t } = useTranslation('setting');
26
14
 
27
- const Header = memo<PropsWithChildren & Pick<DrawerProps, 'getContainer'>>(
28
- ({ children, getContainer }) => {
29
- const [open, setOpen] = useState(false);
30
- const { styles, theme } = useStyles();
31
- const { t } = useTranslation('setting');
15
+ const activeKey = useActiveSettingsKey();
32
16
 
33
- const activeKey = useActiveSettingsKey();
17
+ return (
18
+ <ChatHeader
19
+ left={
20
+ <div style={{ paddingLeft: 8 }}>
21
+ <ChatHeaderTitle
22
+ title={
23
+ <Flexbox align={'center'} gap={8} horizontal>
24
+ {t(`tab.${activeKey}`)}
34
25
 
35
- return (
36
- <>
37
- <ChatHeader
38
- className={styles.container}
39
- left={
40
- <div style={{ paddingLeft: 8 }}>
41
- <ChatHeaderTitle
42
- title={
43
- <Flexbox align={'center'} className={styles.title} gap={4} horizontal>
44
- <ActionIcon
45
- color={theme.colorText}
46
- icon={Menu}
47
- onClick={() => setOpen(true)}
48
- size={{ blockSize: 32, fontSize: 18 }}
49
- />
50
- {t(`tab.${activeKey}`)}
51
- {activeKey === SettingsTabs.Sync && (
52
- <Tag color={'gold'}>{t('tab.experiment')}</Tag>
53
- )}
54
- </Flexbox>
55
- }
56
- />
57
- </div>
58
- }
59
- />
60
- <Drawer
61
- bodyStyle={{
62
- display: 'flex',
63
- flexDirection: 'column',
64
- gap: 20,
65
- justifyContent: 'space-between',
66
- padding: 16,
67
- }}
68
- getContainer={getContainer}
69
- headerStyle={{ display: 'none' }}
70
- maskStyle={{ background: 'transparent' }}
71
- onClick={() => setOpen(false)}
72
- onClose={() => setOpen(false)}
73
- open={open}
74
- placement={'left'}
75
- rootStyle={{ position: 'absolute' }}
76
- style={{
77
- background: theme.colorBgContainer,
78
- borderRight: `1px solid ${theme.colorSplit}`,
79
- }}
80
- width={260}
81
- zIndex={10}
82
- >
83
- {children}
84
- <BrandWatermark paddingInline={12} />
85
- </Drawer>
86
- </>
87
- );
88
- },
89
- );
26
+ {activeKey === SettingsTabs.Sync && <Tag color={'gold'}>{t('tab.experiment')}</Tag>}
27
+ </Flexbox>
28
+ }
29
+ />
30
+ </div>
31
+ }
32
+ />
33
+ );
34
+ });
90
35
 
91
36
  export default Header;
@@ -1,59 +1,47 @@
1
1
  'use client';
2
2
 
3
- import { createStyles } from 'antd-style';
3
+ import { createStyles, useResponsive } from 'antd-style';
4
+ import { memo } from 'react';
4
5
  import { useTranslation } from 'react-i18next';
5
- import { Flexbox, FlexboxProps } from 'react-layout-kit';
6
+ import { Flexbox } from 'react-layout-kit';
6
7
 
7
- import BrandWatermark from '@/components/BrandWatermark';
8
+ import { useActiveSettingsKey } from '@/hooks/useActiveSettingsKey';
8
9
 
9
- const useStyles = createStyles(({ token, css }) => ({
10
+ import SettingList from '../../features/SettingList';
11
+ import UpgradeAlert from '../../features/UpgradeAlert';
12
+
13
+ const useStyles = createStyles(({ stylish, token, css }) => ({
14
+ body: stylish.noScrollbar,
10
15
  container: css`
11
- padding: 24px 12px 16px;
12
- background: ${token.colorBgContainer};
13
16
  border-inline-end: 1px solid ${token.colorBorder};
14
17
  `,
15
- desc: css`
16
- line-height: 1.4;
17
- color: ${token.colorTextDescription};
18
- `,
19
- header: css`
20
- padding: 0 0.75rem;
21
- `,
22
18
  logo: css`
23
19
  fill: ${token.colorText};
24
20
  `,
25
- title: css`
26
- margin: 0;
27
- font-size: 26px;
28
- font-weight: 600;
29
- line-height: 1.3;
21
+ top: css`
22
+ font-size: 20px;
23
+ font-weight: bold;
30
24
  `,
31
25
  }));
32
26
 
33
- interface SidebarLayoutProps extends FlexboxProps {
34
- desc?: string;
35
- title?: string;
36
- }
27
+ const SideBar = memo(() => {
28
+ const { styles } = useStyles();
29
+ const activeKey = useActiveSettingsKey();
30
+
31
+ const { t } = useTranslation('common');
32
+ const { mobile } = useResponsive();
37
33
 
38
- const SidebarLayout = ({ children, className, title, desc, ...rest }: SidebarLayoutProps) => {
39
- const { cx, styles } = useStyles();
40
- const { t } = useTranslation('setting');
41
34
  return (
42
- <Flexbox
43
- className={cx(styles.container, className)}
44
- flex={'none'}
45
- gap={20}
46
- width={280}
47
- {...rest}
48
- >
49
- <Flexbox className={styles.header} gap={4}>
50
- <h1 className={styles.title}>{title || t('header.title')}</h1>
51
- <p className={styles.desc}>{desc || t('header.desc')}</p>
35
+ <Flexbox className={styles.container} width={280}>
36
+ <Flexbox className={styles.top} padding={16}>
37
+ {t('setting')}
38
+ </Flexbox>
39
+ <Flexbox gap={8} style={{ paddingInline: 8 }}>
40
+ <UpgradeAlert />
41
+ <SettingList activeTab={activeKey} mobile={mobile} />
52
42
  </Flexbox>
53
- {children}
54
- <BrandWatermark paddingInline={12} />
55
43
  </Flexbox>
56
44
  );
57
- };
45
+ });
58
46
 
59
- export default SidebarLayout;
47
+ export default SideBar;
@@ -1,51 +1,27 @@
1
1
  'use client';
2
2
 
3
- import { useResponsive } from 'antd-style';
4
- import { memo, useRef } from 'react';
5
- import { Flexbox } from 'react-layout-kit';
3
+ import { PropsWithChildren, memo } from 'react';
4
+ import { Center, Flexbox } from 'react-layout-kit';
5
+
6
+ import SafeSpacing from '@/components/SafeSpacing';
7
+ import ClientResponsiveLayout from '@/components/client/ClientResponsiveLayout';
6
8
 
7
- import { LayoutProps } from '../type';
8
9
  import Header from './Header';
9
10
  import SideBar from './SideBar';
10
11
 
11
- const Layout = memo<LayoutProps>(({ children, category }) => {
12
- const ref = useRef<any>(null);
13
- const { md = true, mobile = false } = useResponsive();
14
-
15
- return (
16
- <Flexbox
17
- height={'100%'}
18
- horizontal={md}
19
- ref={ref}
20
- style={{ position: 'relative' }}
21
- width={'100%'}
22
- >
23
- {md ? (
24
- <SideBar>{category}</SideBar>
25
- ) : (
26
- <Header getContainer={() => ref.current}>{category}</Header>
27
- )}
28
- <Flexbox
29
- align={'center'}
30
- height={'100%'}
31
- style={{ overflowX: 'hidden', overflowY: 'auto' }}
32
- width={'100%'}
33
- >
34
- <Flexbox
35
- gap={64}
36
- style={{
37
- maxWidth: 1024,
38
- padding: mobile ? undefined : '1.75rem 1.5rem 1.75rem 2rem',
39
- }}
40
- width={'100%'}
41
- >
12
+ const Desktop = memo<PropsWithChildren>(({ children }) => (
13
+ <>
14
+ <SideBar />
15
+ <Flexbox flex={1} height={'100%'} style={{ position: 'relative' }}>
16
+ <Header />
17
+ <Flexbox align={'center'} flex={1} padding={24} style={{ overflowY: 'scroll' }}>
18
+ <SafeSpacing />
19
+ <Center gap={16} width={'100%'}>
42
20
  {children}
43
- </Flexbox>
21
+ </Center>
44
22
  </Flexbox>
45
23
  </Flexbox>
46
- );
47
- });
48
-
49
- Layout.displayName = 'DesktopSettingsLayout';
24
+ </>
25
+ ));
50
26
 
51
- export default Layout;
27
+ export default ClientResponsiveLayout({ Desktop, Mobile: () => import('../Mobile') });
@@ -1,5 +1,3 @@
1
- 'use client';
2
-
3
1
  import { MobileNavBar, MobileNavBarTitle } from '@lobehub/ui';
4
2
  import { Tag } from 'antd';
5
3
  import { useRouter } from 'next/navigation';
@@ -30,7 +28,7 @@ const Header = memo(() => {
30
28
  }
31
29
  />
32
30
  }
33
- onBackClick={() => router.push('/me')}
31
+ onBackClick={() => router.push('/settings')}
34
32
  showBackButton
35
33
  style={mobileHeaderSticky}
36
34
  />
@@ -1,12 +1,23 @@
1
+ 'use client';
2
+
3
+ import { PropsWithChildren } from 'react';
4
+
1
5
  import MobileContentLayout from '@/components/server/MobileNavLayout';
6
+ import { useIsSubSlug } from '@/hooks/useIsSubSlug';
2
7
 
3
- import { LayoutProps } from '../type';
4
- import Header from './Header';
8
+ import SubSettingHeader from './SubSettingHeader';
5
9
 
6
- const Layout = ({ children }: LayoutProps) => {
7
- return <MobileContentLayout header={<Header />}>{children}</MobileContentLayout>;
8
- };
10
+ const MobileLayout = ({ children }: PropsWithChildren) => {
11
+ const isSubPath = useIsSubSlug();
9
12
 
10
- Layout.displayName = 'MobileSettingsLayout';
13
+ if (isSubPath)
14
+ return (
15
+ <MobileContentLayout header={<SubSettingHeader />} withNav={false}>
16
+ {children}
17
+ </MobileContentLayout>
18
+ );
19
+
20
+ return children;
21
+ };
11
22
 
12
- export default Layout;
23
+ export default MobileLayout;
@@ -0,0 +1,53 @@
1
+ import { Feather, FileClock, Heart } from 'lucide-react';
2
+ import { memo } from 'react';
3
+ import { useTranslation } from 'react-i18next';
4
+ import { Flexbox } from 'react-layout-kit';
5
+
6
+ import { ABOUT, CHANGELOG, FEEDBACK } from '@/const/url';
7
+
8
+ import Item from '../features/SettingList/Item';
9
+ import { useStyles } from './style';
10
+
11
+ const AboutList = memo(() => {
12
+ const { t } = useTranslation('setting');
13
+ const { styles } = useStyles();
14
+ const items = [
15
+ {
16
+ icon: Feather,
17
+ label: t('feedback', { ns: 'common' }),
18
+ onClick: () => window.open(FEEDBACK, '__blank'),
19
+ value: 'feedback',
20
+ },
21
+ {
22
+ icon: FileClock,
23
+ label: t('changelog', { ns: 'common' }),
24
+ onClick: () => window.open(CHANGELOG, '__blank'),
25
+ value: 'changelog',
26
+ },
27
+ {
28
+ icon: Heart,
29
+ label: t('about', { ns: 'common' }),
30
+ onClick: () => window.open(ABOUT, '__blank'),
31
+ value: 'about',
32
+ },
33
+ ];
34
+
35
+ return (
36
+ <div className={styles.wrapper}>
37
+ <Flexbox className={styles.container} gap={24} padding={16}>
38
+ <Flexbox className={styles.title} gap={8} horizontal>
39
+ {t('about.title')}
40
+ </Flexbox>
41
+ <Flexbox width={'100%'}>
42
+ {items.map(({ value, icon, label, onClick }) => (
43
+ <div key={value} onClick={onClick}>
44
+ <Item active={false} icon={icon} label={label} />
45
+ </div>
46
+ ))}
47
+ </Flexbox>
48
+ </Flexbox>
49
+ </div>
50
+ );
51
+ });
52
+
53
+ export default AboutList;