@lobehub/chat 0.152.0 → 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 (255) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/README.md +8 -8
  3. package/README.zh-CN.md +8 -8
  4. package/locales/ar/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 +12 -0
  76. package/src/app/(main)/market/{features/AgentDetailContent/AgentInfo → @detail/features/AgentDetailContent}/Header.tsx +30 -21
  77. package/src/app/(main)/market/{features/AgentDetailContent/AgentInfo → @detail/features/AgentDetailContent}/index.tsx +10 -4
  78. package/src/app/(main)/market/{features/AgentDetailContent/AgentInfo → @detail/features/AgentDetailContent}/style.ts +7 -11
  79. package/src/app/(main)/market/@detail/loading.tsx +1 -0
  80. package/src/app/(main)/market/_layout/Desktop/{AgentDetail.tsx → DetailSidebar.tsx} +17 -12
  81. package/src/app/(main)/market/_layout/Desktop/Header.tsx +3 -6
  82. package/src/app/(main)/market/_layout/Desktop/Hero.tsx +39 -0
  83. package/src/app/(main)/market/_layout/Desktop/index.tsx +24 -44
  84. package/src/app/(main)/market/{(mobile)/features/AgentDetail.tsx → _layout/Mobile/DetailModal.tsx} +9 -7
  85. package/src/app/(main)/market/_layout/Mobile/Header.tsx +2 -2
  86. package/src/app/(main)/market/_layout/Mobile/index.tsx +17 -9
  87. package/src/app/(main)/market/_layout/type.ts +6 -0
  88. package/src/app/(main)/market/features/AgentCard/AgentCardBanner.tsx +10 -9
  89. package/src/app/(main)/market/features/AgentCard/index.tsx +133 -58
  90. package/src/app/(main)/market/features/AgentList.tsx +94 -0
  91. package/src/app/(main)/market/features/AgentSearchBar.tsx +42 -0
  92. package/src/app/(main)/market/features/ShareAgentButton/Inner.tsx +9 -7
  93. package/src/app/(main)/market/features/ShareAgentButton/index.tsx +22 -15
  94. package/src/app/(main)/market/features/TagList.tsx +65 -0
  95. package/src/app/(main)/market/layout.tsx +11 -0
  96. package/src/app/(main)/market/loading.tsx +2 -2
  97. package/src/app/(main)/market/page.tsx +22 -12
  98. package/src/app/(main)/settings/@category/default.tsx +16 -0
  99. package/src/app/(main)/settings/@category/features/CategoryContent.tsx +35 -0
  100. package/src/app/(main)/settings/@category/features/UpgradeAlert.tsx +38 -0
  101. package/src/app/(main)/settings/_layout/Desktop/Header.tsx +78 -23
  102. package/src/app/(main)/settings/_layout/Desktop/SideBar.tsx +39 -27
  103. package/src/app/(main)/settings/_layout/Desktop/index.tsx +41 -17
  104. package/src/app/(main)/settings/_layout/Mobile/{SubSettingHeader.tsx → Header.tsx} +3 -1
  105. package/src/app/(main)/settings/_layout/Mobile/index.tsx +7 -18
  106. package/src/app/(main)/settings/_layout/type.ts +6 -0
  107. package/src/app/(main)/settings/about/features/AboutList.tsx +122 -0
  108. package/src/app/(main)/settings/about/features/Analytics.tsx +42 -0
  109. package/src/app/(main)/settings/about/layout.tsx +26 -0
  110. package/src/app/(main)/settings/about/loading.tsx +5 -0
  111. package/src/app/(main)/settings/about/page.tsx +20 -25
  112. package/src/app/(main)/settings/agent/layout.tsx +35 -0
  113. package/src/app/(main)/settings/agent/loading.tsx +4 -2
  114. package/src/app/(main)/settings/agent/page.tsx +25 -12
  115. package/src/app/(main)/settings/common/{Common.tsx → features/Common.tsx} +7 -5
  116. package/src/app/(main)/settings/common/{Theme.tsx → features/Theme/index.tsx} +8 -6
  117. package/src/app/(main)/settings/common/page.tsx +21 -4
  118. package/src/app/(main)/settings/error.tsx +5 -0
  119. package/src/app/(main)/settings/features/Footer.tsx +2 -0
  120. package/src/app/(main)/settings/features/UpgradeAlert.tsx +21 -13
  121. package/src/app/(main)/settings/hooks/useCategory.tsx +54 -0
  122. package/src/app/(main)/settings/hooks/useSyncSettings.ts +2 -2
  123. package/src/app/(main)/settings/layout.ts +4 -1
  124. package/src/app/(main)/settings/llm/Anthropic/index.tsx +4 -10
  125. package/src/app/(main)/settings/llm/Azure/index.tsx +3 -1
  126. package/src/app/(main)/settings/llm/Bedrock/index.tsx +3 -1
  127. package/src/app/(main)/settings/llm/Google/index.tsx +4 -2
  128. package/src/app/(main)/settings/llm/Groq/index.tsx +3 -1
  129. package/src/app/(main)/settings/llm/Minimax/index.tsx +3 -9
  130. package/src/app/(main)/settings/llm/Mistral/index.tsx +3 -9
  131. package/src/app/(main)/settings/llm/Moonshot/index.tsx +3 -1
  132. package/src/app/(main)/settings/llm/Ollama/index.tsx +3 -1
  133. package/src/app/(main)/settings/llm/OpenAI/index.tsx +2 -0
  134. package/src/app/(main)/settings/llm/OpenRouter/index.tsx +3 -9
  135. package/src/app/(main)/settings/llm/Perplexity/index.tsx +3 -9
  136. package/src/app/(main)/settings/llm/TogetherAI/index.tsx +3 -9
  137. package/src/app/(main)/settings/llm/ZeroOne/index.tsx +3 -9
  138. package/src/app/(main)/settings/llm/Zhipu/index.tsx +3 -10
  139. package/src/app/(main)/settings/llm/components/Checker.tsx +2 -0
  140. package/src/app/(main)/settings/llm/components/Footer.tsx +26 -0
  141. package/src/app/(main)/settings/llm/components/ProviderConfig/index.tsx +16 -1
  142. package/src/app/(main)/settings/llm/page.tsx +57 -3
  143. package/src/app/(main)/settings/loading.tsx +9 -0
  144. package/src/app/(main)/settings/not-found.tsx +3 -0
  145. package/src/app/(main)/settings/page.tsx +2 -14
  146. package/src/app/(main)/settings/sync/{DeviceInfo → features/DeviceInfo}/Card.tsx +6 -5
  147. package/src/app/(main)/settings/sync/features/DeviceInfo/DeviceName.tsx +63 -0
  148. package/src/app/(main)/settings/sync/{components → features/DeviceInfo}/SystemIcon.tsx +6 -14
  149. package/src/app/(main)/settings/sync/{DeviceInfo → features/DeviceInfo}/index.tsx +22 -36
  150. package/src/app/(main)/settings/sync/{WebRTC → features/WebRTC}/ChannelNameInput.tsx +3 -3
  151. package/src/app/(main)/settings/sync/{WebRTC → features/WebRTC}/index.tsx +10 -9
  152. package/src/app/(main)/settings/sync/page.tsx +19 -11
  153. package/src/app/(main)/settings/tts/features/OpenAI.tsx +54 -0
  154. package/src/app/(main)/settings/tts/{TTS/index.tsx → features/STT.tsx} +11 -27
  155. package/src/app/(main)/settings/tts/page.tsx +17 -11
  156. package/src/app/@modal/(.)settings/about/layout.tsx +1 -0
  157. package/src/app/@modal/(.)settings/about/page.tsx +1 -0
  158. package/src/app/@modal/(.)settings/agent/layout.tsx +1 -0
  159. package/src/app/@modal/(.)settings/agent/page.tsx +1 -0
  160. package/src/app/@modal/(.)settings/common/page.tsx +1 -0
  161. package/src/app/@modal/(.)settings/layout.tsx +28 -0
  162. package/src/app/@modal/(.)settings/llm/page.tsx +1 -0
  163. package/src/app/@modal/(.)settings/loading.tsx +5 -0
  164. package/src/app/@modal/(.)settings/sync/page.tsx +1 -0
  165. package/src/app/@modal/(.)settings/tts/page.tsx +1 -0
  166. package/src/app/@modal/_layout/SettingModalLayout.tsx +59 -0
  167. package/src/app/@modal/chat/(.)settings/features/CategoryContent.tsx +36 -0
  168. package/src/app/@modal/chat/(.)settings/features/useCategory.tsx +62 -0
  169. package/src/app/@modal/chat/(.)settings/layout.tsx +55 -0
  170. package/src/app/@modal/chat/(.)settings/loading.tsx +5 -0
  171. package/src/app/@modal/chat/(.)settings/page.tsx +40 -0
  172. package/src/app/@modal/default.tsx +1 -0
  173. package/src/app/@modal/layout.tsx +30 -0
  174. package/src/app/@modal/loading.tsx +5 -0
  175. package/src/app/layout.tsx +11 -3
  176. package/src/components/BrandWatermark/index.tsx +39 -0
  177. package/src/components/Cell/Divider.tsx +19 -0
  178. package/src/components/Cell/index.tsx +38 -0
  179. package/src/components/Menu/index.tsx +97 -0
  180. package/src/components/SkeletonLoading/index.tsx +21 -0
  181. package/src/const/url.ts +1 -0
  182. package/src/features/AgentSetting/AgentChat/index.tsx +135 -0
  183. package/src/features/AgentSetting/AgentMeta/index.tsx +4 -3
  184. package/src/features/AgentSetting/AgentModal/index.tsx +95 -0
  185. package/src/features/AgentSetting/AgentPlugin/index.tsx +65 -66
  186. package/src/features/AgentSetting/AgentPrompt/index.tsx +101 -47
  187. package/src/features/AgentSetting/AgentTTS/index.tsx +4 -0
  188. package/src/features/AgentSetting/StoreUpdater.tsx +2 -0
  189. package/src/features/AgentSetting/index.tsx +6 -6
  190. package/src/features/AgentSetting/store/index.ts +2 -0
  191. package/src/features/AvatarWithUpload/index.tsx +2 -0
  192. package/src/features/ChatInput/STT/browser.tsx +1 -1
  193. package/src/features/ChatInput/STT/openai.tsx +1 -1
  194. package/src/features/Conversation/components/InboxWelcome/AgentsSuggest.tsx +2 -2
  195. package/src/hooks/useQuery.ts +7 -0
  196. package/src/hooks/useQueryRoute.ts +16 -0
  197. package/src/locales/default/common.ts +14 -0
  198. package/src/locales/default/setting.ts +3 -0
  199. package/src/locales/resources.ts +1 -0
  200. package/src/server/redirectHard.ts +9 -0
  201. package/src/server/translation.ts +20 -0
  202. package/src/services/__tests__/chat.test.ts +1 -1
  203. package/src/store/global/initialState.ts +1 -0
  204. package/src/store/market/action.ts +1 -1
  205. package/src/store/session/slices/session/action.ts +1 -1
  206. package/src/utils/difference.ts +2 -1
  207. package/src/app/(main)/@nav/_layout/Desktop/Avatar.tsx +0 -11
  208. package/src/app/(main)/chat/settings/(desktop)/index.tsx +0 -23
  209. package/src/app/(main)/chat/settings/(mobile)/index.tsx +0 -16
  210. package/src/app/(main)/market/(desktop)/index.tsx +0 -20
  211. package/src/app/(main)/market/(mobile)/features/AgentCard.tsx +0 -31
  212. package/src/app/(main)/market/(mobile)/index.tsx +0 -25
  213. package/src/app/(main)/market/components/Loading.tsx +0 -13
  214. package/src/app/(main)/market/features/AgentCard/AgentCardItem.tsx +0 -54
  215. package/src/app/(main)/market/features/AgentCard/style.ts +0 -33
  216. package/src/app/(main)/market/features/AgentDetailContent/index.tsx +0 -12
  217. package/src/app/(main)/market/features/AgentSearchBar/index.tsx +0 -40
  218. package/src/app/(main)/market/features/PageTitle/index.tsx +0 -13
  219. package/src/app/(main)/market/features/TagList/Inner.tsx +0 -28
  220. package/src/app/(main)/market/features/TagList/index.tsx +0 -23
  221. package/src/app/(main)/market/layout.ts +0 -8
  222. package/src/app/(main)/settings/(desktop)/index.tsx +0 -23
  223. package/src/app/(main)/settings/(mobile)/features/AvatarBanner.tsx +0 -68
  224. package/src/app/(main)/settings/(mobile)/features/ExtraList.tsx +0 -65
  225. package/src/app/(main)/settings/(mobile)/index.tsx +0 -53
  226. package/src/app/(main)/settings/about/AboutList.tsx +0 -53
  227. package/src/app/(main)/settings/about/Analytics.tsx +0 -40
  228. package/src/app/(main)/settings/about/style.ts +0 -22
  229. package/src/app/(main)/settings/agent/Agent.tsx +0 -29
  230. package/src/app/(main)/settings/common/index.tsx +0 -24
  231. package/src/app/(main)/settings/common/loading.tsx +0 -3
  232. package/src/app/(main)/settings/features/SettingList/index.tsx +0 -47
  233. package/src/app/(main)/settings/llm/index.tsx +0 -59
  234. package/src/app/(main)/settings/llm/layout.tsx +0 -11
  235. package/src/app/(main)/settings/llm/loading.tsx +0 -3
  236. package/src/app/(main)/settings/sync/DeviceInfo/DeviceName.tsx +0 -66
  237. package/src/app/(main)/settings/sync/PageTitle.tsx +0 -11
  238. package/src/app/(main)/settings/sync/layout.tsx +0 -12
  239. package/src/app/(main)/settings/sync/loading.tsx +0 -3
  240. package/src/app/(main)/settings/tts/loading.tsx +0 -3
  241. package/src/features/AgentSetting/AgentConfig/index.tsx +0 -202
  242. package/src/features/AgentSetting/AgentConfig/useSyncConfig.ts +0 -23
  243. /package/src/app/(main)/market/{features/AgentDetailContent/AgentInfo → @detail/features/AgentDetailContent}/Comment.tsx +0 -0
  244. /package/src/app/(main)/market/{features/AgentDetailContent/AgentInfo → @detail/features/AgentDetailContent}/Loading.tsx +0 -0
  245. /package/src/app/(main)/market/{features/AgentDetailContent/AgentInfo → @detail/features/AgentDetailContent}/TokenTag.tsx +0 -0
  246. /package/src/app/(main)/settings/{features/SettingList → about/features}/Item.tsx +0 -0
  247. /package/src/app/(main)/settings/{features → common/features/Theme}/ThemeSwatches/ThemeSwatchesNeutral.tsx +0 -0
  248. /package/src/app/(main)/settings/{features → common/features/Theme}/ThemeSwatches/ThemeSwatchesPrimary.tsx +0 -0
  249. /package/src/app/(main)/settings/{features → common/features/Theme}/ThemeSwatches/index.ts +0 -0
  250. /package/src/app/(main)/settings/sync/{Alert.tsx → features/Alert.tsx} +0 -0
  251. /package/src/app/(main)/settings/sync/{components → features/WebRTC}/SyncSwitch/index.css +0 -0
  252. /package/src/app/(main)/settings/sync/{components → features/WebRTC}/SyncSwitch/index.tsx +0 -0
  253. /package/src/app/(main)/settings/sync/{util.ts → features/WebRTC/generateRandomRoomName.ts} +0 -0
  254. /package/src/app/(main)/settings/tts/{TTS/options.ts → features/const.ts} +0 -0
  255. /package/src/features/AgentSetting/{AgentConfig → AgentModal}/ModelSelect.tsx +0 -0
@@ -0,0 +1,26 @@
1
+ 'use client';
2
+
3
+ import { Divider } from 'antd';
4
+ import Link from 'next/link';
5
+ import { memo } from 'react';
6
+ import { Trans } from 'react-i18next';
7
+
8
+ import { MORE_MODEL_PROVIDER_REQUEST_URL } from '@/const/url';
9
+
10
+ const Footer = memo(() => {
11
+ return (
12
+ <Divider>
13
+ <p style={{ fontSize: 14 }}>
14
+ <Trans i18nKey="llm.waitingForMore" ns={'setting'}>
15
+ 更多模型正在
16
+ <Link aria-label={'todo'} href={MORE_MODEL_PROVIDER_REQUEST_URL} target="_blank">
17
+ 计划接入
18
+ </Link>
19
+ 中 ,敬请期待 ✨
20
+ </Trans>
21
+ </p>
22
+ </Divider>
23
+ );
24
+ });
25
+
26
+ export default Footer;
@@ -1,8 +1,11 @@
1
+ 'use client';
2
+
1
3
  import { Form, type FormItemProps, type ItemGroup } from '@lobehub/ui';
2
4
  import { Form as AntForm, Input, Switch } from 'antd';
3
5
  import { debounce } from 'lodash-es';
4
6
  import { ReactNode, memo } from 'react';
5
7
  import { useTranslation } from 'react-i18next';
8
+ import { Flexbox } from 'react-layout-kit';
6
9
 
7
10
  import { useSyncSettings } from '@/app/(main)/settings/hooks/useSyncSettings';
8
11
  import {
@@ -142,7 +145,19 @@ const ProviderConfig = memo<ProviderConfigProps>(
142
145
  value={enabled}
143
146
  />
144
147
  ) : undefined,
145
- title,
148
+ title: (
149
+ <Flexbox
150
+ align={'center'}
151
+ horizontal
152
+ style={{
153
+ height: 24,
154
+ maxHeight: 24,
155
+ ...(enabled ? {} : { filter: 'grayscale(100%)', maxHeight: 24, opacity: 0.66 }),
156
+ }}
157
+ >
158
+ {title}
159
+ </Flexbox>
160
+ ),
146
161
  };
147
162
 
148
163
  return (
@@ -1,5 +1,59 @@
1
- import Page from './index';
1
+ import { notFound } from 'next/navigation';
2
+ import { Flexbox } from 'react-layout-kit';
2
3
 
3
- export default () => {
4
- return <Page />;
4
+ import { serverFeatureFlags } from '@/config/server/featureFlags';
5
+ import { translation } from '@/server/translation';
6
+
7
+ import Anthropic from './Anthropic';
8
+ import Azure from './Azure';
9
+ import Bedrock from './Bedrock';
10
+ import Google from './Google';
11
+ import Groq from './Groq';
12
+ import Minimax from './Minimax';
13
+ import Mistral from './Mistral';
14
+ import Moonshot from './Moonshot';
15
+ import Ollama from './Ollama';
16
+ import OpenAI from './OpenAI';
17
+ import OpenRouter from './OpenRouter';
18
+ import Perplexity from './Perplexity';
19
+ import TogetherAI from './TogetherAI';
20
+ import ZeroOne from './ZeroOne';
21
+ import Zhipu from './Zhipu';
22
+ import Footer from './components/Footer';
23
+
24
+ export const generateMetadata = async () => {
25
+ const { t } = await translation('setting');
26
+ return {
27
+ title: t('tab.llm'),
28
+ };
5
29
  };
30
+
31
+ const Page = () => {
32
+ const showLLM = serverFeatureFlags().showLLM;
33
+ if (!showLLM) return notFound();
34
+
35
+ return (
36
+ <Flexbox gap={24}>
37
+ <OpenAI />
38
+ <Azure />
39
+ <Ollama />
40
+ <Google />
41
+ <Anthropic />
42
+ <Bedrock />
43
+ <OpenRouter />
44
+ <TogetherAI />
45
+ <Groq />
46
+ <Perplexity />
47
+ <Minimax />
48
+ <Mistral />
49
+ <Moonshot />
50
+ <Zhipu />
51
+ <ZeroOne />
52
+ <Footer />
53
+ </Flexbox>
54
+ );
55
+ };
56
+
57
+ Page.displayName = 'LlmSetting';
58
+
59
+ export default Page;
@@ -0,0 +1,9 @@
1
+ import SkeletonLoading from '@/components/SkeletonLoading';
2
+
3
+ export default () => {
4
+ return (
5
+ <div style={{ flex: 1 }}>
6
+ <SkeletonLoading paragraph={{ rows: 8 }} title={false} />
7
+ </div>
8
+ );
9
+ };
@@ -0,0 +1,3 @@
1
+ import dynamic from 'next/dynamic';
2
+
3
+ export default dynamic(() => import('@/components/404'));
@@ -1,19 +1,7 @@
1
- import { getServerConfig } from '@/config/server';
2
- import { isMobileDevice } from '@/utils/responsive';
3
-
4
- import DesktopPage from './(desktop)';
5
- import MobilePage from './(mobile)';
1
+ import { redirect } from 'next/navigation';
6
2
 
7
3
  const Page = () => {
8
- const mobile = isMobileDevice();
9
-
10
- if (mobile) return <MobilePage />;
11
-
12
- const { SHOW_ACCESS_CODE_CONFIG, ENABLE_OAUTH_SSO } = getServerConfig();
13
-
14
- return (
15
- <DesktopPage showAccessCodeConfig={SHOW_ACCESS_CODE_CONFIG} showOAuthLogin={ENABLE_OAUTH_SSO} />
16
- );
4
+ return redirect('/settings/common');
17
5
  };
18
6
 
19
7
  export default Page;
@@ -5,18 +5,18 @@ import { Center, Flexbox } from 'react-layout-kit';
5
5
  const useStyles = createStyles(({ css, token, responsive }) => ({
6
6
  container: css`
7
7
  background: ${token.colorFillTertiary};
8
- border-radius: 12px;
8
+ border-radius: ${token.borderRadius}px;
9
9
 
10
10
  .${responsive.mobile} {
11
11
  width: 100%;
12
12
  }
13
13
  `,
14
14
  icon: css`
15
- width: 40px;
16
- height: 40px;
15
+ width: 24px;
16
+ height: 24px;
17
17
  `,
18
18
  title: css`
19
- font-size: 20px;
19
+ font-size: 16px;
20
20
  `,
21
21
  }));
22
22
 
@@ -27,13 +27,14 @@ const Card = memo<{ icon: ReactNode; title: string }>(({ title, icon }) => {
27
27
  <Flexbox
28
28
  align={'center'}
29
29
  className={styles.container}
30
+ flex={1}
30
31
  gap={12}
31
32
  horizontal
32
33
  paddingBlock={12}
33
34
  paddingInline={20}
34
35
  >
35
36
  <Center className={styles.icon}>{icon}</Center>
36
- <Flexbox className={styles.title}>{title}</Flexbox>
37
+ <div className={styles.title}>{title}</div>
37
38
  </Flexbox>
38
39
  );
39
40
  });
@@ -0,0 +1,63 @@
1
+ 'use client';
2
+
3
+ import { EditableText } from '@lobehub/ui';
4
+ import { Typography } from 'antd';
5
+ import { memo, useState } from 'react';
6
+ import { useTranslation } from 'react-i18next';
7
+ import { Flexbox } from 'react-layout-kit';
8
+
9
+ import { useUserStore } from '@/store/user';
10
+ import { syncSettingsSelectors } from '@/store/user/selectors';
11
+
12
+ const DeviceName = memo(() => {
13
+ const { t } = useTranslation('setting');
14
+
15
+ const [deviceName, setSettings] = useUserStore((s) => [
16
+ syncSettingsSelectors.deviceName(s),
17
+ s.setSettings,
18
+ ]);
19
+
20
+ const [editing, setEditing] = useState(false);
21
+
22
+ const updateDeviceName = (deviceName: string) => {
23
+ setSettings({ sync: { deviceName } });
24
+ setEditing(false);
25
+ };
26
+
27
+ return (
28
+ <Flexbox
29
+ align={'center'}
30
+ flex={1}
31
+ height={40}
32
+ horizontal
33
+ style={{ fontSize: 20, fontWeight: 'bold', lineHeight: 1, minWidth: 240, paddingLeft: 8 }}
34
+ >
35
+ {!deviceName && !editing && (
36
+ <Flexbox
37
+ onClick={() => {
38
+ setEditing(true);
39
+ }}
40
+ style={{ cursor: 'pointer' }}
41
+ >
42
+ <Typography.Text type={'secondary'}>{t('sync.device.deviceName.hint')}</Typography.Text>
43
+ </Flexbox>
44
+ )}
45
+ <EditableText
46
+ editing={editing}
47
+ onBlur={(e) => {
48
+ updateDeviceName(e.target.value);
49
+ }}
50
+ onChange={(e) => {
51
+ updateDeviceName(e);
52
+ }}
53
+ onEditingChange={setEditing}
54
+ placeholder={t('sync.device.deviceName.placeholder')}
55
+ size={'large'}
56
+ type={'block'}
57
+ value={deviceName}
58
+ />
59
+ </Flexbox>
60
+ );
61
+ });
62
+
63
+ export default DeviceName;
@@ -8,28 +8,20 @@ import {
8
8
  } from '@icons-pack/react-simple-icons';
9
9
  import { memo } from 'react';
10
10
 
11
- // TODO: 等 simple icons 修复类型,移除 ignore
12
-
13
11
  const SystemIcon = memo<{ title?: string }>(({ title }) => {
14
12
  if (!title) return;
15
13
 
16
- // @ts-ignore
17
- if (['Mac OS', 'iOS', 'iPadOS'].includes(title)) return <SiApple size={32} />;
14
+ if (['Mac OS', 'iOS', 'iPadOS'].includes(title)) return <SiApple size={24} />;
18
15
 
19
- // @ts-ignore
20
- if (['Windows'].includes(title)) return <SiWindows11 size={32} />;
16
+ if (['Windows'].includes(title)) return <SiWindows11 size={24} />;
21
17
 
22
- // @ts-ignore
23
- if (title === 'Android') return <SiAndroid size={32} />;
18
+ if (title === 'Android') return <SiAndroid size={24} />;
24
19
 
25
- // @ts-ignore
26
- if (['BlackBerry'].includes(title)) return <SiBlackberry size={32} />;
20
+ if (['BlackBerry'].includes(title)) return <SiBlackberry size={24} />;
27
21
 
28
- // @ts-ignore
29
- if (title === 'Linux') return <SiLinux size={32} />;
22
+ if (title === 'Linux') return <SiLinux size={24} />;
30
23
 
31
- // @ts-ignore
32
- if (title === 'Chrome OS') return <SiGooglechrome size={32} />;
24
+ if (title === 'Chrome OS') return <SiGooglechrome size={24} />;
33
25
 
34
26
  return null;
35
27
  });
@@ -10,47 +10,22 @@ import { Flexbox } from 'react-layout-kit';
10
10
  import { BrowserIcon } from '@/components/BrowserIcon';
11
11
  import { MAX_WIDTH } from '@/const/layoutTokens';
12
12
 
13
- import SystemIcon from '../components/SystemIcon';
14
13
  import Card from './Card';
15
14
  import DeviceName from './DeviceName';
15
+ import SystemIcon from './SystemIcon';
16
16
 
17
17
  const useStyles = createStyles(({ css, cx, responsive, isDarkMode, token, stylish }) => ({
18
- cards: css`
19
- flex-direction: row;
20
- ${responsive.mobile} {
21
- flex-direction: column;
22
- width: 100%;
23
- }
24
- `,
25
18
  container: css`
26
19
  position: relative;
27
20
  width: 100%;
28
21
  border-radius: ${token.borderRadiusLG}px;
29
22
  `,
30
- content: cx(
31
- stylish.blurStrong,
32
- css`
33
- z-index: 2;
34
-
35
- flex-direction: row;
36
- justify-content: space-between;
37
-
38
- height: 88px;
39
- padding: 12px;
40
-
41
- background: ${rgba(token.colorBgContainer, isDarkMode ? 0.7 : 1)};
42
- border-radius: ${token.borderRadiusLG - 1}px;
43
-
44
- ${responsive.mobile} {
45
- flex-direction: column;
46
- gap: 16px;
47
- align-items: flex-start;
48
-
49
- width: 100%;
50
- padding: 8px;
51
- }
52
- `,
53
- ),
23
+ content: css`
24
+ z-index: 2;
25
+ padding: 8px;
26
+ background: ${rgba(token.colorBgContainer, isDarkMode ? 0.7 : 1)};
27
+ border-radius: ${token.borderRadiusLG - 1}px;
28
+ `,
54
29
  glow: cx(
55
30
  stylish.gradientAnimation,
56
31
  css`
@@ -90,15 +65,26 @@ const DeviceCard = memo<DeviceCardProps>(({ browser, os }) => {
90
65
  <Flexbox className={styles.container} padding={4}>
91
66
  <Flexbox horizontal paddingBlock={8} paddingInline={12}>
92
67
  <div>
93
- <Typography style={{ fontWeight: 'bold' }}>{t('sync.device.title')}</Typography>
68
+ <Typography style={{ fontSize: 18, fontWeight: 'bold' }}>
69
+ {t('sync.device.title')}
70
+ </Typography>
94
71
  </div>
95
72
  </Flexbox>
96
- <Flexbox align={'center'} className={styles.content} flex={1} padding={12}>
73
+ <Flexbox
74
+ align={'center'}
75
+ className={styles.content}
76
+ flex={1}
77
+ gap={16}
78
+ horizontal
79
+ justify={'space-between'}
80
+ padding={12}
81
+ wrap={'wrap'}
82
+ >
97
83
  <DeviceName />
98
- <Flexbox className={styles.cards} gap={12}>
84
+ <Flexbox flex={1} gap={12} horizontal>
99
85
  <Card icon={<SystemIcon title={os} />} title={os || t('sync.device.unknownOS')} />
100
86
  <Card
101
- icon={browser && <BrowserIcon browser={browser} size={32} />}
87
+ icon={browser && <BrowserIcon browser={browser} size={24} />}
102
88
  title={browser || t('sync.device.unknownBrowser')}
103
89
  />
104
90
  </Flexbox>
@@ -5,13 +5,13 @@ import { LucideDices } from 'lucide-react';
5
5
  import { memo, useState } from 'react';
6
6
  import { useTranslation } from 'react-i18next';
7
7
 
8
- import { generateRandomRoomName } from '../util';
8
+ import { generateRandomRoomName } from './generateRandomRoomName';
9
9
 
10
10
  interface ChannelNameInputProps extends Omit<InputProps, 'form'> {
11
11
  form: FormInstance;
12
12
  }
13
13
 
14
- const ChannelNameInput = memo<ChannelNameInputProps>(({ form, ...res }) => {
14
+ const ChannelNameInput = memo<ChannelNameInputProps>(({ form, ...rest }) => {
15
15
  const { t } = useTranslation('setting');
16
16
  const [loading, setLoading] = useState(false);
17
17
 
@@ -38,7 +38,7 @@ const ChannelNameInput = memo<ChannelNameInputProps>(({ form, ...res }) => {
38
38
  title={t('sync.webrtc.channelName.shuffle')}
39
39
  />
40
40
  }
41
- {...res}
41
+ {...rest}
42
42
  />
43
43
  );
44
44
  });
@@ -7,18 +7,18 @@ import { memo } from 'react';
7
7
  import { useTranslation } from 'react-i18next';
8
8
  import { Flexbox } from 'react-layout-kit';
9
9
 
10
+ import { useSyncSettings } from '@/app/(main)/settings/hooks/useSyncSettings';
10
11
  import { FORM_STYLE } from '@/const/layoutTokens';
11
12
  import SyncStatusInspector from '@/features/SyncStatusInspector';
12
13
  import { useUserStore } from '@/store/user';
13
14
 
14
- import { useSyncSettings } from '../../hooks/useSyncSettings';
15
15
  import ChannelNameInput from './ChannelNameInput';
16
16
 
17
17
  type SettingItemGroup = ItemGroup;
18
18
 
19
19
  const WebRTC = memo(() => {
20
20
  const { t } = useTranslation('setting');
21
- const [form] = AntForm.useForm();
21
+ const [form] = Form.useForm();
22
22
 
23
23
  const [setSettings] = useUserStore((s) => [s.setSettings]);
24
24
 
@@ -70,15 +70,14 @@ const WebRTC = memo(() => {
70
70
  </div>
71
71
  ),
72
72
  title: (
73
- <Flexbox gap={8} horizontal>
74
- {/* @ts-ignore */}
75
- <SiWebrtc />
76
- <Flexbox align={'baseline'} gap={8} horizontal>
73
+ <Flexbox align={'center'} gap={12} horizontal wrap={'wrap'}>
74
+ <Flexbox align={'center'} gap={8} horizontal>
75
+ <SiWebrtc style={{ flex: 'none' }} />
77
76
  {t('sync.webrtc.title')}
78
- <Typography.Text style={{ fontWeight: 'normal' }} type={'secondary'}>
79
- {t('sync.webrtc.desc')}
80
- </Typography.Text>
81
77
  </Flexbox>
78
+ <Typography.Text style={{ fontWeight: 'normal' }} type={'secondary'}>
79
+ {t('sync.webrtc.desc')}
80
+ </Typography.Text>
82
81
  </Flexbox>
83
82
  ),
84
83
  };
@@ -87,8 +86,10 @@ const WebRTC = memo(() => {
87
86
  <Form
88
87
  form={form}
89
88
  items={[config]}
89
+ itemsType={'group'}
90
90
  onFinish={setSettings}
91
91
  onValuesChange={setSettings}
92
+ variant={'pure'}
92
93
  {...FORM_STYLE}
93
94
  />
94
95
  );
@@ -1,28 +1,36 @@
1
1
  import { notFound } from 'next/navigation';
2
2
 
3
3
  import { serverFeatureFlags } from '@/config/server/featureFlags';
4
+ import { translation } from '@/server/translation';
4
5
  import { gerServerDeviceInfo, isMobileDevice } from '@/utils/responsive';
5
6
 
6
- import Alert from './Alert';
7
- import DeviceCard from './DeviceInfo';
8
- import PageTitle from './PageTitle';
9
- import WebRTC from './WebRTC';
7
+ import Alert from './features/Alert';
8
+ import DeviceInfo from './features/DeviceInfo';
9
+ import WebRTC from './features/WebRTC';
10
10
 
11
- export default () => {
12
- const enableWebrtc = serverFeatureFlags().enableWebrtc;
11
+ export const generateMetadata = async () => {
12
+ const { t } = await translation('setting');
13
+ return {
14
+ title: t('tab.sync'),
15
+ };
16
+ };
13
17
 
18
+ const Page = () => {
19
+ const enableWebrtc = serverFeatureFlags().enableWebrtc;
14
20
  if (!enableWebrtc) return notFound();
15
21
 
16
- const { os, browser } = gerServerDeviceInfo();
17
22
  const isMobile = isMobileDevice();
23
+ const { os, browser } = gerServerDeviceInfo();
18
24
 
19
25
  return (
20
26
  <>
21
- {isMobile && <Alert mobile />}
22
- <PageTitle />
23
- <DeviceCard browser={browser} os={os} />
27
+ <DeviceInfo browser={browser} os={os} />
24
28
  <WebRTC />
25
- {!isMobile && <Alert />}
29
+ <Alert mobile={isMobile} />
26
30
  </>
27
31
  );
28
32
  };
33
+
34
+ Page.displayName = 'SyncSetting';
35
+
36
+ export default Page;
@@ -0,0 +1,54 @@
1
+ 'use client';
2
+
3
+ import { Form, type ItemGroup } from '@lobehub/ui';
4
+ import { Select } from 'antd';
5
+ import isEqual from 'fast-deep-equal';
6
+ import { memo } from 'react';
7
+ import { useTranslation } from 'react-i18next';
8
+
9
+ import { FORM_STYLE } from '@/const/layoutTokens';
10
+ import { useUserStore } from '@/store/user';
11
+ import { settingsSelectors } from '@/store/user/selectors';
12
+
13
+ import { opeanaiSTTOptions, opeanaiTTSOptions } from './const';
14
+
15
+ type SettingItemGroup = ItemGroup;
16
+
17
+ const TTS_SETTING_KEY = 'tts';
18
+
19
+ const OpenAI = memo(() => {
20
+ const { t } = useTranslation('setting');
21
+ const [form] = Form.useForm();
22
+ const settings = useUserStore(settingsSelectors.currentSettings, isEqual);
23
+ const [setSettings] = useUserStore((s) => [s.setSettings]);
24
+
25
+ const openai: SettingItemGroup = {
26
+ children: [
27
+ {
28
+ children: <Select options={opeanaiTTSOptions} />,
29
+ label: t('settingTTS.openai.ttsModel'),
30
+ name: [TTS_SETTING_KEY, 'openAI', 'ttsModel'],
31
+ },
32
+ {
33
+ children: <Select options={opeanaiSTTOptions} />,
34
+ label: t('settingTTS.openai.sttModel'),
35
+ name: [TTS_SETTING_KEY, 'openAI', 'sttModel'],
36
+ },
37
+ ],
38
+ title: t('settingTTS.openai.title'),
39
+ };
40
+
41
+ return (
42
+ <Form
43
+ form={form}
44
+ initialValues={settings}
45
+ items={[openai]}
46
+ itemsType={'group'}
47
+ onValuesChange={setSettings}
48
+ variant={'pure'}
49
+ {...FORM_STYLE}
50
+ />
51
+ );
52
+ });
53
+
54
+ export default OpenAI;
@@ -1,8 +1,8 @@
1
+ 'use client';
2
+
1
3
  import { Form, type ItemGroup } from '@lobehub/ui';
2
- import { Form as AntForm, Select, Switch } from 'antd';
4
+ import { Select, Switch } from 'antd';
3
5
  import isEqual from 'fast-deep-equal';
4
- import { debounce } from 'lodash-es';
5
- import { Mic, Webhook } from 'lucide-react';
6
6
  import { memo } from 'react';
7
7
  import { useTranslation } from 'react-i18next';
8
8
 
@@ -10,15 +10,15 @@ import { FORM_STYLE } from '@/const/layoutTokens';
10
10
  import { useUserStore } from '@/store/user';
11
11
  import { settingsSelectors } from '@/store/user/selectors';
12
12
 
13
- import { opeanaiSTTOptions, opeanaiTTSOptions, sttOptions } from './options';
13
+ import { sttOptions } from './const';
14
14
 
15
15
  type SettingItemGroup = ItemGroup;
16
16
 
17
17
  const TTS_SETTING_KEY = 'tts';
18
18
 
19
- const TTS = memo(() => {
19
+ const STT = memo(() => {
20
20
  const { t } = useTranslation('setting');
21
- const [form] = AntForm.useForm();
21
+ const [form] = Form.useForm();
22
22
  const settings = useUserStore(settingsSelectors.currentSettings, isEqual);
23
23
  const [setSettings] = useUserStore((s) => [s.setSettings]);
24
24
 
@@ -39,36 +39,20 @@ const TTS = memo(() => {
39
39
  valuePropName: 'checked',
40
40
  },
41
41
  ],
42
- icon: Mic,
43
42
  title: t('settingTTS.stt'),
44
43
  };
45
44
 
46
- const openai: SettingItemGroup = {
47
- children: [
48
- {
49
- children: <Select options={opeanaiTTSOptions} />,
50
- label: t('settingTTS.openai.ttsModel'),
51
- name: [TTS_SETTING_KEY, 'openAI', 'ttsModel'],
52
- },
53
- {
54
- children: <Select options={opeanaiSTTOptions} />,
55
- label: t('settingTTS.openai.sttModel'),
56
- name: [TTS_SETTING_KEY, 'openAI', 'sttModel'],
57
- },
58
- ],
59
- icon: Webhook,
60
- title: t('settingTTS.openai.title'),
61
- };
62
-
63
45
  return (
64
46
  <Form
65
47
  form={form}
66
48
  initialValues={settings}
67
- items={[stt, openai]}
68
- onValuesChange={debounce(setSettings, 100)}
49
+ items={[stt]}
50
+ itemsType={'group'}
51
+ onValuesChange={setSettings}
52
+ variant={'pure'}
69
53
  {...FORM_STYLE}
70
54
  />
71
55
  );
72
56
  });
73
57
 
74
- export default TTS;
58
+ export default STT;
@@ -1,18 +1,24 @@
1
- 'use client';
1
+ import { translation } from '@/server/translation';
2
2
 
3
- import { memo } from 'react';
4
- import { useTranslation } from 'react-i18next';
3
+ import OpenAI from './features/OpenAI';
4
+ import STT from './features/STT';
5
5
 
6
- import PageTitle from '@/components/PageTitle';
6
+ export const generateMetadata = async () => {
7
+ const { t } = await translation('setting');
8
+ return {
9
+ title: t('tab.tts'),
10
+ };
11
+ };
7
12
 
8
- import TTS from './TTS';
9
-
10
- export default memo(() => {
11
- const { t } = useTranslation('setting');
13
+ const Page = () => {
12
14
  return (
13
15
  <>
14
- <PageTitle title={t('tab.tts')} />
15
- <TTS />
16
+ <STT />
17
+ <OpenAI />
16
18
  </>
17
19
  );
18
- });
20
+ };
21
+
22
+ Page.displayName = 'TtsSetting';
23
+
24
+ export default Page;