dsh-token-gauge 0.1.4 → 0.1.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.
- package/lib/client.mjs +72 -23
- package/package.json +1 -1
- package/src/client.ts +108 -30
package/lib/client.mjs
CHANGED
|
@@ -946,33 +946,82 @@ var gaugeRef = (el) => {
|
|
|
946
946
|
function GaugeTab() {
|
|
947
947
|
return import_react.default.createElement("div", { ref: gaugeRef, className: "tg-tab-root" });
|
|
948
948
|
}
|
|
949
|
+
var GaugeIcon = (size) => {
|
|
950
|
+
const s = typeof size === "number" && size > 0 ? size : 16;
|
|
951
|
+
const svgProps = {
|
|
952
|
+
width: s,
|
|
953
|
+
height: s,
|
|
954
|
+
viewBox: "0 0 16 16",
|
|
955
|
+
fill: "none",
|
|
956
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
957
|
+
"aria-hidden": "true"
|
|
958
|
+
};
|
|
959
|
+
const arc = import_react.default.createElement("path", {
|
|
960
|
+
d: "M2.6 11.6a5.6 5.6 0 1 1 10.8 0",
|
|
961
|
+
stroke: "currentColor",
|
|
962
|
+
strokeWidth: 1.5,
|
|
963
|
+
strokeLinecap: "round"
|
|
964
|
+
});
|
|
965
|
+
const needle = import_react.default.createElement("path", {
|
|
966
|
+
d: "M8 11.6 10.4 7.2",
|
|
967
|
+
stroke: "currentColor",
|
|
968
|
+
strokeWidth: 1.5,
|
|
969
|
+
strokeLinecap: "round"
|
|
970
|
+
});
|
|
971
|
+
return import_react.default.createElement("svg", svgProps, arc, needle);
|
|
972
|
+
};
|
|
973
|
+
var TAB_ORDER = 90;
|
|
949
974
|
var name = PLUGIN_ID;
|
|
950
975
|
function apply(ctx) {
|
|
951
|
-
let
|
|
952
|
-
|
|
953
|
-
const
|
|
954
|
-
if (
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
};
|
|
965
|
-
if (!tryRegister()) {
|
|
966
|
-
const timer = setInterval(() => {
|
|
967
|
-
if (tryRegister()) clearInterval(timer);
|
|
968
|
-
}, 200);
|
|
969
|
-
setTimeout(() => clearInterval(timer), 15e3);
|
|
970
|
-
if (typeof ctx.on === "function") {
|
|
971
|
-
ctx.on("dispose", () => {
|
|
972
|
-
disposed = true;
|
|
973
|
-
clearInterval(timer);
|
|
976
|
+
let registered = false;
|
|
977
|
+
let unregister = void 0;
|
|
978
|
+
const register = (sidebar) => {
|
|
979
|
+
if (registered || !sidebar || typeof sidebar.registerTab !== "function") return;
|
|
980
|
+
registered = true;
|
|
981
|
+
try {
|
|
982
|
+
unregister = sidebar.registerTab({
|
|
983
|
+
id: PLUGIN_ID,
|
|
984
|
+
title: "Token \u4EEA\u8868\u76D8",
|
|
985
|
+
single: true,
|
|
986
|
+
order: TAB_ORDER,
|
|
987
|
+
icon: GaugeIcon,
|
|
988
|
+
component: GaugeTab
|
|
974
989
|
});
|
|
990
|
+
} catch (e) {
|
|
991
|
+
registered = false;
|
|
975
992
|
}
|
|
993
|
+
};
|
|
994
|
+
let disposeInject = void 0;
|
|
995
|
+
try {
|
|
996
|
+
disposeInject = ctx.inject(["betterSidebar"], (sidebarCtx) => {
|
|
997
|
+
register(sidebarCtx && sidebarCtx.betterSidebar);
|
|
998
|
+
});
|
|
999
|
+
} catch (e) {
|
|
1000
|
+
}
|
|
1001
|
+
const tryRead = () => {
|
|
1002
|
+
if (registered) return;
|
|
1003
|
+
try {
|
|
1004
|
+
const s = typeof ctx.get === "function" ? ctx.get("betterSidebar") : ctx.betterSidebar;
|
|
1005
|
+
register(s);
|
|
1006
|
+
} catch (e) {
|
|
1007
|
+
}
|
|
1008
|
+
};
|
|
1009
|
+
tryRead();
|
|
1010
|
+
let timer = void 0;
|
|
1011
|
+
if (!registered) {
|
|
1012
|
+
timer = setInterval(() => {
|
|
1013
|
+
tryRead();
|
|
1014
|
+
if (registered && timer !== void 0) clearInterval(timer);
|
|
1015
|
+
}, 500);
|
|
976
1016
|
}
|
|
1017
|
+
const stop = setTimeout(() => {
|
|
1018
|
+
if (timer !== void 0) clearInterval(timer);
|
|
1019
|
+
}, 3e4);
|
|
1020
|
+
return () => {
|
|
1021
|
+
if (timer !== void 0) clearInterval(timer);
|
|
1022
|
+
clearTimeout(stop);
|
|
1023
|
+
if (typeof unregister === "function") unregister();
|
|
1024
|
+
if (typeof disposeInject === "function") disposeInject();
|
|
1025
|
+
};
|
|
977
1026
|
}
|
|
978
1027
|
; return module.exports; } });
|
package/package.json
CHANGED
package/src/client.ts
CHANGED
|
@@ -203,39 +203,117 @@ function GaugeTab(): React.ReactElement {
|
|
|
203
203
|
return React.createElement('div', { ref: gaugeRef, className: 'tg-tab-root' })
|
|
204
204
|
}
|
|
205
205
|
|
|
206
|
+
// 侧边栏图标:better-sidebar 以 `icon(size)` 形式调用(见其内置 tab:
|
|
207
|
+
// `icon: (size) => jsx(Icon, { size })`),故这里接收数字尺寸。用 currentColor
|
|
208
|
+
// 着色以自适应明暗主题,纯 SVG 零依赖。
|
|
209
|
+
const GaugeIcon = (size?: number): any => {
|
|
210
|
+
const s = typeof size === 'number' && size > 0 ? size : 16
|
|
211
|
+
const svgProps: any = {
|
|
212
|
+
width: s,
|
|
213
|
+
height: s,
|
|
214
|
+
viewBox: '0 0 16 16',
|
|
215
|
+
fill: 'none',
|
|
216
|
+
xmlns: 'http://www.w3.org/2000/svg',
|
|
217
|
+
'aria-hidden': 'true',
|
|
218
|
+
}
|
|
219
|
+
// 仪表盘弧 + 指针
|
|
220
|
+
const arc = React.createElement('path', {
|
|
221
|
+
d: 'M2.6 11.6a5.6 5.6 0 1 1 10.8 0',
|
|
222
|
+
stroke: 'currentColor',
|
|
223
|
+
strokeWidth: 1.5,
|
|
224
|
+
strokeLinecap: 'round',
|
|
225
|
+
})
|
|
226
|
+
const needle = React.createElement('path', {
|
|
227
|
+
d: 'M8 11.6 10.4 7.2',
|
|
228
|
+
stroke: 'currentColor',
|
|
229
|
+
strokeWidth: 1.5,
|
|
230
|
+
strokeLinecap: 'round',
|
|
231
|
+
})
|
|
232
|
+
return React.createElement('svg', svgProps, arc, needle)
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// 在「+ 新建 Tab」菜单里的排序位。内置 tab 用 20/91/110 等,order 缺省为 100
|
|
236
|
+
// 会排到菜单最底部不易发现,这里显式给一个偏前的值。
|
|
237
|
+
const TAB_ORDER = 90
|
|
238
|
+
|
|
206
239
|
export const name = PLUGIN_ID
|
|
207
|
-
|
|
208
|
-
//
|
|
209
|
-
//
|
|
210
|
-
//
|
|
211
|
-
//
|
|
212
|
-
//
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
240
|
+
|
|
241
|
+
// 兄弟 bundle 提供的服务(betterSidebar)在本机这个 cordis 里两种读法都不行,必须用
|
|
242
|
+
// ctx.inject 回调模式。原因(已实测坐实,见本文件末尾注释与 dsh-plugin-guide 官方
|
|
243
|
+
// postmortem):
|
|
244
|
+
// 1) 插件级 `export const inject = ['betterSidebar']`
|
|
245
|
+
// -> cordis 把整插件 defer,单趟 boot 的 assertEntriesActivated 检查点在
|
|
246
|
+
// loader.await() 后跑,此时兄弟 bundle 的 provide 还没落到本 fiber,
|
|
247
|
+
// 直接判 "pending (waiting for service: betterSidebar)"(0.1.3 实测)。
|
|
248
|
+
// 2) apply 顶层 `ctx.get('betterSidebar')` 或 `ctx.betterSidebar`
|
|
249
|
+
// -> 0811 cordis 是「严格注入」:未声明 inject 直接读服务属性,走 ancestor-only
|
|
250
|
+
// fiber 遍历到 root 找不到就抛
|
|
251
|
+
// "cannot get property betterSidebar without inject"(0.1.4 实测)。
|
|
252
|
+
// 正确姿势:插件级不声明任何 inject(插件立即激活,不 pending),改用
|
|
253
|
+
// ctx.inject(['betterSidebar'], cb) —— 回调拿到的子上下文里 betterSidebar 是已注入的
|
|
254
|
+
// 合法属性,读它不触发守卫;且注册被延迟到服务就绪那一刻(兄弟 bundle 提供得早或晚
|
|
255
|
+
// 都能注册上)。生态插件 @linxin666/dsh-client-ui-aionui-panel 用的正是这个模式。
|
|
256
|
+
export function apply(ctx: any): (() => void) | void {
|
|
257
|
+
let registered = false
|
|
258
|
+
let unregister: unknown = void 0
|
|
259
|
+
|
|
260
|
+
// 注册一次即止(registerTab 对重复 id 会抛 "already registered")
|
|
261
|
+
const register = (sidebar: any): void => {
|
|
262
|
+
if (registered || !sidebar || typeof sidebar.registerTab !== 'function') return
|
|
263
|
+
registered = true
|
|
264
|
+
try {
|
|
265
|
+
unregister = sidebar.registerTab({
|
|
266
|
+
id: PLUGIN_ID,
|
|
267
|
+
title: 'Token 仪表盘',
|
|
268
|
+
single: true,
|
|
269
|
+
order: TAB_ORDER,
|
|
270
|
+
icon: GaugeIcon,
|
|
271
|
+
component: GaugeTab,
|
|
272
|
+
})
|
|
273
|
+
} catch (e) {
|
|
274
|
+
registered = false // 失败则允许后续重试
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// 主路径:ctx.inject 回调——服务就绪时触发,回调内读 sidebarCtx.betterSidebar 合法
|
|
279
|
+
let disposeInject: unknown = void 0
|
|
280
|
+
try {
|
|
281
|
+
disposeInject = ctx.inject(['betterSidebar'], (sidebarCtx: any) => {
|
|
282
|
+
register(sidebarCtx && sidebarCtx.betterSidebar)
|
|
226
283
|
})
|
|
227
|
-
|
|
284
|
+
} catch (e) {
|
|
285
|
+
/* 运行时无 ctx.inject:交由下面的轮询兜底 */
|
|
228
286
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
ctx.
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
287
|
+
|
|
288
|
+
// 兜底:轮询读取。0811 严格注入下未声明 inject 时 ctx.get('betterSidebar')
|
|
289
|
+
// 会「抛异常」(而非返回 undefined),所以必须用 try/catch 包住读取。
|
|
290
|
+
const tryRead = (): void => {
|
|
291
|
+
if (registered) return
|
|
292
|
+
try {
|
|
293
|
+
const s = typeof ctx.get === 'function' ? ctx.get('betterSidebar') : ctx.betterSidebar
|
|
294
|
+
register(s)
|
|
295
|
+
} catch (e) {
|
|
296
|
+
/* 服务此刻不可达,下一轮再试 */
|
|
239
297
|
}
|
|
240
298
|
}
|
|
299
|
+
tryRead()
|
|
300
|
+
|
|
301
|
+
let timer: unknown = void 0
|
|
302
|
+
if (!registered) {
|
|
303
|
+
timer = setInterval(() => {
|
|
304
|
+
tryRead()
|
|
305
|
+
if (registered && timer !== void 0) clearInterval(timer as number)
|
|
306
|
+
}, 500)
|
|
307
|
+
}
|
|
308
|
+
const stop = setTimeout(() => {
|
|
309
|
+
if (timer !== void 0) clearInterval(timer as number)
|
|
310
|
+
}, 30000)
|
|
311
|
+
|
|
312
|
+
// 插件级 disposer
|
|
313
|
+
return () => {
|
|
314
|
+
if (timer !== void 0) clearInterval(timer as number)
|
|
315
|
+
clearTimeout(stop)
|
|
316
|
+
if (typeof unregister === 'function') (unregister as () => void)()
|
|
317
|
+
if (typeof disposeInject === 'function') (disposeInject as () => void)()
|
|
318
|
+
}
|
|
241
319
|
}
|