@yuuichi/openlist-assets 4.2.6-ym.1 → 4.2.6-ym.3
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/dist/assets/previews-CoVCUlRx.js +1 -1
- package/dist/assets/previews-legacy-DOedQYss.js +1 -1
- package/dist/brand/global-search.js +120 -0
- package/dist/brand/music-player.js +21 -5
- package/dist/brand/upload-add.js +164 -100
- package/dist/brand/ym-bundle.js +309 -106
- package/dist/esa-entry.js +87 -86
- package/package.json +1 -1
package/dist/brand/ym-bundle.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* Yuuichi brand bundle — generated, do not edit directly.
|
|
2
|
-
* Source order: footer-links.js, upload-direct.js, upload-add.js, notify-auto-close.js, bg-mask-toggle.js, music-player.js */
|
|
2
|
+
* Source order: footer-links.js, upload-direct.js, upload-add.js, notify-auto-close.js, bg-mask-toggle.js, global-search.js, music-player.js */
|
|
3
3
|
"use strict";
|
|
4
4
|
/* ===== footer-links.js ===== */
|
|
5
5
|
;(function(){
|
|
@@ -300,53 +300,45 @@
|
|
|
300
300
|
(function () {
|
|
301
301
|
"use strict";
|
|
302
302
|
|
|
303
|
-
//
|
|
304
|
-
//
|
|
305
|
-
// “-/s” 的阶段:取直传地址(presign) → 分片直传(第 x/N 片 + 实时速率 + 并发)
|
|
306
|
-
// → 云端合并(complete)。
|
|
307
|
-
//
|
|
308
|
-
// 文件的添加/拖放完全使用上传弹窗原生能力:闲置视图自带“拖放区 / 选择文件 /
|
|
309
|
-
// 选择文件夹”;上传过程中点“返回上传”即可继续添加(原上传不中断)。
|
|
310
|
-
// 本脚本不再注入任何额外的虚线框或全屏拖放层。
|
|
311
|
-
|
|
303
|
+
// 上传状态面板:状态只以真实事件为准,避免“文件已传完仍显示直传中”或
|
|
304
|
+
// “没有速度却显示传输中”。速率由各活跃分片的 1s 滑动窗口聚合计算。
|
|
312
305
|
var PANEL_ID = "ym-upload-panel";
|
|
313
306
|
|
|
314
|
-
var
|
|
315
|
-
var
|
|
316
|
-
var merge = { on: false, at: 0 };
|
|
307
|
+
var uploads = Object.create(null);
|
|
308
|
+
var phase = { name: "idle", at: 0 };
|
|
317
309
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
function
|
|
321
|
-
if (
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
310
|
+
function nowMs() { return Date.now(); }
|
|
311
|
+
|
|
312
|
+
function ensure(id) {
|
|
313
|
+
if (!uploads[id]) {
|
|
314
|
+
uploads[id] = {
|
|
315
|
+
total: 0,
|
|
316
|
+
doneCount: 0,
|
|
317
|
+
done: Object.create(null),
|
|
318
|
+
waiting: new Set(),
|
|
319
|
+
active: Object.create(null),
|
|
320
|
+
finished: false,
|
|
321
|
+
};
|
|
327
322
|
}
|
|
328
|
-
|
|
329
|
-
render();
|
|
323
|
+
return uploads[id];
|
|
330
324
|
}
|
|
331
325
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
render();
|
|
343
|
-
}, 90000);
|
|
344
|
-
render();
|
|
326
|
+
function activeUploadCount() { return Object.keys(uploads).length; }
|
|
327
|
+
function anyWaiting() {
|
|
328
|
+
return Object.keys(uploads).some(function (id) { return uploads[id].waiting.size > 0; });
|
|
329
|
+
}
|
|
330
|
+
function allPartsDone() {
|
|
331
|
+
var ids = Object.keys(uploads);
|
|
332
|
+
return ids.length > 0 && ids.every(function (id) {
|
|
333
|
+
var u = uploads[id];
|
|
334
|
+
return u.total > 0 && u.doneCount >= u.total;
|
|
335
|
+
});
|
|
345
336
|
}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
337
|
+
|
|
338
|
+
function resetAll(reason) {
|
|
339
|
+
uploads = Object.create(null);
|
|
340
|
+
phase = reason ? { name: reason, at: nowMs() } : { name: "idle", at: 0 };
|
|
341
|
+
render();
|
|
350
342
|
}
|
|
351
343
|
|
|
352
344
|
var cssInjected = false;
|
|
@@ -361,17 +353,18 @@
|
|
|
361
353
|
" box-shadow:0 2px 10px rgba(2,132,199,.18);}",
|
|
362
354
|
"#" + PANEL_ID + ".ym-merge{color:#7c2d12;background:linear-gradient(135deg,#ffedd5,#fed7aa);border-color:#fdba74;}",
|
|
363
355
|
"#" + PANEL_ID + ".ym-wait{color:#854d0e;background:linear-gradient(135deg,#fef9c3,#fde68a);border-color:#facc15;}",
|
|
356
|
+
"#" + PANEL_ID + ".ym-done{color:#14532d;background:linear-gradient(135deg,#dcfce7,#bbf7d0);border-color:#86efac;}",
|
|
364
357
|
"#" + PANEL_ID + " .ym-spin{width:18px;height:18px;margin-top:2px;flex:0 0 auto;",
|
|
365
358
|
" border:3px solid rgba(2,132,199,.25);border-top-color:#0284c7;border-radius:50%;animation:ym-sp .8s linear infinite;}",
|
|
366
359
|
"#" + PANEL_ID + ".ym-merge .ym-spin{border-color:rgba(194,65,12,.25);border-top-color:#c2410c;}",
|
|
367
360
|
"#" + PANEL_ID + ".ym-wait .ym-spin{border-color:rgba(161,98,7,.25);border-top-color:#a16207;}",
|
|
361
|
+
"#" + PANEL_ID + ".ym-done .ym-spin{display:none;}",
|
|
368
362
|
"#" + PANEL_ID + " .ym-sub{display:block;font-size:12px;font-weight:600;opacity:.92;margin-top:3px;}",
|
|
369
363
|
"@keyframes ym-sp{to{transform:rotate(360deg)}}",
|
|
370
364
|
].join("\n");
|
|
371
365
|
document.head.appendChild(st);
|
|
372
366
|
}
|
|
373
367
|
|
|
374
|
-
// 上传弹窗:可见的 role=dialog,且内容含上传视图的特征文案
|
|
375
368
|
function findUploadModal() {
|
|
376
369
|
var dlgs = document.querySelectorAll('[role="dialog"].hope-modal__content, [role="dialog"]');
|
|
377
370
|
for (var i = 0; i < dlgs.length; i++) {
|
|
@@ -386,9 +379,7 @@
|
|
|
386
379
|
t.indexOf("选择文件夹") !== -1 ||
|
|
387
380
|
t.indexOf("上传中") !== -1 ||
|
|
388
381
|
t.indexOf("后台上传中") !== -1
|
|
389
|
-
)
|
|
390
|
-
return d;
|
|
391
|
-
}
|
|
382
|
+
) return d;
|
|
392
383
|
}
|
|
393
384
|
return null;
|
|
394
385
|
}
|
|
@@ -405,51 +396,112 @@
|
|
|
405
396
|
}
|
|
406
397
|
|
|
407
398
|
function summarize() {
|
|
408
|
-
var ids = Object.keys(
|
|
399
|
+
var ids = Object.keys(uploads);
|
|
400
|
+
var done = 0, total = 0, active = 0, bytesLoaded = 0, bytesTotal = 0, bps = 0;
|
|
409
401
|
ids.forEach(function (id) {
|
|
410
|
-
var
|
|
411
|
-
total +=
|
|
412
|
-
done +=
|
|
413
|
-
Object.keys(
|
|
402
|
+
var u = uploads[id];
|
|
403
|
+
total += u.total || 0;
|
|
404
|
+
done += u.doneCount || 0;
|
|
405
|
+
Object.keys(u.active).forEach(function (k) {
|
|
406
|
+
var a = u.active[k];
|
|
407
|
+
active++;
|
|
408
|
+
bytesLoaded += a.loaded || 0;
|
|
409
|
+
bytesTotal += a.bytes || a.total || 0;
|
|
410
|
+
bps += currentPartSpeed(a);
|
|
411
|
+
});
|
|
414
412
|
});
|
|
415
|
-
return { done: done, total: total, bps: bps,
|
|
413
|
+
return { done: done, total: total, active: active, bps: bps, bytesLoaded: bytesLoaded, bytesTotal: bytesTotal };
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
function currentPartSpeed(a) {
|
|
417
|
+
if (!a.samples || a.samples.length < 2) return 0;
|
|
418
|
+
var first = a.samples[0], last = a.samples[a.samples.length - 1];
|
|
419
|
+
var dt = (last.t - first.t) / 1000;
|
|
420
|
+
if (dt <= 0) return 0;
|
|
421
|
+
return Math.max(0, (last.loaded - first.loaded) / dt);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
function pushSample(a, loaded) {
|
|
425
|
+
var t = nowMs();
|
|
426
|
+
a.loaded = loaded;
|
|
427
|
+
if (!a.samples) a.samples = [];
|
|
428
|
+
a.samples.push({ t: t, loaded: loaded });
|
|
429
|
+
while (a.samples.length > 2 && t - a.samples[0].t > 1500) a.samples.shift();
|
|
416
430
|
}
|
|
417
431
|
|
|
418
432
|
function onEvent(ev) {
|
|
419
|
-
var d = ev.detail || {}
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
if (d.type === "
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
433
|
+
var d = ev.detail || {};
|
|
434
|
+
var id = d.uploadId || "_";
|
|
435
|
+
|
|
436
|
+
if (d.type === "upload:finish") {
|
|
437
|
+
if (id && uploads[id]) delete uploads[id];
|
|
438
|
+
else uploads = Object.create(null);
|
|
439
|
+
if (!activeUploadCount()) {
|
|
440
|
+
phase = { name: "done", at: nowMs() };
|
|
441
|
+
render();
|
|
442
|
+
setTimeout(function () { if (phase.name === "done") resetAll("idle"); }, 1200);
|
|
443
|
+
}
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
if (d.type === "complete:start" || d.state === "merging") {
|
|
447
|
+
// 前端在发出 complete 请求后、本地最后一个 part:done 事件到达前可能先触发本事件;
|
|
448
|
+
// 仍有活跃分片时必须显示“传输中”,不能提前显示“合并中”。
|
|
449
|
+
var st = summarize();
|
|
450
|
+
phase = { name: st.active > 0 || anyWaiting() ? "parts" : "merging", at: nowMs() };
|
|
451
|
+
render();
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
if (d.type === "complete:done") {
|
|
455
|
+
if (d.ok) {
|
|
456
|
+
phase = { name: "done", at: nowMs() };
|
|
457
|
+
uploads = Object.create(null);
|
|
458
|
+
render();
|
|
459
|
+
setTimeout(function () { resetAll("idle"); }, 1200);
|
|
460
|
+
} else {
|
|
461
|
+
phase = { name: "parts", at: nowMs() };
|
|
462
|
+
render();
|
|
463
|
+
}
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
if (d.type === "presign:start" || d.type === "part:start" || d.type === "part:progress" ||
|
|
468
|
+
d.type === "part:done" || d.type === "part:error" || d.type === "relay") {
|
|
469
|
+
if (phase.name === "idle" || phase.name === "done") phase = { name: "parts", at: nowMs() };
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
var u = ensure(id);
|
|
473
|
+
if (d.total) u.total = d.total;
|
|
474
|
+
|
|
475
|
+
if (d.type === "presign:start") {
|
|
476
|
+
u.waiting.add(d.index);
|
|
477
|
+
} else if (d.type === "presign:done") {
|
|
478
|
+
u.waiting.delete(d.index);
|
|
479
|
+
} else if (d.type === "part:start") {
|
|
480
|
+
u.waiting.delete(d.index);
|
|
481
|
+
u.active[d.index] = {
|
|
482
|
+
index: d.index,
|
|
483
|
+
total: d.total,
|
|
484
|
+
bytes: d.bytes || 0,
|
|
485
|
+
loaded: 0,
|
|
486
|
+
samples: [{ t: nowMs(), loaded: 0 }],
|
|
487
|
+
};
|
|
434
488
|
} else if (d.type === "part:progress") {
|
|
435
|
-
if (!
|
|
436
|
-
|
|
437
|
-
|
|
489
|
+
if (!u.active[d.index]) {
|
|
490
|
+
u.active[d.index] = { index: d.index, total: d.total, bytes: d.bytes || 0, loaded: 0, samples: [] };
|
|
491
|
+
}
|
|
492
|
+
if (d.bytes) u.active[d.index].bytes = d.bytes;
|
|
493
|
+
pushSample(u.active[d.index], d.loaded || 0);
|
|
438
494
|
} else if (d.type === "part:done") {
|
|
439
|
-
if (!
|
|
440
|
-
delete
|
|
441
|
-
|
|
442
|
-
if (
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
// 看门狗:本地分片已全部直传,若 60s 内既没等到 complete 也没收到
|
|
446
|
-
// 服务端 status=completed/404(极端漏网),强制收尾,杜绝状态条卡死。
|
|
447
|
-
setTimeout(function () { if (parts[key]) finishUpload(key); }, 60000);
|
|
448
|
-
})(id);
|
|
495
|
+
if (!u.done[d.index]) { u.done[d.index] = 1; u.doneCount++; }
|
|
496
|
+
delete u.active[d.index];
|
|
497
|
+
u.waiting.delete(d.index);
|
|
498
|
+
if (u.total && u.doneCount >= u.total) {
|
|
499
|
+
u.finished = true;
|
|
500
|
+
phase = { name: "finalizing", at: nowMs() };
|
|
449
501
|
}
|
|
450
502
|
} else if (d.type === "part:error" || d.type === "relay") {
|
|
451
|
-
delete
|
|
452
|
-
|
|
503
|
+
delete u.active[d.index];
|
|
504
|
+
u.waiting.delete(d.index);
|
|
453
505
|
}
|
|
454
506
|
render();
|
|
455
507
|
}
|
|
@@ -457,39 +509,48 @@
|
|
|
457
509
|
function render() {
|
|
458
510
|
var body = panelBody();
|
|
459
511
|
var panel = document.getElementById(PANEL_ID);
|
|
460
|
-
var
|
|
461
|
-
var
|
|
512
|
+
var hasUploads = activeUploadCount() > 0;
|
|
513
|
+
var s = hasUploads ? summarize() : null;
|
|
462
514
|
|
|
463
|
-
if (
|
|
515
|
+
if (phase.name === "merging" || phase.name === "finalizing") {
|
|
464
516
|
if (!body) return;
|
|
465
517
|
if (!panel) { panel = document.createElement("div"); panel.id = PANEL_ID; body.insertBefore(panel, body.firstChild); }
|
|
518
|
+
var secs = Math.max(1, Math.round((nowMs() - phase.at) / 1000));
|
|
519
|
+
var merging = phase.name === "merging" || (s && s.active === 0 && allPartsDone());
|
|
466
520
|
panel.className = "ym-merge";
|
|
467
|
-
var secs = Math.round((Date.now() - merge.at) / 1000);
|
|
468
521
|
panel.innerHTML =
|
|
469
|
-
'<span class="ym-spin"></span><span
|
|
470
|
-
|
|
522
|
+
'<span class="ym-spin"></span><span>' +
|
|
523
|
+
(merging ? "正在云端合并分片…(已 " + secs + " 秒)" : "分片已全部上传,正在提交合并请求…") +
|
|
524
|
+
'<span class="ym-sub">此阶段由网盘服务器处理,不再上传文件内容,因此下方速度显示为 0 或 “-/s” 属正常;大文件可能需要几秒到几十秒,请勿关闭窗口。</span></span>';
|
|
525
|
+
return;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
if (phase.name === "done") {
|
|
529
|
+
if (!body) return;
|
|
530
|
+
if (!panel) { panel = document.createElement("div"); panel.id = PANEL_ID; body.insertBefore(panel, body.firstChild); }
|
|
531
|
+
panel.className = "ym-done";
|
|
532
|
+
panel.innerHTML = "<span>✓</span><span>上传完成,文件正在列表中刷新…</span>";
|
|
471
533
|
return;
|
|
472
534
|
}
|
|
473
535
|
|
|
474
|
-
if (!
|
|
536
|
+
if (!hasUploads) { if (panel) panel.remove(); return; }
|
|
475
537
|
if (!body) return;
|
|
476
538
|
if (!panel) { panel = document.createElement("div"); panel.id = PANEL_ID; body.insertBefore(panel, body.firstChild); }
|
|
477
539
|
|
|
478
|
-
var s = summarize();
|
|
479
540
|
var pct = s.total ? Math.min(99, Math.round((s.done / s.total) * 100)) : 0;
|
|
480
541
|
var line1 = "大文件切片直传中 · 已完成 " + s.done + (s.total ? " / " + s.total + " 片(" + pct + "%)" : " 片");
|
|
481
542
|
var line2;
|
|
482
|
-
if (s.
|
|
483
|
-
|
|
484
|
-
line2 =
|
|
485
|
-
"正在传输第 " + (a.index + 1) + (a.total ? " / " + a.total : "") + " 片 · 实时速率 " +
|
|
486
|
-
fmtSpeed(s.bps) + (s.act.length > 1 ? " · " + s.act.length + " 路并发" : "");
|
|
543
|
+
if (s.active > 0 && s.bps > 1024) {
|
|
544
|
+
line2 = "正在传输 " + s.active + (s.active > 1 ? " 个分片" : " 个分片") + " · 实时速率 " + fmtSpeed(s.bps);
|
|
487
545
|
panel.className = "";
|
|
488
|
-
} else if (
|
|
489
|
-
line2 = "
|
|
546
|
+
} else if (s.active > 0) {
|
|
547
|
+
line2 = "正在传输 " + s.active + (s.active > 1 ? " 个分片" : " 个分片") + " · 正在建立连接/等待首包,暂不计速";
|
|
548
|
+
panel.className = "ym-wait";
|
|
549
|
+
} else if (anyWaiting()) {
|
|
550
|
+
line2 = "正在向网盘申请分片直传地址…(这一步不传文件,暂时没有速度)";
|
|
490
551
|
panel.className = "ym-wait";
|
|
491
552
|
} else {
|
|
492
|
-
line2 = "
|
|
553
|
+
line2 = "正在准备下一片…(暂不传文件,速度为 0)";
|
|
493
554
|
panel.className = "ym-wait";
|
|
494
555
|
}
|
|
495
556
|
panel.innerHTML =
|
|
@@ -502,15 +563,18 @@
|
|
|
502
563
|
scheduled = true;
|
|
503
564
|
requestAnimationFrame(function () {
|
|
504
565
|
scheduled = false;
|
|
505
|
-
// 廉价门控:仅在「已存在面板需要更新位置」或「页面上可能有弹窗」时
|
|
506
|
-
// 才执行较重的 findUploadModal()(含 getBoundingClientRect 与文案扫描),
|
|
507
|
-
// 避免列表导航等无关 DOM 变更也反复触发布局查询。
|
|
508
566
|
var panel = document.getElementById(PANEL_ID);
|
|
509
567
|
if (panel || document.querySelector('[role="dialog"]')) render();
|
|
510
568
|
});
|
|
511
569
|
}
|
|
512
570
|
|
|
513
|
-
setInterval(function () {
|
|
571
|
+
setInterval(function () {
|
|
572
|
+
if (phase.name === "merging" || phase.name === "finalizing") render();
|
|
573
|
+
else if (activeUploadCount()) {
|
|
574
|
+
var s = summarize();
|
|
575
|
+
if (s.active > 0) render();
|
|
576
|
+
}
|
|
577
|
+
}, 1000);
|
|
514
578
|
|
|
515
579
|
function boot() {
|
|
516
580
|
injectCss();
|
|
@@ -955,6 +1019,129 @@
|
|
|
955
1019
|
else boot();
|
|
956
1020
|
})();
|
|
957
1021
|
})();
|
|
1022
|
+
/* ===== global-search.js ===== */
|
|
1023
|
+
;(function(){
|
|
1024
|
+
(function () {
|
|
1025
|
+
"use strict";
|
|
1026
|
+
|
|
1027
|
+
// 官方前端搜索框固定把当前路径作为 parent,后端 /fs/search 本身已支持递归,
|
|
1028
|
+
// 因此这里在弹窗内增加“全局 / 当前目录”开关,并在请求发出前改写 parent。
|
|
1029
|
+
var KEY = "ym-global-search";
|
|
1030
|
+
var globalByDefault = true;
|
|
1031
|
+
|
|
1032
|
+
function isGlobal() {
|
|
1033
|
+
try {
|
|
1034
|
+
return localStorage.getItem(KEY) !== "0";
|
|
1035
|
+
} catch (e) {
|
|
1036
|
+
return globalByDefault;
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
function setGlobal(v) {
|
|
1041
|
+
try { localStorage.setItem(KEY, v ? "1" : "0"); } catch (e) {}
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
function rewriteBody(body) {
|
|
1045
|
+
try {
|
|
1046
|
+
if (typeof body !== "string" || body.indexOf("/fs/search") === -1) return body;
|
|
1047
|
+
var data = JSON.parse(body);
|
|
1048
|
+
if (isGlobal()) data.parent = "/";
|
|
1049
|
+
return JSON.stringify(data);
|
|
1050
|
+
} catch (e) {
|
|
1051
|
+
return body;
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
function installFetchPatch() {
|
|
1056
|
+
if (window.__ymSearchFetchPatched) return;
|
|
1057
|
+
window.__ymSearchFetchPatched = true;
|
|
1058
|
+
var ofetch = window.fetch;
|
|
1059
|
+
window.fetch = function (input, init) {
|
|
1060
|
+
try {
|
|
1061
|
+
var url = typeof input === "string" ? input : input && input.url;
|
|
1062
|
+
if (url && url.indexOf("/fs/search") !== -1 && init && typeof init.body === "string") {
|
|
1063
|
+
init = Object.assign({}, init, { body: rewriteBody(init.body) });
|
|
1064
|
+
}
|
|
1065
|
+
} catch (e) {}
|
|
1066
|
+
return ofetch.apply(this, arguments);
|
|
1067
|
+
};
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
function installXhrPatch() {
|
|
1071
|
+
if (window.__ymSearchXhrPatched) return;
|
|
1072
|
+
window.__ymSearchXhrPatched = true;
|
|
1073
|
+
var open = XMLHttpRequest.prototype.open;
|
|
1074
|
+
var send = XMLHttpRequest.prototype.send;
|
|
1075
|
+
XMLHttpRequest.prototype.open = function (method, url) {
|
|
1076
|
+
this.__ymSearchUrl = url || "";
|
|
1077
|
+
return open.apply(this, arguments);
|
|
1078
|
+
};
|
|
1079
|
+
XMLHttpRequest.prototype.send = function (body) {
|
|
1080
|
+
try {
|
|
1081
|
+
if (this.__ymSearchUrl.indexOf("/fs/search") !== -1 && typeof body === "string") {
|
|
1082
|
+
arguments[0] = rewriteBody(body);
|
|
1083
|
+
}
|
|
1084
|
+
} catch (e) {}
|
|
1085
|
+
return send.apply(this, arguments);
|
|
1086
|
+
};
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
function injectCss() {
|
|
1090
|
+
if (document.getElementById("ym-search-toggle-css")) return;
|
|
1091
|
+
var st = document.createElement("style");
|
|
1092
|
+
st.id = "ym-search-toggle-css";
|
|
1093
|
+
st.textContent = [
|
|
1094
|
+
".ym-search-scope{display:inline-flex;align-items:center;gap:5px;margin-left:6px;padding:0 8px;",
|
|
1095
|
+
"height:32px;border-radius:8px;border:1px solid var(--hope-colors-neutral7,#cbd5e1);",
|
|
1096
|
+
"font-size:12px;white-space:nowrap;cursor:pointer;color:var(--hope-colors-neutral11,#475569);",
|
|
1097
|
+
"background:var(--hope-colors-neutral2,#f8fafc);user-select:none;}",
|
|
1098
|
+
".ym-search-scope input{margin:0;cursor:pointer;}",
|
|
1099
|
+
].join("");
|
|
1100
|
+
document.head.appendChild(st);
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
function findModal() {
|
|
1104
|
+
var nodes = document.querySelectorAll('[role="dialog"]');
|
|
1105
|
+
for (var i = 0; i < nodes.length; i++) {
|
|
1106
|
+
var n = nodes[i];
|
|
1107
|
+
if (n.querySelector("#search-input") && n.getBoundingClientRect().width > 0) return n;
|
|
1108
|
+
}
|
|
1109
|
+
return null;
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
function ensureToggle() {
|
|
1113
|
+
var modal = findModal();
|
|
1114
|
+
if (!modal || modal.querySelector(".ym-search-scope")) return;
|
|
1115
|
+
var input = modal.querySelector("#search-input");
|
|
1116
|
+
if (!input) return;
|
|
1117
|
+
var holder = input.closest("div");
|
|
1118
|
+
if (!holder || !holder.parentElement) return;
|
|
1119
|
+
var row = holder.parentElement;
|
|
1120
|
+
var label = document.createElement("label");
|
|
1121
|
+
label.className = "ym-search-scope";
|
|
1122
|
+
label.title = "全局:从根目录递归搜索全部存储;当前目录:仅搜索所在文件夹及其子目录";
|
|
1123
|
+
var cb = document.createElement("input");
|
|
1124
|
+
cb.type = "checkbox";
|
|
1125
|
+
cb.checked = isGlobal();
|
|
1126
|
+
cb.addEventListener("change", function () { setGlobal(cb.checked); });
|
|
1127
|
+
label.appendChild(cb);
|
|
1128
|
+
label.appendChild(document.createTextNode("全局"));
|
|
1129
|
+
row.appendChild(label);
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
function boot() {
|
|
1133
|
+
injectCss();
|
|
1134
|
+
installFetchPatch();
|
|
1135
|
+
installXhrPatch();
|
|
1136
|
+
new MutationObserver(function () {
|
|
1137
|
+
if (document.querySelector("#search-input")) ensureToggle();
|
|
1138
|
+
}).observe(document.body, { childList: true, subtree: true });
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1141
|
+
if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", boot);
|
|
1142
|
+
else boot();
|
|
1143
|
+
})();
|
|
1144
|
+
})();
|
|
958
1145
|
/* ===== music-player.js ===== */
|
|
959
1146
|
;(function(){
|
|
960
1147
|
/* =============================================================================
|
|
@@ -984,7 +1171,6 @@
|
|
|
984
1171
|
spotify: [
|
|
985
1172
|
{ id: "3bePpYfOLDwFtVVs6cqwyh", name: "Spotify 歌单" }
|
|
986
1173
|
],
|
|
987
|
-
metingApi: "https://yuuichi-music-api.hoshinoyuuichi.workers.dev/",
|
|
988
1174
|
defaultTab: "netease", // "netease" 或 "spotify"
|
|
989
1175
|
autoplay: false, // 网易云是否自动播放(多数浏览器会拦截,建议 false)
|
|
990
1176
|
fabHint: "音乐"
|
|
@@ -998,7 +1184,7 @@
|
|
|
998
1184
|
["netease", "spotify"].forEach(function (k) {
|
|
999
1185
|
if (Array.isArray(__ov[k])) MUSIC_CONFIG[k] = __ov[k];
|
|
1000
1186
|
});
|
|
1001
|
-
["
|
|
1187
|
+
["defaultTab", "fabHint"].forEach(function (k) {
|
|
1002
1188
|
if (typeof __ov[k] === "string" && __ov[k]) MUSIC_CONFIG[k] = __ov[k];
|
|
1003
1189
|
});
|
|
1004
1190
|
if (typeof __ov.autoplay === "boolean") MUSIC_CONFIG.autoplay = __ov.autoplay;
|
|
@@ -1041,8 +1227,9 @@
|
|
|
1041
1227
|
".fab { position:fixed; left:18px; bottom:18px; width:54px; height:54px; border-radius:50%;",
|
|
1042
1228
|
" border:none; cursor:pointer; color:#fff; display:flex; align-items:center; justify-content:center;",
|
|
1043
1229
|
" background:linear-gradient(135deg,#38bdf8,#0284c7); box-shadow:0 8px 24px rgba(2,132,199,.45);",
|
|
1044
|
-
" transition:transform .
|
|
1045
|
-
".
|
|
1230
|
+
" transform:translateX(-58%); transition:transform .22s cubic-bezier(.2,.8,.2,1), box-shadow .18s ease; padding:0; }",
|
|
1231
|
+
".wrap:hover .fab, .fab:focus-visible, .fab.peek { transform:translateX(0); }",
|
|
1232
|
+
".fab:hover { box-shadow:0 12px 30px rgba(2,132,199,.55); }",
|
|
1046
1233
|
".fab:active { transform:scale(.94); }",
|
|
1047
1234
|
".fab svg { width:26px; height:26px; }",
|
|
1048
1235
|
".panel { position:fixed; left:18px; bottom:84px; width:360px; height:560px; max-width:calc(100vw - 24px);",
|
|
@@ -1421,10 +1608,26 @@
|
|
|
1421
1608
|
}
|
|
1422
1609
|
function close() {
|
|
1423
1610
|
panel.classList.remove("open");
|
|
1611
|
+
fab.classList.remove("peek");
|
|
1424
1612
|
state.ready.netease = false;
|
|
1425
1613
|
try { localStorage.setItem("ym-open", "0"); } catch (e) {}
|
|
1426
1614
|
}
|
|
1427
|
-
fab.addEventListener("click", function () {
|
|
1615
|
+
fab.addEventListener("click", function (ev) {
|
|
1616
|
+
// 第一次点击在半露出吸附态时只负责全露出,不立刻打开面板;再次点击才打开。
|
|
1617
|
+
if (!panel.classList.contains("open") && !fab.classList.contains("peek")) {
|
|
1618
|
+
fab.classList.add("peek");
|
|
1619
|
+
ev.stopPropagation();
|
|
1620
|
+
return;
|
|
1621
|
+
}
|
|
1622
|
+
fab.classList.remove("peek");
|
|
1623
|
+
panel.classList.contains("open") ? close() : open();
|
|
1624
|
+
});
|
|
1625
|
+
// 触屏没有 hover:点 FAB 之外恢复半露出;面板打开时不收起,避免遮挡交互。
|
|
1626
|
+
document.addEventListener("pointerdown", function (ev) {
|
|
1627
|
+
if (panel.classList.contains("open")) return;
|
|
1628
|
+
if (wrap.contains(ev.target)) return;
|
|
1629
|
+
fab.classList.remove("peek");
|
|
1630
|
+
}, true);
|
|
1428
1631
|
|
|
1429
1632
|
/* 记忆位置/尺寸/上次标签 */
|
|
1430
1633
|
try {
|