@arcblock/ux 3.4.15 → 3.5.1

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 (333) hide show
  1. package/lib/package.json.js +1 -1
  2. package/package.json +10 -7
  3. package/src/ActionButton/ActionButton.stories.jsx +0 -61
  4. package/src/ActionButton/index.jsx +0 -106
  5. package/src/ActivityIndicator/ActivityIndicator.stories.jsx +0 -9
  6. package/src/ActivityIndicator/index.jsx +0 -140
  7. package/src/Address/Address.stories.jsx +0 -38
  8. package/src/Address/compact-text.jsx +0 -76
  9. package/src/Address/did-address.tsx +0 -223
  10. package/src/Address/index.tsx +0 -21
  11. package/src/Address/responsive-did-address.tsx +0 -154
  12. package/src/Alert/Alert.stories.jsx +0 -100
  13. package/src/Alert/index.jsx +0 -130
  14. package/src/AnimationWaiter/AnimationWaiter.stories.jsx +0 -35
  15. package/src/AnimationWaiter/dark-animation.json +0 -1
  16. package/src/AnimationWaiter/default-animation.json +0 -1
  17. package/src/AnimationWaiter/index.jsx +0 -296
  18. package/src/Async/index.tsx +0 -44
  19. package/src/Avatar/Avatar.stories.jsx +0 -11
  20. package/src/Avatar/did-motif.jsx +0 -38
  21. package/src/Avatar/etherscan-blockies.js +0 -81
  22. package/src/Avatar/index.jsx +0 -195
  23. package/src/Badge/Badge.stories.jsx +0 -41
  24. package/src/Badge/index.jsx +0 -101
  25. package/src/Blocklet/Blocklet.stories.jsx +0 -21
  26. package/src/Blocklet/blocklet.jsx +0 -276
  27. package/src/Blocklet/index.js +0 -5
  28. package/src/Blocklet/utils.jsx +0 -58
  29. package/src/BlockletContext/index.tsx +0 -72
  30. package/src/BlockletNFT/BlockletNFT.stories.jsx +0 -21
  31. package/src/BlockletNFT/index.jsx +0 -378
  32. package/src/BlockletV2/Blocklet.stories.jsx +0 -34
  33. package/src/BlockletV2/blocklet.tsx +0 -247
  34. package/src/BlockletV2/components/icon-text.tsx +0 -47
  35. package/src/BlockletV2/components/tooltip-icon.tsx +0 -52
  36. package/src/BlockletV2/index.ts +0 -6
  37. package/src/BlockletV2/utils.js +0 -75
  38. package/src/Button/Button.stories.jsx +0 -24
  39. package/src/Button/index.js +0 -9
  40. package/src/Button/wrap.jsx +0 -126
  41. package/src/ButtonGroup/index.js +0 -16
  42. package/src/CardSelector/index.tsx +0 -136
  43. package/src/Center/Center.stories.jsx +0 -20
  44. package/src/Center/index.tsx +0 -33
  45. package/src/ClickToCopy/ClickToCopy.stories.jsx +0 -24
  46. package/src/ClickToCopy/copy-button.tsx +0 -43
  47. package/src/ClickToCopy/hook.ts +0 -42
  48. package/src/ClickToCopy/index.tsx +0 -96
  49. package/src/CloseButton/index.tsx +0 -37
  50. package/src/CodeBlock/CodeBlock.stories.jsx +0 -22
  51. package/src/CodeBlock/LightBox.tsx +0 -87
  52. package/src/CodeBlock/index.tsx +0 -217
  53. package/src/Colors/Colors.stories.jsx +0 -211
  54. package/src/Colors/index.ts +0 -4
  55. package/src/Colors/themes/default.ts +0 -8
  56. package/src/Colors/themes/did-connect.ts +0 -64
  57. package/src/Colors/themes/temp.ts +0 -52
  58. package/src/Config/Config.stories.jsx +0 -16
  59. package/src/Config/config-provider.tsx +0 -62
  60. package/src/Config/index.ts +0 -2
  61. package/src/Config/theme-mode-toggle.tsx +0 -38
  62. package/src/ContactForm/ContactForm.stories.jsx +0 -32
  63. package/src/ContactForm/index.tsx +0 -264
  64. package/src/CookieConsent/CookieConsent.stories.jsx +0 -33
  65. package/src/CookieConsent/index.tsx +0 -104
  66. package/src/CountDown/CountDown.stories.jsx +0 -15
  67. package/src/CountDown/index.tsx +0 -170
  68. package/src/DID/DID.stories.jsx +0 -37
  69. package/src/DID/index.tsx +0 -393
  70. package/src/DIDConnect/app-icon.tsx +0 -37
  71. package/src/DIDConnect/app-info-item.tsx +0 -93
  72. package/src/DIDConnect/auth-apps/auth-apps-info.tsx +0 -77
  73. package/src/DIDConnect/auth-apps/index.tsx +0 -278
  74. package/src/DIDConnect/auth-apps/switch-role.tsx +0 -47
  75. package/src/DIDConnect/did-connect-container.tsx +0 -326
  76. package/src/DIDConnect/did-connect-footer.tsx +0 -76
  77. package/src/DIDConnect/did-connect-logo.tsx +0 -8
  78. package/src/DIDConnect/icons/did-wallet-logo.tsx +0 -18
  79. package/src/DIDConnect/icons/github-logo.tsx +0 -17
  80. package/src/DIDConnect/index.ts +0 -11
  81. package/src/DIDConnect/landing-page.tsx +0 -218
  82. package/src/DIDConnect/powered-by.tsx +0 -48
  83. package/src/DIDConnect/provider-icon.tsx +0 -62
  84. package/src/DIDConnect/request-storage-access-api-dialog.tsx +0 -304
  85. package/src/DIDConnect/with-container.tsx +0 -323
  86. package/src/DIDConnect/with-ux-theme.tsx +0 -22
  87. package/src/DIDLogo/Logo.stories.jsx +0 -11
  88. package/src/DIDLogo/index.tsx +0 -168
  89. package/src/Datatable/CustomToolbar.jsx +0 -415
  90. package/src/Datatable/Datatable.stories.jsx +0 -92
  91. package/src/Datatable/DatatableContext.jsx +0 -35
  92. package/src/Datatable/TableSearch.jsx +0 -166
  93. package/src/Datatable/index.jsx +0 -652
  94. package/src/Datatable/utils.js +0 -161
  95. package/src/Dialog/Dialog.stories.jsx +0 -21
  96. package/src/Dialog/confirm.jsx +0 -143
  97. package/src/Dialog/dialog.jsx +0 -199
  98. package/src/Dialog/index.js +0 -4
  99. package/src/Dialog/types.d.ts +0 -20
  100. package/src/Dialog/use-confirm.jsx +0 -188
  101. package/src/DriftBot/index.tsx +0 -81
  102. package/src/Earth/Earth.stories.jsx +0 -39
  103. package/src/Earth/countries.json +0 -8057
  104. package/src/Earth/index.tsx +0 -515
  105. package/src/Earth/util.ts +0 -72
  106. package/src/Empty/Empty.stories.jsx +0 -23
  107. package/src/Empty/index.jsx +0 -48
  108. package/src/ErrorBoundary/ErrorBoundary.stories.jsx +0 -13
  109. package/src/ErrorBoundary/fallback.tsx +0 -85
  110. package/src/ErrorBoundary/index.ts +0 -1
  111. package/src/Footer/Footer.stories.jsx +0 -13
  112. package/src/Footer/index.tsx +0 -130
  113. package/src/Header/Header.stories.jsx +0 -30
  114. package/src/Header/addon-button.tsx +0 -41
  115. package/src/Header/auto-hidden.tsx +0 -31
  116. package/src/Header/header-addons.tsx +0 -37
  117. package/src/Header/header.tsx +0 -214
  118. package/src/Header/index.ts +0 -3
  119. package/src/Header/responsive-header.tsx +0 -145
  120. package/src/Icon/Icon.stories.jsx +0 -45
  121. package/src/Icon/image.tsx +0 -53
  122. package/src/Icon/index.tsx +0 -63
  123. package/src/Img/Img.stories.jsx +0 -17
  124. package/src/Img/index.jsx +0 -258
  125. package/src/InfoRow/InfoRow.stories.jsx +0 -14
  126. package/src/InfoRow/index.tsx +0 -91
  127. package/src/Layout/Layout.stories.jsx +0 -24
  128. package/src/Layout/dashboard/external-link.tsx +0 -59
  129. package/src/Layout/dashboard/full-page.tsx +0 -58
  130. package/src/Layout/dashboard/index.tsx +0 -260
  131. package/src/Layout/dashboard/sidebar.tsx +0 -198
  132. package/src/Layout/dashboard-legacy/header.tsx +0 -156
  133. package/src/Layout/dashboard-legacy/index.tsx +0 -127
  134. package/src/Layout/dashboard-legacy/sidebar.tsx +0 -129
  135. package/src/Layout/index.tsx +0 -310
  136. package/src/LoadingMask/index.tsx +0 -108
  137. package/src/Locale/LocaleSelector.stories.jsx +0 -44
  138. package/src/Locale/browser-lang.ts +0 -65
  139. package/src/Locale/context.tsx +0 -162
  140. package/src/Locale/languages.ts +0 -58
  141. package/src/Locale/selector.tsx +0 -174
  142. package/src/Locale/util.ts +0 -38
  143. package/src/Logo/Logo.stories.jsx +0 -23
  144. package/src/Logo/images/logo-dark-text.svg +0 -3
  145. package/src/Logo/images/logo-dark-top.svg +0 -6
  146. package/src/Logo/images/logo-light-text.svg +0 -3
  147. package/src/Logo/images/logo-light-top.svg +0 -6
  148. package/src/Logo/index.tsx +0 -58
  149. package/src/Metric/Metric.stories.jsx +0 -29
  150. package/src/Metric/index.tsx +0 -130
  151. package/src/MuiWrap/index.tsx +0 -10
  152. package/src/NFTDisplay/NFTBroken.svg +0 -34
  153. package/src/NFTDisplay/NFTDisplay.stories.jsx +0 -30
  154. package/src/NFTDisplay/README.md +0 -59
  155. package/src/NFTDisplay/aspect-ratio-container.tsx +0 -36
  156. package/src/NFTDisplay/broken.tsx +0 -51
  157. package/src/NFTDisplay/displayApi.ts +0 -43
  158. package/src/NFTDisplay/index.tsx +0 -393
  159. package/src/NFTDisplay/loading.tsx +0 -16
  160. package/src/NFTDisplay/preview.tsx +0 -84
  161. package/src/NFTDisplay/render-svg.tsx +0 -21
  162. package/src/NFTDisplay/svg-embedder/img.tsx +0 -27
  163. package/src/NFTDisplay/svg-embedder/inline-svg.tsx +0 -36
  164. package/src/NavMenu/NavMenu.stories.jsx +0 -17
  165. package/src/NavMenu/images/OCAP.svg +0 -1
  166. package/src/NavMenu/images/abt-network.svg +0 -1
  167. package/src/NavMenu/images/ai-kit.svg +0 -1
  168. package/src/NavMenu/images/aigne-image-smith.svg +0 -1
  169. package/src/NavMenu/images/aigne.svg +0 -1
  170. package/src/NavMenu/images/aistro.png +0 -0
  171. package/src/NavMenu/images/arcsphere.svg +0 -1
  172. package/src/NavMenu/images/blocklet-framework.svg +0 -1
  173. package/src/NavMenu/images/blocklet-launcher.svg +0 -1
  174. package/src/NavMenu/images/blocklet-server.svg +0 -1
  175. package/src/NavMenu/images/blocklet-store.svg +0 -1
  176. package/src/NavMenu/images/creator-studio.svg +0 -1
  177. package/src/NavMenu/images/did-wallet.svg +0 -1
  178. package/src/NavMenu/images/did.svg +0 -1
  179. package/src/NavMenu/images/nft-studio.svg +0 -1
  180. package/src/NavMenu/images/payment-kit.png +0 -0
  181. package/src/NavMenu/images/vc.svg +0 -1
  182. package/src/NavMenu/images/web3-kit.svg +0 -1
  183. package/src/NavMenu/index.ts +0 -3
  184. package/src/NavMenu/nav-menu-context.tsx +0 -30
  185. package/src/NavMenu/nav-menu.tsx +0 -441
  186. package/src/NavMenu/products.tsx +0 -830
  187. package/src/NavMenu/style.ts +0 -258
  188. package/src/NavMenu/sub-container.tsx +0 -125
  189. package/src/NavMenu/sub-item-group.tsx +0 -42
  190. package/src/OrgTransfer/index.tsx +0 -53
  191. package/src/OrgTransfer/locales.ts +0 -25
  192. package/src/OrgTransfer/selector.tsx +0 -252
  193. package/src/OrgTransfer/type.ts +0 -31
  194. package/src/PageScroller/index.tsx +0 -316
  195. package/src/PageScroller/story/FifthComponent.jsx +0 -7
  196. package/src/PageScroller/story/FirstComponent.jsx +0 -7
  197. package/src/PageScroller/story/FourthComponent.jsx +0 -7
  198. package/src/PageScroller/story/FullPage.jsx +0 -55
  199. package/src/PageScroller/story/PageContain.jsx +0 -59
  200. package/src/PageScroller/story/PageScroller.stories.jsx +0 -18
  201. package/src/PageScroller/story/SecondComponent.jsx +0 -7
  202. package/src/PageScroller/story/ThirdComponent.jsx +0 -7
  203. package/src/PageScroller/story/index.css +0 -115
  204. package/src/PageScroller/usePrevValue.ts +0 -11
  205. package/src/Passport/index.ts +0 -3
  206. package/src/Passport/passport.tsx +0 -118
  207. package/src/PhoneInput/PhoneInput.stories.jsx +0 -12
  208. package/src/PhoneInput/country-select.tsx +0 -148
  209. package/src/PhoneInput/index.tsx +0 -269
  210. package/src/PoweredByArcBlock/index.tsx +0 -27
  211. package/src/PricingTable/PricingPlan.tsx +0 -120
  212. package/src/PricingTable/PricingTable.stories.jsx +0 -38
  213. package/src/PricingTable/index.tsx +0 -59
  214. package/src/QRCode/QRCode.stories.jsx +0 -13
  215. package/src/QRCode/index.tsx +0 -66
  216. package/src/RelativeTime/RelativeTime.stories.jsx +0 -20
  217. package/src/RelativeTime/index.tsx +0 -334
  218. package/src/Result/Result.stories.jsx +0 -61
  219. package/src/Result/common.tsx +0 -119
  220. package/src/Result/index.tsx +0 -30
  221. package/src/Result/result.tsx +0 -65
  222. package/src/Result/translations.ts +0 -57
  223. package/src/Screenshot/BaseScreenshot/index.tsx +0 -73
  224. package/src/Screenshot/BaseScreenshot/shells/Macbook.tsx +0 -38
  225. package/src/Screenshot/BaseScreenshot/shells/Phone.tsx +0 -35
  226. package/src/Screenshot/Screenshot.stories.jsx +0 -44
  227. package/src/Screenshot/devices.css +0 -1366
  228. package/src/Screenshot/index.tsx +0 -300
  229. package/src/SessionBlocklet/index.tsx +0 -178
  230. package/src/SessionManager/SessionManager.stories.jsx +0 -9
  231. package/src/SessionManager/index.tsx +0 -3
  232. package/src/SessionPermission/index.tsx +0 -26
  233. package/src/SessionUser/components/did-space.tsx +0 -68
  234. package/src/SessionUser/components/logged-in.tsx +0 -338
  235. package/src/SessionUser/components/quick-login-item.tsx +0 -132
  236. package/src/SessionUser/components/session-user-item.tsx +0 -93
  237. package/src/SessionUser/components/session-user-switch.tsx +0 -240
  238. package/src/SessionUser/components/un-login.tsx +0 -257
  239. package/src/SessionUser/components/user-info.tsx +0 -201
  240. package/src/SessionUser/index.tsx +0 -68
  241. package/src/SessionUser/libs/translation.ts +0 -30
  242. package/src/SessionUser/libs/utils.ts +0 -39
  243. package/src/SharedBridge/index.tsx +0 -126
  244. package/src/SocialShare/index.tsx +0 -194
  245. package/src/Sparkline/Sparkline.stories.jsx +0 -13
  246. package/src/Sparkline/index.tsx +0 -231
  247. package/src/Spinner/Spinner.stories.jsx +0 -98
  248. package/src/Spinner/index.tsx +0 -20
  249. package/src/SplitButton/SplitButton.stories.jsx +0 -32
  250. package/src/SplitButton/index.tsx +0 -116
  251. package/src/SplitButton/useClickAway.tsx +0 -24
  252. package/src/Success/index.tsx +0 -175
  253. package/src/Switch/Switch.stories.jsx +0 -16
  254. package/src/Switch/index.jsx +0 -79
  255. package/src/Tabs/Tabs.stories.jsx +0 -18
  256. package/src/Tabs/index.tsx +0 -255
  257. package/src/Tag/Tag.stories.jsx +0 -15
  258. package/src/Tag/index.jsx +0 -106
  259. package/src/TextCollapse/TextCollapse.stories.jsx +0 -73
  260. package/src/TextCollapse/index.tsx +0 -85
  261. package/src/Theme/Theme.stories.jsx +0 -11
  262. package/src/Theme/index.ts +0 -21
  263. package/src/Theme/theme-provider.tsx +0 -374
  264. package/src/Theme/theme.ts +0 -229
  265. package/src/Toast/Toast.stories.jsx +0 -28
  266. package/src/Toast/index.tsx +0 -80
  267. package/src/Typography/index.tsx +0 -124
  268. package/src/UserCard/Cards/avatar-only.tsx +0 -27
  269. package/src/UserCard/Cards/basic-info.tsx +0 -43
  270. package/src/UserCard/Cards/index.tsx +0 -16
  271. package/src/UserCard/Cards/social-actions.tsx +0 -196
  272. package/src/UserCard/Container/card.tsx +0 -63
  273. package/src/UserCard/Container/dialog.tsx +0 -37
  274. package/src/UserCard/Content/basic.tsx +0 -330
  275. package/src/UserCard/Content/clock.tsx +0 -82
  276. package/src/UserCard/Content/minimal.tsx +0 -113
  277. package/src/UserCard/Content/shorten-label.tsx +0 -32
  278. package/src/UserCard/Content/tooltip-avatar.tsx +0 -80
  279. package/src/UserCard/UserCard.stories.jsx +0 -19
  280. package/src/UserCard/components.tsx +0 -81
  281. package/src/UserCard/index.tsx +0 -132
  282. package/src/UserCard/types.ts +0 -165
  283. package/src/UserCard/use-follow.tsx +0 -111
  284. package/src/UserCard/utils.ts +0 -155
  285. package/src/Util/WebWalletOpener.stories.jsx +0 -5
  286. package/src/Util/client.ts +0 -4
  287. package/src/Util/constant.ts +0 -70
  288. package/src/Util/deprecate.tsx +0 -29
  289. package/src/Util/federated.ts +0 -125
  290. package/src/Util/iframe.ts +0 -19
  291. package/src/Util/index.ts +0 -760
  292. package/src/Util/logger.ts +0 -44
  293. package/src/Util/passport.ts +0 -127
  294. package/src/Util/security.ts +0 -72
  295. package/src/Util/style.ts +0 -17
  296. package/src/Util/wallet.ts +0 -35
  297. package/src/VerificationCode/index.tsx +0 -83
  298. package/src/Video/Video.stories.jsx +0 -6
  299. package/src/Video/index.tsx +0 -70
  300. package/src/Wallet/Action.stories.jsx +0 -8
  301. package/src/Wallet/Action.tsx +0 -118
  302. package/src/Wallet/Download.stories.jsx +0 -9
  303. package/src/Wallet/Download.tsx +0 -157
  304. package/src/Wallet/Open.tsx +0 -47
  305. package/src/Wallet/OpenInWallet.stories.jsx +0 -5
  306. package/src/Wallet/images/abtwallet.png +0 -0
  307. package/src/Wallet/images/android_download.svg +0 -22
  308. package/src/Wallet/images/app-store.svg +0 -30
  309. package/src/Wallet/images/google-play.svg +0 -69
  310. package/src/WalletOSIcon/index.tsx +0 -47
  311. package/src/WebWalletSWKeeper/index.tsx +0 -117
  312. package/src/WechatPrompt/images/android.png +0 -0
  313. package/src/WechatPrompt/images/ios.png +0 -0
  314. package/src/WechatPrompt/index.tsx +0 -75
  315. package/src/global.d.ts +0 -28
  316. package/src/hooks/use-blocklet-logo.tsx +0 -32
  317. package/src/hooks/use-clock.tsx +0 -62
  318. package/src/hooks/use-location-state.tsx +0 -117
  319. package/src/hooks/use-mobile.tsx +0 -6
  320. package/src/index.ts +0 -79
  321. package/src/type.d.ts +0 -44
  322. package/src/withTheme/index.tsx +0 -72
  323. package/src/withTracker/README.md +0 -37
  324. package/src/withTracker/action/bind-wallet.tsx +0 -17
  325. package/src/withTracker/action/login.tsx +0 -18
  326. package/src/withTracker/action/pay.tsx +0 -14
  327. package/src/withTracker/action/switch-passport.tsx +0 -20
  328. package/src/withTracker/constant/index.tsx +0 -3
  329. package/src/withTracker/env.tsx +0 -1
  330. package/src/withTracker/error_boundary.jsx +0 -34
  331. package/src/withTracker/index.tsx +0 -50
  332. package/src/withTracker/libs/utm.ts +0 -46
  333. 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
- };