@lobehub/chat 1.17.6 → 1.18.0

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.

Potentially problematic release.


This version of @lobehub/chat might be problematic. Click here for more details.

Files changed (339) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/locales/ar/common.json +1 -1
  3. package/locales/ar/discover.json +204 -0
  4. package/locales/ar/metadata.json +20 -3
  5. package/locales/ar/models.json +845 -0
  6. package/locales/ar/providers.json +80 -0
  7. package/locales/bg-BG/common.json +1 -1
  8. package/locales/bg-BG/discover.json +204 -0
  9. package/locales/bg-BG/metadata.json +20 -3
  10. package/locales/bg-BG/models.json +845 -0
  11. package/locales/bg-BG/providers.json +80 -0
  12. package/locales/de-DE/common.json +1 -1
  13. package/locales/de-DE/discover.json +204 -0
  14. package/locales/de-DE/metadata.json +20 -3
  15. package/locales/de-DE/models.json +845 -0
  16. package/locales/de-DE/providers.json +80 -0
  17. package/locales/en-US/common.json +1 -1
  18. package/locales/en-US/discover.json +204 -0
  19. package/locales/en-US/metadata.json +20 -3
  20. package/locales/en-US/models.json +845 -0
  21. package/locales/en-US/providers.json +80 -0
  22. package/locales/es-ES/common.json +1 -1
  23. package/locales/es-ES/discover.json +204 -0
  24. package/locales/es-ES/metadata.json +20 -3
  25. package/locales/es-ES/models.json +845 -0
  26. package/locales/es-ES/providers.json +80 -0
  27. package/locales/fr-FR/common.json +1 -1
  28. package/locales/fr-FR/discover.json +204 -0
  29. package/locales/fr-FR/metadata.json +20 -3
  30. package/locales/fr-FR/models.json +845 -0
  31. package/locales/fr-FR/providers.json +80 -0
  32. package/locales/it-IT/common.json +1 -1
  33. package/locales/it-IT/discover.json +204 -0
  34. package/locales/it-IT/metadata.json +20 -3
  35. package/locales/it-IT/models.json +845 -0
  36. package/locales/it-IT/providers.json +80 -0
  37. package/locales/ja-JP/common.json +1 -1
  38. package/locales/ja-JP/discover.json +204 -0
  39. package/locales/ja-JP/metadata.json +20 -3
  40. package/locales/ja-JP/models.json +845 -0
  41. package/locales/ja-JP/providers.json +80 -0
  42. package/locales/ko-KR/common.json +1 -1
  43. package/locales/ko-KR/discover.json +204 -0
  44. package/locales/ko-KR/metadata.json +20 -3
  45. package/locales/ko-KR/models.json +845 -0
  46. package/locales/ko-KR/providers.json +80 -0
  47. package/locales/nl-NL/common.json +1 -1
  48. package/locales/nl-NL/discover.json +204 -0
  49. package/locales/nl-NL/metadata.json +20 -3
  50. package/locales/nl-NL/models.json +845 -0
  51. package/locales/nl-NL/providers.json +80 -0
  52. package/locales/pl-PL/common.json +1 -1
  53. package/locales/pl-PL/discover.json +204 -0
  54. package/locales/pl-PL/metadata.json +20 -3
  55. package/locales/pl-PL/models.json +845 -0
  56. package/locales/pl-PL/providers.json +80 -0
  57. package/locales/pt-BR/common.json +1 -1
  58. package/locales/pt-BR/discover.json +204 -0
  59. package/locales/pt-BR/metadata.json +20 -3
  60. package/locales/pt-BR/models.json +845 -0
  61. package/locales/pt-BR/providers.json +80 -0
  62. package/locales/ru-RU/common.json +1 -1
  63. package/locales/ru-RU/discover.json +204 -0
  64. package/locales/ru-RU/metadata.json +20 -3
  65. package/locales/ru-RU/models.json +845 -0
  66. package/locales/ru-RU/providers.json +80 -0
  67. package/locales/tr-TR/common.json +1 -1
  68. package/locales/tr-TR/discover.json +204 -0
  69. package/locales/tr-TR/metadata.json +20 -3
  70. package/locales/tr-TR/models.json +845 -0
  71. package/locales/tr-TR/providers.json +80 -0
  72. package/locales/vi-VN/common.json +1 -1
  73. package/locales/vi-VN/discover.json +204 -0
  74. package/locales/vi-VN/metadata.json +20 -3
  75. package/locales/vi-VN/models.json +845 -0
  76. package/locales/vi-VN/providers.json +80 -0
  77. package/locales/zh-CN/common.json +1 -1
  78. package/locales/zh-CN/discover.json +204 -0
  79. package/locales/zh-CN/metadata.json +20 -3
  80. package/locales/zh-CN/models.json +845 -0
  81. package/locales/zh-CN/providers.json +80 -0
  82. package/locales/zh-CN/welcome.json +1 -1
  83. package/locales/zh-TW/common.json +1 -1
  84. package/locales/zh-TW/discover.json +204 -0
  85. package/locales/zh-TW/metadata.json +20 -3
  86. package/locales/zh-TW/models.json +845 -0
  87. package/locales/zh-TW/providers.json +80 -0
  88. package/package.json +3 -2
  89. package/src/app/(main)/@nav/_layout/Desktop/TopActions.test.tsx +3 -3
  90. package/src/app/(main)/@nav/_layout/Desktop/TopActions.tsx +3 -3
  91. package/src/app/(main)/@nav/_layout/Mobile.tsx +3 -3
  92. package/src/app/(main)/_layout/Mobile.tsx +9 -1
  93. package/src/app/(main)/discover/(detail)/_layout/Desktop.tsx +24 -0
  94. package/src/app/(main)/discover/(detail)/_layout/Mobile/Header.tsx +25 -0
  95. package/src/app/(main)/discover/(detail)/_layout/Mobile/index.tsx +17 -0
  96. package/src/app/(main)/discover/(detail)/assistant/[slug]/features/Actions.tsx +35 -0
  97. package/src/app/(main)/discover/(detail)/assistant/[slug]/features/AddAgent.tsx +86 -0
  98. package/src/app/(main)/discover/(detail)/assistant/[slug]/features/ConversationExample/TopicList.tsx +74 -0
  99. package/src/app/(main)/discover/(detail)/assistant/[slug]/features/ConversationExample/index.tsx +100 -0
  100. package/src/app/(main)/discover/(detail)/assistant/[slug]/features/Header.tsx +118 -0
  101. package/src/app/(main)/discover/(detail)/assistant/[slug]/features/InfoSidebar/SuggestionItem.tsx +62 -0
  102. package/src/app/(main)/discover/(detail)/assistant/[slug]/features/InfoSidebar/ToolItem.tsx +19 -0
  103. package/src/app/(main)/discover/(detail)/assistant/[slug]/features/InfoSidebar/index.tsx +64 -0
  104. package/src/app/(main)/discover/(detail)/assistant/[slug]/features/SystemRole.tsx +35 -0
  105. package/src/app/(main)/discover/(detail)/assistant/[slug]/features/Temp.tsx +44 -0
  106. package/src/app/(main)/discover/(detail)/assistant/[slug]/page.tsx +121 -0
  107. package/src/app/(main)/discover/(detail)/error.tsx +5 -0
  108. package/src/app/(main)/discover/(detail)/features/Back.tsx +42 -0
  109. package/src/app/(main)/discover/(detail)/features/Block.tsx +50 -0
  110. package/src/app/(main)/discover/(detail)/features/DetailLayout.tsx +91 -0
  111. package/src/app/(main)/discover/(detail)/features/HighlightBlock.tsx +82 -0
  112. package/src/app/(main)/discover/(detail)/features/ShareButton.tsx +160 -0
  113. package/src/app/(main)/discover/(detail)/features/SidebarContainer.tsx +19 -0
  114. package/src/app/(main)/discover/(detail)/layout.tsx +12 -0
  115. package/src/app/(main)/discover/(detail)/loading.tsx +38 -0
  116. package/src/app/(main)/discover/(detail)/model/[...slugs]/features/Actions.tsx +46 -0
  117. package/src/app/(main)/discover/(detail)/model/[...slugs]/features/ChatWithModel.tsx +93 -0
  118. package/src/app/(main)/discover/(detail)/model/[...slugs]/features/Header.tsx +85 -0
  119. package/src/app/(main)/discover/(detail)/model/[...slugs]/features/InfoSidebar/SuggestionItem.tsx +75 -0
  120. package/src/app/(main)/discover/(detail)/model/[...slugs]/features/InfoSidebar/index.tsx +49 -0
  121. package/src/app/(main)/discover/(detail)/model/[...slugs]/features/ParameterList/ParameterItem.tsx +71 -0
  122. package/src/app/(main)/discover/(detail)/model/[...slugs]/features/ParameterList/index.tsx +110 -0
  123. package/src/app/(main)/discover/(detail)/model/[...slugs]/features/ProviderList/ProviderItem.tsx +152 -0
  124. package/src/app/(main)/discover/(detail)/model/[...slugs]/features/ProviderList/index.tsx +45 -0
  125. package/src/app/(main)/discover/(detail)/model/[...slugs]/page.tsx +114 -0
  126. package/src/app/(main)/discover/(detail)/not-found.tsx +3 -0
  127. package/src/app/(main)/discover/(detail)/plugin/[slug]/features/Actions.tsx +35 -0
  128. package/src/app/(main)/discover/(detail)/plugin/[slug]/features/Header.tsx +114 -0
  129. package/src/app/(main)/discover/(detail)/plugin/[slug]/features/InfoSidebar/SuggestionItem.tsx +62 -0
  130. package/src/app/(main)/discover/(detail)/plugin/[slug]/features/InfoSidebar/index.tsx +49 -0
  131. package/src/app/(main)/discover/(detail)/plugin/[slug]/features/InstallPlugin.tsx +87 -0
  132. package/src/app/(main)/discover/(detail)/plugin/[slug]/features/ParameterList.tsx +95 -0
  133. package/src/app/(main)/discover/(detail)/plugin/[slug]/features/Schema.tsx +23 -0
  134. package/src/app/(main)/discover/(detail)/plugin/[slug]/page.tsx +103 -0
  135. package/src/app/(main)/discover/(detail)/provider/[slug]/features/Actions.tsx +49 -0
  136. package/src/app/(main)/discover/(detail)/provider/[slug]/features/Header.tsx +73 -0
  137. package/src/app/(main)/discover/(detail)/provider/[slug]/features/InfoSidebar/SuggestionItem.tsx +75 -0
  138. package/src/app/(main)/discover/(detail)/provider/[slug]/features/InfoSidebar/index.tsx +49 -0
  139. package/src/app/(main)/discover/(detail)/provider/[slug]/features/ModelList/ModelItem.tsx +148 -0
  140. package/src/app/(main)/discover/(detail)/provider/[slug]/features/ModelList/index.tsx +60 -0
  141. package/src/app/(main)/discover/(detail)/provider/[slug]/features/ProviderConfig.tsx +80 -0
  142. package/src/app/(main)/discover/(detail)/provider/[slug]/page.tsx +116 -0
  143. package/src/app/(main)/discover/(list)/(home)/Client.tsx +42 -0
  144. package/src/app/(main)/discover/(list)/(home)/features/AssistantList.tsx +33 -0
  145. package/src/app/(main)/discover/(list)/(home)/features/ModelList.tsx +22 -0
  146. package/src/app/(main)/discover/(list)/(home)/features/PluginList.tsx +25 -0
  147. package/src/app/(main)/discover/(list)/(home)/loading.tsx +1 -0
  148. package/src/app/(main)/discover/(list)/(home)/page.tsx +54 -0
  149. package/src/app/(main)/discover/(list)/_layout/Desktop/Nav.tsx +118 -0
  150. package/src/app/(main)/discover/(list)/_layout/Desktop/index.tsx +37 -0
  151. package/src/app/(main)/discover/(list)/_layout/Desktop/useScroll.ts +33 -0
  152. package/src/app/(main)/discover/(list)/_layout/Mobile/Header.tsx +62 -0
  153. package/src/app/(main)/discover/(list)/_layout/Mobile/Nav.tsx +94 -0
  154. package/src/app/(main)/discover/(list)/_layout/Mobile/index.tsx +27 -0
  155. package/src/app/(main)/discover/(list)/assistants/[slug]/page.tsx +64 -0
  156. package/src/app/(main)/discover/(list)/assistants/_layout/Desktop.tsx +22 -0
  157. package/src/app/(main)/discover/(list)/assistants/_layout/Mobile.tsx +9 -0
  158. package/src/app/(main)/discover/(list)/assistants/features/Card.tsx +176 -0
  159. package/src/app/(main)/discover/(list)/assistants/features/Category.tsx +48 -0
  160. package/src/app/(main)/discover/(list)/assistants/features/List.tsx +97 -0
  161. package/src/app/(main)/discover/(list)/assistants/features/useCategory.tsx +116 -0
  162. package/src/app/(main)/discover/(list)/assistants/layout.tsx +12 -0
  163. package/src/app/(main)/discover/(list)/assistants/loading.tsx +1 -0
  164. package/src/app/(main)/discover/(list)/assistants/page.tsx +51 -0
  165. package/src/app/(main)/discover/(list)/error.tsx +5 -0
  166. package/src/app/(main)/{market → discover/(list)}/layout.tsx +4 -3
  167. package/src/app/(main)/discover/(list)/loading.tsx +39 -0
  168. package/src/app/(main)/discover/(list)/models/[slug]/page.tsx +70 -0
  169. package/src/app/(main)/discover/(list)/models/_layout/Desktop.tsx +28 -0
  170. package/src/app/(main)/discover/(list)/models/_layout/Mobile.tsx +9 -0
  171. package/src/app/(main)/discover/(list)/models/features/Card.tsx +116 -0
  172. package/src/app/(main)/discover/(list)/models/features/Category.tsx +67 -0
  173. package/src/app/(main)/discover/(list)/models/features/List.tsx +72 -0
  174. package/src/app/(main)/discover/(list)/models/features/const.ts +9 -0
  175. package/src/app/(main)/discover/(list)/models/layout.tsx +12 -0
  176. package/src/app/(main)/discover/(list)/models/loading.tsx +1 -0
  177. package/src/app/(main)/discover/(list)/models/page.tsx +61 -0
  178. package/src/app/(main)/discover/(list)/not-found.tsx +3 -0
  179. package/src/app/(main)/discover/(list)/plugins/[slug]/page.tsx +64 -0
  180. package/src/app/(main)/discover/(list)/plugins/_layout/Desktop.tsx +22 -0
  181. package/src/app/(main)/discover/(list)/plugins/_layout/Mobile.tsx +9 -0
  182. package/src/app/(main)/discover/(list)/plugins/features/Card.tsx +154 -0
  183. package/src/app/(main)/discover/(list)/plugins/features/Category.tsx +45 -0
  184. package/src/app/(main)/discover/(list)/plugins/features/List.tsx +96 -0
  185. package/src/app/(main)/discover/(list)/plugins/features/useCategory.tsx +80 -0
  186. package/src/app/(main)/discover/(list)/plugins/layout.tsx +12 -0
  187. package/src/app/(main)/discover/(list)/plugins/loading.tsx +1 -0
  188. package/src/app/(main)/discover/(list)/plugins/page.tsx +52 -0
  189. package/src/app/(main)/discover/(list)/providers/features/Card.tsx +117 -0
  190. package/src/app/(main)/discover/(list)/providers/features/List.tsx +71 -0
  191. package/src/app/(main)/discover/(list)/providers/loading.tsx +1 -0
  192. package/src/app/(main)/discover/(list)/providers/page.tsx +52 -0
  193. package/src/app/(main)/discover/_layout/Desktop/Header.tsx +36 -0
  194. package/src/app/(main)/discover/_layout/Desktop/index.tsx +21 -0
  195. package/src/app/(main)/discover/_layout/Mobile/index.tsx +9 -0
  196. package/src/app/(main)/{market/features/AgentCard/AgentCardBanner.tsx → discover/components/CardBanner.tsx} +5 -5
  197. package/src/app/(main)/discover/components/CategoryContainer.tsx +18 -0
  198. package/src/app/(main)/discover/components/CategoryMenu.tsx +39 -0
  199. package/src/app/(main)/discover/components/GitHubAvatar.tsx +19 -0
  200. package/src/app/(main)/discover/components/GridLoadingCard.tsx +69 -0
  201. package/src/app/(main)/discover/components/ListLoading.tsx +66 -0
  202. package/src/app/(main)/discover/components/Loading.tsx +17 -0
  203. package/src/app/(main)/discover/components/SearchResultCount.tsx +37 -0
  204. package/src/app/(main)/discover/components/Statistic.tsx +92 -0
  205. package/src/app/(main)/discover/components/Title.tsx +76 -0
  206. package/src/app/(main)/discover/components/VirtuosoGridList/index.tsx +52 -0
  207. package/src/app/(main)/discover/components/VirtuosoGridList/useScrollParent.ts +19 -0
  208. package/src/app/(main)/discover/error.tsx +5 -0
  209. package/src/app/(main)/{market/features/ShareAgentButton → discover/features/CreateButton}/Inner.tsx +9 -10
  210. package/src/app/(main)/{market/features/ShareAgentButton → discover/features/CreateButton}/index.tsx +9 -9
  211. package/src/app/(main)/discover/features/LikeButton.tsx +73 -0
  212. package/src/app/(main)/discover/features/ModelFeatureTags.tsx +77 -0
  213. package/src/app/(main)/discover/features/StoreSearchBar.tsx +84 -0
  214. package/src/app/(main)/discover/features/const.ts +2 -0
  215. package/src/app/(main)/discover/features/useNav.tsx +71 -0
  216. package/src/app/(main)/discover/layout.tsx +12 -0
  217. package/src/app/(main)/discover/loading.tsx +9 -0
  218. package/src/app/(main)/discover/not-found.tsx +3 -0
  219. package/src/app/(main)/discover/search/_layout/Desktop.tsx +42 -0
  220. package/src/app/(main)/discover/search/_layout/Mobile/Header.tsx +31 -0
  221. package/src/app/(main)/discover/search/_layout/Mobile/Nav.tsx +56 -0
  222. package/src/app/(main)/discover/search/_layout/Mobile/index.tsx +32 -0
  223. package/src/app/(main)/discover/search/features/AssistantsResult.tsx +27 -0
  224. package/src/app/(main)/discover/search/features/Category.tsx +41 -0
  225. package/src/app/(main)/discover/search/features/ModelsResult.tsx +27 -0
  226. package/src/app/(main)/discover/search/features/PluginsResult.tsx +27 -0
  227. package/src/app/(main)/discover/search/features/ProvidersResult.tsx +26 -0
  228. package/src/app/(main)/discover/search/layout.tsx +12 -0
  229. package/src/app/(main)/discover/search/loading.tsx +1 -0
  230. package/src/app/(main)/discover/search/page.tsx +78 -0
  231. package/src/app/(main)/settings/llm/components/ProviderConfig/index.tsx +0 -6
  232. package/src/app/(main)/welcome/features/Actions.tsx +1 -1
  233. package/src/app/@modal/(.)discover/assistant/[slug]/page.tsx +1 -0
  234. package/src/app/@modal/(.)discover/layout.tsx +29 -0
  235. package/src/app/@modal/(.)discover/loading.tsx +3 -0
  236. package/src/app/@modal/(.)discover/model/[...slugs]/page.tsx +1 -0
  237. package/src/app/@modal/(.)discover/plugin/[slug]/page.tsx +1 -0
  238. package/src/app/@modal/(.)discover/provider/[slug]/page.tsx +1 -0
  239. package/src/app/@modal/features/InterceptingContext.tsx +9 -0
  240. package/src/app/@modal/layout.tsx +58 -21
  241. package/src/app/api/{market → assistant}/[id]/route.ts +2 -3
  242. package/src/app/api/{market → assistant/store}/route.ts +2 -5
  243. package/src/app/api/plugin/store/route.ts +1 -4
  244. package/src/app/metadata.ts +3 -0
  245. package/src/app/redirect/page.tsx +15 -0
  246. package/src/components/FetchErrorNotification/Description.tsx +2 -0
  247. package/src/components/InterceptingLink/index.tsx +27 -0
  248. package/src/components/mdx/CodeBlock.tsx +46 -0
  249. package/src/components/mdx/Link.tsx +21 -0
  250. package/src/components/mdx/index.tsx +51 -0
  251. package/src/config/modelProviders/ollama.ts +0 -8
  252. package/src/const/discover.ts +63 -1
  253. package/src/features/Conversation/Error/PluginSettings.tsx +1 -1
  254. package/src/features/Conversation/Messages/Tool/Inspector/Settings.tsx +1 -1
  255. package/src/features/Conversation/components/InboxWelcome/AgentsSuggest.tsx +41 -24
  256. package/src/features/MobileTabBar/index.tsx +3 -3
  257. package/src/features/PluginDetailModal/APIs.tsx +1 -1
  258. package/src/features/PluginDevModal/UrlManifestForm.tsx +1 -1
  259. package/src/features/PluginStore/PluginItem/Action.tsx +1 -1
  260. package/src/features/PluginsUI/Render/DefaultType/index.tsx +1 -1
  261. package/src/features/PluginsUI/Render/StandaloneType/index.tsx +1 -1
  262. package/src/hooks/useInterceptingRoutes.ts +21 -1
  263. package/src/hooks/useShare.tsx +191 -0
  264. package/src/libs/agent-runtime/utils/streams/openai.test.ts +43 -0
  265. package/src/libs/agent-runtime/utils/streams/openai.ts +1 -1
  266. package/src/locales/create.ts +1 -1
  267. package/src/locales/default/common.ts +1 -1
  268. package/src/locales/default/discover.ts +205 -0
  269. package/src/locales/default/index.ts +6 -2
  270. package/src/locales/default/metadata.ts +23 -3
  271. package/src/locales/default/models.ts +15 -0
  272. package/src/locales/default/providers.ts +15 -0
  273. package/src/locales/default/welcome.ts +1 -1
  274. package/src/locales/resources.ts +2 -0
  275. package/src/server/ld.ts +85 -11
  276. package/src/server/metadata.ts +41 -3
  277. package/src/{app/api/market/AgentMarket.test.ts → server/modules/AssistantStore/index.test.ts} +15 -15
  278. package/src/{app/api/market/AgentMarket.ts → server/modules/AssistantStore/index.ts} +7 -3
  279. package/src/{app/api/plugin/store/Store.test.ts → server/modules/PluginStore/index.test.ts} +1 -1
  280. package/src/server/services/discover/index.ts +352 -0
  281. package/src/server/services/doc/index.tsx +40 -0
  282. package/src/server/translation.ts +11 -5
  283. package/src/services/__tests__/__snapshots__/tool.test.ts.snap +1 -1
  284. package/src/services/{_auth.test.ts → __tests__/_auth.test.ts} +1 -1
  285. package/src/services/__tests__/assistant.test.ts +82 -0
  286. package/src/services/__tests__/tool.test.ts +13 -13
  287. package/src/services/_url.ts +2 -2
  288. package/src/services/assistant.ts +30 -0
  289. package/src/services/chat.ts +1 -1
  290. package/src/services/tool.ts +7 -129
  291. package/src/store/chat/slices/plugin/action.test.ts +112 -0
  292. package/src/store/chat/slices/plugin/action.ts +1 -3
  293. package/src/store/global/initialState.ts +1 -1
  294. package/src/store/tool/selectors/tool.test.ts +1 -1
  295. package/src/store/tool/slices/customPlugin/action.test.ts +1 -1
  296. package/src/store/tool/slices/customPlugin/action.ts +1 -1
  297. package/src/store/tool/slices/plugin/action.ts +1 -1
  298. package/src/store/tool/slices/plugin/selectors.test.ts +3 -3
  299. package/src/store/tool/slices/plugin/selectors.ts +3 -3
  300. package/src/store/tool/slices/store/action.test.ts +16 -22
  301. package/src/store/tool/slices/store/action.ts +8 -8
  302. package/src/types/discover.ts +152 -0
  303. package/src/types/llm.ts +4 -2
  304. package/src/types/meta.ts +1 -0
  305. package/src/utils/format.test.ts +191 -112
  306. package/src/utils/format.ts +36 -0
  307. package/src/utils/toolManifest.ts +124 -0
  308. package/src/app/(main)/market/@detail/default.tsx +0 -12
  309. package/src/app/(main)/market/@detail/features/AgentDetailContent.tsx +0 -73
  310. package/src/app/(main)/market/@detail/features/Banner.tsx +0 -46
  311. package/src/app/(main)/market/@detail/features/Comment.tsx +0 -16
  312. package/src/app/(main)/market/@detail/features/Header.tsx +0 -81
  313. package/src/app/(main)/market/@detail/features/Loading.tsx +0 -63
  314. package/src/app/(main)/market/@detail/features/TokenTag.tsx +0 -27
  315. package/src/app/(main)/market/@detail/features/style.ts +0 -32
  316. package/src/app/(main)/market/_layout/Desktop/DetailSidebar.tsx +0 -84
  317. package/src/app/(main)/market/_layout/Desktop/Header.tsx +0 -29
  318. package/src/app/(main)/market/_layout/Desktop/Hero.tsx +0 -40
  319. package/src/app/(main)/market/_layout/Desktop/index.tsx +0 -46
  320. package/src/app/(main)/market/_layout/Mobile/DetailModal.tsx +0 -32
  321. package/src/app/(main)/market/_layout/Mobile/Header.tsx +0 -20
  322. package/src/app/(main)/market/_layout/Mobile/index.tsx +0 -25
  323. package/src/app/(main)/market/_layout/type.ts +0 -6
  324. package/src/app/(main)/market/features/AgentCard/index.tsx +0 -139
  325. package/src/app/(main)/market/features/AgentList.tsx +0 -103
  326. package/src/app/(main)/market/features/AgentSearchBar.tsx +0 -42
  327. package/src/app/(main)/market/features/TagList.tsx +0 -69
  328. package/src/app/(main)/market/loading.tsx +0 -15
  329. package/src/app/(main)/market/page.tsx +0 -44
  330. package/src/const/market.ts +0 -15
  331. package/src/locales/default/market.ts +0 -32
  332. package/src/services/market.ts +0 -22
  333. package/src/store/market/action.ts +0 -82
  334. package/src/store/market/index.ts +0 -3
  335. package/src/store/market/initialState.ts +0 -19
  336. package/src/store/market/selectors.ts +0 -38
  337. package/src/store/market/store.ts +0 -48
  338. package/src/types/market.ts +0 -20
  339. /package/src/{app/api/plugin/store/Store.ts → server/modules/PluginStore/index.ts} +0 -0
@@ -0,0 +1,15 @@
1
+ import type { Metadata } from 'next';
2
+ import { redirect } from 'next/navigation';
3
+
4
+ export default function Page({ searchParams }: { searchParams: { url: string } }) {
5
+ redirect(searchParams.url);
6
+ }
7
+
8
+ export function generateMetadata(): Metadata {
9
+ return {
10
+ robots: {
11
+ follow: false,
12
+ index: false,
13
+ },
14
+ };
15
+ }
@@ -1,3 +1,5 @@
1
+ 'use client';
2
+
1
3
  import { Icon } from '@lobehub/ui';
2
4
  import { Skeleton } from 'antd';
3
5
  import { css, cx } from 'antd-style';
@@ -0,0 +1,27 @@
1
+ import Link, { LinkProps } from 'next/link';
2
+ import { CSSProperties, ReactNode, memo } from 'react';
3
+
4
+ import { useInterceptingRoutes } from '@/hooks/useInterceptingRoutes';
5
+
6
+ interface InterceptingLinkProps extends LinkProps {
7
+ children: ReactNode;
8
+ className?: string;
9
+ disableIntercepting?: boolean;
10
+ style?: CSSProperties;
11
+ }
12
+
13
+ const InterceptingLink = memo<InterceptingLinkProps>(({ href, disableIntercepting, ...rest }) => {
14
+ const router = useInterceptingRoutes();
15
+ return (
16
+ <Link
17
+ href={href}
18
+ onClick={(e) => {
19
+ e.preventDefault();
20
+ router.push(href as any, disableIntercepting);
21
+ }}
22
+ {...rest}
23
+ />
24
+ );
25
+ });
26
+
27
+ export default InterceptingLink;
@@ -0,0 +1,46 @@
1
+ 'use client';
2
+
3
+ import { Pre, PreSingleLine } from '@lobehub/ui/mdx';
4
+ import { FC, PropsWithChildren } from 'react';
5
+
6
+ const countLines = (str: string): number => {
7
+ const regex = /\n/g;
8
+ const matches = str.match(regex);
9
+ return matches ? matches.length : 1;
10
+ };
11
+
12
+ const useCode = (raw: any) => {
13
+ if (!raw) return;
14
+
15
+ const { children, className } = raw.props;
16
+
17
+ if (!children) return;
18
+
19
+ const content = (Array.isArray(children) ? (children[0] as string) : children).trim();
20
+
21
+ const lang = className?.replace('language-', '') || 'txt';
22
+
23
+ const isSingleLine = countLines(content) <= 1 && content.length <= 32;
24
+
25
+ return {
26
+ content,
27
+ isSingleLine,
28
+ lang,
29
+ };
30
+ };
31
+
32
+ const CodeBlock: FC<PropsWithChildren> = ({ children }) => {
33
+ const code = useCode(children);
34
+
35
+ if (!code) return;
36
+
37
+ if (code.isSingleLine) return <PreSingleLine language={code.lang}>{code.content}</PreSingleLine>;
38
+
39
+ return (
40
+ <Pre allowChangeLanguage={false} fullFeatured language={code.lang}>
41
+ {code.content}
42
+ </Pre>
43
+ );
44
+ };
45
+
46
+ export default CodeBlock;
@@ -0,0 +1,21 @@
1
+ 'use client';
2
+
3
+ import Link, { LinkProps } from 'next/link';
4
+ import { FC } from 'react';
5
+
6
+ const EXTERNAL_HREF_REGEX = /https?:\/\//;
7
+
8
+ const A: FC<LinkProps> = ({ href = '', ...props }) => {
9
+ const isOutbound = EXTERNAL_HREF_REGEX.test(href as string);
10
+ const isOfficial = String(href).includes('lobechat') || String(href).includes('lobehub');
11
+ return (
12
+ <Link
13
+ href={href}
14
+ rel={isOutbound && !isOfficial ? 'nofollow' : undefined}
15
+ target={isOutbound ? '_blank' : undefined}
16
+ {...props}
17
+ />
18
+ );
19
+ };
20
+
21
+ export default A;
@@ -0,0 +1,51 @@
1
+ import { Typography as Typo, TypographyProps } from '@lobehub/ui';
2
+ import { mdxComponents } from '@lobehub/ui/mdx';
3
+ import { MDXRemote, type MDXRemoteProps } from 'next-mdx-remote/rsc';
4
+ import { FC } from 'react';
5
+ import remarkGfm from 'remark-gfm';
6
+
7
+ import CodeBlock from './CodeBlock';
8
+ import Link from './Link';
9
+
10
+ export const Typography = ({
11
+ children,
12
+ mobile,
13
+ style,
14
+ ...rest
15
+ }: { mobile?: boolean } & TypographyProps) => {
16
+ const headerMultiple = mobile ? 0.2 : 0.4;
17
+ return (
18
+ <Typo
19
+ fontSize={14}
20
+ headerMultiple={headerMultiple}
21
+ style={{ width: '100%', ...style }}
22
+ {...rest}
23
+ >
24
+ {children}
25
+ </Typo>
26
+ );
27
+ };
28
+
29
+ export const CustomMDX: FC<MDXRemoteProps & { mobile?: boolean }> = ({ mobile, ...rest }) => {
30
+ // ref: https://github.com/hashicorp/next-mdx-remote/issues/405
31
+ const list: any = {};
32
+ Object.entries({
33
+ ...mdxComponents,
34
+ a: Link,
35
+ pre: CodeBlock,
36
+ ...rest.components,
37
+ }).forEach(([key, Render]: any) => {
38
+ list[key] = (props: any) => <Render {...props} />;
39
+ });
40
+
41
+ return (
42
+ <Typography mobile={mobile}>
43
+ <MDXRemote
44
+ {...rest}
45
+ components={list}
46
+ // @ts-ignore
47
+ options={{ mdxOptions: { remarkPlugins: [remarkGfm] } }}
48
+ />
49
+ </Typography>
50
+ );
51
+ };
@@ -274,14 +274,6 @@ const Ollama: ModelProviderCard = {
274
274
  tokens: 4096,
275
275
  vision: true,
276
276
  },
277
- {
278
- description: 'MiniCPM-V 是 OpenBMB 推出的新一代多模态大模型,具备卓越的 OCR 识别和多模态理解能力,支持广泛的应用场景。',
279
- displayName: 'MiniCPM-V 8B',
280
- enabled: true,
281
- id: 'minicpm-v:8b',
282
- tokens: 128_000,
283
- vision:true,
284
- },
285
277
  {
286
278
  description: 'MiniCPM-V 是 OpenBMB 推出的新一代多模态大模型,具备卓越的 OCR 识别和多模态理解能力,支持广泛的应用场景。',
287
279
  displayName: 'MiniCPM-V 8B',
@@ -1 +1,63 @@
1
- export const CNYtoUSD = 7.14;
1
+ import { DEFAULT_AGENT_CONFIG } from '@/const/settings';
2
+ import {
3
+ DiscoverAssistantItem,
4
+ DiscoverModelItem,
5
+ DiscoverPlugintem,
6
+ DiscoverProviderItem,
7
+ } from '@/types/discover';
8
+
9
+ export const CNY_TO_USD = 7.14;
10
+
11
+ const DEFAULT_CREATED_AT = new Date().toISOString();
12
+
13
+ export const DEFAULT_DISCOVER_ASSISTANT_ITEM: Partial<DiscoverAssistantItem> = {
14
+ author: '',
15
+ config: DEFAULT_AGENT_CONFIG,
16
+ createdAt: DEFAULT_CREATED_AT,
17
+ homepage: '',
18
+ identifier: '',
19
+ schemaVersion: 1,
20
+ socialData: {
21
+ conversations: 0,
22
+ likes: 0,
23
+ users: 0,
24
+ },
25
+ };
26
+
27
+ export const DEFAULT_DISCOVER_PLUGIN_ITEM: Partial<DiscoverPlugintem> = {
28
+ author: '',
29
+ createdAt: DEFAULT_CREATED_AT,
30
+ homepage: '',
31
+ identifier: '',
32
+ schemaVersion: 1,
33
+ socialData: {
34
+ called: 0,
35
+ executionTime: 0,
36
+ likes: 0,
37
+ relatedAssistants: 0,
38
+ successRate: 1,
39
+ users: 0,
40
+ },
41
+ };
42
+
43
+ export const DEFAULT_DISCOVER_MODEL_ITEM: Partial<DiscoverModelItem> = {
44
+ createdAt: DEFAULT_CREATED_AT,
45
+ identifier: '',
46
+ providers: [],
47
+ socialData: {
48
+ conversations: 0,
49
+ likes: 0,
50
+ tokens: 0,
51
+ },
52
+ };
53
+
54
+ export const DEFAULT_DISCOVER_PROVIDER_ITEM: Partial<DiscoverProviderItem> = {
55
+ createdAt: DEFAULT_CREATED_AT,
56
+ identifier: '',
57
+ models: [],
58
+ socialData: {
59
+ conversations: 0,
60
+ likes: 0,
61
+ users: 0,
62
+ },
63
+ };
@@ -26,7 +26,7 @@ const PluginSettings = memo<PluginSettingsProps>(({ id, plugin }) => {
26
26
  const [resend, deleteMessage] = useChatStore((s) => [s.regenerateMessage, s.deleteMessage]);
27
27
  const pluginIdentifier = plugin?.identifier as string;
28
28
  const pluginMeta = useToolStore(pluginSelectors.getPluginMetaById(pluginIdentifier), isEqual);
29
- const manifest = useToolStore(pluginSelectors.getPluginManifestById(pluginIdentifier), isEqual);
29
+ const manifest = useToolStore(pluginSelectors.getToolManifestById(pluginIdentifier), isEqual);
30
30
 
31
31
  return (
32
32
  !!manifest && (
@@ -8,7 +8,7 @@ import { pluginHelpers, useToolStore } from '@/store/tool';
8
8
  import { pluginSelectors } from '@/store/tool/selectors';
9
9
 
10
10
  const Settings = memo<{ id: string }>(({ id }) => {
11
- const item = useToolStore(pluginSelectors.getPluginManifestById(id));
11
+ const item = useToolStore(pluginSelectors.getToolManifestById(id));
12
12
  const [open, setOpen] = useState(false);
13
13
  const { t } = useTranslation('plugin');
14
14
  const hasSettings = pluginHelpers.isSettingSchemaNonEmpty(item?.settings);
@@ -3,14 +3,18 @@
3
3
  import { ActionIcon, Avatar, Grid } from '@lobehub/ui';
4
4
  import { Skeleton, Typography } from 'antd';
5
5
  import { createStyles } from 'antd-style';
6
- import isEqual from 'fast-deep-equal';
7
6
  import { RefreshCw } from 'lucide-react';
8
- import Link from 'next/link';
9
7
  import { memo, useState } from 'react';
10
8
  import { useTranslation } from 'react-i18next';
11
9
  import { Flexbox } from 'react-layout-kit';
10
+ import useSWR from 'swr';
11
+ import urlJoin from 'url-join';
12
12
 
13
- import { useMarketStore } from '@/store/market';
13
+ import InterceptingLink from '@/components/InterceptingLink';
14
+ import { assistantService } from '@/services/assistant';
15
+ import { useUserStore } from '@/store/user';
16
+ import { userGeneralSettingsSelectors } from '@/store/user/selectors';
17
+ import { DiscoverAssistantItem } from '@/types/discover';
14
18
 
15
19
  const { Paragraph } = Typography;
16
20
 
@@ -56,11 +60,19 @@ const useStyles = createStyles(({ css, token, responsive }) => ({
56
60
 
57
61
  const AgentsSuggest = memo<{ mobile?: boolean }>(({ mobile }) => {
58
62
  const { t } = useTranslation('welcome');
59
-
63
+ const locale = useUserStore(userGeneralSettingsSelectors.currentLanguage);
60
64
  const [sliceStart, setSliceStart] = useState(0);
61
- const useFetchAgentList = useMarketStore((s) => s.useFetchAgentList);
62
- const { isLoading } = useFetchAgentList();
63
- const agentList = useMarketStore((s) => s.agentList, isEqual);
65
+
66
+ const { data: assistantList, isLoading } = useSWR(
67
+ ['assistant-list', locale].join('-'),
68
+ async () => await assistantService.getAssistantList(),
69
+ {
70
+ refreshWhenOffline: false,
71
+ revalidateOnFocus: false,
72
+ revalidateOnReconnect: false,
73
+ },
74
+ );
75
+
64
76
  const { styles } = useStyles();
65
77
 
66
78
  const agentLength = mobile ? 2 : 4;
@@ -72,8 +84,8 @@ const AgentsSuggest = memo<{ mobile?: boolean }>(({ mobile }) => {
72
84
  ));
73
85
 
74
86
  const handleRefresh = () => {
75
- if (!agentList) return;
76
- setSliceStart(Math.floor((Math.random() * agentList.length) / 2));
87
+ if (!assistantList) return;
88
+ setSliceStart(Math.floor((Math.random() * assistantList.length) / 2));
77
89
  };
78
90
 
79
91
  return (
@@ -88,23 +100,28 @@ const AgentsSuggest = memo<{ mobile?: boolean }>(({ mobile }) => {
88
100
  />
89
101
  </Flexbox>
90
102
  <Grid gap={8} rows={2}>
91
- {isLoading
103
+ {isLoading || !assistantList
92
104
  ? loadingCards
93
- : agentList.slice(sliceStart, sliceStart + agentLength).map((agent) => (
94
- <Link href={`/market?agent=${agent.identifier}`} key={agent.identifier}>
95
- <Flexbox className={styles.card} gap={8} horizontal>
96
- <Avatar avatar={agent.meta.avatar} style={{ flex: 'none' }} />
97
- <Flexbox gap={mobile ? 2 : 8} style={{ overflow: 'hidden', width: '100%' }}>
98
- <Paragraph className={styles.cardTitle} ellipsis={{ rows: 1 }}>
99
- {agent.meta.title}
100
- </Paragraph>
101
- <Paragraph className={styles.cardDesc} ellipsis={{ rows: mobile ? 1 : 2 }}>
102
- {agent.meta.description}
103
- </Paragraph>
105
+ : assistantList
106
+ .slice(sliceStart, sliceStart + agentLength)
107
+ .map((item: DiscoverAssistantItem) => (
108
+ <InterceptingLink
109
+ href={urlJoin('/discover/assistant/', item.identifier)}
110
+ key={item.identifier}
111
+ >
112
+ <Flexbox className={styles.card} gap={8} horizontal>
113
+ <Avatar avatar={item.meta.avatar} style={{ flex: 'none' }} />
114
+ <Flexbox gap={mobile ? 2 : 8} style={{ overflow: 'hidden', width: '100%' }}>
115
+ <Paragraph className={styles.cardTitle} ellipsis={{ rows: 1 }}>
116
+ {item.meta.title}
117
+ </Paragraph>
118
+ <Paragraph className={styles.cardDesc} ellipsis={{ rows: mobile ? 1 : 2 }}>
119
+ {item.meta.description}
120
+ </Paragraph>
121
+ </Flexbox>
104
122
  </Flexbox>
105
- </Flexbox>
106
- </Link>
107
- ))}
123
+ </InterceptingLink>
124
+ ))}
108
125
  </Grid>
109
126
  </Flexbox>
110
127
  );
@@ -47,11 +47,11 @@ export default memo<Props>(({ className, tabBarKey }) => {
47
47
  icon: (active: boolean) => (
48
48
  <Icon className={active ? styles.active : undefined} icon={Bot} />
49
49
  ),
50
- key: SidebarTabKey.Market,
50
+ key: SidebarTabKey.Discover,
51
51
  onClick: () => {
52
- router.push('/market');
52
+ router.push('/discover');
53
53
  },
54
- title: t('tab.market'),
54
+ title: t('tab.discover'),
55
55
  },
56
56
  {
57
57
  icon: (active: boolean) => (
@@ -11,7 +11,7 @@ const APIs = memo<{
11
11
  id: string;
12
12
  }>(({ id }) => {
13
13
  const { t } = useTranslation('plugin');
14
- const pluginManifest = useToolStore(pluginSelectors.getPluginManifestById(id), isEqual);
14
+ const pluginManifest = useToolStore(pluginSelectors.getToolManifestById(id), isEqual);
15
15
 
16
16
  if (!pluginManifest?.api) return <Empty />;
17
17
 
@@ -78,7 +78,7 @@ const UrlManifestForm = memo<{ form: FormInstance; isEditMode: boolean }>(
78
78
 
79
79
  try {
80
80
  const useProxy = form.getFieldValue(proxyKey);
81
- const data = await toolService.getPluginManifest(value, useProxy);
81
+ const data = await toolService.getToolManifest(value, useProxy);
82
82
  setManifest(data);
83
83
 
84
84
  form.setFieldsValue({ identifier: data.identifier, manifest: data });
@@ -30,7 +30,7 @@ const Actions = memo<ActionsProps>(({ identifier, type }) => {
30
30
  const isCustomPlugin = type === 'customPlugin';
31
31
  const { t } = useTranslation('plugin');
32
32
  const [open, setOpen] = useState(false);
33
- const plugin = useToolStore(pluginSelectors.getPluginManifestById(identifier));
33
+ const plugin = useToolStore(pluginSelectors.getToolManifestById(identifier));
34
34
  const { modal } = App.useApp();
35
35
  const [tab, setTab] = useState('info');
36
36
  const hasSettings = pluginHelpers.isSettingSchemaNonEmpty(plugin?.settings);
@@ -18,7 +18,7 @@ export interface PluginDefaultTypeProps {
18
18
  }
19
19
 
20
20
  const PluginDefaultType = memo<PluginDefaultTypeProps>(({ content, name, loading }) => {
21
- const manifest = useToolStore(pluginSelectors.getPluginManifestById(name || ''));
21
+ const manifest = useToolStore(pluginSelectors.getToolManifestById(name || ''));
22
22
 
23
23
  const { isJSON, data } = useParseContent(content);
24
24
 
@@ -13,7 +13,7 @@ export interface PluginStandaloneTypeProps {
13
13
  }
14
14
 
15
15
  const PluginDefaultType = memo<PluginStandaloneTypeProps>(({ payload, id, name = 'unknown' }) => {
16
- const manifest = useToolStore(pluginSelectors.getPluginManifestById(name));
16
+ const manifest = useToolStore(pluginSelectors.getToolManifestById(name));
17
17
 
18
18
  if (!manifest?.ui) return;
19
19
 
@@ -1,6 +1,7 @@
1
- import { useMemo } from 'react';
1
+ import { useContext, useMemo } from 'react';
2
2
  import urlJoin from 'url-join';
3
3
 
4
+ import { InterceptContext } from '@/app/@modal/features/InterceptingContext';
4
5
  import { INBOX_SESSION_ID } from '@/const/session';
5
6
  import { useIsMobile } from '@/hooks/useIsMobile';
6
7
  import { useQueryRoute } from '@/hooks/useQueryRoute';
@@ -44,3 +45,22 @@ export const useOpenChatSettings = (tab: ChatSettingsTabs = ChatSettingsTabs.Met
44
45
  }
45
46
  }, [openSettings, mobile, activeId, router, tab]);
46
47
  };
48
+
49
+ export const useInterceptingRoutes = () => {
50
+ const router = useQueryRoute();
51
+ const mobile = useIsMobile();
52
+ const isIntercepted = useContext(InterceptContext);
53
+ return useMemo(
54
+ () => ({
55
+ isIntercepted,
56
+ push: (url: string, disableIntercepting?: boolean) => {
57
+ if (disableIntercepting || mobile) {
58
+ router.push(`/redirect`, { query: { url } });
59
+ return;
60
+ }
61
+ router.push(url);
62
+ },
63
+ }),
64
+ [mobile, router, isIntercepted],
65
+ );
66
+ };
@@ -0,0 +1,191 @@
1
+ import {
2
+ SiLinkedin,
3
+ SiMastodon,
4
+ SiReddit,
5
+ SiSinaweibo,
6
+ SiTelegram,
7
+ SiWhatsapp,
8
+ SiX,
9
+ } from '@icons-pack/react-simple-icons';
10
+ import { camelCase, identity, pickBy } from 'lodash-es';
11
+ import qs from 'query-string';
12
+
13
+ const stringifyHashtags = (hashtags: string[], joinfix: string = ',', prefix?: string) => {
14
+ // eslint-disable-next-line no-param-reassign
15
+ if (prefix) hashtags = hashtags.map((tag) => prefix + camelCase(tag));
16
+ return hashtags.filter(Boolean).join(joinfix);
17
+ };
18
+ export const useShare = ({
19
+ url,
20
+ title,
21
+ desc,
22
+ hashtags = [],
23
+ }: {
24
+ desc: string;
25
+ hashtags?: string[];
26
+ title: string;
27
+ url: string;
28
+ }) => {
29
+ const genRedditLink = () => {
30
+ const query = pickBy(
31
+ {
32
+ title: [
33
+ [title, desc].filter(Boolean).join(' - '),
34
+ hashtags && stringifyHashtags(hashtags, ' ', '#'),
35
+ ]
36
+ .filter(Boolean)
37
+ .join(' '),
38
+ url,
39
+ },
40
+ identity,
41
+ ) as any;
42
+ return qs.stringifyUrl({
43
+ query,
44
+ url: 'https://www.reddit.com/submit',
45
+ });
46
+ };
47
+
48
+ const genTelegramLink = () => {
49
+ const query = pickBy(
50
+ {
51
+ text: [
52
+ [title, desc].filter(Boolean).join(' - '),
53
+ hashtags && stringifyHashtags(hashtags, ' ', '#'),
54
+ ]
55
+ .filter(Boolean)
56
+ .join(' '),
57
+ url,
58
+ },
59
+ identity,
60
+ ) as any;
61
+ return qs.stringifyUrl({
62
+ query,
63
+ url: 'https://t.me/share/url"',
64
+ });
65
+ };
66
+
67
+ const genWeiboLink = () => {
68
+ const query = pickBy(
69
+ {
70
+ sharesource: 'weibo',
71
+ title: [
72
+ [title, desc].filter(Boolean).join(' - '),
73
+ hashtags && stringifyHashtags(hashtags, ' ', '#'),
74
+ ]
75
+ .filter(Boolean)
76
+ .join(' '),
77
+ url,
78
+ },
79
+ identity,
80
+ ) as any;
81
+ return qs.stringifyUrl({
82
+ query,
83
+ url: 'http://service.weibo.com/share/share.php',
84
+ });
85
+ };
86
+
87
+ const genWhatsappLink = () => {
88
+ const query = pickBy(
89
+ {
90
+ text: [
91
+ [title, desc].filter(Boolean).join(' - '),
92
+ url,
93
+ hashtags && stringifyHashtags(hashtags, ' ', '#'),
94
+ ]
95
+ .filter(Boolean)
96
+ .join(' '),
97
+ },
98
+ identity,
99
+ ) as any;
100
+ return qs.stringifyUrl({
101
+ query,
102
+ url: 'https://api.whatsapp.com/send',
103
+ });
104
+ };
105
+
106
+ const genXLink = () => {
107
+ const query = pickBy(
108
+ {
109
+ hashtags: hashtags && stringifyHashtags(hashtags),
110
+ text: [title, desc].filter(Boolean).join(' - '),
111
+ url,
112
+ },
113
+ identity,
114
+ ) as any;
115
+ return qs.stringifyUrl({
116
+ query,
117
+ url: 'https://x.com/intent/tweet',
118
+ });
119
+ };
120
+
121
+ const genLinkdinLink = () => {
122
+ const query = pickBy(
123
+ {
124
+ url,
125
+ },
126
+ identity,
127
+ ) as any;
128
+ return qs.stringifyUrl({
129
+ query,
130
+ url: 'https://www.linkedin.com/sharing/share-offsite/',
131
+ });
132
+ };
133
+
134
+ const genMastodonLink = () => {
135
+ const query = pickBy(
136
+ {
137
+ text: [
138
+ [title, desc].filter(Boolean).join(' - '),
139
+
140
+ hashtags && stringifyHashtags(hashtags, ' ', '#'),
141
+ ]
142
+ .filter(Boolean)
143
+ .join(' '),
144
+ url,
145
+ },
146
+ identity,
147
+ ) as any;
148
+ return qs.stringifyUrl({
149
+ query,
150
+ url: 'https://mastodon.social/share',
151
+ });
152
+ };
153
+
154
+ return {
155
+ linkedin: {
156
+ icon: SiLinkedin,
157
+ link: genLinkdinLink(),
158
+ title: 'Linkedin',
159
+ },
160
+ mastodon: {
161
+ icon: SiMastodon,
162
+ link: genMastodonLink(),
163
+ title: 'Mastodon',
164
+ },
165
+ reddit: {
166
+ icon: SiReddit,
167
+ link: genRedditLink(),
168
+ title: 'Reddit',
169
+ },
170
+ telegram: {
171
+ icon: SiTelegram,
172
+ link: genTelegramLink(),
173
+ title: 'Telegram',
174
+ },
175
+ weibo: {
176
+ icon: SiSinaweibo,
177
+ link: genWeiboLink(),
178
+ title: 'Weibo',
179
+ },
180
+ whatsapp: {
181
+ icon: SiWhatsapp,
182
+ link: genWhatsappLink(),
183
+ title: 'WhatsApp',
184
+ },
185
+ x: {
186
+ icon: SiX,
187
+ link: genXLink(),
188
+ title: 'X',
189
+ },
190
+ };
191
+ };