@arcblock/ux 3.4.14 → 3.5.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.
Files changed (335) hide show
  1. package/lib/Util/constant.d.ts +6 -0
  2. package/lib/Util/constant.js +25 -16
  3. package/lib/package.json.js +1 -1
  4. package/package.json +12 -9
  5. package/src/ActionButton/ActionButton.stories.jsx +0 -61
  6. package/src/ActionButton/index.jsx +0 -106
  7. package/src/ActivityIndicator/ActivityIndicator.stories.jsx +0 -9
  8. package/src/ActivityIndicator/index.jsx +0 -140
  9. package/src/Address/Address.stories.jsx +0 -38
  10. package/src/Address/compact-text.jsx +0 -76
  11. package/src/Address/did-address.tsx +0 -223
  12. package/src/Address/index.tsx +0 -21
  13. package/src/Address/responsive-did-address.tsx +0 -154
  14. package/src/Alert/Alert.stories.jsx +0 -100
  15. package/src/Alert/index.jsx +0 -130
  16. package/src/AnimationWaiter/AnimationWaiter.stories.jsx +0 -35
  17. package/src/AnimationWaiter/dark-animation.json +0 -1
  18. package/src/AnimationWaiter/default-animation.json +0 -1
  19. package/src/AnimationWaiter/index.jsx +0 -296
  20. package/src/Async/index.tsx +0 -44
  21. package/src/Avatar/Avatar.stories.jsx +0 -11
  22. package/src/Avatar/did-motif.jsx +0 -38
  23. package/src/Avatar/etherscan-blockies.js +0 -81
  24. package/src/Avatar/index.jsx +0 -195
  25. package/src/Badge/Badge.stories.jsx +0 -41
  26. package/src/Badge/index.jsx +0 -101
  27. package/src/Blocklet/Blocklet.stories.jsx +0 -21
  28. package/src/Blocklet/blocklet.jsx +0 -276
  29. package/src/Blocklet/index.js +0 -5
  30. package/src/Blocklet/utils.jsx +0 -58
  31. package/src/BlockletContext/index.tsx +0 -72
  32. package/src/BlockletNFT/BlockletNFT.stories.jsx +0 -21
  33. package/src/BlockletNFT/index.jsx +0 -378
  34. package/src/BlockletV2/Blocklet.stories.jsx +0 -34
  35. package/src/BlockletV2/blocklet.tsx +0 -247
  36. package/src/BlockletV2/components/icon-text.tsx +0 -47
  37. package/src/BlockletV2/components/tooltip-icon.tsx +0 -52
  38. package/src/BlockletV2/index.ts +0 -6
  39. package/src/BlockletV2/utils.js +0 -75
  40. package/src/Button/Button.stories.jsx +0 -24
  41. package/src/Button/index.js +0 -9
  42. package/src/Button/wrap.jsx +0 -126
  43. package/src/ButtonGroup/index.js +0 -16
  44. package/src/CardSelector/index.tsx +0 -136
  45. package/src/Center/Center.stories.jsx +0 -20
  46. package/src/Center/index.tsx +0 -33
  47. package/src/ClickToCopy/ClickToCopy.stories.jsx +0 -24
  48. package/src/ClickToCopy/copy-button.tsx +0 -43
  49. package/src/ClickToCopy/hook.ts +0 -42
  50. package/src/ClickToCopy/index.tsx +0 -96
  51. package/src/CloseButton/index.tsx +0 -37
  52. package/src/CodeBlock/CodeBlock.stories.jsx +0 -22
  53. package/src/CodeBlock/LightBox.tsx +0 -87
  54. package/src/CodeBlock/index.tsx +0 -217
  55. package/src/Colors/Colors.stories.jsx +0 -211
  56. package/src/Colors/index.ts +0 -4
  57. package/src/Colors/themes/default.ts +0 -8
  58. package/src/Colors/themes/did-connect.ts +0 -64
  59. package/src/Colors/themes/temp.ts +0 -52
  60. package/src/Config/Config.stories.jsx +0 -16
  61. package/src/Config/config-provider.tsx +0 -62
  62. package/src/Config/index.ts +0 -2
  63. package/src/Config/theme-mode-toggle.tsx +0 -38
  64. package/src/ContactForm/ContactForm.stories.jsx +0 -32
  65. package/src/ContactForm/index.tsx +0 -264
  66. package/src/CookieConsent/CookieConsent.stories.jsx +0 -33
  67. package/src/CookieConsent/index.tsx +0 -104
  68. package/src/CountDown/CountDown.stories.jsx +0 -15
  69. package/src/CountDown/index.tsx +0 -170
  70. package/src/DID/DID.stories.jsx +0 -37
  71. package/src/DID/index.tsx +0 -393
  72. package/src/DIDConnect/app-icon.tsx +0 -37
  73. package/src/DIDConnect/app-info-item.tsx +0 -93
  74. package/src/DIDConnect/auth-apps/auth-apps-info.tsx +0 -77
  75. package/src/DIDConnect/auth-apps/index.tsx +0 -278
  76. package/src/DIDConnect/auth-apps/switch-role.tsx +0 -47
  77. package/src/DIDConnect/did-connect-container.tsx +0 -326
  78. package/src/DIDConnect/did-connect-footer.tsx +0 -76
  79. package/src/DIDConnect/did-connect-logo.tsx +0 -8
  80. package/src/DIDConnect/icons/did-wallet-logo.tsx +0 -18
  81. package/src/DIDConnect/icons/github-logo.tsx +0 -17
  82. package/src/DIDConnect/index.ts +0 -11
  83. package/src/DIDConnect/landing-page.tsx +0 -218
  84. package/src/DIDConnect/powered-by.tsx +0 -48
  85. package/src/DIDConnect/provider-icon.tsx +0 -62
  86. package/src/DIDConnect/request-storage-access-api-dialog.tsx +0 -304
  87. package/src/DIDConnect/with-container.tsx +0 -323
  88. package/src/DIDConnect/with-ux-theme.tsx +0 -22
  89. package/src/DIDLogo/Logo.stories.jsx +0 -11
  90. package/src/DIDLogo/index.tsx +0 -168
  91. package/src/Datatable/CustomToolbar.jsx +0 -415
  92. package/src/Datatable/Datatable.stories.jsx +0 -92
  93. package/src/Datatable/DatatableContext.jsx +0 -35
  94. package/src/Datatable/TableSearch.jsx +0 -166
  95. package/src/Datatable/index.jsx +0 -652
  96. package/src/Datatable/utils.js +0 -161
  97. package/src/Dialog/Dialog.stories.jsx +0 -21
  98. package/src/Dialog/confirm.jsx +0 -143
  99. package/src/Dialog/dialog.jsx +0 -199
  100. package/src/Dialog/index.js +0 -4
  101. package/src/Dialog/types.d.ts +0 -20
  102. package/src/Dialog/use-confirm.jsx +0 -188
  103. package/src/DriftBot/index.tsx +0 -81
  104. package/src/Earth/Earth.stories.jsx +0 -39
  105. package/src/Earth/countries.json +0 -8057
  106. package/src/Earth/index.tsx +0 -515
  107. package/src/Earth/util.ts +0 -72
  108. package/src/Empty/Empty.stories.jsx +0 -23
  109. package/src/Empty/index.jsx +0 -48
  110. package/src/ErrorBoundary/ErrorBoundary.stories.jsx +0 -13
  111. package/src/ErrorBoundary/fallback.tsx +0 -85
  112. package/src/ErrorBoundary/index.ts +0 -1
  113. package/src/Footer/Footer.stories.jsx +0 -13
  114. package/src/Footer/index.tsx +0 -130
  115. package/src/Header/Header.stories.jsx +0 -30
  116. package/src/Header/addon-button.tsx +0 -41
  117. package/src/Header/auto-hidden.tsx +0 -31
  118. package/src/Header/header-addons.tsx +0 -37
  119. package/src/Header/header.tsx +0 -214
  120. package/src/Header/index.ts +0 -3
  121. package/src/Header/responsive-header.tsx +0 -145
  122. package/src/Icon/Icon.stories.jsx +0 -45
  123. package/src/Icon/image.tsx +0 -53
  124. package/src/Icon/index.tsx +0 -63
  125. package/src/Img/Img.stories.jsx +0 -17
  126. package/src/Img/index.jsx +0 -258
  127. package/src/InfoRow/InfoRow.stories.jsx +0 -14
  128. package/src/InfoRow/index.tsx +0 -91
  129. package/src/Layout/Layout.stories.jsx +0 -24
  130. package/src/Layout/dashboard/external-link.tsx +0 -59
  131. package/src/Layout/dashboard/full-page.tsx +0 -58
  132. package/src/Layout/dashboard/index.tsx +0 -260
  133. package/src/Layout/dashboard/sidebar.tsx +0 -198
  134. package/src/Layout/dashboard-legacy/header.tsx +0 -156
  135. package/src/Layout/dashboard-legacy/index.tsx +0 -127
  136. package/src/Layout/dashboard-legacy/sidebar.tsx +0 -129
  137. package/src/Layout/index.tsx +0 -310
  138. package/src/LoadingMask/index.tsx +0 -108
  139. package/src/Locale/LocaleSelector.stories.jsx +0 -44
  140. package/src/Locale/browser-lang.ts +0 -65
  141. package/src/Locale/context.tsx +0 -162
  142. package/src/Locale/languages.ts +0 -58
  143. package/src/Locale/selector.tsx +0 -174
  144. package/src/Locale/util.ts +0 -38
  145. package/src/Logo/Logo.stories.jsx +0 -23
  146. package/src/Logo/images/logo-dark-text.svg +0 -3
  147. package/src/Logo/images/logo-dark-top.svg +0 -6
  148. package/src/Logo/images/logo-light-text.svg +0 -3
  149. package/src/Logo/images/logo-light-top.svg +0 -6
  150. package/src/Logo/index.tsx +0 -58
  151. package/src/Metric/Metric.stories.jsx +0 -29
  152. package/src/Metric/index.tsx +0 -130
  153. package/src/MuiWrap/index.tsx +0 -10
  154. package/src/NFTDisplay/NFTBroken.svg +0 -34
  155. package/src/NFTDisplay/NFTDisplay.stories.jsx +0 -30
  156. package/src/NFTDisplay/README.md +0 -59
  157. package/src/NFTDisplay/aspect-ratio-container.tsx +0 -36
  158. package/src/NFTDisplay/broken.tsx +0 -51
  159. package/src/NFTDisplay/displayApi.ts +0 -43
  160. package/src/NFTDisplay/index.tsx +0 -393
  161. package/src/NFTDisplay/loading.tsx +0 -16
  162. package/src/NFTDisplay/preview.tsx +0 -84
  163. package/src/NFTDisplay/render-svg.tsx +0 -21
  164. package/src/NFTDisplay/svg-embedder/img.tsx +0 -27
  165. package/src/NFTDisplay/svg-embedder/inline-svg.tsx +0 -36
  166. package/src/NavMenu/NavMenu.stories.jsx +0 -17
  167. package/src/NavMenu/images/OCAP.svg +0 -1
  168. package/src/NavMenu/images/abt-network.svg +0 -1
  169. package/src/NavMenu/images/ai-kit.svg +0 -1
  170. package/src/NavMenu/images/aigne-image-smith.svg +0 -1
  171. package/src/NavMenu/images/aigne.svg +0 -1
  172. package/src/NavMenu/images/aistro.png +0 -0
  173. package/src/NavMenu/images/arcsphere.svg +0 -1
  174. package/src/NavMenu/images/blocklet-framework.svg +0 -1
  175. package/src/NavMenu/images/blocklet-launcher.svg +0 -1
  176. package/src/NavMenu/images/blocklet-server.svg +0 -1
  177. package/src/NavMenu/images/blocklet-store.svg +0 -1
  178. package/src/NavMenu/images/creator-studio.svg +0 -1
  179. package/src/NavMenu/images/did-wallet.svg +0 -1
  180. package/src/NavMenu/images/did.svg +0 -1
  181. package/src/NavMenu/images/nft-studio.svg +0 -1
  182. package/src/NavMenu/images/payment-kit.png +0 -0
  183. package/src/NavMenu/images/vc.svg +0 -1
  184. package/src/NavMenu/images/web3-kit.svg +0 -1
  185. package/src/NavMenu/index.ts +0 -3
  186. package/src/NavMenu/nav-menu-context.tsx +0 -30
  187. package/src/NavMenu/nav-menu.tsx +0 -441
  188. package/src/NavMenu/products.tsx +0 -830
  189. package/src/NavMenu/style.ts +0 -258
  190. package/src/NavMenu/sub-container.tsx +0 -125
  191. package/src/NavMenu/sub-item-group.tsx +0 -42
  192. package/src/OrgTransfer/index.tsx +0 -53
  193. package/src/OrgTransfer/locales.ts +0 -25
  194. package/src/OrgTransfer/selector.tsx +0 -252
  195. package/src/OrgTransfer/type.ts +0 -31
  196. package/src/PageScroller/index.tsx +0 -316
  197. package/src/PageScroller/story/FifthComponent.jsx +0 -7
  198. package/src/PageScroller/story/FirstComponent.jsx +0 -7
  199. package/src/PageScroller/story/FourthComponent.jsx +0 -7
  200. package/src/PageScroller/story/FullPage.jsx +0 -55
  201. package/src/PageScroller/story/PageContain.jsx +0 -59
  202. package/src/PageScroller/story/PageScroller.stories.jsx +0 -18
  203. package/src/PageScroller/story/SecondComponent.jsx +0 -7
  204. package/src/PageScroller/story/ThirdComponent.jsx +0 -7
  205. package/src/PageScroller/story/index.css +0 -115
  206. package/src/PageScroller/usePrevValue.ts +0 -11
  207. package/src/Passport/index.ts +0 -3
  208. package/src/Passport/passport.tsx +0 -118
  209. package/src/PhoneInput/PhoneInput.stories.jsx +0 -12
  210. package/src/PhoneInput/country-select.tsx +0 -148
  211. package/src/PhoneInput/index.tsx +0 -269
  212. package/src/PoweredByArcBlock/index.tsx +0 -27
  213. package/src/PricingTable/PricingPlan.tsx +0 -120
  214. package/src/PricingTable/PricingTable.stories.jsx +0 -38
  215. package/src/PricingTable/index.tsx +0 -59
  216. package/src/QRCode/QRCode.stories.jsx +0 -13
  217. package/src/QRCode/index.tsx +0 -66
  218. package/src/RelativeTime/RelativeTime.stories.jsx +0 -20
  219. package/src/RelativeTime/index.tsx +0 -334
  220. package/src/Result/Result.stories.jsx +0 -61
  221. package/src/Result/common.tsx +0 -119
  222. package/src/Result/index.tsx +0 -30
  223. package/src/Result/result.tsx +0 -65
  224. package/src/Result/translations.ts +0 -57
  225. package/src/Screenshot/BaseScreenshot/index.tsx +0 -73
  226. package/src/Screenshot/BaseScreenshot/shells/Macbook.tsx +0 -38
  227. package/src/Screenshot/BaseScreenshot/shells/Phone.tsx +0 -35
  228. package/src/Screenshot/Screenshot.stories.jsx +0 -44
  229. package/src/Screenshot/devices.css +0 -1366
  230. package/src/Screenshot/index.tsx +0 -300
  231. package/src/SessionBlocklet/index.tsx +0 -178
  232. package/src/SessionManager/SessionManager.stories.jsx +0 -9
  233. package/src/SessionManager/index.tsx +0 -3
  234. package/src/SessionPermission/index.tsx +0 -26
  235. package/src/SessionUser/components/did-space.tsx +0 -68
  236. package/src/SessionUser/components/logged-in.tsx +0 -338
  237. package/src/SessionUser/components/quick-login-item.tsx +0 -132
  238. package/src/SessionUser/components/session-user-item.tsx +0 -93
  239. package/src/SessionUser/components/session-user-switch.tsx +0 -240
  240. package/src/SessionUser/components/un-login.tsx +0 -257
  241. package/src/SessionUser/components/user-info.tsx +0 -201
  242. package/src/SessionUser/index.tsx +0 -68
  243. package/src/SessionUser/libs/translation.ts +0 -30
  244. package/src/SessionUser/libs/utils.ts +0 -39
  245. package/src/SharedBridge/index.tsx +0 -126
  246. package/src/SocialShare/index.tsx +0 -194
  247. package/src/Sparkline/Sparkline.stories.jsx +0 -13
  248. package/src/Sparkline/index.tsx +0 -231
  249. package/src/Spinner/Spinner.stories.jsx +0 -98
  250. package/src/Spinner/index.tsx +0 -20
  251. package/src/SplitButton/SplitButton.stories.jsx +0 -32
  252. package/src/SplitButton/index.tsx +0 -116
  253. package/src/SplitButton/useClickAway.tsx +0 -24
  254. package/src/Success/index.tsx +0 -175
  255. package/src/Switch/Switch.stories.jsx +0 -16
  256. package/src/Switch/index.jsx +0 -79
  257. package/src/Tabs/Tabs.stories.jsx +0 -18
  258. package/src/Tabs/index.tsx +0 -255
  259. package/src/Tag/Tag.stories.jsx +0 -15
  260. package/src/Tag/index.jsx +0 -106
  261. package/src/TextCollapse/TextCollapse.stories.jsx +0 -73
  262. package/src/TextCollapse/index.tsx +0 -85
  263. package/src/Theme/Theme.stories.jsx +0 -11
  264. package/src/Theme/index.ts +0 -21
  265. package/src/Theme/theme-provider.tsx +0 -374
  266. package/src/Theme/theme.ts +0 -229
  267. package/src/Toast/Toast.stories.jsx +0 -28
  268. package/src/Toast/index.tsx +0 -80
  269. package/src/Typography/index.tsx +0 -124
  270. package/src/UserCard/Cards/avatar-only.tsx +0 -27
  271. package/src/UserCard/Cards/basic-info.tsx +0 -43
  272. package/src/UserCard/Cards/index.tsx +0 -16
  273. package/src/UserCard/Cards/social-actions.tsx +0 -196
  274. package/src/UserCard/Container/card.tsx +0 -63
  275. package/src/UserCard/Container/dialog.tsx +0 -37
  276. package/src/UserCard/Content/basic.tsx +0 -330
  277. package/src/UserCard/Content/clock.tsx +0 -82
  278. package/src/UserCard/Content/minimal.tsx +0 -113
  279. package/src/UserCard/Content/shorten-label.tsx +0 -32
  280. package/src/UserCard/Content/tooltip-avatar.tsx +0 -80
  281. package/src/UserCard/UserCard.stories.jsx +0 -19
  282. package/src/UserCard/components.tsx +0 -81
  283. package/src/UserCard/index.tsx +0 -132
  284. package/src/UserCard/types.ts +0 -165
  285. package/src/UserCard/use-follow.tsx +0 -111
  286. package/src/UserCard/utils.ts +0 -155
  287. package/src/Util/WebWalletOpener.stories.jsx +0 -5
  288. package/src/Util/client.ts +0 -4
  289. package/src/Util/constant.ts +0 -60
  290. package/src/Util/deprecate.tsx +0 -29
  291. package/src/Util/federated.ts +0 -125
  292. package/src/Util/iframe.ts +0 -19
  293. package/src/Util/index.ts +0 -760
  294. package/src/Util/logger.ts +0 -44
  295. package/src/Util/passport.ts +0 -127
  296. package/src/Util/security.ts +0 -72
  297. package/src/Util/style.ts +0 -17
  298. package/src/Util/wallet.ts +0 -35
  299. package/src/VerificationCode/index.tsx +0 -83
  300. package/src/Video/Video.stories.jsx +0 -6
  301. package/src/Video/index.tsx +0 -70
  302. package/src/Wallet/Action.stories.jsx +0 -8
  303. package/src/Wallet/Action.tsx +0 -118
  304. package/src/Wallet/Download.stories.jsx +0 -9
  305. package/src/Wallet/Download.tsx +0 -157
  306. package/src/Wallet/Open.tsx +0 -47
  307. package/src/Wallet/OpenInWallet.stories.jsx +0 -5
  308. package/src/Wallet/images/abtwallet.png +0 -0
  309. package/src/Wallet/images/android_download.svg +0 -22
  310. package/src/Wallet/images/app-store.svg +0 -30
  311. package/src/Wallet/images/google-play.svg +0 -69
  312. package/src/WalletOSIcon/index.tsx +0 -47
  313. package/src/WebWalletSWKeeper/index.tsx +0 -117
  314. package/src/WechatPrompt/images/android.png +0 -0
  315. package/src/WechatPrompt/images/ios.png +0 -0
  316. package/src/WechatPrompt/index.tsx +0 -75
  317. package/src/global.d.ts +0 -28
  318. package/src/hooks/use-blocklet-logo.tsx +0 -32
  319. package/src/hooks/use-clock.tsx +0 -62
  320. package/src/hooks/use-location-state.tsx +0 -117
  321. package/src/hooks/use-mobile.tsx +0 -6
  322. package/src/index.ts +0 -79
  323. package/src/type.d.ts +0 -44
  324. package/src/withTheme/index.tsx +0 -72
  325. package/src/withTracker/README.md +0 -37
  326. package/src/withTracker/action/bind-wallet.tsx +0 -17
  327. package/src/withTracker/action/login.tsx +0 -18
  328. package/src/withTracker/action/pay.tsx +0 -14
  329. package/src/withTracker/action/switch-passport.tsx +0 -20
  330. package/src/withTracker/constant/index.tsx +0 -3
  331. package/src/withTracker/env.tsx +0 -1
  332. package/src/withTracker/error_boundary.jsx +0 -34
  333. package/src/withTracker/index.tsx +0 -50
  334. package/src/withTracker/libs/utm.ts +0 -46
  335. package/vite.config.mjs +0 -37
package/src/Util/index.ts DELETED
@@ -1,760 +0,0 @@
1
- /* eslint-disable no-bitwise */
2
- import { lazy } from 'react';
3
- import padStart from 'lodash/padStart';
4
- import { getDIDMotifInfo, colors } from '@arcblock/did-motif';
5
- import { mergeAllThemeOptions } from '@blocklet/theme';
6
- import isNil from 'lodash/isNil';
7
- import omitBy from 'lodash/omitBy';
8
- import mergeWith from 'lodash/mergeWith';
9
- import pRetry from 'p-retry';
10
- import Cookies from 'js-cookie';
11
- import colorConvert from 'color-convert';
12
- import dayjs from 'dayjs';
13
- import 'dayjs/locale/zh-cn';
14
- import utc from 'dayjs/plugin/utc';
15
- import timezone from 'dayjs/plugin/timezone';
16
- import relativeTime from 'dayjs/plugin/relativeTime';
17
- import updateLocale from 'dayjs/plugin/updateLocale';
18
- import localizedFormat from 'dayjs/plugin/localizedFormat';
19
- import type { AxiosError } from 'axios';
20
- import semver from 'semver';
21
-
22
- import { DID_PREFIX, BLOCKLET_SERVICE_PATH_PREFIX } from './constant';
23
- import pkg from '../../package.json';
24
- import type { $TSFixMe, Locale } from '../type';
25
- import { getFederatedEnabled } from './federated';
26
-
27
- let dateTool: $TSFixMe | null = null;
28
- const IP_V4_REGEX = /^(\d{1,3}\.){3}\d{1,3}(:\d+)?$/;
29
- // 常见顶级域名
30
- const commonSLDs = new Set(['co', 'com', 'net', 'org', 'gov', 'edu', 'ac']);
31
- // 常见国家域名
32
- const commonCcTLDs = new Set(['uk', 'au', 'cn', 'nz', 'za', 'in', 'br', 'mx', 'fr', 'it', 'ca']);
33
-
34
- /** @deprecated for compatibility, please use `import { mergeAllThemeOptions } from '@blocklet/theme'` instead */
35
- export { mergeAllThemeOptions as deepmergeAll };
36
-
37
- /** 是否常见二段式顶级域名 */
38
- export function isTwoSegmentTLD(domain: string) {
39
- if (!domain) {
40
- return false;
41
- }
42
-
43
- const parts = domain.split('.');
44
-
45
- if (parts.length < 2) return false;
46
-
47
- const sld = parts[parts.length - 2];
48
- const tld = parts[parts.length - 1];
49
-
50
- return commonSLDs.has(sld) && commonCcTLDs.has(tld);
51
- }
52
-
53
- /** 获取根域名 */
54
- export function resolveRootDomain() {
55
- const { host } = window.location;
56
-
57
- if (!host) {
58
- return '';
59
- }
60
-
61
- if (IP_V4_REGEX.test(host)) {
62
- return '';
63
- }
64
-
65
- // 移除可能存在的端口号
66
- const hostWithoutPort = host.split(':')[0];
67
- const parts = hostWithoutPort.split('.');
68
-
69
- if (parts.length === 1) {
70
- return '';
71
- }
72
-
73
- // 二段式顶级域名
74
- if (parts.length > 2) {
75
- const tld = parts.slice(-2).join('.');
76
-
77
- if (isTwoSegmentTLD(tld)) {
78
- return `.${parts.slice(-3).join('.')}`;
79
- }
80
- }
81
-
82
- return `.${parts.slice(-2).join('.')}`;
83
- }
84
-
85
- export function parseQuery(str: string) {
86
- return str
87
- .replace(/^\?/, '')
88
- .split('&')
89
- .map((x) => x.split('='))
90
- .filter(([key]) => !!key)
91
- .reduce<Record<string, string | boolean>>((memo, x) => {
92
- const key = x[0];
93
- const value = decodeURIComponent(x[1]) || true;
94
- memo[key] = value;
95
- return memo;
96
- }, {});
97
- }
98
-
99
- export function stringifyQuery(params = {}) {
100
- return new URLSearchParams(params).toString();
101
- }
102
-
103
- export function getCookieOptions(
104
- expireInDays:
105
- | number
106
- | {
107
- expireInDays: number;
108
- path?: string;
109
- domain?: string;
110
- returnDomain?: boolean;
111
- sameSite?: Cookies.CookieAttributes['sameSite'];
112
- secure?: boolean;
113
- } = 1
114
- ) {
115
- let opts = expireInDays;
116
-
117
- if (typeof opts === 'number') {
118
- opts = { expireInDays: opts };
119
- }
120
-
121
- if (opts.path === undefined) {
122
- opts.path = '/';
123
- }
124
-
125
- if (!opts.expireInDays) {
126
- opts.expireInDays = 1;
127
- }
128
-
129
- const options: Cookies.CookieAttributes = {
130
- expires: opts.expireInDays,
131
- path: opts.path,
132
- domain: opts.domain || '',
133
- sameSite: opts.sameSite || 'Lax',
134
- // 允许自定义设置为 false,默认是 true
135
- secure: opts.secure !== false,
136
- };
137
- if (typeof window === 'undefined' || opts.domain || opts.returnDomain === false) {
138
- if (opts.returnDomain === false) {
139
- delete options.domain;
140
- }
141
- return options;
142
- }
143
-
144
- return options;
145
- }
146
-
147
- export const getColor = (props: $TSFixMe) => {
148
- if (props.color) {
149
- return props.color;
150
- }
151
-
152
- if (props.dark) {
153
- return props.theme.palette.common.white;
154
- }
155
-
156
- return props.theme.palette.text.primary;
157
- };
158
-
159
- export const getBackground = (props: $TSFixMe) => {
160
- if (props.background) {
161
- return props.background;
162
- }
163
-
164
- if (props.dark) {
165
- return props.theme.palette.common.black;
166
- }
167
-
168
- return props.theme.palette.common.white;
169
- };
170
-
171
- /**
172
- * 1. 将 props 中以 ::prop:: 开头的字符串替换为 component.defaultProps 中的值
173
- * 2. 将 props 中由 jsonAttrs 指定的 json 字符串转换为对象
174
- * 3. 最后将 props 中的 ::prop:: 字符串替换为 ''
175
- */
176
- export function mergeProps<P extends object>(
177
- props: Record<string, any>,
178
- component: React.ComponentType<P>,
179
- jsonAttrs: string[] = []
180
- ) {
181
- const newProps = Object.assign({}, props);
182
- const defaultProps = (component as any).defaultProps || {};
183
- Object.keys(defaultProps).forEach((x) => {
184
- if (typeof newProps[x] === 'string' && newProps[x].indexOf('::prop::') === 0) {
185
- newProps[x] = defaultProps[x];
186
- }
187
- });
188
-
189
- if (Array.isArray(jsonAttrs)) {
190
- jsonAttrs.forEach((x) => {
191
- if (typeof newProps[x] === 'string') {
192
- try {
193
- newProps[x] = JSON.parse(newProps[x]);
194
- } catch (err) {
195
- // Do nothing
196
- }
197
- }
198
- });
199
- }
200
-
201
- Object.keys(newProps).forEach((x) => {
202
- if (typeof newProps[x] === 'string' && newProps[x].indexOf('::prop::') === 0) {
203
- newProps[x] = '';
204
- }
205
- });
206
-
207
- return newProps;
208
- }
209
-
210
- export function getCopyright(startYear = 2017) {
211
- const currentYear = new Date().getFullYear();
212
- return `${currentYear}` === `${startYear}`
213
- ? `© ArcBlock ${currentYear}`
214
- : `© ArcBlock ${startYear} - ${currentYear}`;
215
- }
216
-
217
- export const getTimezone = () => {
218
- if (
219
- typeof Intl === 'object' &&
220
- typeof Intl.DateTimeFormat === 'function' &&
221
- typeof Intl.DateTimeFormat().resolvedOptions === 'function'
222
- ) {
223
- return Intl.DateTimeFormat().resolvedOptions().timeZone;
224
- }
225
-
226
- return '';
227
- };
228
-
229
- export const str2color = (str: string) => {
230
- let hash = 0;
231
- for (let i = 0; i < str.length; i++) {
232
- hash = str.charCodeAt(i) + ((hash << 5) - hash);
233
- }
234
- let colour = '#';
235
- for (let j = 0; j < 3; j++) {
236
- const value = (hash >> (j * 8)) & 0xff;
237
- colour += `00${value.toString(16)}`.substr(-2);
238
- }
239
- return colour;
240
- };
241
-
242
- export const formatUptime = (uptime: number) => {
243
- const total = Math.round(uptime / 1000);
244
- const hours = Math.floor(total / 3600);
245
- const minutes = Math.floor((total - hours * 3600) / 60);
246
- const seconds = total % 60;
247
- // @ts-expect-error
248
- return `${padStart(hours, 2, '0')}:${padStart(minutes, 2, '0')}:${padStart(seconds, 2, '0')}`;
249
- };
250
-
251
- /**
252
- * Set the date tool library which support for format() and locale() functions,
253
- * moment and dayjs are recommended.
254
- */
255
- export function setDateTool(tool: typeof dateTool) {
256
- dateTool = tool;
257
- }
258
-
259
- export function getDateTool() {
260
- return dateTool;
261
- }
262
-
263
- const createDateFormatter =
264
- (format: string) =>
265
- (date: string | number | Date, { locale, tz, isUtc }: { locale?: Locale; tz?: string; isUtc?: boolean } = {}) => {
266
- if (dateTool === null) {
267
- // 作为默认的 dateTool 使用
268
- dayjs.extend(localizedFormat);
269
- dayjs.extend(utc);
270
- dayjs.extend(timezone);
271
- dayjs.extend(updateLocale);
272
- dayjs.extend(relativeTime);
273
- dayjs.updateLocale('zh-cn', {
274
- // copy with https://github.com/iamkun/dayjs/blob/dev/src/locale/zh-cn.js
275
- relativeTime: {
276
- future: '%s后',
277
- past: '%s前',
278
- s: '几秒',
279
- m: '1 分钟',
280
- mm: '%d 分钟',
281
- h: '1 小时',
282
- hh: '%d 小时',
283
- d: '1 天',
284
- dd: '%d 天',
285
- M: '1 个月',
286
- MM: '%d 个月',
287
- y: '1 年',
288
- yy: '%d 年',
289
- },
290
- });
291
- setDateTool(dayjs);
292
- // throw new Error('call setDateTool to set the date tool library, such as: setDateTool(dayjs)');
293
- }
294
-
295
- if (isNil(date) || date === '') {
296
- return '-';
297
- }
298
-
299
- let instance = dateTool(date);
300
-
301
- if (tz) {
302
- instance = instance.tz(tz);
303
- }
304
-
305
- if (isUtc) {
306
- instance = instance.utc();
307
- }
308
-
309
- if (typeof locale !== 'undefined') {
310
- instance = instance.locale(locale);
311
- }
312
-
313
- return instance.format(format);
314
- };
315
-
316
- /**
317
- * Format the time string as `ll` format: MMM D, YYYY
318
- * Ensure that the setDateTool() function is called first to set the time tool library.
319
- * @returns formatted date string
320
- */
321
- export function formatToDate(
322
- date: string | number | Date,
323
- { locale = 'en', tz }: { locale?: Locale; tz?: string } = {}
324
- ) {
325
- return createDateFormatter('ll')(date, { locale, tz });
326
- }
327
-
328
- /**
329
- * Format the time string as `lll` format: MMM D, YYYY h:mm A
330
- * Ensure that the setDateTool() function is called first to set the time tool library.
331
- * @returns formatted date string
332
- */
333
- export function formatToDatetime(
334
- date: string | number | Date,
335
- {
336
- locale = 'en',
337
- tz,
338
- isUtc = false,
339
- format = 'lll',
340
- }: { locale?: Locale; tz?: string; isUtc?: boolean; format?: string } = {}
341
- ) {
342
- return createDateFormatter(format)(date, { locale, tz, isUtc });
343
- }
344
-
345
- export function detectWalletExtension() {
346
- // @ts-expect-error Property 'ABT_DEV' does not exist on type 'Window & typeof globalThis'.
347
- const extension = window?.ABT_DEV || window.ABT;
348
- if (extension && typeof extension.open === 'function') {
349
- return extension;
350
- }
351
-
352
- return null;
353
- }
354
-
355
- export function openWebWallet({
356
- webWalletUrl,
357
- action = 'login',
358
- locale = 'en',
359
- url,
360
- windowFeatures,
361
- appInfo,
362
- memberAppInfo,
363
- }: {
364
- webWalletUrl: string;
365
- action?: string;
366
- locale?: Locale;
367
- url: string;
368
- windowFeatures: $TSFixMe;
369
- appInfo: $TSFixMe;
370
- memberAppInfo: $TSFixMe;
371
- }) {
372
- // web wallet extension
373
- const extension = detectWalletExtension();
374
- if (extension) {
375
- extension.open({
376
- action,
377
- locale,
378
- url: encodeURIComponent(url),
379
- appInfo: {
380
- ...appInfo,
381
- },
382
- memberAppInfo: {
383
- ...memberAppInfo,
384
- },
385
- });
386
-
387
- return { type: 'extension' };
388
- }
389
-
390
- const defaultWindowFeatures = {
391
- toolbar: 'no',
392
- location: 'no',
393
- status: 'no',
394
- menubar: 'no',
395
- scrollbars: 'yes',
396
- resizable: 'yes',
397
- // iphone 8plus size
398
- width: 414,
399
- height: 736,
400
- };
401
- const windowUrl = `${webWalletUrl}?action=${action}&locale=${locale}&url=${encodeURIComponent(url)}`;
402
- const mergedWindowFeatures = Object.assign({}, defaultWindowFeatures, windowFeatures);
403
- const getWindowWidth = (win: Window) => {
404
- return win.innerWidth || win.document.documentElement.clientWidth || win.document.body.clientWidth;
405
- };
406
- // 默认在浏览器右上角弹出窗口
407
- if (!('left' in mergedWindowFeatures)) {
408
- const winWidth = getWindowWidth(window.top || window);
409
- const winLeft = window.screenLeft || window.screenX;
410
- mergedWindowFeatures.left = winWidth + winLeft - mergedWindowFeatures.width;
411
- }
412
- if (!('top' in mergedWindowFeatures)) {
413
- const winTop = window.screenTop || window.screenY;
414
- mergedWindowFeatures.top = winTop;
415
- }
416
- const strWindowFeatures = Object.keys(mergedWindowFeatures)
417
- .map((key) => `${key}=${mergedWindowFeatures[key]}`)
418
- .join(',');
419
- // 这里打开的是钱包的 URL,是安全的
420
- window.open(windowUrl, 'targetWindow', strWindowFeatures);
421
- return { type: 'web' };
422
- }
423
-
424
- export const getFontSize = (size: string | number) => {
425
- // 12px 及以上的 size 有效, 否则返回 inherit
426
- if (size && Number(size) >= 12) {
427
- return `${Number(size)}px`;
428
- }
429
- return 'inherit';
430
- };
431
-
432
- // 参考: asset-chain @arcblock/did
433
- export const isEthereumDid = (did: string) => {
434
- const address = did.replace(DID_PREFIX, '');
435
- // check if it has the basic requirements of an address
436
- if (!/^(0x)?[0-9a-f]{40}$/i.test(address)) {
437
- return false;
438
- }
439
- return true;
440
- };
441
-
442
- export const appendParams = (
443
- url: string,
444
- params: {
445
- imageFilter: 'crop' | 'resize';
446
- w?: number;
447
- h?: number;
448
- r?: 0 | 90 | 180 | 270;
449
- }
450
- ) => {
451
- if (!params) {
452
- return url;
453
- }
454
- try {
455
- // HACK: 如果 url 中带有域名,则 urlInstance.origin 为 url 中的域名;否则,借用当前页面的 location.origin 作为域名来拼接一个 url
456
- const urlInstance = new URL(url, window.location.origin);
457
- Object.keys(params).forEach((key) => {
458
- urlInstance.searchParams.set(key, String(params[key as keyof typeof params]));
459
- });
460
- // HACK: 如果前后域名一致,代表前面已经借用了 location.origin,这个时候只需要返回 urlInstance.pathname + urlInstance.search 即可
461
- if (urlInstance.origin === window.location.origin) {
462
- return urlInstance.pathname + urlInstance.search;
463
- }
464
- return urlInstance.href;
465
- } catch {
466
- return url;
467
- }
468
- };
469
-
470
- export const getUserAvatar = (avatar: string, size = 48) => {
471
- if (!avatar) {
472
- return avatar;
473
- }
474
-
475
- if (avatar.indexOf(BLOCKLET_SERVICE_PATH_PREFIX) >= 0) {
476
- return appendParams(avatar, {
477
- imageFilter: 'resize',
478
- w: size,
479
- h: size,
480
- });
481
- }
482
-
483
- return avatar;
484
- };
485
-
486
- export const sleep = (time = 0) => {
487
- return new Promise<void>((resolve) => {
488
- setTimeout(() => {
489
- resolve();
490
- }, time);
491
- });
492
- };
493
-
494
- export const isUrl = (str: string) => {
495
- return /^https?:\/\//.test(str);
496
- };
497
-
498
- const visitorIdKey = 'vid';
499
- const visitorIdKeyLegacy = '__visitor_id';
500
-
501
- export const getVisitorId = () => {
502
- // FIXME: @zhanghan 短期内做一个兼容,确保在 migrate 前的请求能够携带正确的 vid
503
- return Cookies.get(visitorIdKey) || localStorage.getItem(visitorIdKeyLegacy);
504
- };
505
-
506
- export const setVisitorId = (value: string | null) => {
507
- if (value === null) {
508
- Cookies.remove(visitorIdKey, {
509
- sameSite: 'None',
510
- secure: true,
511
- });
512
- } else {
513
- Cookies.set(visitorIdKey, value, {
514
- sameSite: 'None',
515
- secure: true,
516
- expires: 365,
517
- });
518
- }
519
- };
520
-
521
- export const ensureVisitorId = () => {
522
- let visitorId = localStorage.getItem(visitorIdKeyLegacy);
523
- if (visitorId) {
524
- localStorage.removeItem(visitorIdKeyLegacy);
525
- setVisitorId(visitorId);
526
- }
527
- if (getVisitorId()) {
528
- return;
529
- }
530
-
531
- if (!getFederatedEnabled()) {
532
- try {
533
- // 在支持 crypto.randomUUID 的环境中使用
534
- if (window.crypto && typeof window.crypto.randomUUID === 'function') {
535
- visitorId = window.crypto.randomUUID();
536
- } else {
537
- // 在不支持 crypto.randomUUID 的环境中生成随机 ID
538
- const randomValues = new Uint8Array(16);
539
- if (window.crypto && typeof window.crypto.getRandomValues === 'function') {
540
- window.crypto.getRandomValues(randomValues);
541
- } else {
542
- // 降级方案:使用 Math.random 生成
543
- for (let i = 0; i < 16; i++) {
544
- randomValues[i] = Math.floor(Math.random() * 256);
545
- }
546
- }
547
-
548
- // 转换为 UUID 格式
549
- const hexArray = Array.from(randomValues).map((b) => b.toString(16).padStart(2, '0'));
550
- visitorId = [
551
- hexArray.slice(0, 4).join(''),
552
- hexArray.slice(4, 6).join(''),
553
- hexArray.slice(6, 8).join(''),
554
- hexArray.slice(8, 10).join(''),
555
- hexArray.slice(10, 16).join(''),
556
- ].join('-');
557
- }
558
- } catch (error) {
559
- // 如果上述方法都失败,使用时间戳和随机数生成
560
- visitorId = `${Date.now()}-${Math.random().toString(36).substring(2, 15)}`;
561
- }
562
- }
563
-
564
- if (visitorId) {
565
- setVisitorId(visitorId);
566
- }
567
- };
568
-
569
- export const getDIDColor = (did: string) => {
570
- if (isEthereumDid(did)) {
571
- const index =
572
- Uint8Array.from(
573
- did
574
- .slice(2)
575
- .match(/.{1,2}/g)!
576
- .map((pair) => parseInt(pair, 16))
577
- )
578
- .slice(0, 8)
579
- .reduce((acc, val) => acc + val, 0) % colors.length;
580
-
581
- return colors[index];
582
- }
583
- try {
584
- const didMotifInfo = getDIDMotifInfo(did);
585
- return didMotifInfo?.color;
586
- } catch {
587
- return null;
588
- }
589
- };
590
-
591
- type NestedTranslation = {
592
- [key: string]: string | NestedTranslation;
593
- };
594
-
595
- type TranslationsObject = {
596
- [locale: string]: NestedTranslation;
597
- };
598
-
599
- /**
600
- * Retrieves the appropriate translation based on the locale, with fallback options.
601
- * @return {string} The translated string based on the locale, with fallback options if necessary.
602
- */
603
- export const getTranslation = (
604
- translations: TranslationsObject,
605
- locale: Locale,
606
- options: { fallbackLocale?: Locale; defaultValue?: string } = {}
607
- ) => {
608
- const { fallbackLocale = 'en', defaultValue = 'unknown' } = options;
609
-
610
- if (typeof translations === 'string') {
611
- return translations;
612
- }
613
-
614
- let translation;
615
- if (locale) {
616
- translation = translations[locale];
617
- }
618
- if (!translation || typeof translation !== 'string') {
619
- translation = translations[fallbackLocale];
620
- }
621
- if (!translation || typeof translation !== 'string') {
622
- translation = defaultValue;
623
- }
624
-
625
- return translation;
626
- };
627
-
628
- export const lazyRetry = (fn: () => Promise<any>) =>
629
- lazy(() =>
630
- pRetry(
631
- async () => {
632
- try {
633
- return await fn();
634
- } catch (error: unknown) {
635
- // HACK: pRetry 不会对 TypeError 的错误进行重试,手动放行了部分 network error 的错误,但此处的错误是经过 react-router 包装过的,不适用于上述的判断,所以这里需要特殊逻辑来进行处理
636
- if (error instanceof TypeError && !error.message.includes('Failed to fetch')) {
637
- throw error;
638
- }
639
- if (error instanceof Error) {
640
- throw new Error(error.message);
641
- }
642
- throw new Error('Unknown error');
643
- }
644
- },
645
- // 只需要重试两次,加上原本的一次,总共三次
646
- { retries: 2 }
647
- )
648
- );
649
-
650
- export const cleanedObj = (obj: object) => {
651
- return omitBy(obj, isNil);
652
- };
653
-
654
- /**
655
- * 将十六进制颜色转换为 RGBA
656
- * @param hex 十六进制颜色字符串 (例如: "#FF0000" 或 "FF0000")
657
- * @param alpha 透明度值 (0-1 之间,默认为 1)
658
- * @returns RGBA 颜色字符串 (例如: "rgba(255, 0, 0, 1)")
659
- */
660
- export function hexToRgba(hex: string, alpha = 1) {
661
- const [r, g, b] = colorConvert.hex.rgb(hex);
662
- // 返回 RGBA 格式
663
- return `rgba(${r}, ${g}, ${b}, ${alpha})`;
664
- }
665
-
666
- // 获取 server 的版本号
667
- export const getServerVersion = () => {
668
- return window.blocklet?.serverVersion || window.env?.serverVersion || '';
669
- };
670
-
671
- // 获取 UX 包版本号
672
- export const getUxPackageVersion = () => {
673
- return pkg.version || '';
674
- };
675
-
676
- export const getJsSdkVersion = () => {
677
- // 从 package.json 的 dependencies 中获取 @blocklet/js-sdk 的版本
678
- const jsSdkVersion = pkg.dependencies?.['@blocklet/js-sdk'];
679
- if (!jsSdkVersion) {
680
- return '';
681
- }
682
- // 移除版本前缀符号 (^, ~, >=, 等)
683
- return jsSdkVersion.replace(/^[\^~>=<]+/, '');
684
- };
685
-
686
- /**
687
- * 比较两个版本号,version1 是否大于等于 version2
688
- * @param {*} version1
689
- * @param {*} version2
690
- * @returns boolean
691
- */
692
- export const compareVersions = (version1: string, version2: string): boolean => {
693
- const getDateVersion = (version: string) => {
694
- const match = version.match(/^(\d+\.\d+\.\d+(?:-[^-]+?-\d{8}))/);
695
- return match ? match[1] : version;
696
- };
697
- // 如果版本号为空,返回 false
698
- if (!version1 || !version2) {
699
- return false;
700
- }
701
-
702
- const dateVersion1 = getDateVersion(version1);
703
- const dateVersion2 = getDateVersion(version2);
704
-
705
- // 如果基础版本相同,但完整版本不同(意味着有额外部分),返回false
706
- if (dateVersion1 === dateVersion2 && version1 !== version2) {
707
- return false;
708
- }
709
-
710
- try {
711
- // 其他情况正常比较
712
- return semver.gte(dateVersion1, dateVersion2);
713
- } catch {
714
- return false;
715
- }
716
- };
717
-
718
- /**
719
- * 是否支持用户的 follow 关系
720
- * 通过 server 的版本和 ux 的版本共同决定
721
- */
722
- export const isSupportFollow = () => {
723
- // HACK: 本地开发时,为了测试方便,暂时放开限制
724
- if (process.env.NODE_ENV === 'development') {
725
- return true;
726
- }
727
- const serverVersion = getServerVersion();
728
- const uxVersion = getUxPackageVersion();
729
- const jsSdkVersion = getJsSdkVersion();
730
-
731
- if (!serverVersion || !uxVersion || !jsSdkVersion) {
732
- return false;
733
- }
734
- // UX 包支持
735
- const uxVersionSupport = compareVersions(uxVersion, '3.1.29');
736
- // 服务端接口实现支持
737
- const serverVersionSupport = compareVersions(serverVersion, '1.16.49-beta-20250822-070545-6d3344cc');
738
- // SDK 接口实现支持
739
- const jsSdkVersionSupport = compareVersions(jsSdkVersion, '1.16.49-beta-20250822-070545-6d3344cc');
740
- return uxVersionSupport && serverVersionSupport && jsSdkVersionSupport;
741
- };
742
-
743
- export const formatAxiosError = (err: AxiosError) => {
744
- const { response } = err;
745
-
746
- if (response) {
747
- return `Request failed: ${response.status} ${response.statusText}: ${JSON.stringify(response.data)}`;
748
- }
749
-
750
- return err.message || 'Unknown error occurred';
751
- };
752
-
753
- export const mergeIgnoreEmpty = (...objects: Array<Record<string, any>>) => {
754
- return mergeWith({}, ...objects, (objValue: any, srcValue: any) => {
755
- if (srcValue === '' || srcValue === null || srcValue === undefined) {
756
- return objValue; // 保留前面的值
757
- }
758
- return srcValue; // 使用后面的值
759
- });
760
- };