dsh-bili-watch 0.2.6 → 0.2.7
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/client.js +82 -2
- package/index.js +25 -0
- package/package.json +1 -1
package/client.js
CHANGED
|
@@ -364,22 +364,102 @@ window.__ModuleLoader__.load({
|
|
|
364
364
|
)
|
|
365
365
|
}
|
|
366
366
|
|
|
367
|
+
// 缺依赖横幅(shell.overlay)
|
|
368
|
+
function OverlayBanner() {
|
|
369
|
+
const [st, setSt] = React.useState(null)
|
|
370
|
+
const [visible, setVisible] = React.useState(false)
|
|
371
|
+
const [dismissed, setDismissed] = React.useState(false)
|
|
372
|
+
|
|
373
|
+
React.useEffect(() => {
|
|
374
|
+
jget('/status').then((j) => {
|
|
375
|
+
if (!j.ok) return
|
|
376
|
+
setSt(j.data)
|
|
377
|
+
const missing = (j.data.deps || []).filter((d) => !d.ok)
|
|
378
|
+
if (missing.length > 0 && j.data.ui?.hintDismissed !== true) {
|
|
379
|
+
setVisible(true)
|
|
380
|
+
}
|
|
381
|
+
}).catch(() => {})
|
|
382
|
+
}, [])
|
|
383
|
+
|
|
384
|
+
if (!visible || dismissed) return null
|
|
385
|
+
const missing = (st?.deps || []).filter((d) => !d.ok)
|
|
386
|
+
const names = missing.map((d) => d.name).join('、')
|
|
387
|
+
|
|
388
|
+
return h('div', { 'data-bl-overlay': '' },
|
|
389
|
+
h('span', { 'data-bl-overlay-text': '' }, `bili-watch 还缺 ${missing.length} 个依赖(${names})`),
|
|
390
|
+
h('button', { 'data-bl-btn': 'primary', onClick: async () => { await jpost('/download', { target: 'all' }) } }, '去安装'),
|
|
391
|
+
h('button', { 'data-bl-btn': '', onClick: () => setDismissed(true) }, '×'),
|
|
392
|
+
h('button', { 'data-bl-btn': '', onClick: async () => {
|
|
393
|
+
await jpost('/config', { hintDismissed: true })
|
|
394
|
+
setDismissed(true)
|
|
395
|
+
} }, '不再提示'),
|
|
396
|
+
)
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// 启用指引(plugins.bundle.activation)
|
|
400
|
+
function ActivationGuide() {
|
|
401
|
+
const [seen, setSeen] = React.useState(false)
|
|
402
|
+
React.useEffect(() => {
|
|
403
|
+
jget('/status').then((j) => {
|
|
404
|
+
if (j.ok && j.data.ui?.activationSeen === true) setSeen(true)
|
|
405
|
+
}).catch(() => {})
|
|
406
|
+
}, [])
|
|
407
|
+
if (seen) return null
|
|
408
|
+
return h('div', { 'data-bl-activation': '' },
|
|
409
|
+
h('div', { 'data-bl-title': '' }, 'B站看视频插件已启用'),
|
|
410
|
+
h('div', { 'data-bl-note': '' }, '用它之前建议先装依赖:ffmpeg(抽帧/取音轨)、转写模型(本地转写)。没装也能用:元数据、评论、弹幕、搜索、热榜。'),
|
|
411
|
+
h('div', { 'data-bl-row': '' },
|
|
412
|
+
h('button', { 'data-bl-btn': 'primary', onClick: async () => { await jpost('/download', { target: 'all' }) } }, '去安装'),
|
|
413
|
+
h('button', { 'data-bl-btn': '', onClick: async () => {
|
|
414
|
+
await jpost('/config', { activationSeen: true })
|
|
415
|
+
setSeen(true)
|
|
416
|
+
} }, '先不装')),
|
|
417
|
+
)
|
|
418
|
+
}
|
|
419
|
+
|
|
367
420
|
return {
|
|
368
421
|
inject: ['slots'],
|
|
369
422
|
apply(ctx) {
|
|
370
423
|
const style = document.createElement('style')
|
|
371
424
|
style.setAttribute('data-plugin-css', 'dsh-bili-watch')
|
|
372
|
-
style.textContent = CSS
|
|
425
|
+
style.textContent = CSS + `
|
|
426
|
+
[data-bl-overlay]{position:fixed;top:0;left:0;right:0;z-index:9999;display:flex;align-items:center;gap:12px;padding:8px 16px;background:var(--dsw-alias-bg-strong,#2d2d2d);color:var(--dsw-alias-label-primary,#e5e7eb);font-size:13px;box-shadow:0 2px 8px rgba(0,0,0,.3);}
|
|
427
|
+
[data-bl-overlay-text]{flex:1;}
|
|
428
|
+
[data-bl-activation]{display:flex;flex-direction:column;gap:8px;padding:12px;border:1px solid var(--dsw-alias-border-l2,rgba(128,128,128,.18));border-radius:8px;background:var(--dsw-alias-bg2,rgba(255,255,255,.04));}
|
|
429
|
+
`
|
|
373
430
|
document.head.appendChild(style)
|
|
374
431
|
if (typeof ctx.effect === 'function') ctx.effect(() => () => style.remove(), 'dsh-bili-watch: 面板样式')
|
|
375
432
|
|
|
376
433
|
const slots = (typeof ctx.get === 'function' ? ctx.get('slots') : undefined) || ctx.slots
|
|
377
434
|
if (!slots) return
|
|
378
|
-
|
|
435
|
+
|
|
436
|
+
// ① 插件详情页配置区(原有)
|
|
379
437
|
slots.inject('plugins.bundle.config', () => slots.register(
|
|
380
438
|
{ name: 'plugins.bundle.config', key: PKG },
|
|
381
439
|
Panel,
|
|
382
440
|
))
|
|
441
|
+
|
|
442
|
+
// ② 启用指引(用户从插件列表点「启用」后渲染)
|
|
443
|
+
slots.inject('plugins.bundle.activation', () => slots.register(
|
|
444
|
+
{ name: 'plugins.bundle.activation', key: PKG },
|
|
445
|
+
ActivationGuide,
|
|
446
|
+
))
|
|
447
|
+
|
|
448
|
+
// ③ 缺依赖横幅(全页浮层)
|
|
449
|
+
slots.inject('shell.overlay', () => slots.register(
|
|
450
|
+
{ name: 'shell.overlay', key: PKG },
|
|
451
|
+
OverlayBanner,
|
|
452
|
+
))
|
|
453
|
+
|
|
454
|
+
// ④ 设置页双面板(读 showInSettings 决定是否注册)
|
|
455
|
+
jget('/status').then((j) => {
|
|
456
|
+
if (j.ok && j.data.ui?.showInSettings !== false) {
|
|
457
|
+
slots.inject('settings.section', () => slots.register(
|
|
458
|
+
{ name: 'settings.section', key: PKG, title: '刷B站' },
|
|
459
|
+
Panel,
|
|
460
|
+
))
|
|
461
|
+
}
|
|
462
|
+
}).catch(() => {})
|
|
383
463
|
},
|
|
384
464
|
}
|
|
385
465
|
},
|
package/index.js
CHANGED
|
@@ -45,6 +45,21 @@ const FFMPEG_CANDS = [
|
|
|
45
45
|
const HF_HOME = [join(DEPS, '.hf-home'), join(PROJ, '.hf-home')]
|
|
46
46
|
const SCRIPTS = join(HERE, 'scripts')
|
|
47
47
|
const CACHE_CFG = join(DEPS, 'cache-config.json')
|
|
48
|
+
const UI_CFG = join(DEPS, 'ui-config.json')
|
|
49
|
+
const DEFAULT_UI_CFG = { hintDismissed: false, activationSeen: false, showInSettings: true }
|
|
50
|
+
|
|
51
|
+
function uiCfg() {
|
|
52
|
+
try {
|
|
53
|
+
const raw = JSON.parse(readFileSync(UI_CFG, 'utf8'))
|
|
54
|
+
return { ...DEFAULT_UI_CFG, ...raw }
|
|
55
|
+
} catch { return { ...DEFAULT_UI_CFG } }
|
|
56
|
+
}
|
|
57
|
+
function writeUiCfg(patch) {
|
|
58
|
+
const cur = uiCfg()
|
|
59
|
+
const next = { ...cur, ...patch }
|
|
60
|
+
writeFileSync(UI_CFG, JSON.stringify(next, null, 2), 'utf8')
|
|
61
|
+
return next
|
|
62
|
+
}
|
|
48
63
|
const DEFAULT_CACHE_DAYS = 7
|
|
49
64
|
const DEFAULT_CACHE_MAX_MB = 2048
|
|
50
65
|
const DOWNLOAD_LOG = join(DEPS, 'download.log')
|
|
@@ -674,6 +689,7 @@ function apply(ctx) {
|
|
|
674
689
|
deps: depRows(),
|
|
675
690
|
cache: { ...dirStat(CACHE), ...cacheCfg(), lastAutoClean: cleaned },
|
|
676
691
|
lastRun: readLastRun(),
|
|
692
|
+
ui: uiCfg(),
|
|
677
693
|
},
|
|
678
694
|
})
|
|
679
695
|
}
|
|
@@ -714,6 +730,15 @@ function apply(ctx) {
|
|
|
714
730
|
if (r.state === 'ok') writeLastRun('login', 0)
|
|
715
731
|
return sendJson(res, 200, r)
|
|
716
732
|
}
|
|
733
|
+
if (req.method === 'POST' && url.pathname === '/api/bili-watch/config') {
|
|
734
|
+
const body = await readJsonBody(req)
|
|
735
|
+
const patch = {}
|
|
736
|
+
if (typeof body?.hintDismissed === 'boolean') patch.hintDismissed = body.hintDismissed
|
|
737
|
+
if (typeof body?.activationSeen === 'boolean') patch.activationSeen = body.activationSeen
|
|
738
|
+
if (typeof body?.showInSettings === 'boolean') patch.showInSettings = body.showInSettings
|
|
739
|
+
const next = writeUiCfg(patch)
|
|
740
|
+
return sendJson(res, 200, { ok: true, data: next })
|
|
741
|
+
}
|
|
717
742
|
sendJson(res, 404, { ok: false, why: 'not found' })
|
|
718
743
|
} catch (e) {
|
|
719
744
|
sendJson(res, 500, { ok: false, why: String(e?.message || e) })
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-bili-watch",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.7",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Reads Bilibili (and generic URLs via yt-dlp) into text for DSH agents: search, hot, metadata, comments, danmaku, AI subtitles, local ASR, frame OCR.",
|
|
6
6
|
"type": "module",
|