@arcblock/did-connect-react 3.4.1 → 3.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,8 @@
1
1
  import { jsx as t, jsxs as b, Fragment as He } from "react/jsx-runtime";
2
- import { use as Ve, useRef as le, useState as Ye, useEffect as ue } from "react";
2
+ import { use as Ve, useRef as ce, useState as Ye, useEffect as le } from "react";
3
3
  import e from "prop-types";
4
4
  import { Box as i, Skeleton as Ge, Divider as Ke } from "@mui/material";
5
- import { useUpdate as Qe, useSize as Xe, useCreation as u, useMount as de, useMemoizedFn as F, useDebounceFn as Je, usePrevious as Ze, useUpdateEffect as $e } from "ahooks";
5
+ import { useUpdate as Qe, useSize as Xe, useCreation as u, useMount as ue, useMemoizedFn as F, useDebounceFn as Je, usePrevious as Ze, useUpdateEffect as $e } from "ahooks";
6
6
  import C from "lodash/noop";
7
7
  import et from "lodash/isUndefined";
8
8
  import tt from "@arcblock/ux/lib/CloseButton";
@@ -30,7 +30,7 @@ import It from "./hooks/auth-url.js";
30
30
  import { getWalletDid as vt } from "../User/use-did.js";
31
31
  import Pt from "./fallback-connect.js";
32
32
  import { getWebWalletUrl as _t } from "@arcblock/ux/lib/Util/wallet";
33
- function fe({
33
+ function de({
34
34
  hideCloseButton: y = !1,
35
35
  mode: p = "dialog",
36
36
  action: I,
@@ -41,70 +41,70 @@ function fe({
41
41
  prefix: D = Ct,
42
42
  tokenKey: B = "_t_",
43
43
  locale: q = "en",
44
- encKey: me = "_ek_",
45
- autoConnect: pe = !0,
44
+ encKey: fe = "_ek_",
45
+ autoConnect: me = !0,
46
46
  forceConnected: H = !0,
47
- saveConnect: he = !0,
48
- useSocket: be = !0,
47
+ saveConnect: pe = !0,
48
+ useSocket: he = !0,
49
49
  allowWallet: V = !0,
50
- provider: ge = "",
50
+ provider: be = "",
51
51
  messages: d = {},
52
52
  passkeyBehavior: Y = "none",
53
- webWalletUrl: xe = _t(),
54
- enabledConnectTypes: Ce = ["web", "mobile", ...Object.keys(j)],
53
+ webWalletUrl: ge = _t(),
54
+ enabledConnectTypes: xe = ["web", "mobile", ...Object.keys(j)],
55
55
  extraContent: G = null,
56
56
  disableSwitchApp: T = !1,
57
57
  magicToken: K = void 0,
58
- customItems: ye = [],
58
+ customItems: Ce = [],
59
59
  onClose: O = C,
60
60
  onError: Q = C,
61
61
  onSuccess: R = C,
62
62
  onRecreateSession: X = C,
63
- setColor: Se = C
63
+ setColor: ye = C
64
64
  }) {
65
- const A = at(), J = Qe(), ke = Ve(lt), we = vt(ke?.session?.user), {
65
+ const A = at(), J = Qe(), Se = Ve(lt), ke = vt(Se?.session?.user), {
66
66
  t: Z,
67
- staticState: Ie,
67
+ staticState: we,
68
68
  connectState: s,
69
- extraParams: ve,
70
- currentAppInfo: Pe,
69
+ extraParams: Ie,
70
+ currentAppInfo: ve,
71
71
  currentAppColor: W,
72
72
  // 插件相关
73
73
  selectedPlugin: a,
74
74
  blocklet: $,
75
- masterBlocklet: _e,
75
+ masterBlocklet: Pe,
76
76
  showWalletOptions: f,
77
- setShowWalletOptions: De,
78
- lastLoginMethod: Te
79
- } = dt(), { state: o, generate: ee, cancelWhenScanned: Oe } = pt({
77
+ setShowWalletOptions: _e,
78
+ lastLoginMethod: De
79
+ } = dt(), { state: o, generate: ee, cancelWhenScanned: Te } = pt({
80
80
  action: I,
81
81
  baseUrl: g,
82
82
  checkFn: v,
83
83
  checkInterval: P,
84
84
  checkTimeout: _,
85
- extraParams: ve,
85
+ extraParams: Ie,
86
86
  prefix: D,
87
87
  onError: Q,
88
88
  onSuccess: R,
89
89
  locale: q,
90
90
  tokenKey: B,
91
- encKey: me,
92
- autoConnect: pe,
93
- forceConnected: H === !0 ? we || !0 : H,
94
- saveConnect: he,
95
- useSocket: be,
96
- provider: ge
97
- }), z = le(!1), te = le(null), x = Xe(te), oe = u(() => x ? x.width < N - 50 : !0, [x, x?.width]), [re, Re] = Ye(!1);
98
- de(() => {
99
- Re(x?.width < N - 50);
91
+ encKey: fe,
92
+ autoConnect: me,
93
+ forceConnected: H === !0 ? ke || !0 : H,
94
+ saveConnect: pe,
95
+ useSocket: he,
96
+ provider: be
97
+ }), z = ce(!1), te = ce(null), x = Xe(te), oe = u(() => x ? x.width < N - 50 : !0, [x, x?.width]), [re, Oe] = Ye(!1);
98
+ ue(() => {
99
+ Oe(x?.width < N - 50);
100
100
  });
101
- const { oauthState: c, setBaseUrl: Ae } = ht(), { passkeyState: l, setTargetAppPid: We } = gt();
102
- de(() => {
103
- Ae(g), We($?.appPid), o.reset(), c.reset(), l.reset();
104
- }), ue(() => {
105
- Se(W);
101
+ const { oauthState: c, setBaseUrl: Re } = ht(), { passkeyState: l, setTargetAppPid: Ae } = gt();
102
+ ue(() => {
103
+ Re(g), Ae($?.appPid), o.reset(), c.reset(), l.reset();
104
+ }), le(() => {
105
+ ye(W);
106
106
  }, [W]);
107
- const ze = u(() => ({
107
+ const We = u(() => ({
108
108
  confirm: d.confirm,
109
109
  success: d.success,
110
110
  error: a?.state?.error || o.error || l.error || c.error || ""
@@ -117,34 +117,34 @@ function fe({
117
117
  a?.state?.error
118
118
  ]), S = u(() => w.includes(l.status) || w.includes(c.status) || w.includes(o.status) || w.includes(a?.state?.computedStatus), [o.status, c.status, l.status, a?.state?.computedStatus]), ne = F(async () => {
119
119
  X(), c.reset(), l.reset(), await ee(!1);
120
- }), Ee = F(() => {
120
+ }), ze = F(() => {
121
121
  s?.retryConnect();
122
- }), Le = F(() => {
123
- X(), c.reset(), l.reset(), a?.state?.reset(), Ie.current.cancelCount++, Oe();
124
- }), { run: Me } = Je(
122
+ }), Ee = F(() => {
123
+ X(), c.reset(), l.reset(), a?.state?.reset(), we.current.cancelCount++, Te();
124
+ }), { run: Le } = Je(
125
125
  () => {
126
126
  z.current || o.status === "timeout" && (z.current = !0, o.reset(), ne(), z.current = !1);
127
127
  },
128
128
  { leading: !0, trailing: !1 }
129
129
  );
130
- ue(Me, [o.status]);
131
- const Ue = u(() => ot[s.chooseMethod] || "DID Wallet", [s.chooseMethod]), { providerList: Fe, hideQRCode: m, hideChooseList: r, loadingProviderList: Ne } = wt({
130
+ le(Le, [o.status]);
131
+ const Me = u(() => ot[s.chooseMethod] || "DID Wallet", [s.chooseMethod]), { providerList: Ue, hideQRCode: m, hideChooseList: r, loadingProviderList: Fe } = wt({
132
132
  action: o.action,
133
133
  sourceAppPid: s?.sourceAppPid,
134
134
  allowWallet: V,
135
135
  passkeyBehavior: Y,
136
136
  mode: p,
137
- blocklet: s?.sourceAppPid ? _e : $,
137
+ blocklet: s?.sourceAppPid ? Pe : $,
138
138
  isSmallView: oe,
139
- lastLoginMethod: Te
140
- }), je = Ze(s?.sourceAppPid);
139
+ lastLoginMethod: De
140
+ }), Ne = Ze(s?.sourceAppPid);
141
141
  $e(() => {
142
- et(je) || ee();
142
+ et(Ne) || ee();
143
143
  }, [s?.sourceAppPid]);
144
144
  const n = (k) => {
145
145
  const h = A.spacing(k);
146
146
  return parseInt(h, 10);
147
- }, Be = u(() => y ? null : /* @__PURE__ */ t(
147
+ }, je = u(() => y ? null : /* @__PURE__ */ t(
148
148
  tt,
149
149
  {
150
150
  onClose: O,
@@ -154,14 +154,12 @@ function fe({
154
154
  top: 14
155
155
  }
156
156
  }
157
- ), [y, O]);
158
- let ie = null;
159
- S && (ie = /* @__PURE__ */ t(
157
+ ), [y, O]), Be = /* @__PURE__ */ t(
160
158
  i,
161
159
  {
162
160
  sx: {
163
161
  flex: 1,
164
- display: "flex",
162
+ display: S ? "flex" : "none",
165
163
  alignItems: "center",
166
164
  justifyContent: "center"
167
165
  },
@@ -171,21 +169,20 @@ function fe({
171
169
  status: a?.state?.computedStatus || c.status || l.status || o.status,
172
170
  nextWorkflow: o.nextWorkflow,
173
171
  mfaCode: o.mfaCode,
174
- onCancel: Le,
175
- onRetry: Ee,
172
+ onCancel: Ee,
173
+ onRetry: ze,
176
174
  onClose: O,
177
- messages: ze,
175
+ messages: We,
178
176
  locale: q,
179
177
  className: "did-connect__auth-status auth-status",
180
178
  loadingIcon: s.chooseMethod ? /* @__PURE__ */ t(ct, { provider: s.chooseMethod, sx: { color: "text.primary" } }) : null,
181
- chooseMethod: Ue,
179
+ chooseMethod: Me,
182
180
  hideRetry: s.chooseMethod === "email",
183
181
  hideBack: !!K
184
182
  }
185
183
  ) })
186
184
  }
187
- ));
188
- const se = It({ disableSwitchApp: T, tokenState: o }), E = u(() => {
185
+ ), ie = It({ disableSwitchApp: T, tokenState: o }), E = u(() => {
189
186
  const k = A.mode === "dark" ? A.palette.grey[600] : "white";
190
187
  let h = r ? 240 - n(3) * 2 : 196 - n(2) * 2, U = r ? 3 : 2;
191
188
  return f && (U = 1, h += n(U) * 2), /* @__PURE__ */ t(
@@ -200,7 +197,7 @@ function fe({
200
197
  children: o.url ? /* @__PURE__ */ t(
201
198
  it,
202
199
  {
203
- data: se,
200
+ data: ie,
204
201
  size: h,
205
202
  sx: {
206
203
  width: h + n(1) * 2,
@@ -241,7 +238,7 @@ function fe({
241
238
  )
242
239
  }
243
240
  );
244
- }, [se, r, f]), qe = u(() => r ? "column-reverse" : !m && re ? "column" : "row", [r, re, m]), ae = u(() => E ? /* @__PURE__ */ t(
241
+ }, [ie, r, f]), qe = u(() => r ? "column-reverse" : !m && re ? "column" : "row", [r, re, m]), se = u(() => E ? /* @__PURE__ */ t(
245
242
  i,
246
243
  {
247
244
  sx: {
@@ -317,7 +314,7 @@ function fe({
317
314
  },
318
315
  children: [
319
316
  !S && !m ? /* @__PURE__ */ b(He, { children: [
320
- ae,
317
+ se,
321
318
  r ? null : /* @__PURE__ */ t(i, { children: /* @__PURE__ */ t(
322
319
  Ke,
323
320
  {
@@ -341,7 +338,7 @@ function fe({
341
338
  flex: 1
342
339
  },
343
340
  children: [
344
- ie,
341
+ Be,
345
342
  /* @__PURE__ */ t(
346
343
  ft,
347
344
  {
@@ -358,17 +355,17 @@ function fe({
358
355
  tokenKey: B,
359
356
  onSuccess: R,
360
357
  passkeyBehavior: Y,
361
- webWalletUrl: xe,
358
+ webWalletUrl: ge,
362
359
  extraContent: G,
363
- enabledConnectTypes: Ce,
360
+ enabledConnectTypes: xe,
364
361
  onReset: ne,
365
362
  disableSwitchApp: T,
366
363
  forceUpdate: J,
367
364
  magicToken: K,
368
365
  baseUrl: g,
369
- customItems: ye,
370
- providerList: Fe,
371
- qrcode: ae
366
+ customItems: Ce,
367
+ providerList: Ue,
368
+ qrcode: se
372
369
  }
373
370
  )
374
371
  ]
@@ -384,8 +381,8 @@ function fe({
384
381
  onSuccess: R,
385
382
  onError: Q
386
383
  }) : M = L;
387
- const ce = m || S ? rt : N;
388
- return Ne ? /* @__PURE__ */ t(Pt, {}) : /* @__PURE__ */ b(
384
+ const ae = m || S ? rt : N;
385
+ return Fe ? /* @__PURE__ */ t(Pt, {}) : /* @__PURE__ */ b(
389
386
  i,
390
387
  {
391
388
  ref: te,
@@ -399,7 +396,7 @@ function fe({
399
396
  maxWidth: "100%",
400
397
  width: (
401
398
  // eslint-disable-next-line no-nested-ternary
402
- p === "drawer" ? "100%" : f ? ce - 20 : ce
399
+ p === "drawer" ? "100%" : f ? ae - 20 : ae
403
400
  ),
404
401
  transition: "width 0.2s ease-in-out",
405
402
  margin: "auto",
@@ -417,17 +414,17 @@ function fe({
417
414
  extraContent: G,
418
415
  disableSwitchApp: T,
419
416
  showWalletOptions: f,
420
- onBack: () => De(!1)
417
+ onBack: () => _e(!1)
421
418
  }
422
419
  ),
423
420
  /* @__PURE__ */ t(mt, { initHeight: 72, children: M }),
424
- /* @__PURE__ */ t(st, { currentAppInfo: Pe, currentAppColor: W }),
425
- Be
421
+ /* @__PURE__ */ t(st, { currentAppInfo: ve, currentAppColor: W }),
422
+ je
426
423
  ]
427
424
  }
428
425
  );
429
426
  }
430
- fe.propTypes = {
427
+ de.propTypes = {
431
428
  mode: e.oneOf(["dialog", "drawer", "page"]),
432
429
  action: e.string.isRequired,
433
430
  baseUrl: e.string,
@@ -485,7 +482,7 @@ function Dt({ testOnlyBorderColor: y = void 0, ...p }) {
485
482
  boxSizing: "border-box"
486
483
  }
487
484
  },
488
- children: /* @__PURE__ */ t(fe, { ...p })
485
+ children: /* @__PURE__ */ t(de, { ...p })
489
486
  }
490
487
  );
491
488
  }
@@ -1,74 +1,74 @@
1
- import { useRef as I, useEffect as C } from "react";
2
- import T from "lodash/get";
3
- import ue from "js-cookie";
4
- import B from "lodash/omitBy";
5
- import M from "lodash/isNil";
6
- import fe from "lodash/omit";
7
- import de from "lodash/cloneDeep";
8
- import { useReactive as H, useCreation as pe, useMemoizedFn as E } from "ahooks";
1
+ import { useRef as S, useEffect as C } from "react";
2
+ import W from "lodash/get";
3
+ import fe from "js-cookie";
4
+ import M from "lodash/omitBy";
5
+ import H from "lodash/isNil";
6
+ import de from "lodash/omit";
7
+ import pe from "lodash/cloneDeep";
8
+ import { useReactive as Q, useCreation as me, useMemoizedFn as T } from "ahooks";
9
9
  import ke from "@arcblock/react-hooks/lib/useInterval";
10
- import me from "@arcblock/react-hooks/lib/useBrowser";
11
- import { getVisitorId as he, stringifyQuery as $, isUrl as ge } from "@arcblock/ux/lib/Util";
12
- import { WsClient as be } from "@arcblock/ws";
13
- import { sleep as q, getExtraHeaders as x, getConnectedInfo as we, updateConnectedInfo as Ce, parseNextWorkflow as Q, createAxios as z, decodeConnectUrl as Se, parseTokenFromConnectUrl as Ie } from "../../utils.js";
14
- import V from "../assets/locale.js";
15
- import $e from "./security.js";
16
- import xe from "./page-show.js";
17
- import { RELAY_SOCKET_PREFIX as G } from "../../constant.js";
18
- function ve(o) {
10
+ import ge from "@arcblock/react-hooks/lib/useBrowser";
11
+ import { getVisitorId as he, stringifyQuery as x, isUrl as be } from "@arcblock/ux/lib/Util";
12
+ import { WsClient as we } from "@arcblock/ws";
13
+ import { sleep as G, getExtraHeaders as v, getConnectedInfo as Se, updateConnectedInfo as Ce, parseNextWorkflow as z, createAxios as V, decodeConnectUrl as Ie, parseTokenFromConnectUrl as $e } from "../../utils.js";
14
+ import X from "../assets/locale.js";
15
+ import xe from "./security.js";
16
+ import ve from "./page-show.js";
17
+ import { RELAY_SOCKET_PREFIX as J } from "../../constant.js";
18
+ function Ue(o) {
19
19
  const l = o || window.location.href;
20
20
  return new URL(l).host;
21
21
  }
22
22
  const P = {};
23
- function Ue({ action: o, prefix: l, checkFn: k, extraParams: v, baseUrl: m }) {
24
- const d = `${l}/token?${$(v)}`;
23
+ function Ae({ action: o, prefix: l, checkFn: m, extraParams: U, baseUrl: k }) {
24
+ const d = `${l}/token?${x(U)}`;
25
25
  return P[d] || (P[d] = async function() {
26
- const f = +/* @__PURE__ */ new Date(), h = await k(d, { headers: x(m) }), g = +/* @__PURE__ */ new Date();
27
- if (g - f < 500 && await q(500 - (g - f)), h?.data?.token)
28
- return h.data;
29
- if (h?.data?.error)
30
- throw new Error(h.data.error);
31
- const U = ge(l) ? l : `${m}${l}`;
32
- throw new Error(`Error generating ${o} QR Code from: ${U}`);
26
+ const f = +/* @__PURE__ */ new Date(), g = await m(d, { headers: v(k) }), h = +/* @__PURE__ */ new Date();
27
+ if (h - f < 500 && await G(500 - (h - f)), g?.data?.token)
28
+ return g.data;
29
+ if (g?.data?.error)
30
+ throw new Error(g.data.error);
31
+ const A = be(l) ? l : `${k}${l}`;
32
+ throw new Error(`Error generating ${o} QR Code from: ${A}`);
33
33
  }), P[d];
34
34
  }
35
- const Ae = () => {
35
+ const ye = () => {
36
36
  try {
37
37
  const l = new URL(window.location.href).searchParams.get("__connect_url__");
38
38
  if (!l)
39
39
  return null;
40
- const k = Se(l);
40
+ const m = Ie(l);
41
41
  return {
42
- token: Ie(k),
43
- url: k
42
+ token: $e(m),
43
+ url: m
44
44
  };
45
45
  } catch (o) {
46
46
  return {
47
47
  error: o
48
48
  };
49
49
  }
50
- }, J = () => T(globalThis, "blocklet.appPid") || T(globalThis, "blocklet.appId") || T(globalThis, "env.appId") || "", ye = () => (T(globalThis, "env.apiPrefix") || "/").replace(/\/$/, "").replace(G, ""), R = (o) => `relay:${J()}:${o}`, Ee = () => window.location.protocol === "https:" ? "wss:" : "ws:", X = (o) => !o || new URL(o).origin === window.location.origin, Y = (o) => ["succeed", "error", "timeout", "busy"].includes(o);
51
- function Xe({
50
+ }, Z = () => W(globalThis, "blocklet.appPid") || W(globalThis, "blocklet.appId") || W(globalThis, "env.appId") || "", Ee = () => (W(globalThis, "env.apiPrefix") || "/").replace(/\/$/, "").replace(J, ""), _ = (o) => `relay:${Z()}:${o}`, Te = () => window.location.protocol === "https:" ? "wss:" : "ws:", Y = (o) => !o || new URL(o).origin === window.location.origin, q = (o) => ["succeed", "error", "timeout", "busy"].includes(o);
51
+ function Ye({
52
52
  action: o,
53
53
  checkFn: l,
54
- checkInterval: k,
55
- checkTimeout: v,
56
- extraParams: m,
54
+ checkInterval: m,
55
+ checkTimeout: U,
56
+ extraParams: k,
57
57
  locale: d,
58
- prefix: _,
58
+ prefix: F,
59
59
  tokenKey: f,
60
- encKey: h,
61
- onError: g,
62
- onSuccess: U,
63
- baseUrl: Z,
64
- autoConnect: K = !0,
65
- forceConnected: ee = !0,
66
- saveConnect: re = !0,
60
+ encKey: g,
61
+ onError: h,
62
+ onSuccess: A,
63
+ baseUrl: K,
64
+ autoConnect: ee = !0,
65
+ forceConnected: re = !0,
66
+ saveConnect: te = !0,
67
67
  // FIXME: @zhanghan 将来需要设置为默认 false,仅在需要的时候进行保存 login, switch/role/profile
68
- useSocket: te = !0,
69
- provider: ne = "wallet"
68
+ useSocket: ne = !0,
69
+ provider: oe = "wallet"
70
70
  }) {
71
- const e = H({
71
+ const e = Q({
72
72
  checking: !1,
73
73
  loading: !1,
74
74
  token: "",
@@ -76,7 +76,6 @@ function Xe({
76
76
  store: null,
77
77
  status: "created",
78
78
  error: "",
79
- checkCount: 0,
80
79
  mfaCode: 0,
81
80
  appInfo: null,
82
81
  memberAppInfo: null,
@@ -84,80 +83,80 @@ function Xe({
84
83
  saveConnect: !1,
85
84
  inExistingSession: !1,
86
85
  nextWorkflow: "",
87
- baseUrl: Z,
88
- prefix: `${_}/${o}`,
89
- extraParams: B(m, M),
86
+ baseUrl: K,
87
+ prefix: `${F}/${o}`,
88
+ extraParams: M(k, H),
90
89
  checkFn: l,
91
90
  results: {},
92
91
  action: o,
93
- provider: ne,
92
+ provider: oe,
94
93
  reset() {
95
94
  this.error = "", this.status = "created";
96
95
  }
97
- }), F = I(null), S = V[d] || V.en, u = pe(() => Ae(), []), oe = Math.ceil(v / k), c = H({
96
+ }), I = S(0), D = S(null), $ = X[d] || X.en, u = me(() => ye(), []), se = Math.ceil(U / m), c = Q({
98
97
  onSuccessCalled: !1,
99
98
  cancelWhenScannedCounter: 0,
100
99
  isSocketAvailable: !1
101
- }), { encryptKey: se, decrypt: A } = $e(), D = me(), O = he(), a = I(null), p = I(null), b = {
100
+ }), { encryptKey: ae, decrypt: y } = xe(), O = ge(), L = he(), a = S(null), p = S(null), b = {
102
101
  ...e.extraParams,
103
102
  locale: d,
104
103
  [f]: e.token || u?.token,
105
104
  provider: e.provider
106
- }, L = async () => {
105
+ }, j = async () => {
107
106
  if (!(u?.token && u?.token === e.token)) {
108
107
  try {
109
- b[f] && e.status === "created" && await e.checkFn(`${e.prefix}/timeout?${$(b)}`, {
110
- headers: x(e.baseUrl)
108
+ b[f] && e.status === "created" && await e.checkFn(`${e.prefix}/timeout?${x(b)}`, {
109
+ headers: v(e.baseUrl)
111
110
  });
112
111
  } catch {
113
112
  }
114
113
  try {
115
- e.token && p.current && (await a.current.unsubscribe(R(e.token)), p.current = null);
114
+ e.token && p.current && (await a.current.unsubscribe(_(e.token)), p.current = null);
116
115
  } catch {
117
116
  }
118
117
  }
119
- }, ae = E((...t) => {
118
+ }, ce = T((...t) => {
120
119
  const r = {
121
- [h]: se,
120
+ [g]: ae,
122
121
  ...e.extraParams,
123
122
  locale: d,
124
- forceConnected: ee,
123
+ forceConnected: re,
125
124
  // - autoConnect 请求参数用于控制服务端是否给钱包应用发送自动连接通知
126
125
  // - 使用 connect 组件时明确传入了 autoConnect = false, 则 autoConnect 请求参数 为 false
127
126
  // - 如果 cancelWhenScannedCounter > 0, 说明用户进行过 cancel 操作, 则临时禁用自动连接, autoConnect 请求参数 为 false
128
127
  // (避免 "无限自动连接问题")
129
128
  // - 如果上次连接设备 (connected_wallet_os) 不是 ios/android, 则禁用自动连接
130
- autoConnect: K && // 如果是 wallet webview 环境, 不发送通知, 避免 wallet 连续弹出 auth 窗口 2 次 (#341)
131
- !(D.wallet || D.arcSphere) && !c.cancelWhenScannedCounter && ["ios", "android"].includes(ue.get("connected_wallet_os")),
129
+ autoConnect: ee && // 如果是 wallet webview 环境, 不发送通知, 避免 wallet 连续弹出 auth 窗口 2 次 (#341)
130
+ !(O.wallet || O.arcSphere) && !c.cancelWhenScannedCounter && ["ios", "android"].includes(fe.get("connected_wallet_os")),
132
131
  provider: e.provider
133
132
  };
134
- O && (r.visitorId = O);
135
- const n = fe(F.current || {}, ["sourceAppPid", "verbose"]);
133
+ L && (r.visitorId = L);
134
+ const n = de(D.current || {}, ["sourceAppPid", "verbose"]);
136
135
  return Object.keys(n).forEach((s) => {
137
- (!r[s] || s === h && n[s]) && (r[s] = n[s]);
138
- }), u?.token && !r.sourceToken && (r.sourceToken = u?.token), Ue({
136
+ (!r[s] || s === g && n[s]) && (r[s] = n[s]);
137
+ }), u?.token && !r.sourceToken && (r.sourceToken = u?.token), Ae({
139
138
  action: o,
140
139
  prefix: e.prefix,
141
140
  baseUrl: e.baseUrl,
142
141
  checkFn: e.checkFn,
143
142
  extraParams: r
144
143
  })(...t);
145
- }), y = E(async (t = !0) => {
146
- t && L();
144
+ }), E = T(async (t = !0) => {
145
+ t && j();
147
146
  try {
148
- e.loading = !0, e.token = "", e.url = "", e.store = null, e.extraParams = B(m, M), await q();
149
- const r = await ae(), n = r.extra || {};
150
- e.loading = !1, e.token = r.token, e.url = r.url, e.status = "created", e.error = "", e.checkCount = 0, e.appInfo = r.appInfo, e.memberAppInfo = r.memberAppInfo, e.connectedDid = n.connectedDid, e.saveConnect = n.saveConnect;
147
+ e.loading = !0, e.token = "", e.url = "", e.store = null, e.extraParams = M(k, H), await G();
148
+ const r = await ce(), n = r.extra || {};
149
+ e.loading = !1, e.token = r.token, e.url = r.url, e.status = "created", e.error = "", I.current = 0, e.appInfo = r.appInfo, e.memberAppInfo = r.memberAppInfo, e.connectedDid = n.connectedDid, e.saveConnect = n.saveConnect;
151
150
  } catch (r) {
152
- e.loading = !1, e.status = "error", e.error = `${S.generateError}: ${r.message}`;
151
+ e.loading = !1, e.status = "error", e.error = `${$.generateError}: ${r.message}`;
153
152
  }
154
- }), ce = E(() => {
153
+ }), ie = T(() => {
155
154
  c.cancelWhenScannedCounter++;
156
155
  });
157
156
  C(() => {
158
- c.cancelWhenScannedCounter > 0 && (m.nw ? g(new Error(S.retryForbidden)) : y());
159
- }, [c.cancelWhenScannedCounter]), C(() => (!(/^((?!chrome|android).)*safari/i.test(globalThis.navigator.userAgent) || Object.hasOwn(globalThis?.blocklet || {}, "DID_CONNECT_DISABLE_SOCKET")) && te && X(e.baseUrl) && J() ? (!a.current || a.current.isConnected() === !1 || a.current.baseUrl !== e.baseUrl) && (a.current = new be(
160
- `${Ee()}//${ve(e.baseUrl)}${ye()}${G}/relay`,
157
+ c.cancelWhenScannedCounter > 0 && (k.nw ? h(new Error($.retryForbidden)) : E());
158
+ }, [c.cancelWhenScannedCounter]), C(() => (!(/^((?!chrome|android).)*safari/i.test(globalThis.navigator.userAgent) || Object.hasOwn(globalThis?.blocklet || {}, "DID_CONNECT_DISABLE_SOCKET")) && ne && Y(e.baseUrl) && Z() ? (!a.current || a.current.isConnected() === !1 || a.current.baseUrl !== e.baseUrl) && (a.current = new we(
159
+ `${Te()}//${Ue(e.baseUrl)}${Ee()}${J}/relay`,
161
160
  {
162
161
  longpollerTimeout: 5e3,
163
162
  // connection timeout
@@ -168,50 +167,54 @@ function Xe({
168
167
  }), a.current.connect()) : c.isSocketAvailable && (c.isSocketAvailable = !1), () => {
169
168
  a.current && (a.current.disconnect(), a.current = null);
170
169
  }), [e.baseUrl]);
171
- const ie = () => !e.token || e.loading || Y(e.status) ? null : k, j = I(null);
170
+ const le = () => !e.token || e.loading || q(e.status) ? null : m, N = S(null);
172
171
  C(() => {
173
- j.current = { state: e, params: b };
172
+ N.current = { state: e, params: b };
174
173
  }), C(() => () => {
175
- const { state: t, params: r } = j.current;
176
- t.status === "created" && r[f] && t.checkFn(`${t.prefix}/timeout?${$(r)}`, {
177
- headers: x(t.baseUrl)
174
+ const { state: t, params: r } = N.current;
175
+ t.status === "created" && r[f] && t.checkFn(`${t.prefix}/timeout?${x(r)}`, {
176
+ headers: v(t.baseUrl)
178
177
  });
179
178
  }, []);
180
- const w = E(async (t = !1) => {
181
- if ((e.checking || document.hidden) && !t || (e.status === "created" && e.checkCount++, c.isSocketAvailable && !t))
179
+ const w = T(async (t = !1) => {
180
+ if ((e.checking || document.hidden) && !t)
181
+ return null;
182
+ if (e.status === "created" && (I.current++, e.status !== "timeout" && I.current > se))
183
+ return e.status = "timeout", j(), null;
184
+ if (c.isSocketAvailable && !t)
182
185
  return null;
183
186
  try {
184
187
  e.checking = !0;
185
- const r = await e.checkFn(`${e.prefix}/status?${$(b)}`, {
186
- headers: x(e.baseUrl)
188
+ const r = await e.checkFn(`${e.prefix}/status?${x(b)}`, {
189
+ headers: v(e.baseUrl)
187
190
  }), { status: n, error: i, mfaCode: s = 0 } = r.data;
188
191
  if (e.store = r.data, e.mfaCode = s, e.checking = !1, e.status === "scanned" && n === "created" || (e.status = n), n === "error" && i) {
189
- const N = new Error(i);
190
- throw N.response = r, N;
192
+ const B = new Error(i);
193
+ throw B.response = r, B;
191
194
  }
192
195
  return r.data;
193
196
  } catch (r) {
194
197
  const { response: n } = r;
195
198
  if (n?.status) {
196
- b[f] && e.checkFn(`${e.prefix}/timeout?${$(b)}`, {
197
- headers: x(e.baseUrl)
199
+ b[f] && e.checkFn(`${e.prefix}/timeout?${x(b)}`, {
200
+ headers: v(e.baseUrl)
198
201
  });
199
202
  const i = n?.data?.error ? n.data.error : r.message, s = new Error(i);
200
- s.code = n.status, e.status = "error", e.checking = !1, e.error = i, g(s, e?.store, A);
203
+ s.code = n.status, e.status = "error", e.checking = !1, e.error = i, h(s, e?.store, y);
201
204
  } else
202
- e.status = "error", e.checking = !1, e.error = S.generateError;
205
+ e.status = "error", e.checking = !1, e.error = $.generateError;
203
206
  }
204
207
  return null;
205
- }), le = async () => {
208
+ }), ue = async () => {
206
209
  try {
207
210
  if (u.error)
208
211
  throw u.error;
209
212
  e.loading = !0, e.token = u.token, e.url = u.url, e.inExistingSession = !0;
210
213
  let t = await w();
211
- if ((["scanned"].includes(t?.status) || t?.sourceToken === u?.token) && (await y(!1), t = await w()), F.current = t?.extraParams || null, t?.status && !["created"].includes(t?.status))
212
- throw new Error(`${S.invalidSessionStatus} [${t.status}]`);
214
+ if ((["scanned"].includes(t?.status) || t?.sourceToken === u?.token) && (await E(!1), t = await w()), D.current = t?.extraParams || null, t?.status && !["created"].includes(t?.status))
215
+ throw new Error(`${$.invalidSessionStatus} [${t.status}]`);
213
216
  } catch (t) {
214
- e.status = "error", e.error = t.message, g(t, e?.store, A);
217
+ e.status = "error", e.error = t.message, h(t, e?.store, y);
215
218
  } finally {
216
219
  e.loading = !1;
217
220
  }
@@ -219,39 +222,35 @@ function Xe({
219
222
  C(() => {
220
223
  if (!e.token && !e.store && !e.loading && !e.error)
221
224
  if (u)
222
- le();
225
+ ue();
223
226
  else {
224
- y(!1);
227
+ E(!1);
225
228
  return;
226
229
  }
227
- if (e.status !== "timeout" && e.checkCount > oe) {
228
- e.status = "timeout", L();
229
- return;
230
- }
231
230
  if (e.status === "succeed" && !c.onSuccessCalled) {
232
- const t = we({
231
+ const t = Se({
233
232
  ...e.store,
234
233
  appInfo: e.appInfo,
235
234
  memberAppInfo: e.memberAppInfo
236
235
  });
237
- if (X(e.baseUrl) && re && e.saveConnect && e.store.did && Ce(t, !0), e.store) {
236
+ if (Y(e.baseUrl) && te && e.saveConnect && e.store.did && Ce(t, !0), e.store) {
238
237
  const { nextWorkflow: r } = e.store;
239
238
  if (r)
240
239
  try {
241
- const n = Q(r, f);
242
- e.nextWorkflow = n?.nextWorkflow || r, Object.assign(e, n), e.store = null, e.error = "", e.url = "", e.appInfo = null, e.memberAppInfo = null, e.checkCount = 0, e.status = "scanned", e.results = {
240
+ const n = z(r, f);
241
+ e.nextWorkflow = n?.nextWorkflow || r, Object.assign(e, n), e.store = null, e.error = "", e.url = "", e.appInfo = null, e.memberAppInfo = null, I.current = 0, e.status = "scanned", e.results = {
243
242
  ...e.results,
244
243
  [e.token]: e.store
245
- }, e.checkFn = z({ baseURL: n.baseUrl, timeout: 8e3 }).get, w();
244
+ }, e.checkFn = V({ baseURL: n.baseUrl, timeout: 8e3 }).get, w();
246
245
  } catch (n) {
247
246
  console.error(`Invalid nextWorkflow: ${r}`, n), e.status = "error", e.error = `Invalid nextWorkflow: ${r}: ${n.message}`;
248
247
  }
249
- else if (e.nextWorkflow && (e.nextWorkflow = "", e.url = ""), typeof U == "function") {
248
+ else if (e.nextWorkflow && (e.nextWorkflow = "", e.url = ""), typeof A == "function") {
250
249
  const n = Object.values({ ...e.results, [e.token]: e.store });
251
250
  c.onSuccessCalled = !0;
252
- const i = n.length > 1 ? n : n[0], s = de(i);
253
- U(s, A, {
254
- sourceAppPid: m?.sourceAppPid,
251
+ const i = n.length > 1 ? n : n[0], s = pe(i);
252
+ A(s, y, {
253
+ sourceAppPid: k?.sourceAppPid,
255
254
  ...t
256
255
  });
257
256
  }
@@ -261,37 +260,37 @@ function Xe({
261
260
  if (e.store?.nextWorkflow) {
262
261
  const { nextWorkflow: t } = e.store;
263
262
  try {
264
- const r = Q(t, f);
265
- e.nextWorkflow = r?.nextWorkflow || t, Object.assign(e, r), e.store = null, e.error = "", e.url = "", e.appInfo = null, e.memberAppInfo = null, e.checkCount = 0, e.status = "scanned", e.results = {
263
+ const r = z(t, f);
264
+ e.nextWorkflow = r?.nextWorkflow || t, Object.assign(e, r), e.store = null, e.error = "", e.url = "", e.appInfo = null, e.memberAppInfo = null, I.current = 0, e.status = "scanned", e.results = {
266
265
  ...e.results,
267
266
  [e.token]: e.store
268
- }, e.checkFn = z({ baseURL: r.baseUrl, timeout: 8e3 }).get, w();
267
+ }, e.checkFn = V({ baseURL: r.baseUrl, timeout: 8e3 }).get, w();
269
268
  } catch (r) {
270
269
  console.error(`Invalid nextWorkflow: ${t}`, r), e.status = "error", e.error = `Invalid nextWorkflow: ${t}: ${r.message}`;
271
270
  }
272
271
  }
273
272
  });
274
- const W = I(0);
273
+ const R = S(0);
275
274
  return C(() => {
276
275
  if (e.token && c.isSocketAvailable && a.current) {
277
276
  let t = !1;
278
- p.current ? p.current.token !== e.token && (a.current.unsubscribe(R(p.current.token)), t = !0) : t = !0, t && (p.current = a.current.subscribe(R(e.token)), W.current = 0, p.current.token = e.token, p.current.on("updated", ({ response: r }) => {
277
+ p.current ? p.current.token !== e.token && (a.current.unsubscribe(_(p.current.token)), t = !0) : t = !0, t && (p.current = a.current.subscribe(_(e.token)), R.current = 0, p.current.token = e.token, p.current.on("updated", ({ response: r }) => {
279
278
  const n = +new Date(r.updatedAt);
280
- if (n <= W.current) {
279
+ if (n <= R.current) {
281
280
  console.warn("Ignore outdated message", r);
282
281
  return;
283
282
  }
284
- W.current = n;
283
+ R.current = n;
285
284
  let { status: i, error: s } = r;
286
- i === "forbidden" && (s = S.forbidden, i = "error"), e.status = i, e.mfaCode = r.mfaCode || 0, e.store = r, e.error = s, s && g(new Error(s), e?.store, A);
285
+ i === "forbidden" && (s = $.forbidden, i = "error"), e.status = i, e.mfaCode = r.mfaCode || 0, e.store = r, e.error = s, s && h(new Error(s), e?.store, y);
287
286
  }));
288
287
  }
289
- }, [e.token, c.isSocketAvailable, a.current]), ke(w, ie()), xe(() => {
290
- e.token && Y(e.status) === !1 && (e.checking = !1, setTimeout(() => {
288
+ }, [e.token, c.isSocketAvailable, a.current]), ke(w, le()), ve(() => {
289
+ e.token && q(e.status) === !1 && (e.checking = !1, setTimeout(() => {
291
290
  w(!0);
292
291
  }, 100));
293
- }), { state: e, generate: y, cancelWhenScanned: ce };
292
+ }), { state: e, generate: E, cancelWhenScanned: ie };
294
293
  }
295
294
  export {
296
- Xe as default
295
+ Ye as default
297
296
  };
@@ -1,13 +1,14 @@
1
1
  import { jsx as a } from "react/jsx-runtime";
2
- import { useReactive as c, useMemoizedFn as u } from "ahooks";
3
- import f from "@iconify-icons/material-symbols/mail-outline-rounded";
4
- import { LOGIN_PROVIDER as h } from "@arcblock/ux/lib/Util/constant";
5
- import { translate as E } from "@arcblock/ux/lib/Locale/util";
6
- import P from "./list-item.js";
2
+ import { useReactive as u, useMemoizedFn as f } from "ahooks";
3
+ import h from "@iconify-icons/material-symbols/mail-outline-rounded";
4
+ import { LOGIN_PROVIDER as E } from "@arcblock/ux/lib/Util/constant";
5
+ import { translate as P } from "@arcblock/ux/lib/Locale/util";
6
+ import p from "./list-item.js";
7
7
  import g from "./placeholder.js";
8
- function k({ baseUrl: s }) {
9
- const i = c({
10
- baseUrl: s,
8
+ import s from "../../assets/locale.js";
9
+ function q({ baseUrl: l }) {
10
+ const i = u({
11
+ baseUrl: l,
11
12
  status: "idle",
12
13
  get computedStatus() {
13
14
  return this.status === "idle" ? "creating" : this.status === "creating" || this.status === "sending" || this.status === "verifying" ? "scanned" : this.status;
@@ -17,8 +18,9 @@ function k({ baseUrl: s }) {
17
18
  reset() {
18
19
  this.status = "idle", this.error = "", this.magicToken = "";
19
20
  }
20
- }), r = h.EMAIL, t = "Email", o = f, l = {
21
+ }), r = E.EMAIL, t = "Email", o = h, m = {
21
22
  zh: {
23
+ ...s.zh,
22
24
  email: "邮箱地址",
23
25
  emailPlaceholder: "请输入邮箱地址",
24
26
  sendCode: "发送验证邮件",
@@ -31,6 +33,7 @@ function k({ baseUrl: s }) {
31
33
  emailRequired: "邮箱地址不能为空"
32
34
  },
33
35
  en: {
36
+ ...s.en,
34
37
  email: "Email",
35
38
  emailPlaceholder: "Enter your email address",
36
39
  sendCode: "Send Verification Email",
@@ -42,13 +45,13 @@ function k({ baseUrl: s }) {
42
45
  emailInvalid: "Email format is incorrect",
43
46
  emailRequired: "Email is required"
44
47
  }
45
- }, n = u((e, m = {}, d = "en") => E(l, e, d, "en", m));
48
+ }, n = f((e, d = {}, c = "en") => P(m, e, c, "en", d));
46
49
  return {
47
50
  name: r,
48
51
  title: t,
49
52
  icon: o,
50
53
  renderListItem(e) {
51
- return /* @__PURE__ */ a(P, { ...e, state: i, name: r, title: t, icon: o, t: n });
54
+ return /* @__PURE__ */ a(p, { ...e, state: i, name: r, title: t, icon: o, t: n });
52
55
  },
53
56
  renderPlaceholder(e) {
54
57
  return /* @__PURE__ */ a(g, { ...e, state: i, name: r, title: t, icon: o, t: n });
@@ -58,5 +61,5 @@ function k({ baseUrl: s }) {
58
61
  };
59
62
  }
60
63
  export {
61
- k as default
64
+ q as default
62
65
  };
@@ -1,4 +1,4 @@
1
- const o = "3.4.1", s = {
1
+ const o = "3.4.2", s = {
2
2
  version: o
3
3
  };
4
4
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcblock/did-connect-react",
3
- "version": "3.4.1",
3
+ "version": "3.4.2",
4
4
  "description": "Client side library to work with DID Connect by ArcBlock.",
5
5
  "keywords": [
6
6
  "react",
@@ -32,10 +32,10 @@
32
32
  "url": "https://github.com/ArcBlock/ux/issues"
33
33
  },
34
34
  "dependencies": {
35
- "@arcblock/bridge": "3.4.1",
35
+ "@arcblock/bridge": "3.4.2",
36
36
  "@arcblock/did": "^1.28.1",
37
- "@arcblock/icons": "3.4.1",
38
- "@arcblock/react-hooks": "3.4.1",
37
+ "@arcblock/icons": "3.4.2",
38
+ "@arcblock/react-hooks": "3.4.2",
39
39
  "@arcblock/ws": "^1.28.1",
40
40
  "@blocklet/constant": "^1.17.7",
41
41
  "@fontsource/lexend": "^5.2.9",
@@ -81,5 +81,5 @@
81
81
  "eslint-plugin-react-hooks": "^4.6.2",
82
82
  "jest": "^29.7.0"
83
83
  },
84
- "gitHead": "6101f8f54333c0c376437160147a0b15a1548111"
84
+ "gitHead": "9ba657c3d15f93dc93e9029845631ececf385afc"
85
85
  }
@@ -253,40 +253,38 @@ function Connect({
253
253
  );
254
254
  }, [hideCloseButton, onClose]);
255
255
 
256
- let content = null;
257
- if (showStatus) {
258
- content = (
259
- <Box
260
- sx={{
261
- flex: 1,
262
- display: 'flex',
263
- alignItems: 'center',
264
- justifyContent: 'center',
265
- }}>
266
- <Box>
267
- <ConnectStatus
268
- status={selectedPlugin?.state?.computedStatus || oauthState.status || passkeyState.status || state.status}
269
- nextWorkflow={state.nextWorkflow}
270
- mfaCode={state.mfaCode}
271
- onCancel={handleCancel}
272
- onRetry={handleRetry}
273
- onClose={onClose}
274
- messages={statusMessages}
275
- locale={locale}
276
- className="did-connect__auth-status auth-status"
277
- loadingIcon={
278
- connectState.chooseMethod ? (
279
- <ProviderIcon provider={connectState.chooseMethod} sx={{ color: 'text.primary' }} />
280
- ) : null
281
- }
282
- chooseMethod={chooseMethod}
283
- hideRetry={connectState.chooseMethod === 'email'}
284
- hideBack={!!magicToken}
285
- />
286
- </Box>
256
+ // 预渲染 ConnectStatus,通过 CSS 控制显示/隐藏,避免 DOM 的创建/销毁导致卡顿
257
+ const statusContent = (
258
+ <Box
259
+ sx={{
260
+ flex: 1,
261
+ display: showStatus ? 'flex' : 'none',
262
+ alignItems: 'center',
263
+ justifyContent: 'center',
264
+ }}>
265
+ <Box>
266
+ <ConnectStatus
267
+ status={selectedPlugin?.state?.computedStatus || oauthState.status || passkeyState.status || state.status}
268
+ nextWorkflow={state.nextWorkflow}
269
+ mfaCode={state.mfaCode}
270
+ onCancel={handleCancel}
271
+ onRetry={handleRetry}
272
+ onClose={onClose}
273
+ messages={statusMessages}
274
+ locale={locale}
275
+ className="did-connect__auth-status auth-status"
276
+ loadingIcon={
277
+ connectState.chooseMethod ? (
278
+ <ProviderIcon provider={connectState.chooseMethod} sx={{ color: 'text.primary' }} />
279
+ ) : null
280
+ }
281
+ chooseMethod={chooseMethod}
282
+ hideRetry={connectState.chooseMethod === 'email'}
283
+ hideBack={!!magicToken}
284
+ />
287
285
  </Box>
288
- );
289
- }
286
+ </Box>
287
+ );
290
288
 
291
289
  const urlWithParams = useAuthUrl({ disableSwitchApp, tokenState: state });
292
290
 
@@ -455,8 +453,9 @@ function Connect({
455
453
  display: 'flex',
456
454
  flex: 1,
457
455
  }}>
458
- {/* eslint-disable-next-line no-nested-ternary */}
459
- {content}
456
+ {/* ConnectStatus:始终渲染,通过 CSS 控制显示/隐藏 */}
457
+ {statusContent}
458
+ {/* ConnectProviderList:始终渲染,通过 CSS 控制显示/隐藏 */}
460
459
  <ConnectProviderList
461
460
  slotProps={{
462
461
  root: {
@@ -119,7 +119,6 @@ export default function useToken({
119
119
  store: null,
120
120
  status: 'created',
121
121
  error: '',
122
- checkCount: 0,
123
122
  mfaCode: 0,
124
123
  appInfo: null,
125
124
  memberAppInfo: null,
@@ -140,6 +139,8 @@ export default function useToken({
140
139
  },
141
140
  });
142
141
 
142
+ // 使用 ref 存储 checkCount,避免计数时触发不必要的渲染
143
+ const checkCountRef = useRef(0);
143
144
  const statusExtraParams = useRef(null);
144
145
 
145
146
  const translation = translations[locale] || translations.en;
@@ -264,7 +265,7 @@ export default function useToken({
264
265
  state.url = data.url;
265
266
  state.status = 'created';
266
267
  state.error = '';
267
- state.checkCount = 0;
268
+ checkCountRef.current = 0;
268
269
  state.appInfo = data.appInfo;
269
270
  state.memberAppInfo = data.memberAppInfo;
270
271
  state.connectedDid = extra.connectedDid;
@@ -363,7 +364,6 @@ export default function useToken({
363
364
  }, []);
364
365
 
365
366
  // Check auth token status
366
- // FIXME: @zhanghan 这个函数会造成 connect 组件每秒重渲染一次,需要从 setState 入手,优化这个问题。优化的原则是,页面数据没有变更时,不应该触发重渲染
367
367
  const checkStatus = useMemoizedFn(async (force = false) => {
368
368
  if ((state.checking || document.hidden) && !force) {
369
369
  return null;
@@ -371,7 +371,14 @@ export default function useToken({
371
371
 
372
372
  // NOTICE: 仅当状态为 created 时才去计算次数统计
373
373
  if (state.status === 'created') {
374
- state.checkCount++;
374
+ checkCountRef.current++;
375
+
376
+ // 超时判断:超过最大检查次数则标记为超时
377
+ if (state.status !== 'timeout' && checkCountRef.current > maxCheckCount) {
378
+ state.status = 'timeout';
379
+ unsubscribe();
380
+ return null;
381
+ }
375
382
  }
376
383
 
377
384
  if (currentState.isSocketAvailable && !force) {
@@ -467,13 +474,6 @@ export default function useToken({
467
474
  }
468
475
  }
469
476
 
470
- // Mark token as expired if exceed max retry count
471
- if (state.status !== 'timeout' && state.checkCount > maxCheckCount) {
472
- state.status = 'timeout';
473
- unsubscribe();
474
- return;
475
- }
476
-
477
477
  // Trigger on success if we completed the process
478
478
  if (state.status === 'succeed' && !currentState.onSuccessCalled) {
479
479
  // save connected_did to cookie if only on same origin
@@ -499,7 +499,7 @@ export default function useToken({
499
499
  state.url = '';
500
500
  state.appInfo = null;
501
501
  state.memberAppInfo = null;
502
- state.checkCount = 0;
502
+ checkCountRef.current = 0;
503
503
  state.status = 'scanned';
504
504
  state.results = {
505
505
  ...state.results,
@@ -547,7 +547,7 @@ export default function useToken({
547
547
  state.url = '';
548
548
  state.appInfo = null;
549
549
  state.memberAppInfo = null;
550
- state.checkCount = 0;
550
+ checkCountRef.current = 0;
551
551
  state.status = 'scanned';
552
552
  state.results = {
553
553
  ...state.results,
@@ -5,6 +5,7 @@ import { translate } from '@arcblock/ux/lib/Locale/util';
5
5
 
6
6
  import EmailListItem from './list-item';
7
7
  import EmailPlaceholder from './placeholder';
8
+ import defaultTranslations from '../../assets/locale';
8
9
 
9
10
  export default function useEmailPlugin({ baseUrl }) {
10
11
  const state = useReactive({
@@ -38,6 +39,7 @@ export default function useEmailPlugin({ baseUrl }) {
38
39
  const icon = mailOutlineRoundedIcon;
39
40
  const translations = {
40
41
  zh: {
42
+ ...defaultTranslations.zh,
41
43
  email: '邮箱地址',
42
44
  emailPlaceholder: '请输入邮箱地址',
43
45
  sendCode: '发送验证邮件',
@@ -50,6 +52,7 @@ export default function useEmailPlugin({ baseUrl }) {
50
52
  emailRequired: '邮箱地址不能为空',
51
53
  },
52
54
  en: {
55
+ ...defaultTranslations.en,
53
56
  email: 'Email',
54
57
  emailPlaceholder: 'Enter your email address',
55
58
  sendCode: 'Send Verification Email',