@arcblock/ux 2.12.4 → 2.12.6

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.
@@ -5,6 +5,7 @@ declare const colors: {
5
5
  paper0: string;
6
6
  paper1: string;
7
7
  paper2: string;
8
+ paper3: string;
8
9
  };
9
10
  text: {
10
11
  primary: string;
@@ -50,6 +51,8 @@ declare const colors: {
50
51
  };
51
52
  divider: {
52
53
  main: string;
54
+ light: string;
55
+ dark: string;
53
56
  };
54
57
  };
55
58
  export default colors;
@@ -4,7 +4,8 @@ const colors = {
4
4
  default: 'white',
5
5
  paper0: 'white',
6
6
  paper1: '#FAFAFA',
7
- paper2: '#F4F4F5'
7
+ paper2: '#F4F4F5',
8
+ paper3: '#F0F0F1'
8
9
  },
9
10
  text: {
10
11
  primary: '#18181B',
@@ -49,7 +50,9 @@ const colors = {
49
50
  dark: '#00A63E'
50
51
  },
51
52
  divider: {
52
- main: '#F4F4F5'
53
+ main: 'rgba(18, 22, 24, 0.06)',
54
+ light: '#F4F4F5',
55
+ dark: '#D4D4D5'
53
56
  }
54
57
  };
55
58
  export default colors;
@@ -99,7 +99,6 @@ function Header({
99
99
  }
100
100
  const Root = styled(Box)`
101
101
  position: relative;
102
- z-index: ${props => props.theme.zIndex.appBar};
103
102
  font-size: 14px;
104
103
  background: ${props => props.theme.palette.common.white};
105
104
  .header-container {
@@ -86,13 +86,20 @@ export default function LocaleSelector(props) {
86
86
  children: languages.find(x => x.code === locale)?.name
87
87
  }) : '']
88
88
  })
89
- }), /*#__PURE__*/_jsx(StyledPopper, {
89
+ }), /*#__PURE__*/_jsx(Popper, {
90
90
  open: open,
91
91
  anchorEl: anchorEl.current,
92
92
  ...popperProps,
93
- disablePortal: true,
94
- children: /*#__PURE__*/_jsx("div", {
93
+ children: /*#__PURE__*/_jsx(Box, {
95
94
  className: "locales",
95
+ sx: {
96
+ background: getBackground({
97
+ ...popperProps,
98
+ theme
99
+ }),
100
+ boxShadow: `0px 8px 16px 0px ${colors.gray6}, 0px 0px 0px 1px ${colors.gray6}`,
101
+ borderRadius: 2
102
+ },
96
103
  children: /*#__PURE__*/_jsx(ClickAwayListener, {
97
104
  onClickAway: onClose,
98
105
  children: /*#__PURE__*/_jsx(MenuList, {
@@ -102,9 +109,32 @@ export default function LocaleSelector(props) {
102
109
  }) => /*#__PURE__*/_jsxs(MenuItem, {
103
110
  className: "locale-item",
104
111
  onClick: () => onSelect(code),
105
- children: [/*#__PURE__*/_jsx(IconifyIcon, {
112
+ sx: {
113
+ fontSize: 16,
114
+ fontStyle: 'normal',
115
+ fontStretch: 'normal',
116
+ lineHeight: 'normal',
117
+ letterSpacing: '2px',
118
+ textAlign: 'center',
119
+ color: getColor({
120
+ ...popperProps,
121
+ theme
122
+ }),
123
+ cursor: 'pointer',
124
+ display: 'flex',
125
+ padding: '16px',
126
+ alignItems: 'center'
127
+ },
128
+ children: [/*#__PURE__*/_jsx(Box, {
129
+ component: IconifyIcon,
106
130
  icon: CheckIcon,
107
- className: code === locale ? 'check-icon check-icon-visible' : 'check-icon'
131
+ className: code === locale ? 'check-icon check-icon-visible' : 'check-icon',
132
+ sx: [code === locale ? {
133
+ visibility: 'visible'
134
+ } : {}, {
135
+ visibility: 'hidden',
136
+ marginRight: 0.5
137
+ }]
108
138
  }), name]
109
139
  }, code))
110
140
  })
@@ -131,40 +161,11 @@ const Div = styled('div', {
131
161
  color: ${props => getColor(props)};
132
162
  }
133
163
  }
134
-
135
- .locales {
136
- background: ${props => getBackground(props)};
137
- box-shadow:
138
- 0px 8px 16px 0px ${colors.gray6},
139
- 0px 0px 0px 1px ${colors.gray6};
140
- border-radius: 8px;
141
- }
142
-
143
- .locale-item {
144
- font-size: 16px;
145
- font-style: normal;
146
- font-stretch: normal;
147
- line-height: normal;
148
- letter-spacing: 2px;
149
- text-align: center;
150
- color: ${props => getColor(props)};
151
- cursor: pointer;
152
- display: flex;
153
- padding: 16px;
154
- align-items: center;
155
- .check-icon {
156
- visibility: hidden;
157
- margin-right: 4px;
158
- }
159
- .check-icon-visible {
160
- visibility: visible;
161
- }
162
- }
163
164
  `;
164
165
  const StyledPopper = styled(Popper)`
165
166
  z-index: ${({
166
167
  theme
167
168
  }) => {
168
- return theme.zIndex.tooltip + 10;
169
+ return theme.zIndex.modal + 1;
169
170
  }};
170
171
  `;
@@ -1283,58 +1283,58 @@ const translations = {
1283
1283
  },
1284
1284
  products: {
1285
1285
  nftStudio: {
1286
- description: 'Toolkit for NFT creation'
1286
+ description: 'Mint and manage NFTs'
1287
1287
  },
1288
1288
  creatorStudio: {
1289
- description: "Content creators' Swiss knife"
1289
+ description: 'All-in-one creator tool'
1290
1290
  },
1291
1291
  aigne: {
1292
- description: 'Chat with AIGNE'
1292
+ description: 'Your AI assistant'
1293
1293
  },
1294
1294
  aistro: {
1295
- description: 'Al Language Model Astrologer'
1295
+ description: 'AI-powered astrology'
1296
1296
  },
1297
1297
  blockletLauncher: {
1298
- description: 'Launch your blocklet here'
1298
+ description: 'One-click app launcher'
1299
1299
  },
1300
1300
  alKit: {
1301
- description: 'Empowers Al for application'
1301
+ description: 'Boost apps with AI'
1302
1302
  },
1303
1303
  blockletStore: {
1304
- description: 'App Store for all Blocklets'
1304
+ description: 'Discover & deploy apps'
1305
1305
  },
1306
1306
  web3Kit: {
1307
- description: 'Provides series components'
1307
+ description: 'Web3 dev toolkit'
1308
1308
  },
1309
1309
  blockletFramework: {
1310
- description: 'Launch your blocklet here'
1310
+ description: 'Build and run blocklets'
1311
1311
  },
1312
1312
  didSpaces: {
1313
- description: 'Decentralized storage space'
1313
+ description: 'Secure personal storage'
1314
1314
  },
1315
1315
  abtNetwork: {
1316
- description: "ArcBlock's blockchain system"
1316
+ description: 'Fast blockchain network'
1317
1317
  },
1318
1318
  blockletServer: {
1319
- description: 'Runtime Container Service'
1319
+ description: 'Host your apps easily'
1320
1320
  },
1321
- osar: {
1322
- description: 'Supports multpy blockchains'
1321
+ ocap: {
1322
+ description: 'Multi-chain connector'
1323
1323
  },
1324
1324
  did: {
1325
- description: 'Decentralized Identity'
1325
+ description: 'Self-sovereign ID'
1326
1326
  },
1327
1327
  didWallet: {
1328
- description: 'Intelligent digital wallet'
1328
+ description: 'Smart digital wallet'
1329
1329
  },
1330
1330
  didNameService: {
1331
- description: 'Purchase/host domain'
1331
+ description: 'Web3 domain names'
1332
1332
  },
1333
1333
  vc: {
1334
1334
  description: 'Verifiable Credentials'
1335
1335
  },
1336
1336
  didConnect: {
1337
- description: 'Login with DID'
1337
+ description: 'Passwordless login'
1338
1338
  }
1339
1339
  }
1340
1340
  },
@@ -1347,58 +1347,58 @@ const translations = {
1347
1347
  },
1348
1348
  products: {
1349
1349
  nftStudio: {
1350
- description: 'NFT 创作工具包'
1350
+ description: '铸造和管理 NFT'
1351
1351
  },
1352
1352
  creatorStudio: {
1353
- description: '内容创作者的瑞士军刀'
1353
+ description: '一体化创作工具'
1354
1354
  },
1355
1355
  aigne: {
1356
- description: '与 AIGNE 聊天'
1356
+ description: '您的人工智能助手'
1357
1357
  },
1358
1358
  aistro: {
1359
- description: 'Al 语言模型占星师'
1359
+ description: 'AI 占星术'
1360
1360
  },
1361
1361
  blockletLauncher: {
1362
- description: '在这里启动你的 blocklet'
1362
+ description: '一键启动应用程序'
1363
1363
  },
1364
1364
  alKit: {
1365
- description: '为应用赋能 Al'
1365
+ description: 'AI 赋能应用'
1366
1366
  },
1367
1367
  blockletStore: {
1368
- description: '所有 Blocklets 的应用商店'
1368
+ description: '发现和部署应用程序'
1369
1369
  },
1370
1370
  web3Kit: {
1371
- description: '提供系列组件'
1371
+ description: 'Web3 开发工具包'
1372
1372
  },
1373
1373
  blockletFramework: {
1374
- description: '在这里启动你的 blocklet'
1374
+ description: '构建并运行 Blocklet'
1375
1375
  },
1376
1376
  didSpaces: {
1377
- description: '去中心化存储空间'
1377
+ description: '安全的个人存储'
1378
1378
  },
1379
1379
  abtNetwork: {
1380
- description: 'ArcBlock 的区块链系统'
1380
+ description: '快速区块链网络'
1381
1381
  },
1382
1382
  blockletServer: {
1383
- description: '运行时容器服务'
1383
+ description: '轻松托管应用程序'
1384
1384
  },
1385
- osar: {
1386
- description: '支持多链'
1385
+ ocap: {
1386
+ description: '多链连接器'
1387
1387
  },
1388
1388
  did: {
1389
- description: '去中心化身份'
1389
+ description: '自主身份'
1390
1390
  },
1391
1391
  didWallet: {
1392
1392
  description: '智能数字钱包'
1393
1393
  },
1394
1394
  didNameService: {
1395
- description: '购买/托管域名'
1395
+ description: 'Web3 域名'
1396
1396
  },
1397
1397
  vc: {
1398
1398
  description: '可验证凭证'
1399
1399
  },
1400
1400
  didConnect: {
1401
- description: '使用 DID 登录'
1401
+ description: '无密码登录'
1402
1402
  }
1403
1403
  }
1404
1404
  }
@@ -1567,7 +1567,7 @@ export default function Products({
1567
1567
  rel: "noreferrer noopener",
1568
1568
  children: "\u041E\u0421\u0410\u0420"
1569
1569
  }),
1570
- description: t('products.osar.description'),
1570
+ description: t('products.ocap.description'),
1571
1571
  icon: /*#__PURE__*/_jsx(OCAPSvg, {})
1572
1572
  }]]
1573
1573
  }, {
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import DID from '@arcblock/ux/lib/DID';
3
3
  import RelativeTime from '@arcblock/ux/lib/RelativeTime';
4
4
  import WalletOSIcon from '@arcblock/ux/lib/WalletOSIcon';
5
- import { Box, Chip, Typography } from '@mui/material';
5
+ import { Box, Chip, Typography, useMediaQuery } from '@mui/material';
6
6
  import { temp as colors } from '@arcblock/ux/lib/Colors';
7
7
  import noop from 'lodash/noop';
8
8
  import Avatar from '../../Avatar';
@@ -12,6 +12,7 @@ export default function QuickLoginItem({
12
12
  locale = 'en',
13
13
  onClick = noop
14
14
  }) {
15
+ const isMobile = useMediaQuery(theme => theme.breakpoints.down('md'));
15
16
  const isRawWalletAccount = getSourceProvider(userSession?.user) === 'wallet';
16
17
  return /*#__PURE__*/_jsxs(Box, {
17
18
  sx: {
@@ -52,6 +53,7 @@ export default function QuickLoginItem({
52
53
  overflow: 'hidden'
53
54
  },
54
55
  children: [/*#__PURE__*/_jsxs(Typography, {
56
+ component: Box,
55
57
  sx: {
56
58
  fontSize: '16px',
57
59
  fontWeight: 500,
@@ -106,7 +108,7 @@ export default function QuickLoginItem({
106
108
  children: userSession.user.email
107
109
  })]
108
110
  })]
109
- }), userSession.updatedAt && /*#__PURE__*/_jsx(Box, {
111
+ }), userSession.updatedAt && !isMobile && /*#__PURE__*/_jsx(Box, {
110
112
  component: "span",
111
113
  sx: {
112
114
  color: colors.textMuted,
@@ -2,16 +2,19 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
2
2
  import { Box, CircularProgress, Divider, Fade, IconButton, LinearProgress, MenuItem, MenuList, Paper, Popper } from '@mui/material';
3
3
  import { Icon } from '@iconify/react';
4
4
  import UserIcon from '@iconify-icons/tabler/user';
5
- import { useEffect, useRef } from 'react';
5
+ import { Fragment, useEffect, useRef } from 'react';
6
6
  import { useMemoizedFn, useReactive } from 'ahooks';
7
7
  import noop from 'lodash/noop';
8
- import DIDWalletIcon from '@arcblock/icons/lib/DidWallet';
8
+ import DidBrandLogo from '@arcblock/icons/lib/DidBrandLogo';
9
+ import { useBrowser } from '@arcblock/react-hooks';
10
+ import { joinURL } from 'ufo';
9
11
  import { temp as colors, didConnectColors } from '../../Colors';
10
12
  import CloseButton from '../../CloseButton';
11
13
  import { translate } from '../../Locale/util';
12
14
  import { translations } from '../libs/translation';
13
15
  import Typography from '../../Typography';
14
16
  import QuickLoginItem from './quick-login-item';
17
+ import { getFederatedEnabled, getMaster } from '../../Util/federated';
15
18
  export default function UnLogin({
16
19
  session,
17
20
  onLogin = noop,
@@ -22,12 +25,14 @@ export default function UnLogin({
22
25
  const t = useMemoizedFn((key, data = {}) => {
23
26
  return translate(translations, key, locale, 'en', data);
24
27
  });
28
+ const browser = useBrowser();
25
29
  const isFirstLoading = false;
26
30
  const userAnchorRef = useRef(null);
27
31
  const currentState = useReactive({
28
32
  open: false,
29
33
  userSessions: [],
30
- loadingSessionId: null
34
+ loadingSessionId: null,
35
+ loadAppLogoError: false
31
36
  });
32
37
  const onTogglePopper = useMemoizedFn((value = !currentState.open) => {
33
38
  currentState.open = value;
@@ -38,13 +43,24 @@ export default function UnLogin({
38
43
  }
39
44
  session.login(onLogin);
40
45
  });
46
+ const blocklet = window?.blocklet;
47
+ const federatedEnabled = getFederatedEnabled(blocklet);
48
+ const master = getMaster(blocklet);
49
+ const loginApp = federatedEnabled && master ? master : blocklet;
50
+ const loginAppName = loginApp?.appName || 'DID Connect';
51
+ const loginAppLogo = joinURL(loginApp?.appUrl || '/', loginApp?.appLogo || '/.well-known/service/blocklet/logo?imageFilter=convert&f=png&h=80');
41
52
  useEffect(() => {
42
- const timer = setTimeout(async () => {
43
- currentState.userSessions = await session.getUserSessions();
44
- if (currentState.userSessions.length > 0) {
45
- currentState.open = true;
46
- }
47
- }, 1500);
53
+ let timer;
54
+
55
+ // NOTICE: ArcSphere 中使用原生的快捷登录
56
+ if (!browser.arcSphere) {
57
+ timer = setTimeout(async () => {
58
+ currentState.userSessions = await session.getUserSessions();
59
+ if (currentState.userSessions.length > 0) {
60
+ currentState.open = true;
61
+ }
62
+ }, 1500);
63
+ }
48
64
  return () => {
49
65
  clearTimeout(timer);
50
66
  };
@@ -96,15 +112,9 @@ export default function UnLogin({
96
112
  })
97
113
  }), /*#__PURE__*/_jsx(Popper, {
98
114
  open: currentState.open,
99
- anchorEl: userAnchorRef.current
100
- // @ts-expect-error
101
- ,
102
- dark: dark,
115
+ anchorEl: userAnchorRef.current,
103
116
  transition: true,
104
117
  placement: "bottom-end",
105
- sx: {
106
- zIndex: 1100
107
- },
108
118
  modifiers: [{
109
119
  name: 'offset',
110
120
  options: {
@@ -129,21 +139,39 @@ export default function UnLogin({
129
139
  sx: {
130
140
  display: 'flex',
131
141
  alignItems: 'center',
132
- gap: 2,
142
+ gap: 1,
133
143
  p: 2,
134
144
  borderBottom: '1px solid #eee'
135
145
  },
136
- children: [/*#__PURE__*/_jsx(DIDWalletIcon, {
137
- width: 24,
138
- height: 24
146
+ children: [loginAppLogo && !currentState.loadAppLogoError ? /*#__PURE__*/_jsx("img", {
147
+ src: loginAppLogo,
148
+ height: 20,
149
+ style: {
150
+ maxWidth: 100
151
+ },
152
+ onError: () => {
153
+ currentState.loadAppLogoError = true;
154
+ },
155
+ alt: "Login App Logo"
156
+ }) : /*#__PURE__*/_jsx(DidBrandLogo, {
157
+ height: 24,
158
+ width: 24
139
159
  }), /*#__PURE__*/_jsx(Typography, {
140
160
  fontSize: "auto",
141
161
  sx: {
142
162
  fontSize: '16',
143
163
  flex: 1,
144
- color: didConnectColors.text.secondary
164
+ color: didConnectColors.text.secondary,
165
+ // 最多展示三行
166
+ overflow: 'hidden',
167
+ textOverflow: 'ellipsis',
168
+ display: '-webkit-box',
169
+ WebkitLineClamp: 3,
170
+ WebkitBoxOrient: 'vertical'
145
171
  },
146
- children: t('useQuickLogin')
172
+ children: t('useQuickLogin', {
173
+ name: loginAppName
174
+ })
147
175
  }), /*#__PURE__*/_jsx(CloseButton, {
148
176
  onClose: () => onTogglePopper(false)
149
177
  })]
@@ -154,7 +182,7 @@ export default function UnLogin({
154
182
  },
155
183
  children: currentState.userSessions.map((userSessionItem, index) => {
156
184
  const isLoading = currentState.loadingSessionId === userSessionItem.id;
157
- return /*#__PURE__*/_jsxs(_Fragment, {
185
+ return /*#__PURE__*/_jsxs(Fragment, {
158
186
  children: [/*#__PURE__*/_jsxs(MenuItem, {
159
187
  sx: {
160
188
  overflow: 'hidden',
@@ -185,8 +213,8 @@ export default function UnLogin({
185
213
  my: '0px !important',
186
214
  borderColor: '#e4e4e7'
187
215
  }
188
- }) : null]
189
- });
216
+ }, `${userSessionItem.id}-divider`) : null]
217
+ }, `${userSessionItem.id}-root`);
190
218
  })
191
219
  })]
192
220
  })
@@ -11,7 +11,7 @@ export const translations = {
11
11
  logout: 'Sign Out',
12
12
  addAnotherAccount: 'Add another account',
13
13
  disconnected: 'Disconnected',
14
- useQuickLogin: 'Use DID Connect account to login quickly'
14
+ useQuickLogin: 'Use {name} account to login'
15
15
  },
16
16
  zh: {
17
17
  connectDIDWallet: '连接你的 DID Wallet 获得更高的安全性',
@@ -23,6 +23,6 @@ export const translations = {
23
23
  logout: '退出登录',
24
24
  addAnotherAccount: '添加账户',
25
25
  disconnected: '未连接',
26
- useQuickLogin: '使用 DID Connect 账号快速登录'
26
+ useQuickLogin: '使用 {name} 账号登录'
27
27
  }
28
28
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcblock/ux",
3
- "version": "2.12.4",
3
+ "version": "2.12.6",
4
4
  "description": "Common used react components for arcblock products",
5
5
  "keywords": [
6
6
  "react",
@@ -68,12 +68,12 @@
68
68
  "react": ">=18.2.0",
69
69
  "react-router-dom": ">=6.22.3"
70
70
  },
71
- "gitHead": "f8648a2f55bb57212a24a5948a5f026e2c20b1a7",
71
+ "gitHead": "7b92b4bc17fc44c8c331c61a4e41da117340329a",
72
72
  "dependencies": {
73
73
  "@arcblock/did-motif": "^1.1.13",
74
- "@arcblock/icons": "^2.12.4",
75
- "@arcblock/nft-display": "^2.12.4",
76
- "@arcblock/react-hooks": "^2.12.4",
74
+ "@arcblock/icons": "^2.12.6",
75
+ "@arcblock/nft-display": "^2.12.6",
76
+ "@arcblock/react-hooks": "^2.12.6",
77
77
  "@babel/plugin-syntax-dynamic-import": "^7.8.3",
78
78
  "@fontsource/inter": "^5.0.16",
79
79
  "@fontsource/ubuntu-mono": "^5.0.18",
@@ -5,6 +5,7 @@ const colors = {
5
5
  paper0: 'white',
6
6
  paper1: '#FAFAFA',
7
7
  paper2: '#F4F4F5',
8
+ paper3: '#F0F0F1',
8
9
  },
9
10
  text: {
10
11
  primary: '#18181B',
@@ -49,7 +50,9 @@ const colors = {
49
50
  dark: '#00A63E',
50
51
  },
51
52
  divider: {
52
- main: '#F4F4F5',
53
+ main: 'rgba(18, 22, 24, 0.06)',
54
+ light: '#F4F4F5',
55
+ dark: '#D4D4D5',
53
56
  },
54
57
  };
55
58
 
@@ -99,7 +99,6 @@ function Header({
99
99
 
100
100
  const Root = styled(Box)`
101
101
  position: relative;
102
- z-index: ${(props) => props.theme.zIndex.appBar};
103
102
  font-size: 14px;
104
103
  background: ${(props) => props.theme.palette.common.white};
105
104
  .header-container {
@@ -94,23 +94,53 @@ export default function LocaleSelector(props: LocaleSelectorProps) {
94
94
  </Box>
95
95
  </ButtonComponent>
96
96
 
97
- <StyledPopper open={open} anchorEl={anchorEl.current} {...popperProps} disablePortal>
98
- <div className="locales">
97
+ <Popper open={open} anchorEl={anchorEl.current} {...popperProps}>
98
+ <Box
99
+ className="locales"
100
+ sx={{
101
+ background: getBackground({ ...popperProps, theme }),
102
+ boxShadow: `0px 8px 16px 0px ${colors.gray6}, 0px 0px 0px 1px ${colors.gray6}`,
103
+ borderRadius: 2,
104
+ }}>
99
105
  <ClickAwayListener onClickAway={onClose}>
100
106
  <MenuList>
101
107
  {languages.map(({ code, name }) => (
102
- <MenuItem key={code} className="locale-item" onClick={() => onSelect(code)}>
103
- <IconifyIcon
108
+ <MenuItem
109
+ key={code}
110
+ className="locale-item"
111
+ onClick={() => onSelect(code)}
112
+ sx={{
113
+ fontSize: 16,
114
+ fontStyle: 'normal',
115
+ fontStretch: 'normal',
116
+ lineHeight: 'normal',
117
+ letterSpacing: '2px',
118
+ textAlign: 'center',
119
+ color: getColor({ ...popperProps, theme }),
120
+ cursor: 'pointer',
121
+ display: 'flex',
122
+ padding: '16px',
123
+ alignItems: 'center',
124
+ }}>
125
+ <Box
126
+ component={IconifyIcon}
104
127
  icon={CheckIcon}
105
128
  className={code === locale ? 'check-icon check-icon-visible' : 'check-icon'}
129
+ sx={[
130
+ code === locale ? { visibility: 'visible' } : {},
131
+ {
132
+ visibility: 'hidden',
133
+ marginRight: 0.5,
134
+ },
135
+ ]}
106
136
  />
107
137
  {name}
108
138
  </MenuItem>
109
139
  ))}
110
140
  </MenuList>
111
141
  </ClickAwayListener>
112
- </div>
113
- </StyledPopper>
142
+ </Box>
143
+ </Popper>
114
144
  </Div>
115
145
  );
116
146
  }
@@ -137,39 +167,10 @@ const Div = styled('div', {
137
167
  color: ${(props) => getColor(props)};
138
168
  }
139
169
  }
140
-
141
- .locales {
142
- background: ${(props) => getBackground(props)};
143
- box-shadow:
144
- 0px 8px 16px 0px ${colors.gray6},
145
- 0px 0px 0px 1px ${colors.gray6};
146
- border-radius: 8px;
147
- }
148
-
149
- .locale-item {
150
- font-size: 16px;
151
- font-style: normal;
152
- font-stretch: normal;
153
- line-height: normal;
154
- letter-spacing: 2px;
155
- text-align: center;
156
- color: ${(props) => getColor(props)};
157
- cursor: pointer;
158
- display: flex;
159
- padding: 16px;
160
- align-items: center;
161
- .check-icon {
162
- visibility: hidden;
163
- margin-right: 4px;
164
- }
165
- .check-icon-visible {
166
- visibility: visible;
167
- }
168
- }
169
170
  `;
170
171
 
171
172
  const StyledPopper = styled(Popper)`
172
173
  z-index: ${({ theme }) => {
173
- return theme.zIndex.tooltip + 10;
174
+ return theme.zIndex.modal + 1;
174
175
  }};
175
176
  `;
@@ -37,58 +37,58 @@ const translations = {
37
37
  },
38
38
  products: {
39
39
  nftStudio: {
40
- description: 'Toolkit for NFT creation',
40
+ description: 'Mint and manage NFTs',
41
41
  },
42
42
  creatorStudio: {
43
- description: "Content creators' Swiss knife",
43
+ description: 'All-in-one creator tool',
44
44
  },
45
45
  aigne: {
46
- description: 'Chat with AIGNE',
46
+ description: 'Your AI assistant',
47
47
  },
48
48
  aistro: {
49
- description: 'Al Language Model Astrologer',
49
+ description: 'AI-powered astrology',
50
50
  },
51
51
  blockletLauncher: {
52
- description: 'Launch your blocklet here',
52
+ description: 'One-click app launcher',
53
53
  },
54
54
  alKit: {
55
- description: 'Empowers Al for application',
55
+ description: 'Boost apps with AI',
56
56
  },
57
57
  blockletStore: {
58
- description: 'App Store for all Blocklets',
58
+ description: 'Discover & deploy apps',
59
59
  },
60
60
  web3Kit: {
61
- description: 'Provides series components',
61
+ description: 'Web3 dev toolkit',
62
62
  },
63
63
  blockletFramework: {
64
- description: 'Launch your blocklet here',
64
+ description: 'Build and run blocklets',
65
65
  },
66
66
  didSpaces: {
67
- description: 'Decentralized storage space',
67
+ description: 'Secure personal storage',
68
68
  },
69
69
  abtNetwork: {
70
- description: "ArcBlock's blockchain system",
70
+ description: 'Fast blockchain network',
71
71
  },
72
72
  blockletServer: {
73
- description: 'Runtime Container Service',
73
+ description: 'Host your apps easily',
74
74
  },
75
- osar: {
76
- description: 'Supports multpy blockchains',
75
+ ocap: {
76
+ description: 'Multi-chain connector',
77
77
  },
78
78
  did: {
79
- description: 'Decentralized Identity',
79
+ description: 'Self-sovereign ID',
80
80
  },
81
81
  didWallet: {
82
- description: 'Intelligent digital wallet',
82
+ description: 'Smart digital wallet',
83
83
  },
84
84
  didNameService: {
85
- description: 'Purchase/host domain',
85
+ description: 'Web3 domain names',
86
86
  },
87
87
  vc: {
88
88
  description: 'Verifiable Credentials',
89
89
  },
90
90
  didConnect: {
91
- description: 'Login with DID',
91
+ description: 'Passwordless login',
92
92
  },
93
93
  },
94
94
  },
@@ -101,58 +101,58 @@ const translations = {
101
101
  },
102
102
  products: {
103
103
  nftStudio: {
104
- description: 'NFT 创作工具包',
104
+ description: '铸造和管理 NFT',
105
105
  },
106
106
  creatorStudio: {
107
- description: '内容创作者的瑞士军刀',
107
+ description: '一体化创作工具',
108
108
  },
109
109
  aigne: {
110
- description: '与 AIGNE 聊天',
110
+ description: '您的人工智能助手',
111
111
  },
112
112
  aistro: {
113
- description: 'Al 语言模型占星师',
113
+ description: 'AI 占星术',
114
114
  },
115
115
  blockletLauncher: {
116
- description: '在这里启动你的 blocklet',
116
+ description: '一键启动应用程序',
117
117
  },
118
118
  alKit: {
119
- description: '为应用赋能 Al',
119
+ description: 'AI 赋能应用',
120
120
  },
121
121
  blockletStore: {
122
- description: '所有 Blocklets 的应用商店',
122
+ description: '发现和部署应用程序',
123
123
  },
124
124
  web3Kit: {
125
- description: '提供系列组件',
125
+ description: 'Web3 开发工具包',
126
126
  },
127
127
  blockletFramework: {
128
- description: '在这里启动你的 blocklet',
128
+ description: '构建并运行 Blocklet',
129
129
  },
130
130
  didSpaces: {
131
- description: '去中心化存储空间',
131
+ description: '安全的个人存储',
132
132
  },
133
133
  abtNetwork: {
134
- description: 'ArcBlock 的区块链系统',
134
+ description: '快速区块链网络',
135
135
  },
136
136
  blockletServer: {
137
- description: '运行时容器服务',
137
+ description: '轻松托管应用程序',
138
138
  },
139
- osar: {
140
- description: '支持多链',
139
+ ocap: {
140
+ description: '多链连接器',
141
141
  },
142
142
  did: {
143
- description: '去中心化身份',
143
+ description: '自主身份',
144
144
  },
145
145
  didWallet: {
146
146
  description: '智能数字钱包',
147
147
  },
148
148
  didNameService: {
149
- description: '购买/托管域名',
149
+ description: 'Web3 域名',
150
150
  },
151
151
  vc: {
152
152
  description: '可验证凭证',
153
153
  },
154
154
  didConnect: {
155
- description: '使用 DID 登录',
155
+ description: '无密码登录',
156
156
  },
157
157
  },
158
158
  },
@@ -350,7 +350,7 @@ export default function Products({ className, isOpen, ...rest }: ProductsProps)
350
350
  ОСАР
351
351
  </Link>
352
352
  ),
353
- description: t('products.osar.description'),
353
+ description: t('products.ocap.description'),
354
354
  icon: <OCAPSvg />,
355
355
  },
356
356
  ],
@@ -19,11 +19,10 @@ import AccountCircleOffOutlineRoundedIcon from '@iconify-icons/material-symbols/
19
19
  import InviteIcon from '@iconify-icons/material-symbols/featured-seasonal-and-gifts-rounded';
20
20
  import Copy from 'copy-to-clipboard';
21
21
  import noop from 'lodash/noop';
22
- import bridge from '@arcblock/bridge';
23
22
 
24
23
  import Toast from '../../Toast';
25
24
  import DidAvatar from '../../Avatar';
26
- import { getUserAvatar, getVisitorId } from '../../Util';
25
+ import { getUserAvatar } from '../../Util';
27
26
  import UserInfo from './user-info';
28
27
  import { temp as colors } from '../../Colors';
29
28
  import { DASHBOARD_URL, PROFILE_URL } from '../../Util/constant';
@@ -2,7 +2,8 @@ import PropTypes from 'prop-types';
2
2
  import DID from '@arcblock/ux/lib/DID';
3
3
  import RelativeTime from '@arcblock/ux/lib/RelativeTime';
4
4
  import WalletOSIcon from '@arcblock/ux/lib/WalletOSIcon';
5
- import { Box, Chip, Typography } from '@mui/material';
5
+ import { Box, Chip, Typography, useMediaQuery } from '@mui/material';
6
+ import type { Theme } from '@mui/material';
6
7
  import { temp as colors } from '@arcblock/ux/lib/Colors';
7
8
  import noop from 'lodash/noop';
8
9
 
@@ -32,6 +33,7 @@ export default function QuickLoginItem({
32
33
  updatedAt: string;
33
34
  };
34
35
  }) {
36
+ const isMobile = useMediaQuery((theme: Theme) => theme.breakpoints.down('md'));
35
37
  const isRawWalletAccount = getSourceProvider(userSession?.user) === 'wallet';
36
38
 
37
39
  return (
@@ -65,6 +67,7 @@ export default function QuickLoginItem({
65
67
  <Avatar src={userSession.user.avatar} did={userSession.user.did} size={44} variant="circle" shape="circle" />
66
68
  <Box sx={{ flex: 1, overflow: 'hidden' }}>
67
69
  <Typography
70
+ component={Box}
68
71
  sx={{
69
72
  fontSize: '16px',
70
73
  fontWeight: 500,
@@ -120,7 +123,7 @@ export default function QuickLoginItem({
120
123
  )}
121
124
  </Box>
122
125
  </Box>
123
- {userSession.updatedAt && (
126
+ {userSession.updatedAt && !isMobile && (
124
127
  <Box component="span" sx={{ color: colors.textMuted, fontSize: '12px', flexShrink: 0 }}>
125
128
  {/* @ts-ignore */}
126
129
  <RelativeTime value={userSession.updatedAt} locale={locale} />
@@ -12,10 +12,12 @@ import {
12
12
  } from '@mui/material';
13
13
  import { Icon } from '@iconify/react';
14
14
  import UserIcon from '@iconify-icons/tabler/user';
15
- import { useEffect, useRef } from 'react';
15
+ import { Fragment, useEffect, useRef } from 'react';
16
16
  import { useMemoizedFn, useReactive } from 'ahooks';
17
17
  import noop from 'lodash/noop';
18
- import DIDWalletIcon from '@arcblock/icons/lib/DidWallet';
18
+ import DidBrandLogo from '@arcblock/icons/lib/DidBrandLogo';
19
+ import { useBrowser } from '@arcblock/react-hooks';
20
+ import { joinURL } from 'ufo';
19
21
 
20
22
  import { Session } from '../../type';
21
23
  import { temp as colors, didConnectColors } from '../../Colors';
@@ -24,6 +26,7 @@ import { translate } from '../../Locale/util';
24
26
  import { translations } from '../libs/translation';
25
27
  import Typography from '../../Typography';
26
28
  import QuickLoginItem from './quick-login-item';
29
+ import { getFederatedEnabled, getMaster } from '../../Util/federated';
27
30
 
28
31
  export interface UnLoginProps {
29
32
  session: Session;
@@ -37,12 +40,15 @@ export default function UnLogin({ session, onLogin = noop, size = 24, dark = fal
37
40
  const t = useMemoizedFn((key, data = {}) => {
38
41
  return translate(translations, key, locale, 'en', data);
39
42
  });
43
+ const browser = useBrowser();
44
+
40
45
  const isFirstLoading = false;
41
46
  const userAnchorRef = useRef(null);
42
47
  const currentState = useReactive({
43
48
  open: false,
44
49
  userSessions: [] as Session[],
45
50
  loadingSessionId: null,
51
+ loadAppLogoError: false,
46
52
  });
47
53
  const onTogglePopper = useMemoizedFn((value = !currentState.open) => {
48
54
  currentState.open = value;
@@ -54,13 +60,28 @@ export default function UnLogin({ session, onLogin = noop, size = 24, dark = fal
54
60
  session.login(onLogin);
55
61
  });
56
62
 
63
+ const blocklet = window?.blocklet;
64
+ const federatedEnabled = getFederatedEnabled(blocklet);
65
+ const master = getMaster(blocklet);
66
+ const loginApp = federatedEnabled && master ? master : blocklet;
67
+ const loginAppName = loginApp?.appName || 'DID Connect';
68
+ const loginAppLogo = joinURL(
69
+ loginApp?.appUrl || '/',
70
+ loginApp?.appLogo || '/.well-known/service/blocklet/logo?imageFilter=convert&f=png&h=80'
71
+ );
72
+
57
73
  useEffect(() => {
58
- const timer = setTimeout(async () => {
59
- currentState.userSessions = await session.getUserSessions();
60
- if (currentState.userSessions.length > 0) {
61
- currentState.open = true;
62
- }
63
- }, 1500);
74
+ let timer: NodeJS.Timeout;
75
+
76
+ // NOTICE: ArcSphere 中使用原生的快捷登录
77
+ if (!browser.arcSphere) {
78
+ timer = setTimeout(async () => {
79
+ currentState.userSessions = await session.getUserSessions();
80
+ if (currentState.userSessions.length > 0) {
81
+ currentState.open = true;
82
+ }
83
+ }, 1500);
84
+ }
64
85
 
65
86
  return () => {
66
87
  clearTimeout(timer);
@@ -106,11 +127,8 @@ export default function UnLogin({ session, onLogin = noop, size = 24, dark = fal
106
127
  <Popper
107
128
  open={currentState.open}
108
129
  anchorEl={userAnchorRef.current}
109
- // @ts-expect-error
110
- dark={dark}
111
130
  transition
112
131
  placement="bottom-end"
113
- sx={{ zIndex: 1100 }}
114
132
  modifiers={[
115
133
  {
116
134
  name: 'offset',
@@ -135,19 +153,39 @@ export default function UnLogin({ session, onLogin = noop, size = 24, dark = fal
135
153
  sx={{
136
154
  display: 'flex',
137
155
  alignItems: 'center',
138
- gap: 2,
156
+ gap: 1,
139
157
  p: 2,
140
158
  borderBottom: '1px solid #eee',
141
159
  }}>
142
- <DIDWalletIcon width={24} height={24} />
160
+ {loginAppLogo && !currentState.loadAppLogoError ? (
161
+ <img
162
+ src={loginAppLogo}
163
+ height={20}
164
+ style={{
165
+ maxWidth: 100,
166
+ }}
167
+ onError={() => {
168
+ currentState.loadAppLogoError = true;
169
+ }}
170
+ alt="Login App Logo"
171
+ />
172
+ ) : (
173
+ <DidBrandLogo height={24} width={24} />
174
+ )}
143
175
  <Typography
144
176
  fontSize="auto"
145
177
  sx={{
146
178
  fontSize: '16',
147
179
  flex: 1,
148
180
  color: didConnectColors.text.secondary,
181
+ // 最多展示三行
182
+ overflow: 'hidden',
183
+ textOverflow: 'ellipsis',
184
+ display: '-webkit-box',
185
+ WebkitLineClamp: 3,
186
+ WebkitBoxOrient: 'vertical',
149
187
  }}>
150
- {t('useQuickLogin')}
188
+ {t('useQuickLogin', { name: loginAppName })}
151
189
  </Typography>
152
190
  <CloseButton onClose={() => onTogglePopper(false)} />
153
191
  </Box>
@@ -156,7 +194,7 @@ export default function UnLogin({ session, onLogin = noop, size = 24, dark = fal
156
194
  const isLoading = currentState.loadingSessionId === userSessionItem.id;
157
195
 
158
196
  return (
159
- <>
197
+ <Fragment key={`${userSessionItem.id}-root`}>
160
198
  <MenuItem
161
199
  key={userSessionItem.id}
162
200
  sx={{
@@ -185,6 +223,7 @@ export default function UnLogin({ session, onLogin = noop, size = 24, dark = fal
185
223
  </MenuItem>
186
224
  {index < currentState.userSessions.length - 1 ? (
187
225
  <Divider
226
+ key={`${userSessionItem.id}-divider`}
188
227
  sx={{
189
228
  mx: 2,
190
229
  my: '0px !important',
@@ -192,7 +231,7 @@ export default function UnLogin({ session, onLogin = noop, size = 24, dark = fal
192
231
  }}
193
232
  />
194
233
  ) : null}
195
- </>
234
+ </Fragment>
196
235
  );
197
236
  })}
198
237
  </MenuList>
@@ -13,7 +13,7 @@ export const translations: Translations = {
13
13
  logout: 'Sign Out',
14
14
  addAnotherAccount: 'Add another account',
15
15
  disconnected: 'Disconnected',
16
- useQuickLogin: 'Use DID Connect account to login quickly',
16
+ useQuickLogin: 'Use {name} account to login',
17
17
  },
18
18
  zh: {
19
19
  connectDIDWallet: '连接你的 DID Wallet 获得更高的安全性',
@@ -25,6 +25,6 @@ export const translations: Translations = {
25
25
  logout: '退出登录',
26
26
  addAnotherAccount: '添加账户',
27
27
  disconnected: '未连接',
28
- useQuickLogin: '使用 DID Connect 账号快速登录',
28
+ useQuickLogin: '使用 {name} 账号登录',
29
29
  },
30
30
  };