@blocklet/launcher-workflow 2.5.0 → 2.5.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.
@@ -0,0 +1,429 @@
1
+ import Img from '@arcblock/ux/lib/Img';
2
+ import { getBaseURL, getSubscriptionLink } from '@blocklet/launcher-util/es/util';
3
+ import ContentCopyIcon from '@mui/icons-material/ContentCopy';
4
+ import DashboardIcon from '@mui/icons-material/Dashboard';
5
+ import OpenInNewIcon from '@mui/icons-material/OpenInNew';
6
+ import TaskAltIcon from '@mui/icons-material/TaskAlt';
7
+ import { alpha, Box, Button, CircularProgress, Typography, useTheme } from '@mui/material';
8
+ import Chip from '@mui/material/Chip';
9
+ import IconButton from '@mui/material/IconButton';
10
+ import { useSetState } from 'ahooks';
11
+ import PropTypes from 'prop-types';
12
+ import React, { useEffect, useMemo } from 'react';
13
+ import { joinURL } from 'ufo';
14
+ import { useLocaleContext } from '../../../contexts/locale';
15
+ import useRequest from '../../../contexts/request';
16
+ import useSerialPolling from '../../../hooks/use-serial-polling';
17
+ import { checkBlockletAccessible, checkUrlAccessible } from '../../../util';
18
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
19
+ export default function AppSuccessDisplay({
20
+ accessibleUrl,
21
+ sessionId,
22
+ blockletInfo,
23
+ urls,
24
+ launchSession
25
+ }) {
26
+ const theme = useTheme();
27
+ const {
28
+ t
29
+ } = useLocaleContext();
30
+ const {
31
+ api
32
+ } = useRequest();
33
+ const [state, setState] = useSetState({
34
+ accessibleUrls: [accessibleUrl],
35
+ checkingBlockletStatus: true,
36
+ blockletInfo,
37
+ accessibleUrl,
38
+ hasTryStart: false,
39
+ error: null
40
+ });
41
+ const showUrl = useMemo(() => {
42
+ return localStorage.getItem('show-url') === 'true';
43
+ }, []);
44
+ const checkLaunchSession = async () => {
45
+ try {
46
+ const newBlockletInfo = await checkBlockletAccessible(state.accessibleUrl);
47
+ if (!newBlockletInfo) {
48
+ console.warn('the blocklet is not ready or accessible url is not correct, retry getting accessible url');
49
+ return;
50
+ }
51
+ setState({
52
+ blockletInfo: newBlockletInfo
53
+ });
54
+ if (newBlockletInfo.status === 'running') {
55
+ setState({
56
+ blockletInfo: newBlockletInfo,
57
+ checkingBlockletStatus: false
58
+ });
59
+ } else if (newBlockletInfo.status === 'starting') {
60
+ if (!state.hasTryStart) {
61
+ setState(prev => {
62
+ if (Date.now() - prev.startTime > 30 * 1000) {
63
+ api.post(`/launches/${sessionId}/start`);
64
+ return {
65
+ ...prev,
66
+ hasTryStart: true
67
+ };
68
+ }
69
+ return prev;
70
+ });
71
+ }
72
+ } else if (newBlockletInfo.status === 'stopped') {
73
+ api.post(`/launches/${sessionId}/start`);
74
+ setState({
75
+ hasTryStart: true
76
+ });
77
+ } else {
78
+ console.warn('the blocklet is not installed!', newBlockletInfo.status, newBlockletInfo);
79
+ setState({
80
+ error: 'installFailed',
81
+ checkingBlockletStatus: false
82
+ });
83
+ }
84
+ setState({
85
+ retryRequestCount: 0
86
+ });
87
+ } catch (error) {
88
+ setState(prev => {
89
+ if (prev.retryRequestCount < 5) {
90
+ console.warn('check launch session occurred error, retry', prev.retryRequestCount, error);
91
+ return {
92
+ ...prev,
93
+ retryRequestCount: prev.retryRequestCount + 1
94
+ };
95
+ }
96
+ return {
97
+ ...prev,
98
+ error: 'installFailed',
99
+ retryRequestCount: 0
100
+ };
101
+ });
102
+ console.error(error);
103
+ }
104
+ };
105
+
106
+ // 串行检查,确保前一个请求完成后等待指定时间再发起下一个
107
+ useSerialPolling({
108
+ isEnabled: state.checkingBlockletStatus,
109
+ interval: 3000,
110
+ onPoll: checkLaunchSession
111
+ });
112
+
113
+ // 获取应用基本信息
114
+ const appName = blockletInfo?.appName || t('startApp.unknownApp');
115
+ const appVersion = blockletInfo?.version || launchSession.appInfo?.version || launchSession.blockletMeta?.version || '';
116
+ const appLogo = blockletInfo?.appLogo || launchSession.appInfo?.appLogo || '';
117
+ const description = blockletInfo?.appDescription || launchSession.metadata?.description;
118
+ useEffect(() => {
119
+ const stepActive = document.querySelector('.step-active');
120
+ if (stepActive) {
121
+ stepActive.classList.add('step-checked');
122
+ }
123
+ }, []);
124
+ useEffect(() => {
125
+ const checkUrls = urls.filter(url => !state.accessibleUrls.includes(url));
126
+ checkUrls.forEach(url => {
127
+ checkUrlAccessible(url, 10 * 60 * 1000).then(res => {
128
+ if (res) {
129
+ setState(prev => {
130
+ const accessible = [...prev.accessibleUrls, url];
131
+ return {
132
+ ...prev,
133
+ accessibleUrls: accessible
134
+ };
135
+ });
136
+ }
137
+ });
138
+ });
139
+ }, [state.accessibleUrls, urls, setState]);
140
+ const appUrl = state.accessibleUrls[0] || urls[0];
141
+ const started = state.blockletInfo?.status === 'running';
142
+ return /*#__PURE__*/_jsxs(Box, {
143
+ sx: {
144
+ width: '100%',
145
+ maxWidth: 800,
146
+ margin: '0 auto',
147
+ p: {
148
+ xs: 0,
149
+ sm: 3
150
+ }
151
+ },
152
+ children: [/*#__PURE__*/_jsxs(Box, {
153
+ textAlign: "center",
154
+ mb: 4,
155
+ children: [/*#__PURE__*/_jsx(Box, {
156
+ sx: {
157
+ width: 80,
158
+ height: 80,
159
+ borderRadius: '50%',
160
+ backgroundColor: started ? alpha(theme.palette.success.main, 0.2) : alpha(theme.palette.warning.main, 0.1),
161
+ display: 'flex',
162
+ alignItems: 'center',
163
+ justifyContent: 'center',
164
+ margin: '0 auto 16px',
165
+ transition: 'all 0.3s ease'
166
+ },
167
+ children: started ? /*#__PURE__*/_jsx(TaskAltIcon, {
168
+ sx: {
169
+ fontSize: 40,
170
+ color: 'success.main'
171
+ }
172
+ }) : /*#__PURE__*/_jsx(CircularProgress, {
173
+ sx: {
174
+ color: alpha(theme.palette.warning.main, 0.8)
175
+ },
176
+ size: 40
177
+ })
178
+ }), /*#__PURE__*/_jsx(Typography, {
179
+ variant: "h3",
180
+ component: "h1",
181
+ fontWeight: "bold",
182
+ gutterBottom: true,
183
+ children: started ? `🎉 ${t('startApp.started')}` : `🚀 ${t('startApp.starting')}`
184
+ }), /*#__PURE__*/_jsx(Typography, {
185
+ variant: "body1",
186
+ color: "text.secondary",
187
+ children: started ? t('startApp.startedDescription') : t('startApp.startingDescription')
188
+ })]
189
+ }), /*#__PURE__*/_jsxs(Box, {
190
+ sx: {
191
+ p: 3,
192
+ mb: 3,
193
+ borderRadius: 2,
194
+ border: '1px solid',
195
+ borderColor: 'divider',
196
+ backgroundColor: 'background.paper'
197
+ },
198
+ children: [/*#__PURE__*/_jsxs(Box, {
199
+ display: "flex",
200
+ alignItems: "center",
201
+ gap: 2,
202
+ mb: 2,
203
+ flexWrap: "wrap",
204
+ children: [/*#__PURE__*/_jsxs(Box, {
205
+ flex: 1,
206
+ display: "flex",
207
+ alignItems: "center",
208
+ gap: 2,
209
+ children: [appLogo ? /*#__PURE__*/_jsx(Img, {
210
+ src: joinURL(appUrl, appLogo),
211
+ alt: appName,
212
+ width: 48,
213
+ height: 48,
214
+ style: {
215
+ borderRadius: 10,
216
+ overflow: 'hidden'
217
+ }
218
+ }, appUrl) : null, /*#__PURE__*/_jsxs(Box, {
219
+ flex: 1,
220
+ textAlign: "left",
221
+ children: [/*#__PURE__*/_jsx(Typography, {
222
+ variant: "h6",
223
+ color: "text.hint",
224
+ mb: 1,
225
+ children: t('startApp.projectName')
226
+ }), /*#__PURE__*/_jsx(Typography, {
227
+ variant: "body1",
228
+ fontWeight: "medium",
229
+ children: appName
230
+ })]
231
+ })]
232
+ }), /*#__PURE__*/_jsxs(Box, {
233
+ flex: 1,
234
+ display: "flex",
235
+ alignItems: "center",
236
+ gap: 2,
237
+ minWidth: {
238
+ xs: '100%',
239
+ sm: 'auto'
240
+ },
241
+ children: [appVersion ? /*#__PURE__*/_jsxs(Box, {
242
+ flex: 1,
243
+ textAlign: "left",
244
+ children: [/*#__PURE__*/_jsx(Typography, {
245
+ variant: "h6",
246
+ color: "text.hint",
247
+ mb: 1,
248
+ children: t('startApp.version')
249
+ }), /*#__PURE__*/_jsx(Chip, {
250
+ label: `v${appVersion}`,
251
+ size: "small",
252
+ color: "primary",
253
+ variant: "outlined"
254
+ })]
255
+ }) : null, /*#__PURE__*/_jsxs(Box, {
256
+ flex: 1,
257
+ textAlign: "left",
258
+ children: [/*#__PURE__*/_jsx(Typography, {
259
+ variant: "h6",
260
+ color: "text.hint",
261
+ mb: 1,
262
+ children: t('startApp.status')
263
+ }), started ? /*#__PURE__*/_jsx(Chip, {
264
+ label: t('startApp.running'),
265
+ size: "small",
266
+ color: "success"
267
+ }) : /*#__PURE__*/_jsx(Chip, {
268
+ label: t('startApp.startingText'),
269
+ size: "small",
270
+ color: "warning",
271
+ sx: {
272
+ animation: 'pulse 2s infinite',
273
+ '@keyframes pulse': {
274
+ '0%': {
275
+ opacity: 0.85
276
+ },
277
+ '50%': {
278
+ opacity: 0.7
279
+ },
280
+ '100%': {
281
+ opacity: 0.85
282
+ }
283
+ }
284
+ }
285
+ })]
286
+ })]
287
+ })]
288
+ }), description && /*#__PURE__*/_jsx(Typography, {
289
+ variant: "body2",
290
+ color: "text.secondary",
291
+ textAlign: "left",
292
+ children: description
293
+ }), showUrl && /*#__PURE__*/_jsxs(Box, {
294
+ children: [/*#__PURE__*/_jsx(Typography, {
295
+ variant: "h6",
296
+ color: "text.hint",
297
+ textAlign: "left",
298
+ children: t('startApp.visitUrl')
299
+ }), urls.map(url => /*#__PURE__*/_jsxs(Box, {
300
+ display: "flex",
301
+ alignItems: "center",
302
+ mt: 1,
303
+ gap: 1,
304
+ sx: {
305
+ backgroundColor: 'divider',
306
+ borderRadius: 1,
307
+ py: 0.5,
308
+ px: 1.5,
309
+ flex: 1
310
+ },
311
+ children: [/*#__PURE__*/_jsx(Box, {
312
+ sx: {
313
+ width: 8,
314
+ height: 8,
315
+ borderRadius: '50%',
316
+ backgroundColor: state.accessibleUrls.includes(url) ? 'success.main' : 'error.main'
317
+ }
318
+ }), /*#__PURE__*/_jsx(Typography, {
319
+ variant: "body2",
320
+ textAlign: "left",
321
+ sx: {
322
+ flex: 1,
323
+ fontSize: '0.875rem',
324
+ wordBreak: 'break-all'
325
+ },
326
+ children: url
327
+ }), /*#__PURE__*/_jsx(IconButton, {
328
+ size: "small",
329
+ onClick: () => navigator.clipboard.writeText(url),
330
+ children: /*#__PURE__*/_jsx(ContentCopyIcon, {
331
+ sx: {
332
+ fontSize: 16
333
+ }
334
+ })
335
+ })]
336
+ }, url))]
337
+ })]
338
+ }), /*#__PURE__*/_jsxs(Box, {
339
+ display: "flex",
340
+ flexDirection: "column",
341
+ gap: 2,
342
+ mt: 4,
343
+ children: [/*#__PURE__*/_jsx(Box, {
344
+ display: "flex",
345
+ flexDirection: "column",
346
+ gap: 2,
347
+ alignItems: "center",
348
+ children: /*#__PURE__*/_jsxs(Box, {
349
+ display: "flex",
350
+ gap: 2,
351
+ margin: "0 auto",
352
+ flexDirection: {
353
+ xs: 'column-reverse',
354
+ md: 'row'
355
+ },
356
+ children: [/*#__PURE__*/_jsx(Button, {
357
+ variant: "outlined",
358
+ sx: {
359
+ minWidth: 220
360
+ },
361
+ color: "primary",
362
+ onClick: () => window.open(joinURL(getBaseURL(), `/api/launches/${sessionId}/redirect/dashboard?appUrl=${appUrl}&appDid=${blockletInfo.appPid}&ownerDid=${blockletInfo.ownerDid}`), '_blank'),
363
+ startIcon: /*#__PURE__*/_jsx(DashboardIcon, {
364
+ sx: {
365
+ fontSize: 24,
366
+ color: 'primary.main'
367
+ }
368
+ }),
369
+ children: t('startApp.dashboard')
370
+ }), /*#__PURE__*/_jsx(Button, {
371
+ variant: "contained",
372
+ color: started ? 'primary' : 'inherit',
373
+ disabled: !started,
374
+ sx: {
375
+ minWidth: 220,
376
+ opacity: started ? 1 : 0.7,
377
+ transform: started ? 'scale(1)' : 'scale(0.98)',
378
+ transition: 'all 0.4s cubic-bezier(0.4, 0, 0.2, 1)',
379
+ background: started ? undefined : `linear-gradient(45deg, ${alpha(theme.palette.primary.main, 0.1)}, ${alpha(theme.palette.primary.main, 0.2)})`,
380
+ '&:disabled': {
381
+ color: theme.palette.text.secondary
382
+ }
383
+ },
384
+ onClick: () => started && window.open(joinURL(getBaseURL(), `/api/launches/${sessionId}/redirect/app?appUrl=${appUrl}&appDid=${blockletInfo.appPid}&ownerDid=${blockletInfo.ownerDid}`), '_blank'),
385
+ startIcon: started ? /*#__PURE__*/_jsx(OpenInNewIcon, {
386
+ sx: {
387
+ fontSize: 24,
388
+ color: 'inherit'
389
+ }
390
+ }) : /*#__PURE__*/_jsx(OpenInNewIcon, {
391
+ sx: {
392
+ fontSize: 24,
393
+ color: 'inherit',
394
+ opacity: 0.5
395
+ }
396
+ }),
397
+ children: started ? t('startApp.visitApp') : t('startApp.preparing')
398
+ })]
399
+ })
400
+ }), /*#__PURE__*/_jsxs(Typography, {
401
+ variant: "body2",
402
+ color: "text.secondary",
403
+ sx: {
404
+ margin: '0 auto',
405
+ fontWeight: 400,
406
+ cursor: 'pointer',
407
+ display: 'flex',
408
+ alignItems: 'center',
409
+ gap: 0.5,
410
+ opacity: 0.8
411
+ },
412
+ onClick: () => window.open(getSubscriptionLink(launchSession.subscriptionId), '_blank'),
413
+ children: [/*#__PURE__*/_jsx(OpenInNewIcon, {
414
+ sx: {
415
+ fontSize: 14,
416
+ color: 'inherit'
417
+ }
418
+ }), t('startApp.subscription')]
419
+ })]
420
+ })]
421
+ });
422
+ }
423
+ AppSuccessDisplay.propTypes = {
424
+ launchSession: PropTypes.object.isRequired,
425
+ urls: PropTypes.arrayOf(PropTypes.string).isRequired,
426
+ accessibleUrl: PropTypes.string.isRequired,
427
+ sessionId: PropTypes.string.isRequired,
428
+ blockletInfo: PropTypes.object.isRequired
429
+ };
@@ -6,9 +6,10 @@ import { LAUNCH_STATUS } from '@blocklet/launcher-util/es/constant';
6
6
  import { useLocaleContext } from '../../contexts/locale';
7
7
  import useRequest from '../../contexts/request';
8
8
  import useSerialPolling from '../../hooks/use-serial-polling';
9
- import { checkBlockletAccessible, getBlockletUrls, sortUrls, waitingForRaceAccessible } from '../../util';
9
+ import { getBlockletUrls, sortUrls, waitingForRaceAccessible } from '../../util';
10
10
  import BaseServerlessLayout from './shared/base-serverless-layout';
11
- import { AppSuccessDisplay, calculateEstimatedTime, useFormatTime } from './shared/common-components';
11
+ import { calculateEstimatedTime, useFormatTime } from './shared/common-components';
12
+ import AppSuccessDisplay from './shared/success-display';
12
13
  import LoadingDisplayLayout from './shared/loading-display-layout';
13
14
  import RetryErrorMessage from './shared/retry-error-message';
14
15
  import useWorkflowProgress from './shared/use-workflow-progress';
@@ -44,26 +45,20 @@ export default function StartApp({
44
45
  const actions = useMemo(() => {
45
46
  // 基础步骤时间
46
47
  const steps = [{
47
- message: t('startApp.waiting.starting'),
48
- time: 5
49
- }, {
50
- message: t('startApp.waiting.parsing'),
51
- time: 1
52
- }, {
53
48
  message: t('startApp.waiting.initializing'),
54
- time: 3
49
+ time: 1
55
50
  }, {
56
51
  message: t('startApp.waiting.initializingOwner'),
57
- time: 2
52
+ time: 1
58
53
  }, {
59
54
  message: t('startApp.waiting.creatingSecurityRules'),
60
- time: 2
55
+ time: 1
61
56
  }, {
62
57
  message: t('startApp.waiting.assigningDomain'),
63
- time: 2
58
+ time: 1
64
59
  }, {
65
60
  message: t('startApp.waiting.waitingForDomain'),
66
- time: 10
61
+ time: 1
67
62
  }];
68
63
 
69
64
  // 计算总时间
@@ -84,7 +79,7 @@ export default function StartApp({
84
79
  const estimatedTime = useMemo(() => {
85
80
  const components = window.blockletMeta?.components || [];
86
81
  const additionalTime = calculateEstimatedTime(components);
87
- return actions.reduce((acc, action) => acc + action.time, 0) + additionalTime;
82
+ return actions.reduce((acc, action) => acc + action.time, 0) + Math.ceil(additionalTime * 0.4);
88
83
  }, [actions]);
89
84
  const {
90
85
  time,
@@ -107,8 +102,11 @@ export default function StartApp({
107
102
  };
108
103
  const checkOneAccessibleUrl = async urls => {
109
104
  try {
110
- const [accessibleUrl] = await waitingForRaceAccessible(urls);
111
- return accessibleUrl;
105
+ const [accessibleUrl, blockletInfo] = await waitingForRaceAccessible(urls);
106
+ return {
107
+ accessibleUrl,
108
+ blockletInfo
109
+ };
112
110
  } catch (error) {
113
111
  console.error(error);
114
112
  return null;
@@ -136,88 +134,6 @@ export default function StartApp({
136
134
  }
137
135
  return urls;
138
136
  }, [state, setState]);
139
- const checkLaunchSession = async () => {
140
- try {
141
- const {
142
- accessibleUrl
143
- } = state;
144
- if (!accessibleUrl) {
145
- console.warn('the accessible url is not ready, retry getting accessible url');
146
- setState({
147
- checkingAccessible: true,
148
- checkingBlockletStatus: false
149
- });
150
- return;
151
- }
152
- const blockletInfo = await checkBlockletAccessible(accessibleUrl);
153
- if (!blockletInfo) {
154
- console.warn('the blocklet is not ready or accessible url is not correct, retry getting accessible url');
155
- return;
156
- }
157
- setState({
158
- blockletInfo
159
- });
160
- if (blockletInfo.status === 'running') {
161
- setState({
162
- blockletInfo,
163
- starting: false,
164
- started: true,
165
- checkingBlockletStatus: false,
166
- checkingAccessible: false,
167
- isLoading: false
168
- });
169
- } else if (blockletInfo.status === 'starting') {
170
- if (!state.hasTryStart) {
171
- setState(prev => {
172
- if (Date.now() - prev.startTime > estimatedTime * 1000) {
173
- api.post(`/launches/${sessionId}/start`);
174
- return {
175
- ...prev,
176
- hasTryStart: true
177
- };
178
- }
179
- return prev;
180
- });
181
- }
182
- } else if (blockletInfo.status === 'stopped') {
183
- api.post(`/launches/${sessionId}/start`);
184
- } else {
185
- console.warn('the blocklet is not installed!', blockletInfo.status, blockletInfo);
186
- setState({
187
- error: 'installFailed',
188
- starting: false,
189
- checkingBlockletStatus: false
190
- });
191
- }
192
- setState({
193
- retryRequestCount: 0
194
- });
195
- } catch (error) {
196
- setState(prev => {
197
- if (prev.retryRequestCount < 5) {
198
- console.warn('check launch session occurred error, retry', prev.retryRequestCount, error);
199
- return {
200
- ...prev,
201
- retryRequestCount: prev.retryRequestCount + 1
202
- };
203
- }
204
- return {
205
- ...prev,
206
- error: 'installFailed',
207
- starting: false,
208
- retryRequestCount: 0
209
- };
210
- });
211
- console.error(error);
212
- }
213
- };
214
-
215
- // 串行检查,确保前一个请求完成后等待指定时间再发起下一个
216
- useSerialPolling({
217
- isEnabled: state.checkingBlockletStatus,
218
- interval: CHECK_INTERVAL,
219
- onPoll: checkLaunchSession
220
- });
221
137
 
222
138
  // 检查可用性 url
223
139
  const checkAccessibleUrls = async () => {
@@ -233,13 +149,20 @@ export default function StartApp({
233
149
  });
234
150
  return;
235
151
  }
236
- const accessibleUrl = await checkOneAccessibleUrl(urls);
152
+ const {
153
+ accessibleUrl,
154
+ blockletInfo
155
+ } = await checkOneAccessibleUrl(urls);
237
156
  setState(prev => {
238
157
  const obj = accessibleUrl ? {
239
158
  ...prev,
159
+ starting: false,
160
+ started: true,
161
+ isLoading: false,
240
162
  checkingAccessible: false,
241
- checkingBlockletStatus: true,
242
- accessibleUrl
163
+ checkingBlockletStatus: false,
164
+ accessibleUrl,
165
+ blockletInfo
243
166
  } : prev;
244
167
  if (Date.now() - prev.startTime > estimatedTime * 1000 && !prev.hasTryStart) {
245
168
  api.post(`/launches/${sessionId}/start`);
@@ -256,7 +179,7 @@ export default function StartApp({
256
179
  };
257
180
  useSerialPolling({
258
181
  isEnabled: state.checkingAccessible,
259
- interval: 10000,
182
+ interval: CHECK_INTERVAL,
260
183
  onPoll: checkAccessibleUrls
261
184
  });
262
185
  useEffect(() => {
package/es/locales/en.js CHANGED
@@ -91,13 +91,17 @@ export default {
91
91
  },
92
92
  startApp: {
93
93
  pageTitle: 'Start Blocklet',
94
- starting: 'Starting Blocklet...',
95
94
  started: 'Blocklet is ready to use!',
96
95
  startedDescription: 'Your blocklet has been successfully started and is now ready to use.',
96
+ starting: 'Blocklet is starting up',
97
+ startingDescription: 'Your blocklet is starting up and will be ready shortly. Please wait a moment.',
98
+ startingTitle: 'Almost there!',
99
+ startingWaitMessage: 'Your blocklet is starting and will be accessible in a moment. You can access the management panel to monitor the progress.',
97
100
  startFailed: 'Start Blocklet Failed',
98
101
  installFailed: 'Install Blocklet Failed',
99
102
  visit: 'Visit Blocklet',
100
103
  dashboard: 'View Blocklet Dashboard',
104
+ managementPanel: 'Management Panel',
101
105
  subscription: 'Manage Subscription',
102
106
  unknownApp: 'Unknown Blocklet',
103
107
  appInfo: 'Blocklet Information',
@@ -106,9 +110,11 @@ export default {
106
110
  status: 'Status',
107
111
  version: 'Version',
108
112
  running: 'Running',
113
+ startingText: 'Starting',
109
114
  projectName: 'Project Name',
110
115
  visitUrl: 'Visit URL',
111
116
  visitApp: 'Visit Blocklet',
117
+ preparing: 'Preparing...',
112
118
  waiting: {
113
119
  starting: 'Starting blocklet...',
114
120
  parsing: 'Parsing blocklet metadata...',
package/es/locales/zh.js CHANGED
@@ -90,13 +90,17 @@ export default {
90
90
  },
91
91
  startApp: {
92
92
  pageTitle: '启动 Blocklet',
93
- starting: '正在启动 Blocklet...',
94
93
  started: 'Blocklet 启动成功',
95
94
  startedDescription: '您的 Blocklet 已成功启动并准备就绪,现在可以开始使用了。',
95
+ starting: 'Blocklet 正在启动',
96
+ startingDescription: '您的 Blocklet 正在启动中,很快就可以使用了,请稍等片刻。',
97
+ startingTitle: '即将完成!',
98
+ startingWaitMessage: '您的 Blocklet 正在启动中,稍后即可访问。您可以先进入管理面板查看启动进度。',
96
99
  startFailed: '启动 Blocklet 失败',
97
100
  installFailed: '安装 Blocklet 失败',
98
101
  visit: '访问 Blocklet',
99
102
  dashboard: '查看 Blocklet 仪表盘',
103
+ managementPanel: '管理面板',
100
104
  subscription: '管理订阅',
101
105
  unknownApp: '未知 Blocklet',
102
106
  appInfo: 'Blocklet 信息',
@@ -105,9 +109,11 @@ export default {
105
109
  status: '状态',
106
110
  version: '版本',
107
111
  running: '运行中',
112
+ startingText: '启动中',
108
113
  projectName: '项目名称',
109
114
  visitUrl: '访问地址',
110
115
  visitApp: '访问 Blocklet',
116
+ preparing: '准备中...',
111
117
  waiting: {
112
118
  starting: '正在启动 Blocklet...',
113
119
  parsing: '正在解析 Blocklet 元数据...',
package/es/util.js CHANGED
@@ -178,7 +178,7 @@ export const checkBlockletAccessible = async (url, timeout = 5000, controller =
178
178
  try {
179
179
  const urlObj = new URL(url);
180
180
  urlObj.protocol = 'https';
181
- const res = await axios.get(joinURL(urlObj.toString(), '/api/__blocklet__.js?type=json'), {
181
+ const res = await axios.get(joinURL(urlObj.toString(), '/api/__blocklet__.js?type=json&owner=1&force=1&nocache=1'), {
182
182
  timeout,
183
183
  signal: controller?.signal,
184
184
  validateStatus: status => {