@lobehub/chat 0.152.1 → 0.152.2

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 (214) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +8 -8
  3. package/README.zh-CN.md +8 -8
  4. package/locales/ar/common.json +14 -0
  5. package/locales/ar/setting.json +4 -1
  6. package/locales/bg-BG/common.json +14 -0
  7. package/locales/bg-BG/setting.json +4 -1
  8. package/locales/de-DE/common.json +14 -0
  9. package/locales/de-DE/setting.json +4 -1
  10. package/locales/en-US/common.json +14 -0
  11. package/locales/en-US/setting.json +4 -1
  12. package/locales/es-ES/common.json +14 -0
  13. package/locales/es-ES/setting.json +4 -1
  14. package/locales/fr-FR/common.json +14 -0
  15. package/locales/fr-FR/setting.json +4 -1
  16. package/locales/it-IT/common.json +14 -0
  17. package/locales/it-IT/setting.json +4 -1
  18. package/locales/ja-JP/common.json +14 -0
  19. package/locales/ja-JP/setting.json +4 -1
  20. package/locales/ko-KR/common.json +14 -0
  21. package/locales/ko-KR/setting.json +4 -1
  22. package/locales/nl-NL/common.json +14 -0
  23. package/locales/nl-NL/setting.json +4 -1
  24. package/locales/pl-PL/common.json +14 -0
  25. package/locales/pl-PL/setting.json +4 -1
  26. package/locales/pt-BR/common.json +14 -0
  27. package/locales/pt-BR/setting.json +4 -1
  28. package/locales/ru-RU/common.json +14 -0
  29. package/locales/ru-RU/setting.json +4 -1
  30. package/locales/tr-TR/common.json +14 -0
  31. package/locales/tr-TR/setting.json +4 -1
  32. package/locales/vi-VN/common.json +14 -0
  33. package/locales/vi-VN/setting.json +4 -1
  34. package/locales/zh-CN/common.json +14 -0
  35. package/locales/zh-CN/setting.json +4 -1
  36. package/locales/zh-TW/common.json +14 -0
  37. package/locales/zh-TW/setting.json +4 -1
  38. package/package.json +1 -1
  39. package/src/app/(main)/(mobile)/me/features/AvatarBanner.tsx +52 -0
  40. package/src/app/(main)/(mobile)/me/features/Cate.tsx +34 -0
  41. package/src/app/(main)/(mobile)/me/features/ExtraCate.tsx +26 -0
  42. package/src/app/(main)/(mobile)/me/features/useExtraCate.tsx +68 -0
  43. package/src/app/(main)/(mobile)/me/layout.tsx +11 -0
  44. package/src/app/(main)/(mobile)/me/loading.tsx +17 -0
  45. package/src/app/(main)/(mobile)/me/page.tsx +31 -0
  46. package/src/app/(main)/@nav/_layout/Desktop/BottomActions.tsx +7 -120
  47. package/src/app/(main)/@nav/_layout/Desktop/index.tsx +7 -2
  48. package/src/app/(main)/@nav/_layout/Mobile.tsx +3 -3
  49. package/src/app/(main)/@nav/features/UserAvatar.tsx +24 -0
  50. package/src/app/(main)/@nav/features/UserPanel/LangButton.tsx +55 -0
  51. package/src/app/(main)/@nav/features/UserPanel/Popover.tsx +34 -0
  52. package/src/app/(main)/@nav/features/UserPanel/ThemeButton.tsx +70 -0
  53. package/src/app/(main)/@nav/features/UserPanel/UserInfo.tsx +35 -0
  54. package/src/app/(main)/@nav/features/UserPanel/index.tsx +69 -0
  55. package/src/app/(main)/@nav/features/UserPanel/useMenu.tsx +144 -0
  56. package/src/app/(main)/@nav/features/UserPanel/useNewVersion.tsx +12 -0
  57. package/src/app/(main)/chat/(mobile)/features/SessionHeader.tsx +1 -1
  58. package/src/app/(main)/chat/_layout/Desktop/index.tsx +6 -8
  59. package/src/app/(main)/chat/_layout/Mobile/index.tsx +5 -3
  60. package/src/app/(main)/chat/_layout/type.ts +5 -0
  61. package/src/app/(main)/chat/features/SettingButton.tsx +5 -2
  62. package/src/app/(main)/chat/layout.ts +5 -2
  63. package/src/app/(main)/chat/settings/{(desktop) → _layout/Desktop}/Header.tsx +2 -0
  64. package/src/app/(main)/chat/settings/_layout/Desktop/index.tsx +32 -0
  65. package/src/app/(main)/chat/settings/{(mobile) → _layout/Mobile}/Header.tsx +3 -2
  66. package/src/app/(main)/chat/settings/_layout/Mobile/index.tsx +15 -0
  67. package/src/app/(main)/chat/settings/error.tsx +5 -0
  68. package/src/app/(main)/chat/settings/features/HeaderContent.tsx +15 -9
  69. package/src/app/(main)/chat/settings/features/SubmitAgentButton/SubmitAgentModal.tsx +2 -0
  70. package/src/app/(main)/chat/settings/features/SubmitAgentButton/index.tsx +16 -8
  71. package/src/app/(main)/chat/settings/layout.tsx +9 -2
  72. package/src/app/(main)/chat/settings/loading.tsx +3 -0
  73. package/src/app/(main)/chat/settings/not-found.tsx +3 -0
  74. package/src/app/(main)/chat/settings/page.tsx +2 -9
  75. package/src/app/(main)/market/@detail/default.tsx +1 -10
  76. package/src/app/(main)/market/@detail/loading.tsx +1 -0
  77. package/src/app/(main)/market/{@detail/_layout/Desktop.tsx → _layout/Desktop/DetailSidebar.tsx} +2 -2
  78. package/src/app/(main)/market/_layout/Desktop/index.tsx +2 -1
  79. package/src/app/(main)/market/{@detail/_layout/Mobile.tsx → _layout/Mobile/DetailModal.tsx} +2 -2
  80. package/src/app/(main)/market/_layout/Mobile/index.tsx +3 -1
  81. package/src/app/(main)/settings/@category/default.tsx +16 -0
  82. package/src/app/(main)/settings/@category/features/CategoryContent.tsx +35 -0
  83. package/src/app/(main)/settings/@category/features/UpgradeAlert.tsx +38 -0
  84. package/src/app/(main)/settings/_layout/Desktop/Header.tsx +78 -23
  85. package/src/app/(main)/settings/_layout/Desktop/SideBar.tsx +39 -27
  86. package/src/app/(main)/settings/_layout/Desktop/index.tsx +41 -17
  87. package/src/app/(main)/settings/_layout/Mobile/{SubSettingHeader.tsx → Header.tsx} +3 -1
  88. package/src/app/(main)/settings/_layout/Mobile/index.tsx +7 -18
  89. package/src/app/(main)/settings/_layout/type.ts +6 -0
  90. package/src/app/(main)/settings/about/features/AboutList.tsx +122 -0
  91. package/src/app/(main)/settings/about/features/Analytics.tsx +42 -0
  92. package/src/app/(main)/settings/about/layout.tsx +26 -0
  93. package/src/app/(main)/settings/about/loading.tsx +5 -0
  94. package/src/app/(main)/settings/about/page.tsx +20 -25
  95. package/src/app/(main)/settings/agent/layout.tsx +35 -0
  96. package/src/app/(main)/settings/agent/loading.tsx +4 -2
  97. package/src/app/(main)/settings/agent/page.tsx +25 -12
  98. package/src/app/(main)/settings/common/{Common.tsx → features/Common.tsx} +7 -5
  99. package/src/app/(main)/settings/common/{Theme.tsx → features/Theme/index.tsx} +8 -6
  100. package/src/app/(main)/settings/common/page.tsx +21 -4
  101. package/src/app/(main)/settings/error.tsx +5 -0
  102. package/src/app/(main)/settings/features/Footer.tsx +2 -0
  103. package/src/app/(main)/settings/features/UpgradeAlert.tsx +21 -13
  104. package/src/app/(main)/settings/hooks/useCategory.tsx +54 -0
  105. package/src/app/(main)/settings/hooks/useSyncSettings.ts +2 -2
  106. package/src/app/(main)/settings/layout.ts +4 -1
  107. package/src/app/(main)/settings/llm/Anthropic/index.tsx +4 -10
  108. package/src/app/(main)/settings/llm/Azure/index.tsx +3 -1
  109. package/src/app/(main)/settings/llm/Bedrock/index.tsx +3 -1
  110. package/src/app/(main)/settings/llm/Google/index.tsx +4 -2
  111. package/src/app/(main)/settings/llm/Groq/index.tsx +3 -1
  112. package/src/app/(main)/settings/llm/Minimax/index.tsx +3 -9
  113. package/src/app/(main)/settings/llm/Mistral/index.tsx +3 -9
  114. package/src/app/(main)/settings/llm/Moonshot/index.tsx +3 -1
  115. package/src/app/(main)/settings/llm/Ollama/index.tsx +3 -1
  116. package/src/app/(main)/settings/llm/OpenAI/index.tsx +2 -0
  117. package/src/app/(main)/settings/llm/OpenRouter/index.tsx +3 -9
  118. package/src/app/(main)/settings/llm/Perplexity/index.tsx +3 -9
  119. package/src/app/(main)/settings/llm/TogetherAI/index.tsx +3 -9
  120. package/src/app/(main)/settings/llm/ZeroOne/index.tsx +3 -9
  121. package/src/app/(main)/settings/llm/Zhipu/index.tsx +3 -10
  122. package/src/app/(main)/settings/llm/components/Checker.tsx +2 -0
  123. package/src/app/(main)/settings/llm/components/Footer.tsx +26 -0
  124. package/src/app/(main)/settings/llm/components/ProviderConfig/index.tsx +16 -1
  125. package/src/app/(main)/settings/llm/page.tsx +57 -3
  126. package/src/app/(main)/settings/loading.tsx +9 -0
  127. package/src/app/(main)/settings/not-found.tsx +3 -0
  128. package/src/app/(main)/settings/page.tsx +2 -14
  129. package/src/app/(main)/settings/sync/{DeviceInfo → features/DeviceInfo}/Card.tsx +6 -5
  130. package/src/app/(main)/settings/sync/features/DeviceInfo/DeviceName.tsx +63 -0
  131. package/src/app/(main)/settings/sync/{components → features/DeviceInfo}/SystemIcon.tsx +6 -14
  132. package/src/app/(main)/settings/sync/{DeviceInfo → features/DeviceInfo}/index.tsx +22 -36
  133. package/src/app/(main)/settings/sync/{WebRTC → features/WebRTC}/ChannelNameInput.tsx +3 -3
  134. package/src/app/(main)/settings/sync/{WebRTC → features/WebRTC}/index.tsx +10 -9
  135. package/src/app/(main)/settings/sync/page.tsx +19 -11
  136. package/src/app/(main)/settings/tts/features/OpenAI.tsx +54 -0
  137. package/src/app/(main)/settings/tts/{TTS/index.tsx → features/STT.tsx} +11 -27
  138. package/src/app/(main)/settings/tts/page.tsx +17 -11
  139. package/src/app/@modal/(.)settings/about/layout.tsx +1 -0
  140. package/src/app/@modal/(.)settings/about/page.tsx +1 -0
  141. package/src/app/@modal/(.)settings/agent/layout.tsx +1 -0
  142. package/src/app/@modal/(.)settings/agent/page.tsx +1 -0
  143. package/src/app/@modal/(.)settings/common/page.tsx +1 -0
  144. package/src/app/@modal/(.)settings/layout.tsx +28 -0
  145. package/src/app/@modal/(.)settings/llm/page.tsx +1 -0
  146. package/src/app/@modal/(.)settings/loading.tsx +5 -0
  147. package/src/app/@modal/(.)settings/sync/page.tsx +1 -0
  148. package/src/app/@modal/(.)settings/tts/page.tsx +1 -0
  149. package/src/app/@modal/_layout/SettingModalLayout.tsx +59 -0
  150. package/src/app/@modal/chat/(.)settings/features/CategoryContent.tsx +36 -0
  151. package/src/app/@modal/chat/(.)settings/features/useCategory.tsx +62 -0
  152. package/src/app/@modal/chat/(.)settings/layout.tsx +55 -0
  153. package/src/app/@modal/chat/(.)settings/loading.tsx +5 -0
  154. package/src/app/@modal/chat/(.)settings/page.tsx +40 -0
  155. package/src/app/@modal/default.tsx +1 -0
  156. package/src/app/@modal/layout.tsx +30 -0
  157. package/src/app/@modal/loading.tsx +5 -0
  158. package/src/app/layout.tsx +11 -3
  159. package/src/components/BrandWatermark/index.tsx +39 -0
  160. package/src/components/Cell/Divider.tsx +19 -0
  161. package/src/components/Cell/index.tsx +38 -0
  162. package/src/components/Menu/index.tsx +97 -0
  163. package/src/components/SkeletonLoading/index.tsx +21 -0
  164. package/src/const/url.ts +1 -0
  165. package/src/features/AgentSetting/AgentChat/index.tsx +135 -0
  166. package/src/features/AgentSetting/AgentMeta/index.tsx +4 -3
  167. package/src/features/AgentSetting/AgentModal/index.tsx +95 -0
  168. package/src/features/AgentSetting/AgentPlugin/index.tsx +65 -66
  169. package/src/features/AgentSetting/AgentPrompt/index.tsx +101 -47
  170. package/src/features/AgentSetting/AgentTTS/index.tsx +4 -0
  171. package/src/features/AgentSetting/StoreUpdater.tsx +2 -0
  172. package/src/features/AgentSetting/index.tsx +6 -6
  173. package/src/features/AgentSetting/store/index.ts +2 -0
  174. package/src/features/AvatarWithUpload/index.tsx +2 -0
  175. package/src/hooks/useQuery.ts +7 -0
  176. package/src/hooks/useQueryRoute.ts +16 -0
  177. package/src/locales/default/common.ts +14 -0
  178. package/src/locales/default/setting.ts +3 -0
  179. package/src/server/redirectHard.ts +9 -0
  180. package/src/store/global/initialState.ts +1 -0
  181. package/src/app/(main)/@nav/_layout/Desktop/Avatar.tsx +0 -11
  182. package/src/app/(main)/chat/settings/(desktop)/index.tsx +0 -23
  183. package/src/app/(main)/chat/settings/(mobile)/index.tsx +0 -16
  184. package/src/app/(main)/settings/(desktop)/index.tsx +0 -23
  185. package/src/app/(main)/settings/(mobile)/features/AvatarBanner.tsx +0 -68
  186. package/src/app/(main)/settings/(mobile)/features/ExtraList.tsx +0 -65
  187. package/src/app/(main)/settings/(mobile)/index.tsx +0 -53
  188. package/src/app/(main)/settings/about/AboutList.tsx +0 -53
  189. package/src/app/(main)/settings/about/Analytics.tsx +0 -40
  190. package/src/app/(main)/settings/about/style.ts +0 -22
  191. package/src/app/(main)/settings/agent/Agent.tsx +0 -29
  192. package/src/app/(main)/settings/common/index.tsx +0 -24
  193. package/src/app/(main)/settings/common/loading.tsx +0 -3
  194. package/src/app/(main)/settings/features/SettingList/index.tsx +0 -47
  195. package/src/app/(main)/settings/llm/index.tsx +0 -59
  196. package/src/app/(main)/settings/llm/layout.tsx +0 -11
  197. package/src/app/(main)/settings/llm/loading.tsx +0 -3
  198. package/src/app/(main)/settings/sync/DeviceInfo/DeviceName.tsx +0 -66
  199. package/src/app/(main)/settings/sync/PageTitle.tsx +0 -11
  200. package/src/app/(main)/settings/sync/layout.tsx +0 -12
  201. package/src/app/(main)/settings/sync/loading.tsx +0 -3
  202. package/src/app/(main)/settings/tts/loading.tsx +0 -3
  203. package/src/features/AgentSetting/AgentConfig/index.tsx +0 -202
  204. package/src/features/AgentSetting/AgentConfig/useSyncConfig.ts +0 -23
  205. /package/src/app/(main)/settings/{features/SettingList → about/features}/Item.tsx +0 -0
  206. /package/src/app/(main)/settings/{features → common/features/Theme}/ThemeSwatches/ThemeSwatchesNeutral.tsx +0 -0
  207. /package/src/app/(main)/settings/{features → common/features/Theme}/ThemeSwatches/ThemeSwatchesPrimary.tsx +0 -0
  208. /package/src/app/(main)/settings/{features → common/features/Theme}/ThemeSwatches/index.ts +0 -0
  209. /package/src/app/(main)/settings/sync/{Alert.tsx → features/Alert.tsx} +0 -0
  210. /package/src/app/(main)/settings/sync/{components → features/WebRTC}/SyncSwitch/index.css +0 -0
  211. /package/src/app/(main)/settings/sync/{components → features/WebRTC}/SyncSwitch/index.tsx +0 -0
  212. /package/src/app/(main)/settings/sync/{util.ts → features/WebRTC/generateRandomRoomName.ts} +0 -0
  213. /package/src/app/(main)/settings/tts/{TTS/options.ts → features/const.ts} +0 -0
  214. /package/src/features/AgentSetting/{AgentConfig → AgentModal}/ModelSelect.tsx +0 -0
@@ -1,4 +1,5 @@
1
- import { ActionIcon } from '@lobehub/ui';
1
+ import { ActionIcon, Icon } from '@lobehub/ui';
2
+ import { Button } from 'antd';
2
3
  import { useResponsive } from 'antd-style';
3
4
  import { Share2 } from 'lucide-react';
4
5
  import { memo, useState } from 'react';
@@ -8,18 +9,25 @@ import { HEADER_ICON_SIZE } from '@/const/layoutTokens';
8
9
 
9
10
  import SubmitAgentModal from './SubmitAgentModal';
10
11
 
11
- const SubmitAgentButton = memo(() => {
12
+ const SubmitAgentButton = memo<{ modal?: boolean }>(({ modal }) => {
12
13
  const { t } = useTranslation('setting');
13
14
  const { mobile } = useResponsive();
14
15
  const [isModalOpen, setIsModalOpen] = useState(false);
16
+
15
17
  return (
16
18
  <>
17
- <ActionIcon
18
- icon={Share2}
19
- onClick={() => setIsModalOpen(true)}
20
- size={HEADER_ICON_SIZE(mobile)}
21
- title={t('submitAgentModal.tooltips')}
22
- />
19
+ {modal ? (
20
+ <Button block icon={<Icon icon={Share2} />} onClick={() => setIsModalOpen(true)}>
21
+ {t('submitAgentModal.tooltips')}
22
+ </Button>
23
+ ) : (
24
+ <ActionIcon
25
+ icon={Share2}
26
+ onClick={() => setIsModalOpen(true)}
27
+ size={HEADER_ICON_SIZE(mobile)}
28
+ title={t('submitAgentModal.tooltips')}
29
+ />
30
+ )}
23
31
  <SubmitAgentModal onCancel={() => setIsModalOpen(false)} open={isModalOpen} />
24
32
  </>
25
33
  );
@@ -1,14 +1,21 @@
1
1
  import { notFound } from 'next/navigation';
2
2
  import { PropsWithChildren } from 'react';
3
3
 
4
+ import ServerLayout from '@/components/server/ServerLayout';
4
5
  import { serverFeatureFlags } from '@/config/server/featureFlags';
5
6
 
7
+ import Desktop from './_layout/Desktop';
8
+ import Mobile from './_layout/Mobile';
9
+
10
+ const SessionSettingsLayout = ServerLayout({ Desktop, Mobile });
11
+
6
12
  const Layout = ({ children }: PropsWithChildren) => {
7
13
  const isAgentEditable = serverFeatureFlags().isAgentEditable;
8
-
9
14
  if (!isAgentEditable) return notFound();
10
15
 
11
- return children;
16
+ return <SessionSettingsLayout>{children}</SessionSettingsLayout>;
12
17
  };
13
18
 
19
+ Layout.displayName = 'SessionSettingsLayout';
20
+
14
21
  export default Layout;
@@ -0,0 +1,3 @@
1
+ import SkeletonLoading from '@/components/SkeletonLoading';
2
+
3
+ export default () => <SkeletonLoading paragraph={{ rows: 8 }} />;
@@ -0,0 +1,3 @@
1
+ import dynamic from 'next/dynamic';
2
+
3
+ export default dynamic(() => import('@/components/404'), { ssr: false });
@@ -1,14 +1,7 @@
1
- import { isMobileDevice } from '@/utils/responsive';
2
-
3
- import DesktopPage from './(desktop)';
4
- import MobilePage from './(mobile)';
1
+ import EditPage from './features/EditPage';
5
2
 
6
3
  const Page = () => {
7
- const mobile = isMobileDevice();
8
-
9
- const Page = mobile ? MobilePage : DesktopPage;
10
-
11
- return <Page />;
4
+ return <EditPage />;
12
5
  };
13
6
 
14
7
  export default Page;
@@ -1,19 +1,10 @@
1
- import ServerLayout from '@/components/server/ServerLayout';
2
1
  import { isMobileDevice } from '@/utils/responsive';
3
2
 
4
- import Desktop from './_layout/Desktop';
5
- import Mobile from './_layout/Mobile';
6
3
  import AgentDetailContent from './features/AgentDetailContent';
7
4
 
8
- const Layout = ServerLayout({ Desktop, Mobile });
9
-
10
5
  const Detail = () => {
11
6
  const mobile = isMobileDevice();
12
- return (
13
- <Layout>
14
- <AgentDetailContent mobile={mobile} />
15
- </Layout>
16
- );
7
+ return <AgentDetailContent mobile={mobile} />;
17
8
  };
18
9
 
19
10
  Detail.displayName = 'AgentDetail';
@@ -0,0 +1 @@
1
+ export default () => null;
@@ -24,7 +24,7 @@ const useStyles = createStyles(({ css, token, stylish }) => ({
24
24
  noScrollbar: stylish.noScrollbar,
25
25
  }));
26
26
 
27
- const SideBar = memo<PropsWithChildren>(({ children }) => {
27
+ const DetailSidebar = memo<PropsWithChildren>(({ children }) => {
28
28
  const { styles } = useStyles();
29
29
  const { md = true } = useResponsive();
30
30
  const [tempId, setTempId] = useState<string>('');
@@ -81,4 +81,4 @@ const SideBar = memo<PropsWithChildren>(({ children }) => {
81
81
  );
82
82
  });
83
83
 
84
- export default SideBar;
84
+ export default DetailSidebar;
@@ -4,6 +4,7 @@ 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';
7
8
  import Header from './Header';
8
9
  import Hero from './Hero';
9
10
 
@@ -29,7 +30,7 @@ const Layout = ({ children, detail }: LayoutProps) => {
29
30
  {children}
30
31
  </Flexbox>
31
32
  </Flexbox>
32
- {detail}
33
+ <DetailSidebar>{detail}</DetailSidebar>
33
34
  </Flexbox>
34
35
  </Flexbox>
35
36
  );
@@ -6,7 +6,7 @@ import { useTranslation } from 'react-i18next';
6
6
 
7
7
  import { agentMarketSelectors, useMarketStore } from '@/store/market';
8
8
 
9
- const AgentDetail = memo<PropsWithChildren>(({ children }) => {
9
+ const DetailModal = memo<PropsWithChildren>(({ children }) => {
10
10
  const [showAgentSidebar, deactivateAgent] = useMarketStore((s) => [
11
11
  agentMarketSelectors.showSideBar(s),
12
12
  s.deactivateAgent,
@@ -29,4 +29,4 @@ const AgentDetail = memo<PropsWithChildren>(({ children }) => {
29
29
  );
30
30
  });
31
31
 
32
- export default AgentDetail;
32
+ export default DetailModal;
@@ -1,6 +1,7 @@
1
1
  import MobileContentLayout from '@/components/server/MobileNavLayout';
2
2
 
3
3
  import { LayoutProps } from '../type';
4
+ import DetailModal from './DetailModal';
4
5
  import Header from './Header';
5
6
 
6
7
  const Layout = ({ children, detail }: LayoutProps) => {
@@ -10,10 +11,11 @@ const Layout = ({ children, detail }: LayoutProps) => {
10
11
  gap={16}
11
12
  header={<Header />}
12
13
  style={{ paddingInline: 16, paddingTop: 8 }}
14
+ withNav
13
15
  >
14
16
  {children}
15
17
  </MobileContentLayout>
16
- {detail}
18
+ <DetailModal>{detail}</DetailModal>
17
19
  </>
18
20
  );
19
21
  };
@@ -0,0 +1,16 @@
1
+ import UpgradeAlert from '@/app/(main)/settings//features/UpgradeAlert';
2
+
3
+ import CategoryContent from './features/CategoryContent';
4
+
5
+ const Category = () => {
6
+ return (
7
+ <>
8
+ <CategoryContent />
9
+ <UpgradeAlert />
10
+ </>
11
+ );
12
+ };
13
+
14
+ Category.displayName = 'SettingCategory';
15
+
16
+ export default Category;
@@ -0,0 +1,35 @@
1
+ 'use client';
2
+
3
+ import { memo } from 'react';
4
+ import urlJoin from 'url-join';
5
+
6
+ import Menu from '@/components/Menu';
7
+ import { useActiveSettingsKey } from '@/hooks/useActiveSettingsKey';
8
+ import { useQueryRoute } from '@/hooks/useQueryRoute';
9
+
10
+ import { useCategory } from '../../hooks/useCategory';
11
+
12
+ const CategoryContent = memo<{ modal?: boolean }>(({ modal }) => {
13
+ const activeTab = useActiveSettingsKey();
14
+ const cateItems = useCategory();
15
+ const router = useQueryRoute();
16
+
17
+ return (
18
+ <Menu
19
+ items={cateItems}
20
+ onClick={({ key }) => {
21
+ const path = urlJoin('/settings', key);
22
+ if (modal) {
23
+ router.replace(path);
24
+ } else {
25
+ router.push(path);
26
+ }
27
+ }}
28
+ selectable
29
+ selectedKeys={[activeTab as any]}
30
+ variant={'compact'}
31
+ />
32
+ );
33
+ });
34
+
35
+ export default CategoryContent;
@@ -0,0 +1,38 @@
1
+ import { Alert } from '@lobehub/ui';
2
+ import { Button } from 'antd';
3
+ import Link from 'next/link';
4
+ import { memo } from 'react';
5
+ import { useTranslation } from 'react-i18next';
6
+
7
+ import { MANUAL_UPGRADE_URL } from '@/const/url';
8
+ import { useGlobalStore } from '@/store/global';
9
+
10
+ const UpgradeAlert = memo(() => {
11
+ const [hasNewVersion, latestVersion] = useGlobalStore((s) => [s.hasNewVersion, s.latestVersion]);
12
+ const { t } = useTranslation('common');
13
+
14
+ if (!hasNewVersion) return null;
15
+
16
+ return (
17
+ <Alert
18
+ action={
19
+ <Link
20
+ aria-label={t('upgradeVersion.action')}
21
+ href={MANUAL_UPGRADE_URL}
22
+ style={{ marginBottom: 12 }}
23
+ target={'_blank'}
24
+ >
25
+ <Button block size={'small'} type={'primary'}>
26
+ {t('upgradeVersion.action')}
27
+ </Button>
28
+ </Link>
29
+ }
30
+ closable
31
+ message={t('upgradeVersion.newVersion', { version: latestVersion })}
32
+ showIcon={false}
33
+ type={'info'}
34
+ />
35
+ );
36
+ });
37
+
38
+ export default UpgradeAlert;
@@ -1,36 +1,91 @@
1
1
  'use client';
2
2
 
3
- import { ChatHeader, ChatHeaderTitle } from '@lobehub/ui';
4
- import { Tag } from 'antd';
5
- import { memo } from 'react';
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';
6
8
  import { useTranslation } from 'react-i18next';
7
9
  import { Flexbox } from 'react-layout-kit';
8
10
 
11
+ import BrandWatermark from '@/components/BrandWatermark';
9
12
  import { useActiveSettingsKey } from '@/hooks/useActiveSettingsKey';
10
13
  import { SettingsTabs } from '@/store/global/initialState';
11
14
 
12
- const Header = memo(() => {
13
- const { t } = useTranslation('setting');
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
+ }));
14
26
 
15
- const activeKey = useActiveSettingsKey();
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');
16
32
 
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}`)}
33
+ const activeKey = useActiveSettingsKey();
25
34
 
26
- {activeKey === SettingsTabs.Sync && <Tag color={'gold'}>{t('tab.experiment')}</Tag>}
27
- </Flexbox>
28
- }
29
- />
30
- </div>
31
- }
32
- />
33
- );
34
- });
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
+ );
35
90
 
36
91
  export default Header;
@@ -1,47 +1,59 @@
1
1
  'use client';
2
2
 
3
- import { createStyles, useResponsive } from 'antd-style';
4
- import { memo } from 'react';
3
+ import { createStyles } from 'antd-style';
5
4
  import { useTranslation } from 'react-i18next';
6
- import { Flexbox } from 'react-layout-kit';
5
+ import { Flexbox, FlexboxProps } from 'react-layout-kit';
7
6
 
8
- import { useActiveSettingsKey } from '@/hooks/useActiveSettingsKey';
7
+ import BrandWatermark from '@/components/BrandWatermark';
9
8
 
10
- import SettingList from '../../features/SettingList';
11
- import UpgradeAlert from '../../features/UpgradeAlert';
12
-
13
- const useStyles = createStyles(({ stylish, token, css }) => ({
14
- body: stylish.noScrollbar,
9
+ const useStyles = createStyles(({ token, css }) => ({
15
10
  container: css`
11
+ padding: 24px 12px 16px;
12
+ background: ${token.colorBgContainer};
16
13
  border-inline-end: 1px solid ${token.colorBorder};
17
14
  `,
15
+ desc: css`
16
+ line-height: 1.4;
17
+ color: ${token.colorTextDescription};
18
+ `,
19
+ header: css`
20
+ padding: 0 0.75rem;
21
+ `,
18
22
  logo: css`
19
23
  fill: ${token.colorText};
20
24
  `,
21
- top: css`
22
- font-size: 20px;
23
- font-weight: bold;
25
+ title: css`
26
+ margin: 0;
27
+ font-size: 26px;
28
+ font-weight: 600;
29
+ line-height: 1.3;
24
30
  `,
25
31
  }));
26
32
 
27
- const SideBar = memo(() => {
28
- const { styles } = useStyles();
29
- const activeKey = useActiveSettingsKey();
30
-
31
- const { t } = useTranslation('common');
32
- const { mobile } = useResponsive();
33
+ interface SidebarLayoutProps extends FlexboxProps {
34
+ desc?: string;
35
+ title?: string;
36
+ }
33
37
 
38
+ const SidebarLayout = ({ children, className, title, desc, ...rest }: SidebarLayoutProps) => {
39
+ const { cx, styles } = useStyles();
40
+ const { t } = useTranslation('setting');
34
41
  return (
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} />
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>
42
52
  </Flexbox>
53
+ {children}
54
+ <BrandWatermark paddingInline={12} />
43
55
  </Flexbox>
44
56
  );
45
- });
57
+ };
46
58
 
47
- export default SideBar;
59
+ export default SidebarLayout;
@@ -1,27 +1,51 @@
1
1
  'use client';
2
2
 
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';
3
+ import { useResponsive } from 'antd-style';
4
+ import { memo, useRef } from 'react';
5
+ import { Flexbox } from 'react-layout-kit';
8
6
 
7
+ import { LayoutProps } from '../type';
9
8
  import Header from './Header';
10
9
  import SideBar from './SideBar';
11
10
 
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%'}>
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
+ >
20
42
  {children}
21
- </Center>
43
+ </Flexbox>
22
44
  </Flexbox>
23
45
  </Flexbox>
24
- </>
25
- ));
46
+ );
47
+ });
48
+
49
+ Layout.displayName = 'DesktopSettingsLayout';
26
50
 
27
- export default ClientResponsiveLayout({ Desktop, Mobile: () => import('../Mobile') });
51
+ export default Layout;
@@ -1,3 +1,5 @@
1
+ 'use client';
2
+
1
3
  import { MobileNavBar, MobileNavBarTitle } from '@lobehub/ui';
2
4
  import { Tag } from 'antd';
3
5
  import { useRouter } from 'next/navigation';
@@ -28,7 +30,7 @@ const Header = memo(() => {
28
30
  }
29
31
  />
30
32
  }
31
- onBackClick={() => router.push('/settings')}
33
+ onBackClick={() => router.push('/me')}
32
34
  showBackButton
33
35
  style={mobileHeaderSticky}
34
36
  />
@@ -1,23 +1,12 @@
1
- 'use client';
2
-
3
- import { PropsWithChildren } from 'react';
4
-
5
1
  import MobileContentLayout from '@/components/server/MobileNavLayout';
6
- import { useIsSubSlug } from '@/hooks/useIsSubSlug';
7
-
8
- import SubSettingHeader from './SubSettingHeader';
9
2
 
10
- const MobileLayout = ({ children }: PropsWithChildren) => {
11
- const isSubPath = useIsSubSlug();
3
+ import { LayoutProps } from '../type';
4
+ import Header from './Header';
12
5
 
13
- if (isSubPath)
14
- return (
15
- <MobileContentLayout header={<SubSettingHeader />} withNav={false}>
16
- {children}
17
- </MobileContentLayout>
18
- );
19
-
20
- return children;
6
+ const Layout = ({ children }: LayoutProps) => {
7
+ return <MobileContentLayout header={<Header />}>{children}</MobileContentLayout>;
21
8
  };
22
9
 
23
- export default MobileLayout;
10
+ Layout.displayName = 'MobileSettingsLayout';
11
+
12
+ export default Layout;
@@ -0,0 +1,6 @@
1
+ import { ReactNode } from 'react';
2
+
3
+ export interface LayoutProps {
4
+ category: ReactNode;
5
+ children: ReactNode;
6
+ }