@lobehub/lobehub 2.0.0-next.72 → 2.0.0-next.73

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 (337) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/changelog/v1.json +9 -0
  3. package/next.config.ts +5 -5
  4. package/package.json +1 -1
  5. package/scripts/prebuild.mts +1 -1
  6. package/src/app/(backend)/trpc/desktop/[trpc]/route.ts +6 -6
  7. package/src/app/[variants]/(main)/(mobile)/me/(home)/__tests__/UserBanner.test.tsx +7 -4
  8. package/src/app/[variants]/(main)/(mobile)/me/(home)/__tests__/useCategory.test.tsx +4 -4
  9. package/src/app/[variants]/(main)/(mobile)/me/(home)/features/UserBanner.tsx +5 -6
  10. package/src/app/[variants]/(main)/(mobile)/me/(home)/features/useCategory.tsx +5 -8
  11. package/src/app/[variants]/(main)/(mobile)/me/(home)/index.tsx +25 -0
  12. package/src/app/[variants]/(main)/(mobile)/me/(home)/layout.tsx +13 -16
  13. package/src/app/[variants]/(main)/(mobile)/me/profile/features/Category.tsx +6 -6
  14. package/src/app/[variants]/(main)/(mobile)/me/profile/features/Header.tsx +3 -3
  15. package/src/app/[variants]/(main)/(mobile)/me/profile/index.tsx +16 -0
  16. package/src/app/[variants]/(main)/(mobile)/me/profile/layout.tsx +9 -11
  17. package/src/app/[variants]/(main)/(mobile)/me/settings/features/Header.tsx +3 -3
  18. package/src/app/[variants]/(main)/(mobile)/me/settings/features/useCategory.tsx +3 -4
  19. package/src/app/[variants]/(main)/(mobile)/me/settings/index.tsx +16 -0
  20. package/src/app/[variants]/(main)/(mobile)/me/settings/layout.tsx +15 -13
  21. package/src/app/[variants]/(main)/changelog/_layout/Desktop/index.tsx +6 -5
  22. package/src/app/[variants]/(main)/changelog/_layout/Mobile/Header.tsx +3 -3
  23. package/src/app/[variants]/(main)/changelog/_layout/Mobile/index.tsx +5 -5
  24. package/src/app/[variants]/(main)/changelog/features/Post.tsx +7 -4
  25. package/src/app/[variants]/(main)/changelog/index.tsx +55 -0
  26. package/src/app/[variants]/(main)/chat/_layout/Desktop/index.tsx +6 -7
  27. package/src/app/[variants]/(main)/chat/_layout/Mobile.tsx +3 -3
  28. package/src/app/[variants]/(main)/chat/components/WorkspaceLayout.tsx +1 -14
  29. package/src/app/[variants]/(main)/chat/components/conversation/features/ChatHydration/index.tsx +2 -2
  30. package/src/app/[variants]/(main)/chat/components/conversation/features/ChatInput/Desktop/MessageFromUrl.tsx +11 -13
  31. package/src/app/[variants]/(main)/chat/components/conversation/features/ChatInput/Desktop/index.tsx +0 -1
  32. package/src/app/[variants]/(main)/chat/components/conversation/features/ThreadHydration.tsx +2 -2
  33. package/src/app/[variants]/(main)/chat/components/topic/features/Topic/TopicListContent/TopicItem/TopicContent.tsx +20 -11
  34. package/src/app/[variants]/(main)/chat/features/PageTitle/index.tsx +1 -2
  35. package/src/app/[variants]/(main)/chat/index.tsx +29 -0
  36. package/src/app/[variants]/(main)/chat/session/features/SessionHydration.tsx +8 -6
  37. package/src/app/[variants]/(main)/chat/session/features/SessionListContent/Inbox/index.tsx +2 -4
  38. package/src/app/[variants]/(main)/chat/session/features/SessionListContent/List/index.tsx +1 -1
  39. package/src/app/[variants]/(main)/chat/session/layout/Mobile/SessionHeader.tsx +3 -3
  40. package/src/app/[variants]/(main)/chat/settings/_layout/Desktop/Header.tsx +3 -3
  41. package/src/app/[variants]/(main)/chat/settings/_layout/Mobile/Header.tsx +3 -3
  42. package/src/app/[variants]/(main)/chat/settings/features/PublishResultModal/index.tsx +3 -3
  43. package/src/app/[variants]/(main)/chat/{components/SettingsPage.tsx → settings/index.tsx} +6 -35
  44. package/src/app/[variants]/(main)/components/Link.tsx +21 -0
  45. package/src/app/[variants]/(main)/discover/(detail)/_layout/{Desktop.tsx → Desktop/index.tsx} +15 -7
  46. package/src/app/[variants]/(main)/discover/(detail)/_layout/Mobile/index.tsx +3 -3
  47. package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Details/Capabilities/Block.tsx +1 -1
  48. package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Details/Overview/index.tsx +1 -1
  49. package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Details/Related/index.tsx +2 -2
  50. package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Details/SystemRole/index.tsx +3 -3
  51. package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Details/Versions/index.tsx +4 -4
  52. package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Details/index.tsx +1 -1
  53. package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Header.tsx +2 -2
  54. package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Sidebar/ActionButton/AddAgent.tsx +3 -3
  55. package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Sidebar/ActionButton/index.tsx +1 -1
  56. package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Sidebar/Related/index.tsx +1 -1
  57. package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Sidebar/TocList/index.tsx +2 -2
  58. package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/StatusPage/index.tsx +3 -3
  59. package/src/app/[variants]/(main)/discover/(detail)/assistant/{AssistantDetailPage.tsx → index.tsx} +18 -11
  60. package/src/app/[variants]/(main)/discover/(detail)/features/Breadcrumb.tsx +1 -1
  61. package/src/app/[variants]/(main)/discover/(detail)/mcp/{[slug]/features → features}/Details/Related/index.tsx +2 -2
  62. package/src/app/[variants]/(main)/discover/(detail)/mcp/{[slug]/features → features}/Details/Versions/index.tsx +5 -5
  63. package/src/app/[variants]/(main)/discover/(detail)/mcp/{[slug]/features → features}/Details/index.tsx +1 -1
  64. package/src/app/[variants]/(main)/discover/(detail)/mcp/{[slug]/features → features}/Sidebar/Related/index.tsx +2 -2
  65. package/src/app/[variants]/(main)/discover/(detail)/mcp/{[slug]/features → features}/Sidebar/ServerConfig.tsx +4 -4
  66. package/src/app/[variants]/(main)/discover/(detail)/mcp/{[slug]/features → features}/Sidebar/TocList/index.tsx +2 -2
  67. package/src/app/[variants]/(main)/discover/(detail)/mcp/{McpDetailPage.tsx → index.tsx} +15 -7
  68. package/src/app/[variants]/(main)/discover/(detail)/mcp/loading.tsx +1 -0
  69. package/src/app/[variants]/(main)/discover/(detail)/model/{[...slugs]/features → features}/Details/Overview/index.tsx +1 -1
  70. package/src/app/[variants]/(main)/discover/(detail)/model/{[...slugs]/features → features}/Details/Parameter/ParameterItem.tsx +1 -1
  71. package/src/app/[variants]/(main)/discover/(detail)/model/{[...slugs]/features → features}/Details/Related/index.tsx +2 -2
  72. package/src/app/[variants]/(main)/discover/(detail)/model/{[...slugs]/features → features}/Details/index.tsx +1 -1
  73. package/src/app/[variants]/(main)/discover/(detail)/model/{[...slugs]/features → features}/Header.tsx +1 -1
  74. package/src/app/[variants]/(main)/discover/(detail)/model/{[...slugs]/features → features}/Sidebar/ActionButton/ChatWithModel.tsx +3 -3
  75. package/src/app/[variants]/(main)/discover/(detail)/model/{[...slugs]/features → features}/Sidebar/ActionButton/index.tsx +1 -1
  76. package/src/app/[variants]/(main)/discover/(detail)/model/{[...slugs]/features → features}/Sidebar/Related/index.tsx +2 -2
  77. package/src/app/[variants]/(main)/discover/(detail)/model/{[...slugs]/features → features}/Sidebar/RelatedProviders/index.tsx +1 -1
  78. package/src/app/[variants]/(main)/discover/(detail)/model/{ModelDetailPage.tsx → index.tsx} +17 -10
  79. package/src/app/[variants]/(main)/discover/(detail)/model/loading.tsx +1 -0
  80. package/src/app/[variants]/(main)/discover/(detail)/provider/{[...slugs]/features → features}/Details/Related/index.tsx +2 -2
  81. package/src/app/[variants]/(main)/discover/(detail)/provider/{[...slugs]/features → features}/Details/index.tsx +1 -1
  82. package/src/app/[variants]/(main)/discover/(detail)/provider/{[...slugs]/features → features}/Sidebar/ActionButton/ProviderConfig.tsx +5 -4
  83. package/src/app/[variants]/(main)/discover/(detail)/provider/{[...slugs]/features → features}/Sidebar/ActionButton/index.tsx +1 -1
  84. package/src/app/[variants]/(main)/discover/(detail)/provider/{[...slugs]/features → features}/Sidebar/Related/index.tsx +2 -2
  85. package/src/app/[variants]/(main)/discover/(detail)/provider/{[...slugs]/features → features}/Sidebar/RelatedModels/index.tsx +1 -1
  86. package/src/app/[variants]/(main)/discover/(detail)/provider/{ProviderDetailPage.tsx → index.tsx} +17 -10
  87. package/src/app/[variants]/(main)/discover/(detail)/provider/loading.tsx +1 -0
  88. package/src/app/[variants]/(main)/discover/(list)/(home)/{HomePage.tsx → index.tsx} +14 -0
  89. package/src/app/[variants]/(main)/discover/(list)/_layout/Desktop/Nav.tsx +2 -3
  90. package/src/app/[variants]/(main)/discover/(list)/_layout/Desktop/index.tsx +4 -3
  91. package/src/app/[variants]/(main)/discover/(list)/_layout/Mobile/Nav.tsx +3 -4
  92. package/src/app/[variants]/(main)/discover/(list)/_layout/Mobile/index.tsx +4 -3
  93. package/src/app/[variants]/(main)/discover/(list)/assistant/_layout/Desktop.tsx +3 -4
  94. package/src/app/[variants]/(main)/discover/(list)/assistant/_layout/Mobile.tsx +3 -3
  95. package/src/app/[variants]/(main)/discover/(list)/assistant/features/List/Item.tsx +2 -2
  96. package/src/app/[variants]/(main)/discover/(list)/assistant/{AssistantPage.tsx → index.tsx} +18 -4
  97. package/src/app/[variants]/(main)/discover/(list)/features/SortButton/index.tsx +2 -2
  98. package/src/app/[variants]/(main)/discover/(list)/mcp/_layout/Desktop.tsx +3 -3
  99. package/src/app/[variants]/(main)/discover/(list)/mcp/_layout/Mobile.tsx +3 -3
  100. package/src/app/[variants]/(main)/discover/(list)/mcp/features/List/Item.tsx +1 -1
  101. package/src/app/[variants]/(main)/discover/(list)/mcp/{McpPage.tsx → index.tsx} +9 -2
  102. package/src/app/[variants]/(main)/discover/(list)/model/_layout/Desktop.tsx +3 -3
  103. package/src/app/[variants]/(main)/discover/(list)/model/_layout/Mobile.tsx +3 -3
  104. package/src/app/[variants]/(main)/discover/(list)/model/features/List/Item.tsx +1 -1
  105. package/src/app/[variants]/(main)/discover/(list)/model/{ModelPage.tsx → index.tsx} +9 -2
  106. package/src/app/[variants]/(main)/discover/(list)/provider/features/List/Item.tsx +1 -1
  107. package/src/app/[variants]/(main)/discover/(list)/provider/{Client.tsx → index.tsx} +9 -2
  108. package/src/app/[variants]/(main)/discover/_layout/Desktop/index.tsx +4 -4
  109. package/src/app/[variants]/(main)/discover/_layout/Mobile/index.tsx +3 -3
  110. package/src/app/[variants]/(main)/discover/components/Title.tsx +1 -1
  111. package/src/app/[variants]/(main)/discover/features/Search.tsx +2 -2
  112. package/src/app/[variants]/(main)/discover/features/useNav.tsx +11 -12
  113. package/src/app/[variants]/(main)/hooks/useActiveTabKey.ts +40 -0
  114. package/src/app/[variants]/(main)/hooks/usePathname.ts +10 -0
  115. package/src/app/[variants]/(main)/hooks/useQuery.ts +12 -0
  116. package/src/app/[variants]/(main)/hooks/useRouter.ts +22 -0
  117. package/src/app/[variants]/(main)/hooks/useSearchParams.ts +11 -0
  118. package/src/app/[variants]/(main)/image/@menu/features/ConfigPanel/components/ModelSelect/index.tsx +5 -5
  119. package/src/app/[variants]/(main)/image/@topic/features/Topics/TopicUrlSync.tsx +1 -1
  120. package/src/app/[variants]/(main)/image/ComingSoon.tsx +15 -0
  121. package/src/app/[variants]/(main)/image/_layout/Desktop/index.tsx +5 -2
  122. package/src/app/[variants]/(main)/image/_layout/DesktopWrapper.tsx +15 -0
  123. package/src/app/[variants]/(main)/image/_layout/Mobile/index.tsx +3 -1
  124. package/src/app/[variants]/(main)/image/features/ImageWorkspace/index.tsx +1 -2
  125. package/src/app/[variants]/(main)/image/index.tsx +18 -0
  126. package/src/app/[variants]/(main)/knowledge/_layout/Desktop.tsx +17 -0
  127. package/src/app/[variants]/(main)/knowledge/_layout/Mobile.tsx +17 -0
  128. package/src/app/[variants]/(main)/knowledge/components/KnowledgeBaseItem/index.tsx +1 -1
  129. package/src/app/[variants]/(main)/knowledge/components/modal/ModalPageClient.tsx +4 -4
  130. package/src/app/[variants]/(main)/knowledge/routes/KnowledgeBaseDetail/index.tsx +5 -8
  131. package/src/app/[variants]/(main)/knowledge/routes/KnowledgeBaseDetail/menu/Head.tsx +1 -1
  132. package/src/app/[variants]/(main)/knowledge/routes/KnowledgeHome/menu/CategoryMenu.tsx +2 -2
  133. package/src/app/[variants]/(main)/knowledge/routes/KnowledgeHome/menu/KnowledgeBase.tsx +1 -1
  134. package/src/app/[variants]/(main)/{_layout/Desktop → layouts/desktop}/DesktopLayoutContainer.tsx +3 -2
  135. package/src/app/[variants]/(main)/{_layout/Desktop → layouts/desktop}/SideBar/BottomActions.tsx +4 -4
  136. package/src/app/[variants]/(main)/{_layout/Desktop → layouts/desktop}/SideBar/TopActions.test.tsx +9 -9
  137. package/src/app/[variants]/(main)/layouts/desktop/SideBar/TopActions.tsx +117 -0
  138. package/src/app/[variants]/(main)/{_layout/Desktop → layouts/desktop}/index.tsx +9 -4
  139. package/src/app/[variants]/(main)/layouts/index.tsx +11 -0
  140. package/src/app/[variants]/(main)/{_layout/Mobile → layouts/mobile}/NavBar.tsx +5 -5
  141. package/src/app/[variants]/(main)/{_layout/Mobile → layouts/mobile}/index.tsx +10 -7
  142. package/src/app/[variants]/(main)/profile/(home)/desktop.tsx +26 -0
  143. package/src/app/[variants]/(main)/profile/(home)/index.tsx +26 -0
  144. package/src/app/[variants]/(main)/profile/@category/features/CategoryContent.tsx +5 -7
  145. package/src/app/[variants]/(main)/profile/_layout/Desktop/index.tsx +3 -2
  146. package/src/app/[variants]/(main)/profile/_layout/DesktopWrapper.tsx +14 -0
  147. package/src/app/[variants]/(main)/profile/_layout/Mobile/Header.tsx +3 -3
  148. package/src/app/[variants]/(main)/profile/_layout/Mobile/index.tsx +4 -3
  149. package/src/app/[variants]/(main)/profile/apikey/index.tsx +18 -0
  150. package/src/app/[variants]/(main)/profile/hooks/useCategory.tsx +6 -6
  151. package/src/app/[variants]/(main)/profile/security/index.tsx +29 -0
  152. package/src/app/[variants]/(main)/profile/stats/features/AssistantsRank.tsx +4 -4
  153. package/src/app/[variants]/(main)/profile/stats/features/TopicsRank.tsx +4 -4
  154. package/src/app/[variants]/(main)/profile/stats/index.tsx +20 -0
  155. package/src/app/[variants]/(main)/profile/usage/features/UsageTable.tsx +7 -9
  156. package/src/app/[variants]/(main)/profile/usage/index.tsx +13 -0
  157. package/src/app/[variants]/(main)/settings/_layout/Desktop/Header.tsx +2 -2
  158. package/src/app/[variants]/(main)/settings/_layout/Desktop/index.tsx +2 -2
  159. package/src/app/[variants]/(main)/settings/_layout/DesktopWrapper.tsx +23 -0
  160. package/src/app/[variants]/(main)/settings/_layout/Mobile/Header.tsx +8 -7
  161. package/src/app/[variants]/(main)/settings/_layout/Mobile/index.tsx +2 -5
  162. package/src/app/[variants]/(main)/settings/_layout/MobileWrapper.tsx +23 -0
  163. package/src/app/[variants]/(main)/settings/agent/AgentMenu/Menu.tsx +2 -4
  164. package/src/app/[variants]/(main)/settings/agent/index.tsx +2 -4
  165. package/src/app/[variants]/(main)/settings/provider/(list)/index.tsx +2 -3
  166. package/src/app/[variants]/(main)/settings/provider/ProviderMenu/All.tsx +2 -2
  167. package/src/app/[variants]/(main)/settings/provider/ProviderMenu/Item.tsx +38 -37
  168. package/src/app/[variants]/(main)/settings/provider/_layout/Mobile.tsx +2 -2
  169. package/src/app/[variants]/(main)/settings/provider/features/CreateNewProvider/index.tsx +3 -3
  170. package/src/app/[variants]/(main)/settings/provider/features/ProviderConfig/UpdateProviderInfo/SettingModal.tsx +3 -3
  171. package/src/app/[variants]/DesktopRouter.tsx +40 -0
  172. package/src/app/[variants]/MobileRouter.tsx +41 -0
  173. package/src/app/[variants]/desktopRouter.config.tsx +381 -0
  174. package/src/app/[variants]/layout.tsx +1 -3
  175. package/src/app/[variants]/loaders/routeParams.ts +45 -0
  176. package/src/app/[variants]/loading/Server/Redirect.tsx +1 -1
  177. package/src/app/[variants]/mobileRouter.config.tsx +412 -0
  178. package/src/app/[variants]/page.tsx +16 -6
  179. package/src/app/desktop/devtools/page.tsx +1 -1
  180. package/src/app/desktop/layout.tsx +1 -1
  181. package/src/components/BootErrorBoundary/index.tsx +129 -0
  182. package/src/components/mdx/constants.ts +1 -0
  183. package/src/features/ChangelogModal/index.tsx +3 -3
  184. package/src/features/KnowledgeManager/FileExplorer/index.tsx +4 -4
  185. package/src/features/KnowledgeManager/Header/FilesSearchBar.tsx +1 -1
  186. package/src/features/User/UserPanel/PanelContent.tsx +4 -3
  187. package/src/features/User/UserPanel/useMenu.tsx +20 -14
  188. package/src/features/User/__tests__/PanelContent.test.tsx +13 -7
  189. package/src/hooks/useDiscoverTab.ts +2 -2
  190. package/src/hooks/useInterceptingRoutes.test.ts +23 -26
  191. package/src/hooks/useInterceptingRoutes.ts +5 -4
  192. package/src/hooks/usePinnedAgentState.ts +6 -6
  193. package/src/hooks/useQuery.ts +5 -0
  194. package/src/hooks/useQueryParam.ts +322 -0
  195. package/src/hooks/useQueryRoute.test.ts +2 -12
  196. package/src/hooks/useQueryRoute.ts +5 -5
  197. package/src/hooks/useShowMobileWorkspace.ts +1 -1
  198. package/src/hooks/useSwitchSession.ts +4 -3
  199. package/src/layout/GlobalProvider/ImportSettings.tsx +22 -9
  200. package/src/layout/GlobalProvider/StoreInitialization.tsx +9 -1
  201. package/src/proxy.ts +13 -1
  202. package/src/services/message/index.ts +11 -2
  203. package/src/store/chat/agents/createAgentExecutors.ts +31 -16
  204. package/src/store/chat/slices/aiChat/actions/__tests__/streamingExecutor.test.ts +218 -0
  205. package/src/store/chat/slices/aiChat/actions/conversationControl.ts +4 -0
  206. package/src/store/chat/slices/aiChat/actions/conversationLifecycle.ts +9 -3
  207. package/src/store/chat/slices/aiChat/actions/streamingExecutor.ts +142 -61
  208. package/src/store/chat/slices/builtinTool/actions/__tests__/search.test.ts +204 -10
  209. package/src/store/chat/slices/builtinTool/actions/search.ts +51 -26
  210. package/src/store/chat/slices/message/action.test.ts +182 -33
  211. package/src/store/chat/slices/message/actions/optimisticUpdate.ts +79 -36
  212. package/src/store/chat/slices/message/actions/query.ts +7 -5
  213. package/src/store/chat/slices/message/selectors/dbMessage.ts +11 -4
  214. package/src/store/chat/slices/plugin/action.test.ts +257 -54
  215. package/src/store/chat/slices/plugin/actions/optimisticUpdate.ts +63 -26
  216. package/src/store/chat/slices/plugin/actions/pluginTypes.ts +52 -19
  217. package/src/store/chat/slices/plugin/actions/publicApi.ts +6 -1
  218. package/src/store/chat/slices/plugin/actions/workflow.ts +17 -6
  219. package/src/store/chat/slices/thread/action.ts +2 -0
  220. package/src/store/global/action.test.ts +3 -3
  221. package/src/store/global/actions/workspacePane.ts +2 -1
  222. package/src/store/global/initialState.ts +10 -2
  223. package/src/store/user/slices/common/action.ts +4 -0
  224. package/src/app/[variants]/(main)/(mobile)/me/(home)/loading.tsx +0 -38
  225. package/src/app/[variants]/(main)/(mobile)/me/(home)/page.tsx +0 -40
  226. package/src/app/[variants]/(main)/(mobile)/me/profile/loading.tsx +0 -5
  227. package/src/app/[variants]/(main)/(mobile)/me/profile/page.tsx +0 -30
  228. package/src/app/[variants]/(main)/(mobile)/me/settings/loading.tsx +0 -5
  229. package/src/app/[variants]/(main)/(mobile)/me/settings/page.tsx +0 -30
  230. package/src/app/[variants]/(main)/_layout/Desktop/SideBar/TopActions.tsx +0 -106
  231. package/src/app/[variants]/(main)/changelog/layout.tsx +0 -10
  232. package/src/app/[variants]/(main)/changelog/modal/page.tsx +0 -23
  233. package/src/app/[variants]/(main)/changelog/page.tsx +0 -78
  234. package/src/app/[variants]/(main)/chat/ChatRouter.tsx +0 -83
  235. package/src/app/[variants]/(main)/chat/_layout/ChatLayout.tsx +0 -22
  236. package/src/app/[variants]/(main)/chat/components/MainChatPage.tsx +0 -25
  237. package/src/app/[variants]/(main)/chat/error.tsx +0 -3
  238. package/src/app/[variants]/(main)/chat/layout.tsx +0 -10
  239. package/src/app/[variants]/(main)/chat/loading.tsx +0 -3
  240. package/src/app/[variants]/(main)/chat/not-found.tsx +0 -1
  241. package/src/app/[variants]/(main)/chat/page.tsx +0 -12
  242. package/src/app/[variants]/(main)/chat/settings/error.tsx +0 -3
  243. package/src/app/[variants]/(main)/chat/settings/loading.tsx +0 -3
  244. package/src/app/[variants]/(main)/chat/settings/not-found.tsx +0 -1
  245. package/src/app/[variants]/(main)/discover/(detail)/_layout/DetailLayout.tsx +0 -22
  246. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/Client.tsx +0 -51
  247. package/src/app/[variants]/(main)/discover/(detail)/mcp/[slug]/Client.tsx +0 -43
  248. package/src/app/[variants]/(main)/discover/(detail)/mcp/[slug]/loading.tsx +0 -1
  249. package/src/app/[variants]/(main)/discover/(detail)/model/[...slugs]/Client.tsx +0 -40
  250. package/src/app/[variants]/(main)/discover/(detail)/model/[...slugs]/loading.tsx +0 -1
  251. package/src/app/[variants]/(main)/discover/(detail)/provider/[...slugs]/Client.tsx +0 -40
  252. package/src/app/[variants]/(main)/discover/(detail)/provider/[...slugs]/loading.tsx +0 -1
  253. package/src/app/[variants]/(main)/discover/(list)/_layout/ListLayout.tsx +0 -22
  254. package/src/app/[variants]/(main)/discover/(list)/assistant/AssistantLayout.tsx +0 -21
  255. package/src/app/[variants]/(main)/discover/(list)/mcp/Client.tsx +0 -44
  256. package/src/app/[variants]/(main)/discover/(list)/mcp/McpLayout.tsx +0 -21
  257. package/src/app/[variants]/(main)/discover/(list)/model/Client.tsx +0 -44
  258. package/src/app/[variants]/(main)/discover/(list)/model/ModelLayout.tsx +0 -21
  259. package/src/app/[variants]/(main)/discover/(list)/provider/ProviderPage.tsx +0 -43
  260. package/src/app/[variants]/(main)/discover/DiscoverRouter.tsx +0 -170
  261. package/src/app/[variants]/(main)/discover/[[...path]]/page.tsx +0 -12
  262. package/src/app/[variants]/(main)/discover/_layout/DiscoverLayout.tsx +0 -22
  263. package/src/app/[variants]/(main)/discover/error.tsx +0 -3
  264. package/src/app/[variants]/(main)/discover/not-found.tsx +0 -1
  265. package/src/app/[variants]/(main)/error.tsx +0 -3
  266. package/src/app/[variants]/(main)/image/layout.tsx +0 -15
  267. package/src/app/[variants]/(main)/image/page.tsx +0 -45
  268. package/src/app/[variants]/(main)/knowledge/KnowledgeRouter.tsx +0 -74
  269. package/src/app/[variants]/(main)/knowledge/[[...path]]/page.tsx +0 -12
  270. package/src/app/[variants]/(main)/knowledge/components/modal/page.tsx +0 -13
  271. package/src/app/[variants]/(main)/knowledge/layout.tsx +0 -12
  272. package/src/app/[variants]/(main)/layout.tsx +0 -10
  273. package/src/app/[variants]/(main)/not-found.tsx +0 -1
  274. package/src/app/[variants]/(main)/profile/apikey/page.tsx +0 -32
  275. package/src/app/[variants]/(main)/profile/error.tsx +0 -3
  276. package/src/app/[variants]/(main)/profile/layout.tsx +0 -11
  277. package/src/app/[variants]/(main)/profile/loading.tsx +0 -3
  278. package/src/app/[variants]/(main)/profile/not-found.tsx +0 -1
  279. package/src/app/[variants]/(main)/profile/security/page.tsx +0 -28
  280. package/src/app/[variants]/(main)/profile/stats/page.tsx +0 -23
  281. package/src/app/[variants]/(main)/profile/usage/page.tsx +0 -23
  282. package/src/app/[variants]/@modal/(.)changelog/modal/features/Cover.tsx +0 -48
  283. package/src/app/[variants]/@modal/(.)changelog/modal/features/Hero.tsx +0 -29
  284. package/src/app/[variants]/@modal/(.)changelog/modal/features/Post.tsx +0 -57
  285. package/src/app/[variants]/@modal/(.)changelog/modal/features/PublishedTime.tsx +0 -50
  286. package/src/app/[variants]/@modal/(.)changelog/modal/features/ReadDetail.tsx +0 -72
  287. package/src/app/[variants]/@modal/(.)changelog/modal/features/VersionTag.tsx +0 -26
  288. package/src/app/[variants]/@modal/(.)changelog/modal/layout.tsx +0 -41
  289. package/src/app/[variants]/@modal/(.)changelog/modal/loading.tsx +0 -10
  290. package/src/app/[variants]/@modal/(.)changelog/modal/page.tsx +0 -38
  291. package/src/app/[variants]/@modal/_layout/ModalLayout.tsx +0 -63
  292. package/src/app/[variants]/@modal/_layout/SettingModalLayout.tsx +0 -71
  293. package/src/app/[variants]/@modal/default.tsx +0 -3
  294. package/src/app/[variants]/@modal/error.tsx +0 -3
  295. package/src/app/[variants]/@modal/layout.tsx +0 -7
  296. package/src/app/[variants]/@modal/loading.tsx +0 -5
  297. /package/src/app/[variants]/{@modal/(.)changelog/modal → (main)/changelog}/features/Pagination.tsx +0 -0
  298. /package/src/app/[variants]/{@modal/(.)changelog/modal → (main)/changelog}/features/UpdateChangelogStatus.tsx +0 -0
  299. /package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/DetailProvider.tsx +0 -0
  300. /package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Details/Capabilities/Knowledge.tsx +0 -0
  301. /package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Details/Capabilities/KnowledgeItem.tsx +0 -0
  302. /package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Details/Capabilities/PluginItem.tsx +0 -0
  303. /package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Details/Capabilities/Plugins.tsx +0 -0
  304. /package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Details/Capabilities/index.tsx +0 -0
  305. /package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Details/Nav.tsx +0 -0
  306. /package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Details/Overview/TagList.tsx +0 -0
  307. /package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Details/SystemRole/TagList.tsx +0 -0
  308. /package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Sidebar/Related/Item.tsx +0 -0
  309. /package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Sidebar/Summary/index.tsx +0 -0
  310. /package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Sidebar/index.tsx +0 -0
  311. /package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/loading.tsx → loading.tsx} +0 -0
  312. /package/src/app/[variants]/(main)/discover/(detail)/mcp/{[slug]/features → features}/Sidebar/ActionButton/index.tsx +0 -0
  313. /package/src/app/[variants]/(main)/discover/(detail)/mcp/{[slug]/features → features}/Sidebar/ConnectionTypeAlert.tsx +0 -0
  314. /package/src/app/[variants]/(main)/discover/(detail)/mcp/{[slug]/features → features}/Sidebar/Related/Item.tsx +0 -0
  315. /package/src/app/[variants]/(main)/discover/(detail)/mcp/{[slug]/features → features}/Sidebar/index.tsx +0 -0
  316. /package/src/app/[variants]/(main)/discover/(detail)/model/{[...slugs]/features → features}/DetailProvider.tsx +0 -0
  317. /package/src/app/[variants]/(main)/discover/(detail)/model/{[...slugs]/features → features}/Details/Nav.tsx +0 -0
  318. /package/src/app/[variants]/(main)/discover/(detail)/model/{[...slugs]/features → features}/Details/Overview/ProviderList/index.tsx +0 -0
  319. /package/src/app/[variants]/(main)/discover/(detail)/model/{[...slugs]/features → features}/Details/Parameter/index.tsx +0 -0
  320. /package/src/app/[variants]/(main)/discover/(detail)/model/{[...slugs]/features → features}/Sidebar/Related/Item.tsx +0 -0
  321. /package/src/app/[variants]/(main)/discover/(detail)/model/{[...slugs]/features → features}/Sidebar/RelatedProviders/Item.tsx +0 -0
  322. /package/src/app/[variants]/(main)/discover/(detail)/model/{[...slugs]/features → features}/Sidebar/index.tsx +0 -0
  323. /package/src/app/[variants]/(main)/discover/(detail)/provider/{[...slugs]/features → features}/DetailProvider.tsx +0 -0
  324. /package/src/app/[variants]/(main)/discover/(detail)/provider/{[...slugs]/features → features}/Details/Guide/index.tsx +0 -0
  325. /package/src/app/[variants]/(main)/discover/(detail)/provider/{[...slugs]/features → features}/Details/Nav.tsx +0 -0
  326. /package/src/app/[variants]/(main)/discover/(detail)/provider/{[...slugs]/features → features}/Details/Overview/ModelList/index.tsx +0 -0
  327. /package/src/app/[variants]/(main)/discover/(detail)/provider/{[...slugs]/features → features}/Details/Overview/index.tsx +0 -0
  328. /package/src/app/[variants]/(main)/discover/(detail)/provider/{[...slugs]/features → features}/Header.tsx +0 -0
  329. /package/src/app/[variants]/(main)/discover/(detail)/provider/{[...slugs]/features → features}/Sidebar/Related/Item.tsx +0 -0
  330. /package/src/app/[variants]/(main)/discover/(detail)/provider/{[...slugs]/features → features}/Sidebar/RelatedModels/Item.tsx +0 -0
  331. /package/src/app/[variants]/(main)/discover/(detail)/provider/{[...slugs]/features → features}/Sidebar/index.tsx +0 -0
  332. /package/src/app/[variants]/(main)/labs/{page.tsx → index.tsx} +0 -0
  333. /package/src/app/[variants]/(main)/{_layout/Desktop → layouts/desktop}/RegisterHotkeys.tsx +0 -0
  334. /package/src/app/[variants]/(main)/{_layout/Desktop → layouts/desktop}/SideBar/Avatar.test.tsx +0 -0
  335. /package/src/app/[variants]/(main)/{_layout/Desktop → layouts/desktop}/SideBar/Avatar.tsx +0 -0
  336. /package/src/app/[variants]/(main)/{_layout/Desktop → layouts/desktop}/SideBar/PinList/index.tsx +0 -0
  337. /package/src/app/[variants]/(main)/{_layout/Desktop → layouts/desktop}/SideBar/index.tsx +0 -0
@@ -0,0 +1,412 @@
1
+ 'use client';
2
+
3
+ import { useEffect } from 'react';
4
+ import { type LoaderFunction, createBrowserRouter, redirect, useNavigate } from 'react-router-dom';
5
+
6
+ import Loading from '@/components/Loading/BrandTextLoading';
7
+ import { useGlobalStore } from '@/store/global';
8
+ import type { Locales } from '@/types/locale';
9
+
10
+ import MobileChangelogLayout from './(main)/changelog/_layout/Mobile';
11
+ import { MobileMainLayout } from './(main)/layouts/mobile';
12
+ import { idLoader, slugLoader } from './loaders/routeParams';
13
+
14
+ // Component to register navigate function in global store
15
+ const NavigatorRegistrar = () => {
16
+ const navigate = useNavigate();
17
+
18
+ useEffect(() => {
19
+ useGlobalStore.setState({ navigate });
20
+
21
+ return () => {
22
+ useGlobalStore.setState({ navigate: undefined });
23
+ };
24
+ }, [navigate]);
25
+
26
+ return null;
27
+ };
28
+
29
+ // Root layout wrapper component - just registers navigator and renders outlet
30
+ // Note: Mobile layout is provided by individual route components
31
+ const RootLayout = (props: { locale: Locales }) => (
32
+ <>
33
+ <NavigatorRegistrar />
34
+ <MobileMainLayout locale={props.locale} />
35
+ </>
36
+ );
37
+
38
+ // Hydration gate loader - waits for client state to be ready before rendering
39
+ const hydrationGateLoader: LoaderFunction = () => {
40
+ const { isAppHydrated } = useGlobalStore.getState();
41
+
42
+ // 如果状态已经就绪,直接放行
43
+ if (isAppHydrated) {
44
+ return null;
45
+ }
46
+
47
+ // 否则,返回一个 Promise,"暂停" 渲染
48
+ return new Promise((resolve) => {
49
+ console.log('[HydrationGate] Waiting for client state...');
50
+ // 订阅 useGlobalStore 的变化
51
+ const unsubscribe = useGlobalStore.subscribe((state) => {
52
+ if (state.isAppHydrated) {
53
+ console.log('[HydrationGate] Client state ready. Gate opened!');
54
+ unsubscribe(); // 清理订阅
55
+ resolve(null); // Promise 完成,门卫放行
56
+ }
57
+ });
58
+ });
59
+ };
60
+
61
+ // Create mobile router configuration
62
+ export const createMobileRouter = (locale: Locales) =>
63
+ createBrowserRouter([
64
+ {
65
+ HydrateFallback: () => <Loading />,
66
+ children: [
67
+ // Chat routes
68
+ {
69
+ children: [
70
+ {
71
+ index: true,
72
+ lazy: () =>
73
+ import('./(main)/chat/index').then((m) => ({
74
+ Component: m.MobileChatPage,
75
+ })),
76
+ },
77
+ {
78
+ lazy: () =>
79
+ import('./(main)/chat/settings').then((m) => ({
80
+ Component: m.default,
81
+ })),
82
+ path: 'settings',
83
+ },
84
+ ],
85
+ lazy: () =>
86
+ import('./(main)/chat/_layout/Mobile').then((m) => ({
87
+ Component: m.default,
88
+ })),
89
+ path: 'chat',
90
+ },
91
+
92
+ // Discover routes with nested structure
93
+ {
94
+ children: [
95
+ // List routes (with ListLayout)
96
+ {
97
+ children: [
98
+ {
99
+ index: true,
100
+ lazy: () =>
101
+ import('./(main)/discover/(list)/(home)/index').then((m) => ({
102
+ Component: m.MobileHomePage,
103
+ })),
104
+ },
105
+ {
106
+ children: [
107
+ {
108
+ lazy: () =>
109
+ import('./(main)/discover/(list)/assistant/index').then((m) => ({
110
+ Component: m.MobileAssistantPage,
111
+ })),
112
+ path: 'assistant',
113
+ },
114
+ ],
115
+ lazy: () =>
116
+ import('./(main)/discover/(list)/assistant/_layout/Mobile').then((m) => ({
117
+ Component: m.default,
118
+ })),
119
+ },
120
+ {
121
+ children: [
122
+ {
123
+ lazy: () =>
124
+ import('./(main)/discover/(list)/model/index').then((m) => ({
125
+ Component: m.MobileModelPage,
126
+ })),
127
+ path: 'model',
128
+ },
129
+ ],
130
+ lazy: () =>
131
+ import('./(main)/discover/(list)/model/_layout/Mobile').then((m) => ({
132
+ Component: m.default,
133
+ })),
134
+ },
135
+ {
136
+ lazy: () =>
137
+ import('./(main)/discover/(list)/provider/index').then((m) => ({
138
+ Component: m.MobileProviderPage,
139
+ })),
140
+ path: 'provider',
141
+ },
142
+ {
143
+ children: [
144
+ {
145
+ lazy: () =>
146
+ import('./(main)/discover/(list)/mcp/index').then((m) => ({
147
+ Component: m.MobileMcpPage,
148
+ })),
149
+ path: 'mcp',
150
+ },
151
+ ],
152
+ lazy: () =>
153
+ import('./(main)/discover/(list)/mcp/_layout/Mobile').then((m) => ({
154
+ Component: m.default,
155
+ })),
156
+ },
157
+ ],
158
+ lazy: () =>
159
+ import('./(main)/discover/(list)/_layout/Mobile/index').then((m) => ({
160
+ Component: m.default,
161
+ })),
162
+ },
163
+ // Detail routes (with DetailLayout)
164
+ {
165
+ children: [
166
+ {
167
+ lazy: () =>
168
+ import('./(main)/discover/(detail)/assistant/index').then((m) => ({
169
+ Component: m.MobileDiscoverAssistantDetailPage,
170
+ })),
171
+ loader: slugLoader,
172
+ path: 'assistant/:slug',
173
+ },
174
+ {
175
+ lazy: () =>
176
+ import('./(main)/discover/(detail)/model/index').then((m) => ({
177
+ Component: m.MobileModelPage,
178
+ })),
179
+ loader: slugLoader,
180
+ path: 'model/:slug',
181
+ },
182
+ {
183
+ lazy: () =>
184
+ import('./(main)/discover/(detail)/provider/index').then((m) => ({
185
+ Component: m.MobileProviderPage,
186
+ })),
187
+ loader: slugLoader,
188
+ path: 'provider/:slug',
189
+ },
190
+ {
191
+ lazy: () =>
192
+ import('./(main)/discover/(detail)/mcp/index').then((m) => ({
193
+ Component: m.MobileMcpPage,
194
+ })),
195
+ loader: slugLoader,
196
+ path: 'mcp/:slug',
197
+ },
198
+ ],
199
+ lazy: () =>
200
+ import('./(main)/discover/(detail)/_layout/Mobile/index').then((m) => ({
201
+ Component: m.default,
202
+ })),
203
+ },
204
+ ],
205
+ lazy: () =>
206
+ import('./(main)/discover/_layout/Mobile/index').then((m) => ({
207
+ Component: m.default,
208
+ })),
209
+ path: 'discover',
210
+ },
211
+
212
+ // Knowledge routes
213
+ {
214
+ children: [
215
+ {
216
+ index: true,
217
+ lazy: () =>
218
+ import('./(main)/knowledge/routes/KnowledgeHome').then((m) => ({
219
+ Component: m.default,
220
+ })),
221
+ },
222
+ {
223
+ lazy: () =>
224
+ import('./(main)/knowledge/routes/KnowledgeBasesList').then((m) => ({
225
+ Component: m.default,
226
+ })),
227
+ path: 'bases',
228
+ },
229
+ {
230
+ lazy: () =>
231
+ import('./(main)/knowledge/routes/KnowledgeBaseDetail').then((m) => ({
232
+ Component: m.default,
233
+ })),
234
+ loader: idLoader,
235
+ path: 'bases/:id',
236
+ },
237
+ ],
238
+ lazy: () =>
239
+ import('./(main)/knowledge/_layout/Mobile').then((m) => ({
240
+ Component: m.default,
241
+ })),
242
+ path: 'knowledge',
243
+ },
244
+
245
+ // Settings routes
246
+ {
247
+ children: [
248
+ {
249
+ index: true,
250
+ lazy: () =>
251
+ import('./(main)/settings/_layout/Mobile').then((m) => ({
252
+ Component: m.default,
253
+ })),
254
+ },
255
+ ],
256
+ lazy: () =>
257
+ import('./(main)/settings/_layout/MobileWrapper').then((m) => ({
258
+ Component: m.default,
259
+ })),
260
+ path: 'settings',
261
+ },
262
+
263
+ // Image routes
264
+ {
265
+ children: [
266
+ {
267
+ index: true,
268
+ lazy: () =>
269
+ import('./(main)/image/ComingSoon').then((m) => ({
270
+ Component: m.default,
271
+ })),
272
+ },
273
+ ],
274
+ lazy: () =>
275
+ import('./(main)/image/_layout/Mobile').then((m) => ({
276
+ Component: m.default,
277
+ })),
278
+ path: 'image',
279
+ },
280
+
281
+ // Labs routes
282
+ {
283
+ lazy: () =>
284
+ import('./(main)/labs').then((m) => ({
285
+ Component: m.default,
286
+ })),
287
+ path: 'labs',
288
+ },
289
+
290
+ // Changelog routes
291
+ {
292
+ children: [
293
+ {
294
+ index: true,
295
+ lazy: () =>
296
+ import('./(main)/changelog').then((m) => ({
297
+ Component: m.MobilePage,
298
+ })),
299
+ },
300
+ ],
301
+ element: <MobileChangelogLayout locale={locale} />,
302
+ path: 'changelog',
303
+ },
304
+
305
+ // Profile routes
306
+ {
307
+ children: [
308
+ {
309
+ index: true,
310
+ lazy: () =>
311
+ import('./(main)/profile/(home)').then((m) => ({
312
+ Component: m.default,
313
+ })),
314
+ },
315
+ {
316
+ lazy: () =>
317
+ import('./(main)/profile/apikey/index').then((m) => ({
318
+ Component: m.default,
319
+ })),
320
+ path: 'apikey',
321
+ },
322
+ {
323
+ lazy: () =>
324
+ import('./(main)/profile/security').then((m) => ({
325
+ Component: m.MobileProfileSecurityPage,
326
+ })),
327
+ path: 'security',
328
+ },
329
+ {
330
+ lazy: () =>
331
+ import('./(main)/profile/stats').then((m) => ({
332
+ Component: m.MobileProfileStatsPage,
333
+ })),
334
+ path: 'stats',
335
+ },
336
+ ],
337
+ lazy: () =>
338
+ import('./(main)/profile/_layout/Mobile').then((m) => ({
339
+ Component: m.default,
340
+ })),
341
+ path: 'profile',
342
+ },
343
+
344
+ // Me routes (mobile personal center)
345
+ {
346
+ children: [
347
+ {
348
+ children: [
349
+ {
350
+ index: true,
351
+ lazy: () =>
352
+ import('./(main)/(mobile)/me/(home)').then((m) => ({
353
+ Component: m.default,
354
+ })),
355
+ },
356
+ ],
357
+ lazy: () =>
358
+ import('./(main)/(mobile)/me/(home)/layout').then((m) => ({
359
+ Component: m.default,
360
+ })),
361
+ },
362
+ {
363
+ children: [
364
+ {
365
+ lazy: () =>
366
+ import('./(main)/(mobile)/me/profile').then((m) => ({
367
+ Component: m.default,
368
+ })),
369
+ path: 'profile',
370
+ },
371
+ ],
372
+ lazy: () =>
373
+ import('./(main)/(mobile)/me/profile/layout').then((m) => ({
374
+ Component: m.default,
375
+ })),
376
+ },
377
+ {
378
+ children: [
379
+ {
380
+ lazy: () =>
381
+ import('./(main)/(mobile)/me/settings').then((m) => ({
382
+ Component: m.default,
383
+ })),
384
+ path: 'settings',
385
+ },
386
+ ],
387
+ lazy: () =>
388
+ import('./(main)/(mobile)/me/settings/layout').then((m) => ({
389
+ Component: m.default,
390
+ })),
391
+ },
392
+ ],
393
+ path: 'me',
394
+ },
395
+
396
+ // Default route - redirect to chat
397
+ {
398
+ index: true,
399
+ loader: () => redirect('/chat', { status: 302 }),
400
+ },
401
+
402
+ // Catch-all route
403
+ {
404
+ loader: () => redirect('/chat', { status: 302 }),
405
+ path: '*',
406
+ },
407
+ ],
408
+ element: <RootLayout locale={locale} />,
409
+ loader: hydrationGateLoader,
410
+ path: '/',
411
+ },
412
+ ]);
@@ -1,9 +1,19 @@
1
- import { Metadata } from 'next';
1
+ import { DynamicLayoutProps } from '@/types/next';
2
+ import { RouteVariants } from '@/utils/server/routeVariants';
2
3
 
3
- import { getCanonicalUrl } from '@/server/utils/url';
4
+ export default async function Page(props: DynamicLayoutProps) {
5
+ // Get isMobile from variants parameter on server side
6
+ const isMobile = await RouteVariants.getIsMobile(props);
7
+ const { locale } = await RouteVariants.getVariantsFromProps(props);
4
8
 
5
- export const metadata: Metadata = {
6
- alternates: { canonical: getCanonicalUrl('/') },
7
- };
9
+ // Conditionally load and render based on device type
10
+ // Using native dynamic import ensures complete code splitting
11
+ // Mobile and Desktop bundles will be completely separate
12
+ if (isMobile) {
13
+ const { default: MobileRouter } = await import('./MobileRouter');
14
+ return <MobileRouter locale={locale} />;
15
+ }
8
16
 
9
- export { default } from './loading';
17
+ const { default: DesktopRouter } = await import('./DesktopRouter');
18
+ return <DesktopRouter locale={locale} />;
19
+ }
@@ -86,4 +86,4 @@ const DevTools = memo(() => {
86
86
  );
87
87
  });
88
88
 
89
- export default DevTools;
89
+ export default DevTools;
@@ -28,4 +28,4 @@ const RootLayout = async ({ children }: RootLayoutProps) => {
28
28
  );
29
29
  };
30
30
 
31
- export default RootLayout;
31
+ export default RootLayout;
@@ -0,0 +1,129 @@
1
+ 'use client';
2
+
3
+ import { Component, ErrorInfo, ReactNode } from 'react';
4
+
5
+ interface BootErrorBoundaryProps {
6
+ children: ReactNode;
7
+ fallback?: ReactNode;
8
+ /**
9
+ * Number of hard reload attempts we should try before giving up.
10
+ * Defaults to 1 to avoid reload loops.
11
+ */
12
+ maxBootReloads?: number;
13
+ }
14
+
15
+ interface BootErrorBoundaryState {
16
+ hasError: boolean;
17
+ }
18
+
19
+ const DEFAULT_MAX_RELOADS = 1;
20
+ const RELOAD_SESSION_KEY = 'lobe:boot:hard-reload-attempts';
21
+ const FORCE_RELOAD_QUERY_KEY = '__lobe_force_reload';
22
+
23
+ /**
24
+ * BootErrorBoundary guards the SPA bootstrap process. If we hit an error before
25
+ * the first successful render, we force a one-time hard refresh to pull the
26
+ * latest assets (similar to Cmd+Shift+R) to recover from cache mismatches.
27
+ */
28
+ class BootErrorBoundary extends Component<BootErrorBoundaryProps, BootErrorBoundaryState> {
29
+ public state: BootErrorBoundaryState = { hasError: false };
30
+
31
+ private hasBooted = false;
32
+
33
+ public componentDidMount() {
34
+ this.hasBooted = true;
35
+ this.resetReloadAttempts();
36
+ this.cleanForceReloadMarker();
37
+ }
38
+
39
+ public static getDerivedStateFromError(): BootErrorBoundaryState {
40
+ return { hasError: true };
41
+ }
42
+
43
+ public componentDidCatch(error: Error, errorInfo: ErrorInfo) {
44
+ // eslint-disable-next-line no-console
45
+ console.error('Unexpected boot error captured by BootErrorBoundary', error, errorInfo);
46
+
47
+ if (!this.hasBooted && this.tryHardReload()) {
48
+ return;
49
+ }
50
+ }
51
+
52
+ public render() {
53
+ if (this.state.hasError) {
54
+ return this.props.fallback ?? null;
55
+ }
56
+
57
+ return this.props.children;
58
+ }
59
+
60
+ private resetReloadAttempts() {
61
+ if (typeof window === 'undefined') return;
62
+ try {
63
+ window.sessionStorage.removeItem(RELOAD_SESSION_KEY);
64
+ } catch (error) {
65
+ // Access to sessionStorage can fail in restricted environments; ignore.
66
+ if (process.env.NODE_ENV === 'development') {
67
+ // eslint-disable-next-line no-console
68
+ console.warn('BootErrorBoundary failed to reset reload attempts', error);
69
+ }
70
+ }
71
+ }
72
+
73
+ private tryHardReload() {
74
+ if (typeof window === 'undefined') return false;
75
+
76
+ try {
77
+ const maxReloads = this.props.maxBootReloads ?? DEFAULT_MAX_RELOADS;
78
+ const attempts = Number(window.sessionStorage.getItem(RELOAD_SESSION_KEY) ?? '0');
79
+ const href = window.location.href;
80
+
81
+ if (attempts >= maxReloads) {
82
+ // eslint-disable-next-line no-console
83
+ console.warn('BootErrorBoundary reached max reload attempts', {
84
+ attempts,
85
+ href,
86
+ maxReloads,
87
+ });
88
+ return false;
89
+ }
90
+
91
+ // eslint-disable-next-line no-console
92
+ console.info('BootErrorBoundary forcing hard reload', { attempts, href, maxReloads });
93
+ window.sessionStorage.setItem(RELOAD_SESSION_KEY, String(attempts + 1));
94
+ } catch (error) {
95
+ // If sessionStorage is unavailable, we still attempt a reload once.
96
+ if (process.env.NODE_ENV === 'development') {
97
+ // eslint-disable-next-line no-console
98
+ console.warn('BootErrorBoundary failed to persist reload attempts', error);
99
+ }
100
+ }
101
+
102
+ this.forceHardReload();
103
+ return true;
104
+ }
105
+
106
+ private forceHardReload() {
107
+ const { location } = window;
108
+
109
+ // Append a cache-busting query parameter so the browser bypasses cached assets.
110
+ const url = new URL(location.href);
111
+ url.searchParams.set(FORCE_RELOAD_QUERY_KEY, Date.now().toString());
112
+
113
+ location.replace(url.toString());
114
+ }
115
+
116
+ private cleanForceReloadMarker() {
117
+ if (typeof window === 'undefined') return;
118
+ const { history, location } = window;
119
+
120
+ const url = new URL(location.href);
121
+
122
+ if (!url.searchParams.has(FORCE_RELOAD_QUERY_KEY)) return;
123
+
124
+ url.searchParams.delete(FORCE_RELOAD_QUERY_KEY);
125
+ history.replaceState(history.state, '', url.toString());
126
+ }
127
+ }
128
+
129
+ export default BootErrorBoundary;
@@ -0,0 +1 @@
1
+ export const DEFAULT_IMAGE_WIDTH = 800;
@@ -1,8 +1,8 @@
1
1
  'use client';
2
2
 
3
3
  import { useTimeout } from 'ahooks';
4
- import { useRouter } from 'next/navigation';
5
4
  import { memo } from 'react';
5
+ import { useNavigate } from 'react-router-dom';
6
6
 
7
7
  import { useGlobalStore } from '@/store/global';
8
8
 
@@ -11,14 +11,14 @@ const ChangelogModal = memo<{ currentId?: string }>(({ currentId }) => {
11
11
  s.status.latestChangelogId,
12
12
  s.updateSystemStatus,
13
13
  ]);
14
- const router = useRouter();
14
+ const navigate = useNavigate();
15
15
 
16
16
  useTimeout(() => {
17
17
  if (!currentId) return;
18
18
  if (!latestChangelogId) {
19
19
  updateSystemStatus({ latestChangelogId: currentId });
20
20
  } else if (latestChangelogId !== currentId) {
21
- router.push('/changelog/modal');
21
+ navigate('/changelog/modal');
22
22
  }
23
23
  }, 1000);
24
24
 
@@ -3,13 +3,13 @@
3
3
  import { Text } from '@lobehub/ui';
4
4
  import { VirtuosoMasonry } from '@virtuoso.dev/masonry';
5
5
  import { createStyles } from 'antd-style';
6
- import { useQueryState } from 'nuqs';
7
6
  import { rgba } from 'polished';
8
7
  import React, { memo, useMemo, useState } from 'react';
9
8
  import { useTranslation } from 'react-i18next';
10
9
  import { Center, Flexbox } from 'react-layout-kit';
11
10
  import { Virtuoso } from 'react-virtuoso';
12
11
 
12
+ import { useQueryState } from '@/hooks/useQueryParam';
13
13
  import { useFileStore } from '@/store/file';
14
14
  import { useGlobalStore } from '@/store/global';
15
15
  import { FilesTabs, SortType } from '@/types/files';
@@ -113,9 +113,9 @@ const FileExplorer = memo<FileExplorerProps>(({ knowledgeBaseId, category, onOpe
113
113
  const { data, isLoading } = useFetchKnowledgeItems({
114
114
  category,
115
115
  knowledgeBaseId,
116
- q: query,
117
- sortType,
118
- sorter,
116
+ q: query ?? undefined,
117
+ sortType: sortType ?? undefined,
118
+ sorter: sorter ?? undefined,
119
119
  ...viewConfig,
120
120
  });
121
121
 
@@ -1,10 +1,10 @@
1
1
  'use client';
2
2
 
3
3
  import { SearchBar } from '@lobehub/ui';
4
- import { useQueryState } from 'nuqs';
5
4
  import { memo, useEffect, useState } from 'react';
6
5
  import { useTranslation } from 'react-i18next';
7
6
 
7
+ import { useQueryState } from '@/hooks/useQueryParam';
8
8
  import { useUserStore } from '@/store/user';
9
9
  import { settingsSelectors } from '@/store/user/selectors';
10
10
  import { HotkeyEnum } from '@/types/hotkey';
@@ -1,5 +1,4 @@
1
- import { enableNextAuth, isDesktop } from '@lobechat/const';
2
- import Link from 'next/link';
1
+ import { Link } from 'react-router-dom';
3
2
  import { useRouter } from 'next/navigation';
4
3
  import { memo } from 'react';
5
4
  import { Flexbox } from 'react-layout-kit';
@@ -15,6 +14,8 @@ import UserLoginOrSignup from '../UserLoginOrSignup';
15
14
  import LangButton from './LangButton';
16
15
  import ThemeButton from './ThemeButton';
17
16
  import { useMenu } from './useMenu';
17
+ import { enableNextAuth } from '@/const/auth';
18
+ import { isDesktop } from '@/const/version';
18
19
 
19
20
  const PanelContent = memo<{ closePopover: () => void }>(({ closePopover }) => {
20
21
  const router = useRouter();
@@ -41,7 +42,7 @@ const PanelContent = memo<{ closePopover: () => void }>(({ closePopover }) => {
41
42
  <>
42
43
  <UserInfo avatarProps={{ clickable: false }} />
43
44
 
44
- <Link href={'/profile/stats'} style={{ color: 'inherit' }}>
45
+ <Link style={{ color: 'inherit' }} to={'/profile/stats'}>
45
46
  <DataStatistics />
46
47
  </Link>
47
48
  </>