@abtnode/ux 1.16.25-beta-023ec101 → 1.16.25-beta-bc165d9b
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.
- package/es/blocklet/actions.js +19 -10
- package/es/blocklet/component/add-component-core.js +5 -0
- package/es/blocklet/component/component-cell.js +2 -1
- package/es/blocklet/icons.js +3 -1
- package/es/blocklet/overview.js +13 -7
- package/es/blocklet/publish/create-release.js +150 -43
- package/es/blocklet/publish/index.js +0 -4
- package/es/blocklet/publish/project-list.js +133 -29
- package/es/blocklet/publish/release-list.js +18 -4
- package/es/blocklet/publish/resource.js +35 -32
- package/es/blocklet/router/rule-list.js +2 -1
- package/es/locales/ar.js +13 -8
- package/es/locales/de.js +13 -8
- package/es/locales/en.js +12 -7
- package/es/locales/es.js +13 -8
- package/es/locales/fr.js +13 -8
- package/es/locales/hi.js +13 -8
- package/es/locales/i18n.db +0 -0
- package/es/locales/id.js +13 -8
- package/es/locales/ja.js +13 -8
- package/es/locales/ko.js +13 -8
- package/es/locales/pt.js +13 -8
- package/es/locales/ru.js +13 -8
- package/es/locales/th.js +13 -8
- package/es/locales/vi.js +13 -8
- package/es/locales/zh-tw.js +13 -8
- package/es/locales/zh.js +17 -12
- package/es/subscription/blocklet.js +175 -0
- package/es/subscription/chip-label.js +21 -0
- package/es/{subscription.js → subscription/server.js} +31 -30
- package/es/team/members/connections.js +2 -1
- package/es/team/members/member.js +2 -1
- package/es/util/index.js +42 -9
- package/lib/blocklet/actions.js +22 -11
- package/lib/blocklet/component/add-component-core.js +1 -1
- package/lib/blocklet/component/component-cell.js +2 -1
- package/lib/blocklet/icons.js +3 -1
- package/lib/blocklet/overview.js +13 -7
- package/lib/blocklet/publish/create-release.js +154 -43
- package/lib/blocklet/publish/index.js +0 -4
- package/lib/blocklet/publish/project-list.js +133 -29
- package/lib/blocklet/publish/release-list.js +18 -4
- package/lib/blocklet/publish/resource.js +34 -31
- package/lib/blocklet/router/rule-list.js +2 -1
- package/lib/locales/ar.js +13 -8
- package/lib/locales/de.js +13 -8
- package/lib/locales/en.js +12 -7
- package/lib/locales/es.js +13 -8
- package/lib/locales/fr.js +13 -8
- package/lib/locales/hi.js +13 -8
- package/lib/locales/i18n.db +0 -0
- package/lib/locales/id.js +13 -8
- package/lib/locales/ja.js +13 -8
- package/lib/locales/ko.js +13 -8
- package/lib/locales/pt.js +13 -8
- package/lib/locales/ru.js +13 -8
- package/lib/locales/th.js +13 -8
- package/lib/locales/vi.js +13 -8
- package/lib/locales/zh-tw.js +13 -8
- package/lib/locales/zh.js +17 -12
- package/lib/subscription/blocklet.js +189 -0
- package/lib/subscription/chip-label.js +29 -0
- package/lib/{subscription.js → subscription/server.js} +37 -37
- package/lib/team/members/connections.js +2 -1
- package/lib/team/members/member.js +2 -1
- package/lib/util/index.js +51 -18
- package/package.json +16 -16
- package/es/blocklet/publish/create-project.js +0 -205
- package/lib/blocklet/publish/create-project.js +0 -215
package/es/locales/zh-tw.js
CHANGED
|
@@ -655,12 +655,12 @@ export default {
|
|
|
655
655
|
resourceTitle: '資源',
|
|
656
656
|
blockletEmptyTip: '這裡沒有任何區塊元件',
|
|
657
657
|
createBlockletTip: '您可以透過現有的資源、元件和設定,在此應用程式中建立新的 blocklet',
|
|
658
|
-
createBlocklet: '
|
|
658
|
+
createBlocklet: '新的區塊',
|
|
659
659
|
deleteBlockletTip: '刪除後無法恢復區塊,請確認',
|
|
660
660
|
componentNotRunning: '{name}元件未運行,請先啟動。',
|
|
661
661
|
releaseEmptyTip: '這裡沒有任何發布',
|
|
662
662
|
createReleaseTip: '您可以創建一個區塊釋出,附帶釋出說明和資源,供其他人使用',
|
|
663
|
-
createRelease: '
|
|
663
|
+
createRelease: '新版本發布',
|
|
664
664
|
deleteReleaseTip: '刪除後無法還原發布',
|
|
665
665
|
createBlockletDid: '從DID錢包創建',
|
|
666
666
|
createReleaseSuccess: '發佈成功',
|
|
@@ -680,13 +680,18 @@ export default {
|
|
|
680
680
|
noDescription: '需要提供 Blocklet 描述',
|
|
681
681
|
noNote: '需要提供發佈說明'
|
|
682
682
|
},
|
|
683
|
-
packTip: '
|
|
683
|
+
packTip: '目前,blocklet可以直接安裝為應用程序。組件和應用程序配置將自動包含在blocklet中',
|
|
684
684
|
resourceChangedWarning: '您已修改資源,請儘速保存',
|
|
685
|
-
installResourceTip: '
|
|
685
|
+
installResourceTip: '安裝網址:',
|
|
686
686
|
installResourceTip2: '如果您想查看更多提示,請訪問 {name}',
|
|
687
687
|
installResourceHelp: '幫助文件',
|
|
688
688
|
componentIncluded: '已包含',
|
|
689
|
-
componentForceRequired: '強制要求'
|
|
689
|
+
componentForceRequired: '強制要求',
|
|
690
|
+
productListTitle: '發布 Blocklets',
|
|
691
|
+
download: '下載 {name}',
|
|
692
|
+
delete: '刪除 {name}',
|
|
693
|
+
copyInstallUrl: '複製安裝連結',
|
|
694
|
+
install: '安裝{name}'
|
|
690
695
|
},
|
|
691
696
|
titleValidationError: '標題長度必須至少為3到40個字符',
|
|
692
697
|
descriptionValidationError: '描述長度必須介於3到160個字符之間'
|
|
@@ -790,7 +795,7 @@ export default {
|
|
|
790
795
|
switchLabel: '歡迎頁面'
|
|
791
796
|
},
|
|
792
797
|
upgrade: {
|
|
793
|
-
title: '升級 Blocklet 伺服器
|
|
798
|
+
title: '升級 Blocklet 伺服器',
|
|
794
799
|
description: '在升級期間,您的 Blocklet 伺服器將進入維護模式,更新完成後將持續幾分鐘。',
|
|
795
800
|
dialog: '點擊"確認"安裝更新。Blocklet服務器將進入維護模式,直到更新完成並自動返回生產模式。',
|
|
796
801
|
confirm: '升級',
|
|
@@ -803,7 +808,7 @@ export default {
|
|
|
803
808
|
verifying: '正在驗證Blocklet服務器v{version}',
|
|
804
809
|
rollback: '回滾Blocklet伺服器',
|
|
805
810
|
complete: '升級完成!',
|
|
806
|
-
progress: '
|
|
811
|
+
progress: '升級 {name}',
|
|
807
812
|
check: '檢查更新',
|
|
808
813
|
latest: '您正在執行最新版本。'
|
|
809
814
|
},
|
|
@@ -818,7 +823,7 @@ export default {
|
|
|
818
823
|
cleanup: '確保一切正常',
|
|
819
824
|
rollback: '清理髒污狀態',
|
|
820
825
|
complete: '維護完成!',
|
|
821
|
-
progress: '重新啟動
|
|
826
|
+
progress: '重新啟動 {name}'
|
|
822
827
|
},
|
|
823
828
|
register: {
|
|
824
829
|
titleAdded: '已新增至 Blocklet Launcher',
|
package/es/locales/zh.js
CHANGED
|
@@ -655,26 +655,26 @@ export default {
|
|
|
655
655
|
productTitle: 'Blocklet 详情',
|
|
656
656
|
versionTitle: '版本信息',
|
|
657
657
|
imgTitle: '图片资源',
|
|
658
|
-
resourceTitle: '
|
|
659
|
-
blockletEmptyTip: '这里没有任何
|
|
658
|
+
resourceTitle: '资源型 Blocklet',
|
|
659
|
+
blockletEmptyTip: '这里没有任何 Blocklet',
|
|
660
660
|
createBlockletTip: '你可以使用此应用的资源,组件,配置制作新的 Blocklet',
|
|
661
|
-
createBlocklet: '
|
|
661
|
+
createBlocklet: '新的块',
|
|
662
662
|
deleteBlockletTip: '此 Blocklet 删除后不可恢复,是否继续?',
|
|
663
663
|
componentNotRunning: '组件 {name} 未运行',
|
|
664
664
|
releaseEmptyTip: '这里没有任何发布',
|
|
665
|
-
createReleaseTip: '您可以创建 Blocklet
|
|
666
|
-
createRelease: '
|
|
665
|
+
createReleaseTip: '您可以创建 Blocklet 新版本,在发布中包含说明和资源,以供其他人使用',
|
|
666
|
+
createRelease: '创建新的版本',
|
|
667
667
|
deleteReleaseTip: '此发布删除后不可恢复,是否继续?',
|
|
668
668
|
createBlockletDid: '通过 DID 钱包创建',
|
|
669
669
|
createReleaseSuccess: '发布成功',
|
|
670
670
|
saveDraftSuccess: '保存成功',
|
|
671
|
-
packTip: 'Blocklet
|
|
671
|
+
packTip: '您的 Blocklet 现在可以直接安装为应用程序。应用程序配置将自动包含在内',
|
|
672
672
|
resourceChangedWarning: '您修改了资源,请及时保存',
|
|
673
|
-
installResourceTip: '
|
|
673
|
+
installResourceTip: '安装网址:',
|
|
674
674
|
installResourceTip2: '如果你需要更多提示,请查看',
|
|
675
675
|
installResourceHelp: '帮助文档',
|
|
676
676
|
componentIncluded: '包含',
|
|
677
|
-
componentForceRequired: '
|
|
677
|
+
componentForceRequired: '强依赖',
|
|
678
678
|
connect: {
|
|
679
679
|
title: '创建 Blocklet DID',
|
|
680
680
|
scan: '扫描下面的二维码来生成 Blocklet DID',
|
|
@@ -689,7 +689,12 @@ export default {
|
|
|
689
689
|
noVersion: '请填写 Blocklet 版本号',
|
|
690
690
|
noDescription: '请填写 Blocklet 描述',
|
|
691
691
|
noNote: '请填写 发布说明'
|
|
692
|
-
}
|
|
692
|
+
},
|
|
693
|
+
productListTitle: '发布 Blocklets',
|
|
694
|
+
download: '下载 {name}',
|
|
695
|
+
delete: '删除 {name}',
|
|
696
|
+
copyInstallUrl: '复制安装链接',
|
|
697
|
+
install: '安装 {name}'
|
|
693
698
|
},
|
|
694
699
|
titleValidationError: '标题长度必须至少为3到40个字符',
|
|
695
700
|
descriptionValidationError: '描述长度必须在3到160个字符之间'
|
|
@@ -786,7 +791,7 @@ export default {
|
|
|
786
791
|
nftDomainUrl: 'NFT Domain 地址',
|
|
787
792
|
nftDomainUrlPlaceholder: '你可以选择其它的 NFT Domain 服务器, 也可以使用官方提供的版本',
|
|
788
793
|
upgrade: {
|
|
789
|
-
title: '
|
|
794
|
+
title: '升级 Blocklet 服务器',
|
|
790
795
|
description: '在升级期间,节点将会进入维护模式几分钟。',
|
|
791
796
|
dialog: '点击 “确认” 安装更新。节点将进入维护模式,直到更新完成并自动返回生产模式。',
|
|
792
797
|
confirm: '升级',
|
|
@@ -799,7 +804,7 @@ export default {
|
|
|
799
804
|
verifying: '验证节点新版本 v{version}',
|
|
800
805
|
rollback: '回滚此次升级',
|
|
801
806
|
complete: '升级完成!',
|
|
802
|
-
progress: '
|
|
807
|
+
progress: '升级 {name}',
|
|
803
808
|
check: '检查更新',
|
|
804
809
|
latest: '太棒了,你的节点已经是最新版!'
|
|
805
810
|
},
|
|
@@ -814,7 +819,7 @@ export default {
|
|
|
814
819
|
cleanup: '验证重启成功',
|
|
815
820
|
rollback: '撤销重启操作',
|
|
816
821
|
complete: '维护完成',
|
|
817
|
-
progress: '
|
|
822
|
+
progress: '重新开始 {name}'
|
|
818
823
|
},
|
|
819
824
|
welcome: {
|
|
820
825
|
switchLabel: 'Welcome 页面'
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
2
|
+
import dayjs from '@abtnode/util/lib/dayjs';
|
|
3
|
+
import Chip from '@mui/material/Chip';
|
|
4
|
+
import CircularProgress from '@mui/material/CircularProgress';
|
|
5
|
+
import Popover from '@mui/material/Popover';
|
|
6
|
+
import useMediaQuery from '@mui/material/useMediaQuery';
|
|
7
|
+
import PropTypes from 'prop-types';
|
|
8
|
+
import prettyMs from 'pretty-ms-i18n';
|
|
9
|
+
import { useRef } from 'react';
|
|
10
|
+
import useAsyncRetry from 'react-use/lib/useAsyncRetry';
|
|
11
|
+
import useSetState from 'react-use/lib/useSetState';
|
|
12
|
+
import { useNodeContext } from '../contexts/node';
|
|
13
|
+
import { formatPrettyMsLocale, getSubscriptionUrlV2 } from '../util';
|
|
14
|
+
import ChipLabel from './chip-label';
|
|
15
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
16
|
+
const DEFAULT_LAUNCHER_URL = 'https://launcher.arcblock.io/'; // 兼容: 旧版本的 blocklet.controller 没有 launcherUrl 字段
|
|
17
|
+
|
|
18
|
+
const ALERT_THRESHOLD_MS = 30 * 24 * 60 * 60 * 1000;
|
|
19
|
+
function SubscriptionBlocklet({
|
|
20
|
+
launcherUrl,
|
|
21
|
+
chainHost,
|
|
22
|
+
nftId,
|
|
23
|
+
launcherSessionId,
|
|
24
|
+
...props
|
|
25
|
+
}) {
|
|
26
|
+
const {
|
|
27
|
+
t,
|
|
28
|
+
locale
|
|
29
|
+
} = useLocaleContext();
|
|
30
|
+
const node = useNodeContext();
|
|
31
|
+
const [state, setState] = useSetState({
|
|
32
|
+
safeIframeRef: null,
|
|
33
|
+
popoverAnchorEl: null
|
|
34
|
+
});
|
|
35
|
+
const iframeRef = useRef(null);
|
|
36
|
+
const isMobile = useMediaQuery(x => x.breakpoints.down('md'));
|
|
37
|
+
const {
|
|
38
|
+
sx = {},
|
|
39
|
+
...rest
|
|
40
|
+
} = props;
|
|
41
|
+
const typoKey = isMobile ? 'mobile' : 'desktop';
|
|
42
|
+
const asyncState = useAsyncRetry(async () => {
|
|
43
|
+
const [data, subscriptionURL] = await Promise.all([node.api.getLauncherSession({
|
|
44
|
+
input: {
|
|
45
|
+
launcherSessionId,
|
|
46
|
+
launcherUrl
|
|
47
|
+
}
|
|
48
|
+
}), getSubscriptionUrlV2({
|
|
49
|
+
launcherUrl: launcherUrl || DEFAULT_LAUNCHER_URL,
|
|
50
|
+
nftDid: nftId,
|
|
51
|
+
launcherSessionId,
|
|
52
|
+
locale
|
|
53
|
+
})]);
|
|
54
|
+
if (data?.error) {
|
|
55
|
+
throw new Error(data.error);
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
launcherSession: data.launcherSession,
|
|
59
|
+
subscriptionURL
|
|
60
|
+
};
|
|
61
|
+
}, [locale]);
|
|
62
|
+
if (asyncState.loading) {
|
|
63
|
+
return /*#__PURE__*/_jsx(Chip, {
|
|
64
|
+
label: /*#__PURE__*/_jsxs(ChipLabel, {
|
|
65
|
+
children: [!isMobile && t('expiration.desktop.loading'), /*#__PURE__*/_jsx(CircularProgress, {
|
|
66
|
+
size: 16
|
|
67
|
+
})]
|
|
68
|
+
}),
|
|
69
|
+
variant: "success",
|
|
70
|
+
sx: {
|
|
71
|
+
cursor: 'pointer',
|
|
72
|
+
...sx
|
|
73
|
+
},
|
|
74
|
+
...rest
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
if (asyncState.error) {
|
|
78
|
+
console.error(asyncState.error);
|
|
79
|
+
return /*#__PURE__*/_jsx(Chip, {
|
|
80
|
+
label: /*#__PURE__*/_jsx(ChipLabel, {
|
|
81
|
+
children: t(`expiration.${typoKey}.loadFailed`)
|
|
82
|
+
}),
|
|
83
|
+
color: "error",
|
|
84
|
+
variant: "success",
|
|
85
|
+
sx: {
|
|
86
|
+
cursor: 'pointer',
|
|
87
|
+
...sx
|
|
88
|
+
},
|
|
89
|
+
...rest,
|
|
90
|
+
onClick: () => asyncState.retry()
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
const handlePopoverClick = event => {
|
|
94
|
+
setState({
|
|
95
|
+
popoverAnchorEl: event.currentTarget
|
|
96
|
+
});
|
|
97
|
+
};
|
|
98
|
+
const handlePopoverClose = () => {
|
|
99
|
+
setState({
|
|
100
|
+
popoverAnchorEl: null
|
|
101
|
+
});
|
|
102
|
+
};
|
|
103
|
+
const launcherSession = asyncState.value?.launcherSession;
|
|
104
|
+
let status = 'success';
|
|
105
|
+
if (['expired', 'terminated'].includes(asyncState.value?.launcherSession?.statusText)) {
|
|
106
|
+
status = 'error';
|
|
107
|
+
}
|
|
108
|
+
let validity = null;
|
|
109
|
+
if (launcherSession.expirationDate && !launcherSession.subscription) {
|
|
110
|
+
const validityMs = dayjs(launcherSession.expirationDate).diff(dayjs(), 'ms');
|
|
111
|
+
validity = t(`expiration.${typoKey}.tips.${status}`, {
|
|
112
|
+
validity: prettyMs(validityMs, {
|
|
113
|
+
locale: formatPrettyMsLocale(locale),
|
|
114
|
+
compact: true,
|
|
115
|
+
verbose: true
|
|
116
|
+
})
|
|
117
|
+
});
|
|
118
|
+
if (validityMs > 0 && validityMs <= ALERT_THRESHOLD_MS) {
|
|
119
|
+
status = 'warning';
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return /*#__PURE__*/_jsxs(_Fragment, {
|
|
123
|
+
children: [/*#__PURE__*/_jsx(Chip, {
|
|
124
|
+
label: /*#__PURE__*/_jsx(ChipLabel, {
|
|
125
|
+
children: validity || launcherSession?.subscription?.product?.name || t('common.subscription')
|
|
126
|
+
}),
|
|
127
|
+
color: status,
|
|
128
|
+
variant: status !== 'success' ? 'contained' : 'outlined',
|
|
129
|
+
sx: {
|
|
130
|
+
cursor: 'pointer',
|
|
131
|
+
...sx
|
|
132
|
+
},
|
|
133
|
+
...rest,
|
|
134
|
+
onClick: handlePopoverClick
|
|
135
|
+
}), /*#__PURE__*/_jsx(Popover, {
|
|
136
|
+
id: "popover-info",
|
|
137
|
+
open: Boolean(state.popoverAnchorEl),
|
|
138
|
+
anchorEl: state.popoverAnchorEl,
|
|
139
|
+
onClose: handlePopoverClose,
|
|
140
|
+
anchorOrigin: {
|
|
141
|
+
vertical: 'bottom',
|
|
142
|
+
horizontal: 'right'
|
|
143
|
+
},
|
|
144
|
+
transformOrigin: {
|
|
145
|
+
vertical: 'top',
|
|
146
|
+
horizontal: 'right'
|
|
147
|
+
},
|
|
148
|
+
children: /*#__PURE__*/_jsx("iframe", {
|
|
149
|
+
ref: iframeRef,
|
|
150
|
+
title: t('common.subscription'),
|
|
151
|
+
width: "360px",
|
|
152
|
+
height: "600px",
|
|
153
|
+
style: {
|
|
154
|
+
border: 0
|
|
155
|
+
},
|
|
156
|
+
src: asyncState.value?.subscriptionURL
|
|
157
|
+
})
|
|
158
|
+
})]
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
SubscriptionBlocklet.propTypes = {
|
|
162
|
+
chainHost: PropTypes.string.isRequired,
|
|
163
|
+
nftId: PropTypes.string,
|
|
164
|
+
launcherSessionId: PropTypes.string,
|
|
165
|
+
sx: PropTypes.object,
|
|
166
|
+
retention: PropTypes.number,
|
|
167
|
+
launcherUrl: PropTypes.string.isRequired
|
|
168
|
+
};
|
|
169
|
+
SubscriptionBlocklet.defaultProps = {
|
|
170
|
+
sx: {},
|
|
171
|
+
retention: 0,
|
|
172
|
+
nftId: '',
|
|
173
|
+
launcherSessionId: ''
|
|
174
|
+
};
|
|
175
|
+
export default SubscriptionBlocklet;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import AccessTimeIcon from '@mui/icons-material/AccessTime';
|
|
2
|
+
import Box from '@mui/material/Box';
|
|
3
|
+
import PropTypes from 'prop-types';
|
|
4
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
5
|
+
export default function ChipLabel({
|
|
6
|
+
children
|
|
7
|
+
}) {
|
|
8
|
+
return /*#__PURE__*/_jsxs(Box, {
|
|
9
|
+
sx: {
|
|
10
|
+
display: 'flex',
|
|
11
|
+
alignItems: 'center',
|
|
12
|
+
gap: 1
|
|
13
|
+
},
|
|
14
|
+
children: [/*#__PURE__*/_jsx(AccessTimeIcon, {
|
|
15
|
+
fontSize: "small"
|
|
16
|
+
}), children]
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
ChipLabel.propTypes = {
|
|
20
|
+
children: PropTypes.node.isRequired
|
|
21
|
+
};
|
|
@@ -1,41 +1,26 @@
|
|
|
1
1
|
import dayjs from '@abtnode/util/lib/dayjs';
|
|
2
2
|
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
3
|
-
import AccessTimeIcon from '@mui/icons-material/AccessTime';
|
|
4
|
-
import Box from '@mui/material/Box';
|
|
5
3
|
import Chip from '@mui/material/Chip';
|
|
6
4
|
import CircularProgress from '@mui/material/CircularProgress';
|
|
7
5
|
import Popover from '@mui/material/Popover';
|
|
6
|
+
import useMediaQuery from '@mui/material/useMediaQuery';
|
|
8
7
|
import prettyMs from 'pretty-ms-i18n';
|
|
9
8
|
import PropTypes from 'prop-types';
|
|
10
9
|
import { useRef } from 'react';
|
|
11
10
|
import useAsyncRetry from 'react-use/lib/useAsyncRetry';
|
|
12
11
|
import useSetState from 'react-use/lib/useSetState';
|
|
13
|
-
import
|
|
14
|
-
import { formatPrettyMsLocale,
|
|
12
|
+
import { useNodeContext } from '../contexts/node';
|
|
13
|
+
import { formatPrettyMsLocale, getSubscriptionUrlV2 } from '../util';
|
|
14
|
+
import ChipLabel from './chip-label';
|
|
15
15
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
16
16
|
const ALERT_THRESHOLD_MS = 30 * 24 * 60 * 60 * 1000;
|
|
17
17
|
const DEFAULT_LAUNCHER_URL = 'https://launcher.arcblock.io/'; // 兼容: 旧版本的 blocklet.controller 没有 launcherUrl 字段
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
function ChipLabel({
|
|
21
|
-
children
|
|
22
|
-
}) {
|
|
23
|
-
return /*#__PURE__*/_jsxs(Box, {
|
|
24
|
-
sx: {
|
|
25
|
-
display: 'flex',
|
|
26
|
-
alignItems: 'center',
|
|
27
|
-
gap: 1
|
|
28
|
-
},
|
|
29
|
-
children: [/*#__PURE__*/_jsx(AccessTimeIcon, {
|
|
30
|
-
fontSize: "small"
|
|
31
|
-
}), children]
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
function Subscription({
|
|
19
|
+
function SubscriptionServer({
|
|
35
20
|
launcherUrl,
|
|
36
21
|
chainHost,
|
|
37
22
|
nftId,
|
|
38
|
-
|
|
23
|
+
launcherSessionId,
|
|
39
24
|
...props
|
|
40
25
|
}) {
|
|
41
26
|
const {
|
|
@@ -48,19 +33,32 @@ function Subscription({
|
|
|
48
33
|
});
|
|
49
34
|
const iframeRef = useRef(null);
|
|
50
35
|
const isMobile = useMediaQuery(x => x.breakpoints.down('md'));
|
|
36
|
+
const node = useNodeContext();
|
|
51
37
|
const {
|
|
52
38
|
sx = {},
|
|
53
39
|
...rest
|
|
54
40
|
} = props;
|
|
55
41
|
const typoKey = isMobile ? 'mobile' : 'desktop';
|
|
56
42
|
const asyncState = useAsyncRetry(async () => {
|
|
57
|
-
const [
|
|
43
|
+
const [data, subscriptionURL] = await Promise.all([
|
|
44
|
+
// 新 Launch 的 Server 会有 launcherSessionId 信息,旧的 Server 只有 nftId
|
|
45
|
+
// 这里做兼容处理,优先使用 launcherSessionId, 如果没有则使用 nftId
|
|
46
|
+
node.api.getLauncherSession({
|
|
47
|
+
input: {
|
|
48
|
+
launcherSessionId: launcherSessionId || nftId,
|
|
49
|
+
launcherUrl
|
|
50
|
+
}
|
|
51
|
+
}), getSubscriptionUrlV2({
|
|
58
52
|
launcherUrl: launcherUrl || DEFAULT_LAUNCHER_URL,
|
|
59
|
-
nftId,
|
|
53
|
+
nftDid: nftId,
|
|
54
|
+
launcherSessionId,
|
|
60
55
|
locale
|
|
61
56
|
})]);
|
|
57
|
+
if (data?.error) {
|
|
58
|
+
throw new Error(data.error);
|
|
59
|
+
}
|
|
62
60
|
return {
|
|
63
|
-
|
|
61
|
+
launcherSession: data.launcherSession,
|
|
64
62
|
subscriptionURL
|
|
65
63
|
};
|
|
66
64
|
}, [locale]);
|
|
@@ -95,7 +93,7 @@ function Subscription({
|
|
|
95
93
|
onClick: () => asyncState.retry()
|
|
96
94
|
});
|
|
97
95
|
}
|
|
98
|
-
const expirationDate =
|
|
96
|
+
const expirationDate = asyncState.value?.launcherSession?.expirationDate;
|
|
99
97
|
const isExpired = dayjs(expirationDate).isBefore(dayjs());
|
|
100
98
|
const validityMs = dayjs(expirationDate).diff(dayjs(), 'ms');
|
|
101
99
|
let status = 'success';
|
|
@@ -160,15 +158,18 @@ function Subscription({
|
|
|
160
158
|
})]
|
|
161
159
|
});
|
|
162
160
|
}
|
|
163
|
-
|
|
161
|
+
SubscriptionServer.propTypes = {
|
|
164
162
|
chainHost: PropTypes.string.isRequired,
|
|
165
|
-
nftId: PropTypes.string
|
|
163
|
+
nftId: PropTypes.string,
|
|
164
|
+
launcherSessionId: PropTypes.string,
|
|
166
165
|
sx: PropTypes.object,
|
|
167
166
|
retention: PropTypes.number,
|
|
168
167
|
launcherUrl: PropTypes.string.isRequired
|
|
169
168
|
};
|
|
170
|
-
|
|
169
|
+
SubscriptionServer.defaultProps = {
|
|
171
170
|
sx: {},
|
|
172
|
-
retention: 0
|
|
171
|
+
retention: 0,
|
|
172
|
+
nftId: '',
|
|
173
|
+
launcherSessionId: ''
|
|
173
174
|
};
|
|
174
|
-
export default
|
|
175
|
+
export default SubscriptionServer;
|
package/es/util/index.js
CHANGED
|
@@ -6,7 +6,6 @@ import filesize from 'filesize';
|
|
|
6
6
|
import humanizeUrl from 'humanize-url';
|
|
7
7
|
import isUrl from 'is-url';
|
|
8
8
|
import get from 'lodash/get';
|
|
9
|
-
import last from 'lodash/last';
|
|
10
9
|
import trimEnd from 'lodash/trimEnd';
|
|
11
10
|
import qs from 'querystring';
|
|
12
11
|
import joinUrl from 'url-join';
|
|
@@ -531,9 +530,6 @@ export async function getAsset(chainHost, address) {
|
|
|
531
530
|
}
|
|
532
531
|
return state;
|
|
533
532
|
}
|
|
534
|
-
export function getAssetExpiration(asset) {
|
|
535
|
-
return last(get(asset, 'data.value.expirationDate', []));
|
|
536
|
-
}
|
|
537
533
|
|
|
538
534
|
/**
|
|
539
535
|
* 检查url是否 未添加到 store list 中
|
|
@@ -621,11 +617,25 @@ export const sortDomains = domains => {
|
|
|
621
617
|
});
|
|
622
618
|
};
|
|
623
619
|
export const formatMountPoint = value => normalizePathPrefix(urlPathFriendly(value));
|
|
624
|
-
|
|
625
|
-
launcherUrl
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
620
|
+
const getLauncherBaseURL = async launcherUrl => {
|
|
621
|
+
if (!launcherUrl) {
|
|
622
|
+
return '';
|
|
623
|
+
}
|
|
624
|
+
let baseUrl = launcherUrl;
|
|
625
|
+
try {
|
|
626
|
+
const {
|
|
627
|
+
data: appMeta
|
|
628
|
+
} = await axios.get(joinUrl(launcherUrl, '__blocklet__.js?type=json'), {
|
|
629
|
+
timeout: 5000
|
|
630
|
+
});
|
|
631
|
+
const mountPoint = appMeta.componentMountPoints?.find(item => item.did === 'z8iZkFBbrVQxZHvcWWB3Sa2TrfGmSeFz9MSU7');
|
|
632
|
+
const launcherUrlObj = new URL(launcherUrl);
|
|
633
|
+
baseUrl = joinUrl(launcherUrlObj.origin, mountPoint?.mountPoint);
|
|
634
|
+
} catch (error) {
|
|
635
|
+
console.error(error);
|
|
636
|
+
}
|
|
637
|
+
return baseUrl;
|
|
638
|
+
};
|
|
629
639
|
export const getSubscriptionURL = async ({
|
|
630
640
|
launcherUrl = '',
|
|
631
641
|
nftId = '',
|
|
@@ -649,6 +659,29 @@ export const getSubscriptionURL = async ({
|
|
|
649
659
|
}
|
|
650
660
|
return joinUrl(baseUrl, `/${nftId}/subscription?locale=${locale}&return-url=${encodeURIComponent(window.location.href)}`);
|
|
651
661
|
};
|
|
662
|
+
export const getSubscriptionUrlV2 = async ({
|
|
663
|
+
launcherUrl = '',
|
|
664
|
+
launcherSessionId = '',
|
|
665
|
+
nftDid,
|
|
666
|
+
locale = 'en'
|
|
667
|
+
}) => {
|
|
668
|
+
if (!launcherUrl) {
|
|
669
|
+
return '';
|
|
670
|
+
}
|
|
671
|
+
const baseUrl = await getLauncherBaseURL(launcherUrl);
|
|
672
|
+
return joinUrl(baseUrl, `/embed/subscription?launcherSessionId=${launcherSessionId}&nftDid=${nftDid}&locale=${locale}`); // nftDid 是兼容字段
|
|
673
|
+
};
|
|
674
|
+
export const getManageSubscriptionURL = async ({
|
|
675
|
+
launcherUrl = '',
|
|
676
|
+
launcherSessionId = '',
|
|
677
|
+
locale = 'en'
|
|
678
|
+
}) => {
|
|
679
|
+
if (!launcherUrl) {
|
|
680
|
+
return '';
|
|
681
|
+
}
|
|
682
|
+
const baseUrl = await getLauncherBaseURL(launcherUrl);
|
|
683
|
+
return joinUrl(baseUrl, `/embed/manage-subscription?launcherSessionId=${launcherSessionId}&locale=${locale}`);
|
|
684
|
+
};
|
|
652
685
|
export const nanoid = (length = 16) => [...Array(length)].map(() => Math.random().toString(36)[2]).join('');
|
|
653
686
|
export const getSystemDomains = domains => domains.filter(x => x.isProtected);
|
|
654
687
|
export const getLogoHash = logo => encodeURIComponent((logo || '').split('/').slice(-1)[0].slice(0, 7));
|
package/lib/blocklet/actions.js
CHANGED
|
@@ -33,10 +33,10 @@ var _util3 = require("./util");
|
|
|
33
33
|
var _node = require("../contexts/node");
|
|
34
34
|
var _confirm = _interopRequireDefault(require("../confirm"));
|
|
35
35
|
var _icons = _interopRequireDefault(require("./icons"));
|
|
36
|
-
var _blocklet = require("../contexts/blocklet");
|
|
37
36
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
38
37
|
var _templateObject;
|
|
39
|
-
const _excluded = ["blocklet", "onStart", "onComplete", "variant", "hasPermission", "useBlockletUrlEvaluation"]
|
|
38
|
+
const _excluded = ["blocklet", "onStart", "onComplete", "variant", "hasPermission", "useBlockletUrlEvaluation"],
|
|
39
|
+
_excluded2 = ["sx"];
|
|
40
40
|
/* eslint-disable react/no-unstable-nested-components */
|
|
41
41
|
/* eslint-disable operator-linebreak */
|
|
42
42
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
@@ -49,7 +49,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
|
|
|
49
49
|
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
|
50
50
|
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
51
51
|
function BlockletActions(_ref) {
|
|
52
|
-
var _blocklet$controller
|
|
52
|
+
var _blocklet$controller;
|
|
53
53
|
let {
|
|
54
54
|
blocklet,
|
|
55
55
|
onStart,
|
|
@@ -73,14 +73,14 @@ function BlockletActions(_ref) {
|
|
|
73
73
|
loading: recommendedUrlLoading,
|
|
74
74
|
recommendedUrl
|
|
75
75
|
} = useBlockletUrlEvaluation(blocklet);
|
|
76
|
-
const {
|
|
77
|
-
nftState
|
|
78
|
-
} = (0, _blocklet.useBlockletContext)();
|
|
79
76
|
const inProgress = (0, _util.isInProgress)(blocklet.status);
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
77
|
+
const disableStart = (blocklet === null || blocklet === void 0 || (_blocklet$controller = blocklet.controller) === null || _blocklet$controller === void 0 || (_blocklet$controller = _blocklet$controller.status) === null || _blocklet$controller === void 0 ? void 0 : _blocklet$controller.value) === _constant.BLOCKLET_CONTROLLER_STATUS.suspended;
|
|
78
|
+
|
|
79
|
+
// TODO: PaymentKitV2 过期恢复后需要能立即启动
|
|
80
|
+
// if (!nftState?.expired && blocklet?.controller?.status?.reason === SUSPENDED_REASON.expired) {
|
|
81
|
+
// disableStart = false;
|
|
82
|
+
// }
|
|
83
|
+
|
|
84
84
|
const {
|
|
85
85
|
inService
|
|
86
86
|
} = node;
|
|
@@ -319,7 +319,18 @@ function BlockletActions(_ref) {
|
|
|
319
319
|
} : null;
|
|
320
320
|
const cancelDownloadAction = {
|
|
321
321
|
action: 'remove',
|
|
322
|
-
icon:
|
|
322
|
+
icon: _ref3 => {
|
|
323
|
+
let {
|
|
324
|
+
sx
|
|
325
|
+
} = _ref3,
|
|
326
|
+
restProps = _objectWithoutProperties(_ref3, _excluded2);
|
|
327
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_icons.default.Cancel, _objectSpread({
|
|
328
|
+
sx: _objectSpread(_objectSpread({}, sx), {}, {
|
|
329
|
+
paddingRight: '2px',
|
|
330
|
+
zoom: 0.95
|
|
331
|
+
})
|
|
332
|
+
}, restProps));
|
|
333
|
+
},
|
|
323
334
|
name: t('common.cancel'),
|
|
324
335
|
handler: createHandler('cancelDownload', node.api.cancelDownloadBlocklet, true)
|
|
325
336
|
};
|
|
@@ -1179,7 +1179,7 @@ const ContentWrapper = (0, _styled.default)(_Box.default)(_templateObject4 || (_
|
|
|
1179
1179
|
if (className === 'mobileStyle') {
|
|
1180
1180
|
return "\n & > div{\n height: 100%;\n }\n .root-header {\n .app-name-content {\n display: none;\n }\n }\n\n\n\n // content-panel\n .root-header + div{\n padding-top: 0;\n position: relative;\n & > div {\n padding-top: 0;\n }\n }\n\n header + div {\n padding-top: 0;\n }\n\n header {\n .header-title {\n margin-left: 0;\n }\n\n .header-title-name {\n max-width: 100% !important;\n }\n }\n ";
|
|
1181
1181
|
}
|
|
1182
|
-
return "\n position: relative;\n .root-header {\n z-index: auto !important;\n position: fixed !important;\n }\n & > div {\n height: 100%;\n width: 100%;\n max-width: 100%;\n & > div {\n max-height: unset !important;\n max-width: 100%;\n & > div {\n // left-panel\n &:first-child {\n padding: 0;\n width: 25%;\n min-width: 240px;\n & > div:first-child {\n display: none;\n }\n // step\n & > div:last-child {\n // margin-top: 32px;\n margin-top: 0;\n }\n }\n // right-panel\n &:last-child {\n padding-top: 0;\n padding-right: 0px;\n overflow-y: hidden;\n .app-content {\n padding: 0 0 24px 0;\n }\n .button-container {\n padding-right: 0;\n }\n }\n }\n }\n }\n\n ";
|
|
1182
|
+
return "\n position: relative;\n .ll-container { // \u901A\u8FC7 Launcher Layout \u7EC4\u4EF6\u7EA6\u5B9A\u7684 .ll-container class \u81EA\u5B9A\u4E49 Layout \u6837\u5F0F\n width: 100%;\n height: 100%;\n }\n\n .root-header {\n z-index: auto !important;\n position: fixed !important;\n }\n & > div {\n height: 100%;\n width: 100%;\n max-width: 100%;\n & > div {\n max-height: unset !important;\n max-width: 100%;\n & > div {\n // left-panel\n &:first-child {\n padding: 0;\n width: 25%;\n min-width: 240px;\n & > div:first-child {\n display: none;\n }\n // step\n & > div:last-child {\n // margin-top: 32px;\n margin-top: 0;\n }\n }\n // right-panel\n &:last-child {\n padding-top: 0;\n padding-right: 0px;\n overflow-y: hidden;\n .app-content {\n padding: 0 0 24px 0;\n }\n .button-container {\n padding-right: 0;\n }\n }\n }\n }\n }\n\n ";
|
|
1183
1183
|
}, props => isMobileContent(props), props => isMobileContent(props));
|
|
1184
1184
|
const PageHeaderWrapper = (0, _styled.default)(_pageHeader.default)(_templateObject5 || (_templateObject5 = _taggedTemplateLiteral(["\n margin-bottom: 24px;\n"])));
|
|
1185
1185
|
const StoreBlockletItemWrapper = _styled.default.div(_templateObject6 || (_templateObject6 = _taggedTemplateLiteral(["\n position: relative;\n\n .choose-blocklet {\n background-color: rgb(236, 251, 253);\n border-color: rgb(236, 251, 253);\n border-radius: 8px;\n }\n\n .check-container {\n position: absolute;\n right: 0;\n bottom: 0;\n display: flex;\n justify-content: flex-end;\n align-items: flex-end;\n width: 30px;\n height: 30px;\n border-radius: 0 0 8px 0;\n color: ", ";\n overflow: hidden;\n transition: all ease 0.3s;\n &:after {\n position: absolute;\n z-index: 0;\n display: block;\n width: 0;\n height: 0;\n border-top: transparent solid 15px;\n border-left: transparent solid 15px;\n border-bottom: ", " solid 15px;\n border-right: ", " solid 15px;\n transition: all ease 0.1s;\n content: '';\n }\n\n .check-icon {\n position: relative;\n z-index: 2;\n margin: 0 1px 1px 0;\n font-size: 16px;\n transition: all ease 0.2s;\n }\n }\n"])), props => props.theme.palette.common.white, props => props.theme.palette.primary.main, props => props.theme.palette.primary.main);
|
|
@@ -211,7 +211,8 @@ function ComponentCell(_ref) {
|
|
|
211
211
|
}, {
|
|
212
212
|
name: t('common.did'),
|
|
213
213
|
value: /*#__PURE__*/(0, _jsxRuntime.jsx)(_didAddress.default, {
|
|
214
|
-
did: componentInfo.meta.did
|
|
214
|
+
did: componentInfo.meta.did,
|
|
215
|
+
showQrcode: true
|
|
215
216
|
})
|
|
216
217
|
}, {
|
|
217
218
|
name: t('common.author'),
|
package/lib/blocklet/icons.js
CHANGED
|
@@ -12,6 +12,7 @@ var _Autorenew = _interopRequireDefault(require("@mui/icons-material/Autorenew")
|
|
|
12
12
|
var _Settings = _interopRequireDefault(require("@mui/icons-material/Settings"));
|
|
13
13
|
var _Receipt = _interopRequireDefault(require("@mui/icons-material/Receipt"));
|
|
14
14
|
var _Group = _interopRequireDefault(require("@mui/icons-material/Group"));
|
|
15
|
+
var _NotInterested = _interopRequireDefault(require("@mui/icons-material/NotInterested"));
|
|
15
16
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
16
17
|
var _default = exports.default = {
|
|
17
18
|
Start: _PlayArrow.default,
|
|
@@ -21,5 +22,6 @@ var _default = exports.default = {
|
|
|
21
22
|
Remove: _Delete.default,
|
|
22
23
|
Config: _Settings.default,
|
|
23
24
|
Log: _Receipt.default,
|
|
24
|
-
Group: _Group.default
|
|
25
|
+
Group: _Group.default,
|
|
26
|
+
Cancel: _NotInterested.default
|
|
25
27
|
};
|