vitepress-plugin-filelist 0.5.1 → 0.6.0
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/README.md +18 -1
- package/dist/client/browser/index.d.ts +39 -0
- package/dist/client/browser/index.js +511 -165
- package/dist/client/ssr/index.d.ts +39 -0
- package/dist/client/ssr/index.js +351 -96
- package/dist/client/style.css +153 -0
- package/package.json +2 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "../style.css";
|
|
2
|
-
import { Fragment, computed, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, nextTick, normalizeClass, normalizeStyle, onBeforeUnmount, onMounted, openBlock, ref, renderList, toDisplayString, unref, useId, vModelSelect, vModelText, watch, withDirectives, withKeys, withModifiers } from "vue";
|
|
2
|
+
import { Fragment, computed, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, nextTick, normalizeClass, normalizeStyle, onBeforeUnmount, onMounted, openBlock, reactive, ref, renderList, toDisplayString, unref, useId, vModelSelect, vModelText, watch, withDirectives, withKeys, withModifiers } from "vue";
|
|
3
3
|
// src/client/utils.ts
|
|
4
4
|
function joinPath(parent, name) {
|
|
5
5
|
return (parent.endsWith("/") ? parent : `${parent}/`) + name;
|
|
@@ -520,6 +520,79 @@ function createDemoApi(delay = 220) {
|
|
|
520
520
|
clearCache: () => {}
|
|
521
521
|
};
|
|
522
522
|
}
|
|
523
|
+
// src/client/ConfirmDialog.vue
|
|
524
|
+
const _hoisted_1$3 = ["aria-label"];
|
|
525
|
+
const _hoisted_2$3 = {
|
|
526
|
+
key: 0,
|
|
527
|
+
class: "fl-confirm-panel"
|
|
528
|
+
};
|
|
529
|
+
const _hoisted_3$2 = { class: "fl-confirm-title" };
|
|
530
|
+
const _hoisted_4$2 = { class: "fl-confirm-text" };
|
|
531
|
+
const _hoisted_5$2 = {
|
|
532
|
+
key: 0,
|
|
533
|
+
class: "fl-confirm-text"
|
|
534
|
+
};
|
|
535
|
+
const _hoisted_6$2 = { class: "fl-confirm-actions" };
|
|
536
|
+
const _sfc_main$3 = /*@__PURE__*/ defineComponent({
|
|
537
|
+
__name: "ConfirmDialog",
|
|
538
|
+
props: {
|
|
539
|
+
open: { type: Boolean },
|
|
540
|
+
title: {},
|
|
541
|
+
text: {},
|
|
542
|
+
tip: {},
|
|
543
|
+
confirmLabel: {},
|
|
544
|
+
cancelLabel: {}
|
|
545
|
+
},
|
|
546
|
+
emits: ["confirm", "close"],
|
|
547
|
+
setup(__props, { emit: __emit }) {
|
|
548
|
+
/** Small native <dialog> for a yes / no question or a notice (bottom sheet on phones). */
|
|
549
|
+
const props = __props;
|
|
550
|
+
const emit = __emit;
|
|
551
|
+
const dialog = ref();
|
|
552
|
+
watch(() => props.open, (open) => {
|
|
553
|
+
const el = dialog.value;
|
|
554
|
+
if (!el) return;
|
|
555
|
+
if (open && !el.open) {
|
|
556
|
+
if (typeof el.showModal === "function") el.showModal();
|
|
557
|
+
else el.setAttribute("open", "");
|
|
558
|
+
} else if (!open && el.open) {
|
|
559
|
+
if (typeof el.close === "function") el.close();
|
|
560
|
+
else el.removeAttribute("open");
|
|
561
|
+
}
|
|
562
|
+
}, { flush: "post" });
|
|
563
|
+
function onNativeClose() {
|
|
564
|
+
if (props.open) emit("close");
|
|
565
|
+
}
|
|
566
|
+
function onBackdrop(event) {
|
|
567
|
+
if (event.target === dialog.value) emit("close");
|
|
568
|
+
}
|
|
569
|
+
return (_ctx, _cache) => {
|
|
570
|
+
return openBlock(), createElementBlock("dialog", {
|
|
571
|
+
ref_key: "dialog",
|
|
572
|
+
ref: dialog,
|
|
573
|
+
class: "fl-confirm",
|
|
574
|
+
"aria-label": __props.title,
|
|
575
|
+
onClose: onNativeClose,
|
|
576
|
+
onClick: onBackdrop
|
|
577
|
+
}, [__props.open ? (openBlock(), createElementBlock("div", _hoisted_2$3, [
|
|
578
|
+
createElementVNode("p", _hoisted_3$2, toDisplayString(__props.title), 1),
|
|
579
|
+
createElementVNode("p", _hoisted_4$2, toDisplayString(__props.text), 1),
|
|
580
|
+
__props.tip ? (openBlock(), createElementBlock("p", _hoisted_5$2, toDisplayString(__props.tip), 1)) : createCommentVNode("v-if", true),
|
|
581
|
+
createElementVNode("div", _hoisted_6$2, [__props.confirmLabel ? (openBlock(), createElementBlock("button", {
|
|
582
|
+
key: 0,
|
|
583
|
+
class: "fl-btn",
|
|
584
|
+
type: "button",
|
|
585
|
+
onClick: _cache[0] || (_cache[0] = ($event) => emit("close"))
|
|
586
|
+
}, toDisplayString(__props.cancelLabel), 1)) : createCommentVNode("v-if", true), createElementVNode("button", {
|
|
587
|
+
class: "fl-btn fl-btn-primary",
|
|
588
|
+
type: "button",
|
|
589
|
+
autofocus: "",
|
|
590
|
+
onClick: _cache[1] || (_cache[1] = ($event) => __props.confirmLabel ? emit("confirm") : emit("close"))
|
|
591
|
+
}, toDisplayString(__props.confirmLabel || __props.cancelLabel), 1)])
|
|
592
|
+
])) : createCommentVNode("v-if", true)], 40, _hoisted_1$3);
|
|
593
|
+
};
|
|
594
|
+
}
|
|
595
|
+
});
|
|
523
596
|
// src/client/download.ts
|
|
524
597
|
/** Open a file URL; OpenList serves `/p/` and `/d/` as attachments, so this downloads. */
|
|
525
598
|
function openUrl(url) {
|
|
@@ -545,32 +618,93 @@ function saveBlob(blob, name) {
|
|
|
545
618
|
function zipFileName(title) {
|
|
546
619
|
return `${title.replace(/[\\/:*?"<>|]/g, "_")}.zip`;
|
|
547
620
|
}
|
|
621
|
+
/** Whether the browser can write a ZIP straight into a file the user picks (Chromium). */
|
|
622
|
+
function canStreamToDisk() {
|
|
623
|
+
return typeof window !== "undefined" && window.isSecureContext && "showSaveFilePicker" in window;
|
|
624
|
+
}
|
|
548
625
|
/**
|
|
549
|
-
*
|
|
550
|
-
*
|
|
551
|
-
* fetching; packing is the rest.
|
|
626
|
+
* Ask where to save the ZIP. Call it straight from the click, before any other
|
|
627
|
+
* `await`, or the browser refuses. Resolves `null` when the user cancels.
|
|
552
628
|
*/
|
|
553
|
-
async function
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
629
|
+
async function pickZipFile(name) {
|
|
630
|
+
try {
|
|
631
|
+
return await window.showSaveFilePicker({
|
|
632
|
+
suggestedName: name,
|
|
633
|
+
types: [{
|
|
634
|
+
description: "ZIP",
|
|
635
|
+
accept: { "application/zip": [".zip"] }
|
|
636
|
+
}]
|
|
637
|
+
});
|
|
638
|
+
} catch (error) {
|
|
639
|
+
if (error instanceof DOMException && error.name === "AbortError") return null;
|
|
640
|
+
throw error;
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
/**
|
|
644
|
+
* The ZIP as a stream: files are fetched one after another and passed through
|
|
645
|
+
* as they arrive, stored without compression (most shared files are already
|
|
646
|
+
* compressed). Clashing entry names get ` (2)`, ` (3)`...
|
|
647
|
+
*/
|
|
648
|
+
async function zipStream(files, options) {
|
|
649
|
+
const { makeZip } = await import("client-zip");
|
|
650
|
+
const progress = {
|
|
651
|
+
bytes: 0,
|
|
652
|
+
totalBytes: files.reduce((sum, file) => sum + (Number.isFinite(file.size) ? file.size : 0), 0),
|
|
653
|
+
files: 0,
|
|
654
|
+
totalFiles: files.length
|
|
566
655
|
};
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
656
|
+
const report = () => options.onProgress({ ...progress });
|
|
657
|
+
report();
|
|
658
|
+
async function* entries() {
|
|
659
|
+
const used = /* @__PURE__ */ new Set();
|
|
660
|
+
for (const file of files) {
|
|
661
|
+
const response = await fetch(await options.urlOf(file), { signal: options.signal });
|
|
662
|
+
if (!response.ok || !response.body) throw new Error(`${file.name}:HTTP ${response.status}`);
|
|
663
|
+
const counted = response.body.pipeThrough(new TransformStream({
|
|
664
|
+
transform(chunk, controller) {
|
|
665
|
+
progress.bytes += chunk.byteLength;
|
|
666
|
+
report();
|
|
667
|
+
controller.enqueue(chunk);
|
|
668
|
+
},
|
|
669
|
+
flush() {
|
|
670
|
+
progress.files += 1;
|
|
671
|
+
report();
|
|
672
|
+
}
|
|
673
|
+
}));
|
|
674
|
+
const modified = new Date(file.modified);
|
|
675
|
+
yield {
|
|
676
|
+
name: uniqueEntryName(zipEntryName(file.zipPath), used),
|
|
677
|
+
lastModified: Number.isNaN(modified.getTime()) ? void 0 : modified,
|
|
678
|
+
input: counted
|
|
679
|
+
};
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
return makeZip(entries());
|
|
683
|
+
}
|
|
684
|
+
/** Stream the ZIP into a picked file; memory use stays small whatever the size. */
|
|
685
|
+
async function zipToFile(handle, files, options) {
|
|
686
|
+
const stream = await zipStream(files, options);
|
|
687
|
+
const writable = await handle.createWritable();
|
|
688
|
+
await stream.pipeTo(writable, { signal: options.signal });
|
|
689
|
+
}
|
|
690
|
+
/** Build the ZIP in memory (browsers without file streaming). */
|
|
691
|
+
async function zipToBlob(files, options) {
|
|
692
|
+
const reader = (await zipStream(files, options)).getReader();
|
|
693
|
+
const chunks = [];
|
|
694
|
+
const abort = () => void reader.cancel(options.signal.reason).catch(() => {});
|
|
695
|
+
options.signal.addEventListener("abort", abort, { once: true });
|
|
696
|
+
if (options.signal.aborted) abort();
|
|
697
|
+
try {
|
|
698
|
+
for (;;) {
|
|
699
|
+
const { done, value } = await reader.read();
|
|
700
|
+
if (done) break;
|
|
701
|
+
chunks.push(value);
|
|
702
|
+
}
|
|
703
|
+
} finally {
|
|
704
|
+
options.signal.removeEventListener("abort", abort);
|
|
705
|
+
}
|
|
706
|
+
options.signal.throwIfAborted();
|
|
707
|
+
return new Blob(chunks, { type: "application/zip" });
|
|
574
708
|
}
|
|
575
709
|
// src/client/icons.ts
|
|
576
710
|
/** Stroke icons on a 24×24 grid, drawn by `Icon.vue`. */
|
|
@@ -733,7 +867,21 @@ const fileListLocales = {
|
|
|
733
867
|
remembered: "已记住",
|
|
734
868
|
forgetPassword: "忘记",
|
|
735
869
|
unlockFolder: "输入 {name} 的密码",
|
|
736
|
-
networkHint: "可能被跨域拦截:请检查 OpenList 的 cors.allow_origins,或 OpenList-Worker 的 ALLOW_URLS。"
|
|
870
|
+
networkHint: "可能被跨域拦截:请检查 OpenList 的 cors.allow_origins,或 OpenList-Worker 的 ALLOW_URLS。",
|
|
871
|
+
batchProgress: "{done} / {total} · {files} / {count} 个文件",
|
|
872
|
+
batchDone: "已打包 {name}({count} 个文件,{size})",
|
|
873
|
+
batchCanceled: "已取消下载",
|
|
874
|
+
zipWarnTitle: "文件较大({size})",
|
|
875
|
+
zipWarnText: "当前浏览器要先把文件全部放进内存再打包,超过 {limit} 可能失败或让页面崩溃。建议分批下载。",
|
|
876
|
+
zipStreamTip: "在 Chrome 或 Edge 中可以边下载边保存,不受大小限制。",
|
|
877
|
+
zipContinue: "仍然下载",
|
|
878
|
+
zipBlockTitle: "无法打包 {size}",
|
|
879
|
+
zipBlockText: "当前浏览器一次最多打包 {limit},请分批勾选下载。",
|
|
880
|
+
gotIt: "知道了",
|
|
881
|
+
moreRemaining: "还有 {count} 项",
|
|
882
|
+
showMore: "显示更多",
|
|
883
|
+
showAll: "全部显示",
|
|
884
|
+
showRest: "显示剩余 {count} 项"
|
|
737
885
|
},
|
|
738
886
|
"en-US": {
|
|
739
887
|
allFiles: "All files",
|
|
@@ -796,7 +944,21 @@ const fileListLocales = {
|
|
|
796
944
|
remembered: "Remembered",
|
|
797
945
|
forgetPassword: "Forget",
|
|
798
946
|
unlockFolder: "Enter the password for {name}",
|
|
799
|
-
networkHint: "Possibly blocked by CORS: check cors.allow_origins in OpenList, or ALLOW_URLS in OpenList-Worker."
|
|
947
|
+
networkHint: "Possibly blocked by CORS: check cors.allow_origins in OpenList, or ALLOW_URLS in OpenList-Worker.",
|
|
948
|
+
batchProgress: "{done} / {total} · {files} / {count} files",
|
|
949
|
+
batchDone: "Saved {name} ({count} files, {size})",
|
|
950
|
+
batchCanceled: "Download cancelled",
|
|
951
|
+
zipWarnTitle: "Large download ({size})",
|
|
952
|
+
zipWarnText: "This browser has to hold every file in memory to build the ZIP. Above {limit} it may fail or crash the page. Consider downloading in smaller batches.",
|
|
953
|
+
zipStreamTip: "Chrome and Edge save while downloading, with no size limit.",
|
|
954
|
+
zipContinue: "Download anyway",
|
|
955
|
+
zipBlockTitle: "Cannot zip {size}",
|
|
956
|
+
zipBlockText: "This browser can zip at most {limit} at once. Select fewer files.",
|
|
957
|
+
gotIt: "OK",
|
|
958
|
+
moreRemaining: "{count} more",
|
|
959
|
+
showMore: "Show more",
|
|
960
|
+
showAll: "Show all",
|
|
961
|
+
showRest: "Show the remaining {count}"
|
|
800
962
|
}
|
|
801
963
|
};
|
|
802
964
|
function formatLabel(template, values = {}) {
|
|
@@ -1392,113 +1554,129 @@ const _hoisted_3 = {
|
|
|
1392
1554
|
role: "status"
|
|
1393
1555
|
};
|
|
1394
1556
|
const _hoisted_4 = { class: "fl-selection-count" };
|
|
1395
|
-
const _hoisted_5 = {
|
|
1557
|
+
const _hoisted_5 = {
|
|
1558
|
+
key: 0,
|
|
1559
|
+
class: "fl-selection-size"
|
|
1560
|
+
};
|
|
1396
1561
|
const _hoisted_6 = {
|
|
1397
1562
|
key: 1,
|
|
1563
|
+
class: "fl-selection",
|
|
1564
|
+
role: "status"
|
|
1565
|
+
};
|
|
1566
|
+
const _hoisted_7 = { class: "fl-selection-count" };
|
|
1567
|
+
const _hoisted_8 = { class: "fl-selection-size" };
|
|
1568
|
+
const _hoisted_9 = {
|
|
1569
|
+
key: 2,
|
|
1398
1570
|
class: "fl-title"
|
|
1399
1571
|
};
|
|
1400
|
-
const
|
|
1401
|
-
const
|
|
1572
|
+
const _hoisted_10 = { class: "fl-title-text" };
|
|
1573
|
+
const _hoisted_11 = {
|
|
1402
1574
|
key: 0,
|
|
1403
1575
|
class: "fl-demo-badge"
|
|
1404
1576
|
};
|
|
1405
|
-
const
|
|
1406
|
-
const
|
|
1407
|
-
const
|
|
1408
|
-
const
|
|
1409
|
-
const
|
|
1410
|
-
const
|
|
1577
|
+
const _hoisted_12 = ["aria-label", "title"];
|
|
1578
|
+
const _hoisted_13 = { class: "fl-clear-text" };
|
|
1579
|
+
const _hoisted_14 = { class: "fl-tools" };
|
|
1580
|
+
const _hoisted_15 = { class: "fl-search" };
|
|
1581
|
+
const _hoisted_16 = ["placeholder", "aria-label"];
|
|
1582
|
+
const _hoisted_17 = [
|
|
1411
1583
|
"disabled",
|
|
1412
1584
|
"aria-label",
|
|
1413
1585
|
"title"
|
|
1414
1586
|
];
|
|
1415
|
-
const
|
|
1416
|
-
const
|
|
1417
|
-
const _hoisted_17 = {
|
|
1587
|
+
const _hoisted_18 = { class: "fl-row fl-head" };
|
|
1588
|
+
const _hoisted_19 = {
|
|
1418
1589
|
key: 0,
|
|
1419
1590
|
class: "fl-progress",
|
|
1420
1591
|
"aria-hidden": "true"
|
|
1421
1592
|
};
|
|
1422
|
-
const
|
|
1423
|
-
const
|
|
1593
|
+
const _hoisted_20 = { class: "fl-cell fl-cell-check" };
|
|
1594
|
+
const _hoisted_21 = [
|
|
1424
1595
|
"aria-label",
|
|
1596
|
+
"disabled",
|
|
1425
1597
|
"checked",
|
|
1426
1598
|
".indeterminate"
|
|
1427
1599
|
];
|
|
1428
|
-
const
|
|
1429
|
-
const
|
|
1600
|
+
const _hoisted_22 = ["aria-sort", "onClick"];
|
|
1601
|
+
const _hoisted_23 = {
|
|
1430
1602
|
class: "fl-sort",
|
|
1431
1603
|
"aria-hidden": "true"
|
|
1432
1604
|
};
|
|
1433
|
-
const
|
|
1434
|
-
const
|
|
1435
|
-
const
|
|
1605
|
+
const _hoisted_24 = { class: "fl-cell fl-cell-op" };
|
|
1606
|
+
const _hoisted_25 = { class: "fl-sort-select" };
|
|
1607
|
+
const _hoisted_26 = {
|
|
1436
1608
|
class: "fl-sort-current",
|
|
1437
1609
|
"aria-hidden": "true"
|
|
1438
1610
|
};
|
|
1439
|
-
const
|
|
1440
|
-
const
|
|
1441
|
-
const
|
|
1611
|
+
const _hoisted_27 = ["aria-label"];
|
|
1612
|
+
const _hoisted_28 = ["value"];
|
|
1613
|
+
const _hoisted_29 = {
|
|
1442
1614
|
key: 0,
|
|
1443
1615
|
class: "fl-status"
|
|
1444
1616
|
};
|
|
1445
|
-
const
|
|
1446
|
-
const
|
|
1447
|
-
const
|
|
1448
|
-
const
|
|
1617
|
+
const _hoisted_30 = ["for"];
|
|
1618
|
+
const _hoisted_31 = ["id"];
|
|
1619
|
+
const _hoisted_32 = { class: "fl-unlock" };
|
|
1620
|
+
const _hoisted_33 = [
|
|
1449
1621
|
"id",
|
|
1450
1622
|
"data-unlock",
|
|
1451
1623
|
"placeholder",
|
|
1452
1624
|
"aria-invalid",
|
|
1453
1625
|
"aria-describedby"
|
|
1454
1626
|
];
|
|
1455
|
-
const
|
|
1627
|
+
const _hoisted_34 = [
|
|
1456
1628
|
"aria-pressed",
|
|
1457
1629
|
"aria-label",
|
|
1458
1630
|
"title"
|
|
1459
1631
|
];
|
|
1460
|
-
const
|
|
1461
|
-
const
|
|
1632
|
+
const _hoisted_35 = ["disabled"];
|
|
1633
|
+
const _hoisted_36 = {
|
|
1462
1634
|
key: 2,
|
|
1463
1635
|
class: "fl-status fl-error"
|
|
1464
1636
|
};
|
|
1465
|
-
const
|
|
1637
|
+
const _hoisted_37 = {
|
|
1466
1638
|
key: 0,
|
|
1467
1639
|
class: "fl-hint"
|
|
1468
1640
|
};
|
|
1469
|
-
const
|
|
1641
|
+
const _hoisted_38 = {
|
|
1470
1642
|
key: 1,
|
|
1471
1643
|
class: "fl-hint"
|
|
1472
1644
|
};
|
|
1473
|
-
const
|
|
1645
|
+
const _hoisted_39 = {
|
|
1474
1646
|
key: 3,
|
|
1475
1647
|
class: "fl-status"
|
|
1476
1648
|
};
|
|
1477
|
-
const
|
|
1478
|
-
const
|
|
1649
|
+
const _hoisted_40 = { class: "fl-cell fl-more-cell" };
|
|
1650
|
+
const _hoisted_41 = { class: "fl-more-count" };
|
|
1651
|
+
const _hoisted_42 = ["onClick"];
|
|
1652
|
+
const _hoisted_43 = { class: "fl-more-page" };
|
|
1653
|
+
const _hoisted_44 = ["onClick"];
|
|
1654
|
+
const _hoisted_45 = ["onClick"];
|
|
1655
|
+
const _hoisted_46 = { class: "fl-cell fl-cell-check" };
|
|
1656
|
+
const _hoisted_47 = [
|
|
1479
1657
|
"disabled",
|
|
1480
1658
|
"aria-label",
|
|
1481
1659
|
"checked",
|
|
1482
1660
|
".indeterminate",
|
|
1483
1661
|
"onChange"
|
|
1484
1662
|
];
|
|
1485
|
-
const
|
|
1486
|
-
const
|
|
1663
|
+
const _hoisted_48 = ["title"];
|
|
1664
|
+
const _hoisted_49 = [
|
|
1487
1665
|
"aria-label",
|
|
1488
1666
|
"title",
|
|
1489
1667
|
"onClick"
|
|
1490
1668
|
];
|
|
1491
|
-
const
|
|
1669
|
+
const _hoisted_50 = [
|
|
1492
1670
|
"aria-label",
|
|
1493
1671
|
"aria-expanded",
|
|
1494
1672
|
"onClick"
|
|
1495
1673
|
];
|
|
1496
|
-
const
|
|
1674
|
+
const _hoisted_51 = {
|
|
1497
1675
|
key: 2,
|
|
1498
1676
|
class: "fl-arrow-placeholder",
|
|
1499
1677
|
"aria-hidden": "true"
|
|
1500
1678
|
};
|
|
1501
|
-
const
|
|
1679
|
+
const _hoisted_52 = {
|
|
1502
1680
|
key: 3,
|
|
1503
1681
|
class: "fl-folder-icon",
|
|
1504
1682
|
viewBox: "0 0 24 24",
|
|
@@ -1506,27 +1684,27 @@ const _hoisted_44 = {
|
|
|
1506
1684
|
height: "18",
|
|
1507
1685
|
"aria-hidden": "true"
|
|
1508
1686
|
};
|
|
1509
|
-
const
|
|
1510
|
-
const
|
|
1511
|
-
const
|
|
1512
|
-
const
|
|
1513
|
-
const
|
|
1687
|
+
const _hoisted_53 = ["data-kind"];
|
|
1688
|
+
const _hoisted_54 = { class: "fl-label" };
|
|
1689
|
+
const _hoisted_55 = ["onClick"];
|
|
1690
|
+
const _hoisted_56 = { class: "fl-meta" };
|
|
1691
|
+
const _hoisted_57 = {
|
|
1514
1692
|
key: 5,
|
|
1515
1693
|
class: "fl-count"
|
|
1516
1694
|
};
|
|
1517
|
-
const
|
|
1518
|
-
const
|
|
1695
|
+
const _hoisted_58 = ["id"];
|
|
1696
|
+
const _hoisted_59 = [
|
|
1519
1697
|
"aria-label",
|
|
1520
1698
|
"title",
|
|
1521
1699
|
"onClick"
|
|
1522
1700
|
];
|
|
1523
|
-
const
|
|
1701
|
+
const _hoisted_60 = {
|
|
1524
1702
|
key: 8,
|
|
1525
1703
|
class: "fl-loading",
|
|
1526
1704
|
"aria-hidden": "true"
|
|
1527
1705
|
};
|
|
1528
|
-
const
|
|
1529
|
-
const
|
|
1706
|
+
const _hoisted_61 = ["onSubmit", "onKeydown"];
|
|
1707
|
+
const _hoisted_62 = [
|
|
1530
1708
|
"onUpdate:modelValue",
|
|
1531
1709
|
"data-unlock",
|
|
1532
1710
|
"placeholder",
|
|
@@ -1534,43 +1712,45 @@ const _hoisted_54 = [
|
|
|
1534
1712
|
"aria-invalid",
|
|
1535
1713
|
"aria-describedby"
|
|
1536
1714
|
];
|
|
1537
|
-
const
|
|
1715
|
+
const _hoisted_63 = [
|
|
1538
1716
|
"aria-pressed",
|
|
1539
1717
|
"aria-label",
|
|
1540
1718
|
"title",
|
|
1541
1719
|
"onClick"
|
|
1542
1720
|
];
|
|
1543
|
-
const
|
|
1544
|
-
const
|
|
1721
|
+
const _hoisted_64 = ["disabled"];
|
|
1722
|
+
const _hoisted_65 = [
|
|
1545
1723
|
"aria-label",
|
|
1546
1724
|
"title",
|
|
1547
1725
|
"onClick"
|
|
1548
1726
|
];
|
|
1549
|
-
const
|
|
1550
|
-
const
|
|
1551
|
-
const
|
|
1552
|
-
const
|
|
1553
|
-
const
|
|
1727
|
+
const _hoisted_66 = { class: "fl-cell fl-cell-size" };
|
|
1728
|
+
const _hoisted_67 = { class: "fl-cell fl-cell-date" };
|
|
1729
|
+
const _hoisted_68 = { class: "fl-cell fl-cell-op" };
|
|
1730
|
+
const _hoisted_69 = ["aria-label", "onClick"];
|
|
1731
|
+
const _hoisted_70 = [
|
|
1554
1732
|
"aria-label",
|
|
1555
1733
|
"aria-expanded",
|
|
1556
1734
|
"onClick"
|
|
1557
1735
|
];
|
|
1558
|
-
const
|
|
1736
|
+
const _hoisted_71 = [
|
|
1559
1737
|
"aria-label",
|
|
1560
1738
|
"title",
|
|
1561
1739
|
"onClick"
|
|
1562
1740
|
];
|
|
1563
|
-
const
|
|
1741
|
+
const _hoisted_72 = [
|
|
1564
1742
|
"aria-label",
|
|
1565
1743
|
"title",
|
|
1566
1744
|
"onClick"
|
|
1567
1745
|
];
|
|
1568
|
-
const
|
|
1569
|
-
const
|
|
1746
|
+
const _hoisted_73 = { class: "fl-foot" };
|
|
1747
|
+
const _hoisted_74 = {
|
|
1570
1748
|
key: 4,
|
|
1571
1749
|
class: "fl-toast",
|
|
1572
1750
|
role: "status"
|
|
1573
1751
|
};
|
|
1752
|
+
/** Rows shown per folder, beyond the first page; kept across refreshes. */
|
|
1753
|
+
const MB = 1048576;
|
|
1574
1754
|
const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
1575
1755
|
__name: "FileList",
|
|
1576
1756
|
props: {
|
|
@@ -1588,6 +1768,9 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
1588
1768
|
type: Boolean,
|
|
1589
1769
|
default: true
|
|
1590
1770
|
},
|
|
1771
|
+
pageSize: { default: 200 },
|
|
1772
|
+
zipWarnSize: {},
|
|
1773
|
+
zipMaxSize: {},
|
|
1591
1774
|
locale: { default: "zh-CN" },
|
|
1592
1775
|
labels: {}
|
|
1593
1776
|
},
|
|
@@ -1630,7 +1813,8 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
1630
1813
|
const siteTitle = ref("");
|
|
1631
1814
|
const iframePreviews = ref("");
|
|
1632
1815
|
const batchBusy = ref(false);
|
|
1633
|
-
const
|
|
1816
|
+
const zipProgress = ref(null);
|
|
1817
|
+
let zipAbort = null;
|
|
1634
1818
|
let toastTimer;
|
|
1635
1819
|
/** The folder listed in single-path mode, as the parent of the top rows. */
|
|
1636
1820
|
const listedFolder = computed(() => ({
|
|
@@ -1863,6 +2047,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
1863
2047
|
errorMsg.value = "";
|
|
1864
2048
|
try {
|
|
1865
2049
|
roots.value = await buildTree();
|
|
2050
|
+
shown.clear();
|
|
1866
2051
|
rootLock.value = null;
|
|
1867
2052
|
selected.value = /* @__PURE__ */ new Set();
|
|
1868
2053
|
api.value.clearCache();
|
|
@@ -1943,20 +2128,41 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
1943
2128
|
applySort(key, direction !== "desc");
|
|
1944
2129
|
}
|
|
1945
2130
|
});
|
|
1946
|
-
|
|
2131
|
+
/** A “show more” row closing a folder whose children are cut at `pageSize`. */
|
|
2132
|
+
const shown = reactive(/* @__PURE__ */ new Map());
|
|
2133
|
+
function limitOf(key) {
|
|
2134
|
+
const size = Math.max(0, Math.floor(props.pageSize ?? 200));
|
|
2135
|
+
return size ? shown.get(key) ?? size : Number.POSITIVE_INFINITY;
|
|
2136
|
+
}
|
|
2137
|
+
function showMore(row, all) {
|
|
2138
|
+
const size = Math.max(1, Math.floor(props.pageSize ?? 200));
|
|
2139
|
+
shown.set(row.key, all ? Number.POSITIVE_INFINITY : limitOf(row.key) + size);
|
|
2140
|
+
}
|
|
2141
|
+
function isMore(row) {
|
|
2142
|
+
return "more" in row;
|
|
2143
|
+
}
|
|
2144
|
+
const rows = computed(() => {
|
|
1947
2145
|
const out = [];
|
|
1948
2146
|
const query = keyword.value.trim().toLowerCase();
|
|
1949
2147
|
const matches = (node) => !query || node.name.toLowerCase().includes(query) || node.is_dir && node.children.some(matches);
|
|
1950
|
-
const walk = (nodes) => {
|
|
1951
|
-
|
|
1952
|
-
|
|
2148
|
+
const walk = (nodes, key, depth) => {
|
|
2149
|
+
const list = nodes.filter(matches);
|
|
2150
|
+
const limit = query ? list.length : Math.min(list.length, limitOf(key));
|
|
2151
|
+
for (const node of list.slice(0, limit)) {
|
|
1953
2152
|
out.push(node);
|
|
1954
|
-
if (node.is_dir && (node.expanded || query) && node.children.length) walk(node.children);
|
|
2153
|
+
if (node.is_dir && (node.expanded || query) && node.children.length) walk(node.children, node.path, node.depth + 1);
|
|
1955
2154
|
}
|
|
2155
|
+
if (limit < list.length) out.push({
|
|
2156
|
+
more: true,
|
|
2157
|
+
key,
|
|
2158
|
+
depth,
|
|
2159
|
+
remaining: list.length - limit
|
|
2160
|
+
});
|
|
1956
2161
|
};
|
|
1957
|
-
walk(roots.value);
|
|
2162
|
+
walk(roots.value, props.sources.length ? "" : props.path, 0);
|
|
1958
2163
|
return out;
|
|
1959
2164
|
});
|
|
2165
|
+
const visible = computed(() => rows.value.filter((row) => !isMore(row)));
|
|
1960
2166
|
const stats = computed(() => folderStats(roots.value, selected.value));
|
|
1961
2167
|
const noStats = {
|
|
1962
2168
|
files: 0,
|
|
@@ -2043,24 +2249,104 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
2043
2249
|
showToast(t("downloadFailed", { message: errorText(error) }));
|
|
2044
2250
|
}
|
|
2045
2251
|
}
|
|
2252
|
+
function zipLimits() {
|
|
2253
|
+
const touch = typeof window !== "undefined" && !!window.matchMedia?.("(pointer: coarse)").matches;
|
|
2254
|
+
const bytes = (value, fallback) => {
|
|
2255
|
+
const mb = value ?? fallback;
|
|
2256
|
+
return mb > 0 ? mb * MB : Number.POSITIVE_INFINITY;
|
|
2257
|
+
};
|
|
2258
|
+
return {
|
|
2259
|
+
warn: bytes(props.zipWarnSize, touch ? 200 : 500),
|
|
2260
|
+
max: bytes(props.zipMaxSize, touch ? 1024 : 2048)
|
|
2261
|
+
};
|
|
2262
|
+
}
|
|
2263
|
+
const zipNotice = ref(null);
|
|
2264
|
+
/** Only desktop browsers get “use Chrome or Edge”; on iPhone every browser is Safari. */
|
|
2265
|
+
const zipTip = computed(() => typeof window !== "undefined" && !window.matchMedia?.("(pointer: coarse)").matches ? t("zipStreamTip") : "");
|
|
2266
|
+
function zipName() {
|
|
2267
|
+
return zipFileName(props.title || t("defaultZip"));
|
|
2268
|
+
}
|
|
2269
|
+
/**
|
|
2270
|
+
* Chrome / Edge stream into a file the user picks (no size limit). Other
|
|
2271
|
+
* browsers build the ZIP in memory, so large selections ask first or are refused.
|
|
2272
|
+
*/
|
|
2046
2273
|
async function batchDownload() {
|
|
2047
2274
|
const files = selectedFiles.value;
|
|
2048
|
-
if (!files.length) return;
|
|
2275
|
+
if (!files.length || batchBusy.value) return;
|
|
2049
2276
|
if (demo.value) {
|
|
2050
2277
|
showToast(t("demoBatch", { count: files.length }));
|
|
2051
2278
|
return;
|
|
2052
2279
|
}
|
|
2280
|
+
if (canStreamToDisk()) {
|
|
2281
|
+
let handle;
|
|
2282
|
+
try {
|
|
2283
|
+
handle = await pickZipFile(zipName());
|
|
2284
|
+
} catch (error) {
|
|
2285
|
+
showToast(t("batchFailed", { message: errorText(error) }));
|
|
2286
|
+
return;
|
|
2287
|
+
}
|
|
2288
|
+
if (handle) await runZip(files, (options) => zipToFile(handle, files, options), handle.name);
|
|
2289
|
+
return;
|
|
2290
|
+
}
|
|
2291
|
+
const size = totalSize(files);
|
|
2292
|
+
const { warn, max } = zipLimits();
|
|
2293
|
+
if (size > max) zipNotice.value = {
|
|
2294
|
+
kind: "block",
|
|
2295
|
+
size,
|
|
2296
|
+
limit: max,
|
|
2297
|
+
files
|
|
2298
|
+
};
|
|
2299
|
+
else if (size > warn) zipNotice.value = {
|
|
2300
|
+
kind: "warn",
|
|
2301
|
+
size,
|
|
2302
|
+
limit: warn,
|
|
2303
|
+
files
|
|
2304
|
+
};
|
|
2305
|
+
else await zipInMemory(files);
|
|
2306
|
+
}
|
|
2307
|
+
async function zipInMemory(files) {
|
|
2308
|
+
const name = zipName();
|
|
2309
|
+
await runZip(files, async (options) => saveBlob(await zipToBlob(files, options), name), name);
|
|
2310
|
+
}
|
|
2311
|
+
function confirmZip() {
|
|
2312
|
+
const notice = zipNotice.value;
|
|
2313
|
+
zipNotice.value = null;
|
|
2314
|
+
if (notice?.kind === "warn") zipInMemory(notice.files);
|
|
2315
|
+
}
|
|
2316
|
+
async function runZip(files, run, name) {
|
|
2317
|
+
const controller = new AbortController();
|
|
2318
|
+
zipAbort = controller;
|
|
2053
2319
|
batchBusy.value = true;
|
|
2054
|
-
|
|
2320
|
+
zipProgress.value = null;
|
|
2055
2321
|
try {
|
|
2056
|
-
|
|
2322
|
+
await run({
|
|
2323
|
+
urlOf: fileUrlOf,
|
|
2324
|
+
signal: controller.signal,
|
|
2325
|
+
onProgress: (progress) => zipProgress.value = progress
|
|
2326
|
+
});
|
|
2327
|
+
showToast(t("batchDone", {
|
|
2328
|
+
name,
|
|
2329
|
+
count: files.length,
|
|
2330
|
+
size: formatSize(totalSize(files))
|
|
2331
|
+
}));
|
|
2057
2332
|
selected.value = /* @__PURE__ */ new Set();
|
|
2058
2333
|
} catch (error) {
|
|
2059
|
-
showToast(t("batchFailed", { message: errorText(error) }));
|
|
2334
|
+
showToast(controller.signal.aborted ? t("batchCanceled") : t("batchFailed", { message: errorText(error) }));
|
|
2060
2335
|
} finally {
|
|
2336
|
+
zipAbort = null;
|
|
2061
2337
|
batchBusy.value = false;
|
|
2338
|
+
zipProgress.value = null;
|
|
2062
2339
|
}
|
|
2063
2340
|
}
|
|
2341
|
+
function cancelZip() {
|
|
2342
|
+
zipAbort?.abort();
|
|
2343
|
+
}
|
|
2344
|
+
const zipPercent = computed(() => {
|
|
2345
|
+
const progress = zipProgress.value;
|
|
2346
|
+
if (!progress) return 0;
|
|
2347
|
+
const ratio = progress.totalBytes ? progress.bytes / progress.totalBytes : progress.totalFiles ? progress.files / progress.totalFiles : 0;
|
|
2348
|
+
return Math.min(100, Math.floor(ratio * 100));
|
|
2349
|
+
});
|
|
2064
2350
|
/** Only types the dialog can actually render get a preview button. */
|
|
2065
2351
|
function canPreview(node) {
|
|
2066
2352
|
return !node.is_dir && previewKind(node.name) !== "none";
|
|
@@ -2132,6 +2418,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
2132
2418
|
window.addEventListener("resize", measureStickyTop, { passive: true });
|
|
2133
2419
|
});
|
|
2134
2420
|
onBeforeUnmount(() => {
|
|
2421
|
+
zipAbort?.abort();
|
|
2135
2422
|
window.removeEventListener("resize", measureStickyTop);
|
|
2136
2423
|
clearTimeout(toastTimer);
|
|
2137
2424
|
});
|
|
@@ -2147,9 +2434,22 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
2147
2434
|
"aria-busy": refreshing.value || loadingRoot.value
|
|
2148
2435
|
}, [
|
|
2149
2436
|
createElementVNode("div", _hoisted_2, [
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2437
|
+
batchBusy.value ? (openBlock(), createElementBlock("div", _hoisted_3, [
|
|
2438
|
+
createElementVNode("span", _hoisted_4, toDisplayString(t("batching", { percent: zipPercent.value })), 1),
|
|
2439
|
+
zipProgress.value ? (openBlock(), createElementBlock("span", _hoisted_5, toDisplayString(t("batchProgress", {
|
|
2440
|
+
done: unref(formatSize)(zipProgress.value.bytes),
|
|
2441
|
+
total: unref(formatSize)(zipProgress.value.totalBytes),
|
|
2442
|
+
files: zipProgress.value.files,
|
|
2443
|
+
count: zipProgress.value.totalFiles
|
|
2444
|
+
})), 1)) : createCommentVNode("v-if", true),
|
|
2445
|
+
createElementVNode("span", {
|
|
2446
|
+
class: "fl-zip-bar",
|
|
2447
|
+
style: normalizeStyle({ width: `${zipPercent.value}%` }),
|
|
2448
|
+
"aria-hidden": "true"
|
|
2449
|
+
}, null, 4)
|
|
2450
|
+
])) : selected.value.size ? (openBlock(), createElementBlock("div", _hoisted_6, [createElementVNode("span", _hoisted_7, toDisplayString(t("selected", { count: selected.value.size })), 1), createElementVNode("span", _hoisted_8, toDisplayString(t("totalSize", { size: unref(formatSize)(unref(totalSize)(selectedFiles.value)) })), 1)])) : (openBlock(), createElementBlock("div", _hoisted_9, [createElementVNode("span", _hoisted_10, toDisplayString(displayTitle.value), 1), demo.value ? (openBlock(), createElementBlock("span", _hoisted_11, toDisplayString(t("demoBadge")), 1)) : createCommentVNode("v-if", true)])),
|
|
2451
|
+
selected.value.size && !batchBusy.value ? (openBlock(), createElementBlock("button", {
|
|
2452
|
+
key: 3,
|
|
2153
2453
|
class: "fl-clear",
|
|
2154
2454
|
type: "button",
|
|
2155
2455
|
"aria-label": t("clearSelection"),
|
|
@@ -2159,8 +2459,8 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
2159
2459
|
class: "fl-clear-icon",
|
|
2160
2460
|
name: "close",
|
|
2161
2461
|
size: 18
|
|
2162
|
-
}), createElementVNode("span",
|
|
2163
|
-
createElementVNode("div",
|
|
2462
|
+
}), createElementVNode("span", _hoisted_13, toDisplayString(t("clear")), 1)], 8, _hoisted_12)) : createCommentVNode("v-if", true),
|
|
2463
|
+
createElementVNode("div", _hoisted_14, [createElementVNode("label", _hoisted_15, [createVNode(_sfc_main$2, {
|
|
2164
2464
|
name: "search",
|
|
2165
2465
|
size: 15
|
|
2166
2466
|
}), withDirectives(createElementVNode("input", {
|
|
@@ -2168,7 +2468,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
2168
2468
|
type: "text",
|
|
2169
2469
|
placeholder: t("filter"),
|
|
2170
2470
|
"aria-label": t("filter")
|
|
2171
|
-
}, null, 8,
|
|
2471
|
+
}, null, 8, _hoisted_16), [[vModelText, keyword.value]])]), createElementVNode("button", {
|
|
2172
2472
|
class: normalizeClass(["fl-icon-btn fl-refresh", { "fl-spinning": refreshing.value }]),
|
|
2173
2473
|
type: "button",
|
|
2174
2474
|
disabled: refreshing.value || loadingRoot.value,
|
|
@@ -2178,27 +2478,32 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
2178
2478
|
}, [createVNode(_sfc_main$2, {
|
|
2179
2479
|
name: "refresh",
|
|
2180
2480
|
size: 15
|
|
2181
|
-
})], 10,
|
|
2182
|
-
|
|
2183
|
-
key:
|
|
2481
|
+
})], 10, _hoisted_17)]),
|
|
2482
|
+
batchBusy.value ? (openBlock(), createElementBlock("button", {
|
|
2483
|
+
key: 4,
|
|
2484
|
+
class: "fl-btn fl-zip-cancel",
|
|
2485
|
+
type: "button",
|
|
2486
|
+
onClick: cancelZip
|
|
2487
|
+
}, toDisplayString(t("cancel")), 1)) : selected.value.size ? (openBlock(), createElementBlock("button", {
|
|
2488
|
+
key: 5,
|
|
2184
2489
|
class: "fl-btn fl-btn-primary",
|
|
2185
2490
|
type: "button",
|
|
2186
|
-
disabled: batchBusy.value,
|
|
2187
2491
|
onClick: batchDownload
|
|
2188
2492
|
}, [createVNode(_sfc_main$2, {
|
|
2189
2493
|
name: "download",
|
|
2190
2494
|
size: 15
|
|
2191
|
-
}), createTextVNode(" " + toDisplayString(
|
|
2495
|
+
}), createTextVNode(" " + toDisplayString(t("batch")), 1)])) : createCommentVNode("v-if", true)
|
|
2192
2496
|
]),
|
|
2193
|
-
createElementVNode("div",
|
|
2194
|
-
refreshing.value ? (openBlock(), createElementBlock("span",
|
|
2195
|
-
createElementVNode("label",
|
|
2497
|
+
createElementVNode("div", _hoisted_18, [
|
|
2498
|
+
refreshing.value ? (openBlock(), createElementBlock("span", _hoisted_19)) : createCommentVNode("v-if", true),
|
|
2499
|
+
createElementVNode("label", _hoisted_20, [createElementVNode("input", {
|
|
2196
2500
|
type: "checkbox",
|
|
2197
2501
|
"aria-label": t("selectAll"),
|
|
2502
|
+
disabled: batchBusy.value,
|
|
2198
2503
|
checked: allChecked.value,
|
|
2199
2504
|
".indeterminate": someChecked.value,
|
|
2200
2505
|
onChange: toggleCheckAll
|
|
2201
|
-
}, null, 40,
|
|
2506
|
+
}, null, 40, _hoisted_21)]),
|
|
2202
2507
|
(openBlock(), createElementBlock(Fragment, null, renderList([
|
|
2203
2508
|
"name",
|
|
2204
2509
|
"size",
|
|
@@ -2212,11 +2517,11 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
2212
2517
|
type: "button",
|
|
2213
2518
|
"aria-sort": sortKey.value === column ? sortAsc.value ? "ascending" : "descending" : void 0,
|
|
2214
2519
|
onClick: ($event) => setSort(column)
|
|
2215
|
-
}, [createTextVNode(toDisplayString(t(column === "name" ? "columnName" : column === "size" ? "columnSize" : "columnDate")), 1), createElementVNode("span",
|
|
2520
|
+
}, [createTextVNode(toDisplayString(t(column === "name" ? "columnName" : column === "size" ? "columnSize" : "columnDate")), 1), createElementVNode("span", _hoisted_23, toDisplayString(sortKey.value === column ? sortAsc.value ? "▲" : "▼" : ""), 1)], 8, _hoisted_22)], 2);
|
|
2216
2521
|
}), 64)),
|
|
2217
|
-
createElementVNode("span",
|
|
2522
|
+
createElementVNode("span", _hoisted_24, [createElementVNode("label", _hoisted_25, [
|
|
2218
2523
|
createElementVNode("span", null, toDisplayString(t("sortBy")), 1),
|
|
2219
|
-
createElementVNode("span",
|
|
2524
|
+
createElementVNode("span", _hoisted_26, toDisplayString(sortOptions.value.find((option) => option.value === sortValue.value)?.label), 1),
|
|
2220
2525
|
withDirectives(createElementVNode("select", {
|
|
2221
2526
|
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => sortValue.value = $event),
|
|
2222
2527
|
"aria-label": t("sortBy")
|
|
@@ -2224,11 +2529,11 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
2224
2529
|
return openBlock(), createElementBlock("option", {
|
|
2225
2530
|
key: option.value,
|
|
2226
2531
|
value: option.value
|
|
2227
|
-
}, toDisplayString(option.label), 9,
|
|
2228
|
-
}), 128))], 8,
|
|
2532
|
+
}, toDisplayString(option.label), 9, _hoisted_28);
|
|
2533
|
+
}), 128))], 8, _hoisted_27), [[vModelSelect, sortValue.value]])
|
|
2229
2534
|
])])
|
|
2230
2535
|
]),
|
|
2231
|
-
loadingRoot.value ? (openBlock(), createElementBlock("div",
|
|
2536
|
+
loadingRoot.value ? (openBlock(), createElementBlock("div", _hoisted_29, toDisplayString(t("loading")), 1)) : rootLock.value ? (openBlock(), createElementBlock("form", {
|
|
2232
2537
|
key: 1,
|
|
2233
2538
|
class: normalizeClass(["fl-unlock-root", { "fl-unlock-error": rootLock.value.error }]),
|
|
2234
2539
|
onSubmit: withModifiers(submitRootUnlock, ["prevent"])
|
|
@@ -2240,14 +2545,14 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
2240
2545
|
createElementVNode("label", {
|
|
2241
2546
|
class: "fl-unlock-label",
|
|
2242
2547
|
for: `${unref(uid)}-root`
|
|
2243
|
-
}, toDisplayString(t("passwordPrompt")), 9,
|
|
2548
|
+
}, toDisplayString(t("passwordPrompt")), 9, _hoisted_30),
|
|
2244
2549
|
rootLock.value.error ? (openBlock(), createElementBlock("span", {
|
|
2245
2550
|
key: 0,
|
|
2246
2551
|
id: `${unref(uid)}-root-error`,
|
|
2247
2552
|
class: "fl-unlock-message",
|
|
2248
2553
|
role: "alert"
|
|
2249
|
-
}, toDisplayString(unlockErrorText(rootLock.value.error)), 9,
|
|
2250
|
-
createElementVNode("span",
|
|
2554
|
+
}, toDisplayString(unlockErrorText(rootLock.value.error)), 9, _hoisted_31)) : createCommentVNode("v-if", true),
|
|
2555
|
+
createElementVNode("span", _hoisted_32, [
|
|
2251
2556
|
withDirectives(createElementVNode("input", {
|
|
2252
2557
|
id: `${unref(uid)}-root`,
|
|
2253
2558
|
"onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => rootLock.value.input = $event),
|
|
@@ -2257,7 +2562,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
2257
2562
|
placeholder: t("passwordPlaceholder"),
|
|
2258
2563
|
"aria-invalid": !!rootLock.value.error,
|
|
2259
2564
|
"aria-describedby": rootLock.value.error ? `${unref(uid)}-root-error` : void 0
|
|
2260
|
-
}, null, 8,
|
|
2565
|
+
}, null, 8, _hoisted_33), [[vModelText, rootLock.value.input]]),
|
|
2261
2566
|
canRemember.value ? (openBlock(), createElementBlock("button", {
|
|
2262
2567
|
key: 0,
|
|
2263
2568
|
class: "fl-unlock-remember",
|
|
@@ -2266,26 +2571,50 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
2266
2571
|
"aria-label": t("rememberPassword"),
|
|
2267
2572
|
title: t("rememberPassword"),
|
|
2268
2573
|
onClick: _cache[3] || (_cache[3] = ($event) => rootLock.value.remember = !rootLock.value.remember)
|
|
2269
|
-
}, [createVNode(_sfc_main$2, { name: "key" })], 8,
|
|
2574
|
+
}, [createVNode(_sfc_main$2, { name: "key" })], 8, _hoisted_34)) : createCommentVNode("v-if", true),
|
|
2270
2575
|
createElementVNode("button", {
|
|
2271
2576
|
class: "fl-unlock-submit",
|
|
2272
2577
|
type: "submit",
|
|
2273
2578
|
disabled: rootLock.value.busy || !rootLock.value.input
|
|
2274
|
-
}, toDisplayString(t("open")), 9,
|
|
2579
|
+
}, toDisplayString(t("open")), 9, _hoisted_35)
|
|
2275
2580
|
])
|
|
2276
|
-
], 34)) : errorMsg.value ? (openBlock(), createElementBlock("div",
|
|
2581
|
+
], 34)) : errorMsg.value ? (openBlock(), createElementBlock("div", _hoisted_36, [
|
|
2277
2582
|
createTextVNode(toDisplayString(t("loadFailed", { message: errorMsg.value })) + " ", 1),
|
|
2278
|
-
/guest/i.test(errorMsg.value) ? (openBlock(), createElementBlock("p",
|
|
2279
|
-
unref(isNetworkError)(errorMsg.value) ? (openBlock(), createElementBlock("p",
|
|
2583
|
+
/guest/i.test(errorMsg.value) ? (openBlock(), createElementBlock("p", _hoisted_37, toDisplayString(t("guestHint")), 1)) : createCommentVNode("v-if", true),
|
|
2584
|
+
unref(isNetworkError)(errorMsg.value) ? (openBlock(), createElementBlock("p", _hoisted_38, toDisplayString(t("corsHint")), 1)) : createCommentVNode("v-if", true),
|
|
2280
2585
|
createElementVNode("button", {
|
|
2281
2586
|
class: "fl-btn",
|
|
2282
2587
|
type: "button",
|
|
2283
2588
|
onClick: loadRoot
|
|
2284
2589
|
}, toDisplayString(t("retry")), 1)
|
|
2285
|
-
])) : visible.value.length === 0 ? (openBlock(), createElementBlock("div",
|
|
2286
|
-
(openBlock(true), createElementBlock(Fragment, null, renderList(
|
|
2287
|
-
return openBlock(), createElementBlock("div", {
|
|
2288
|
-
key:
|
|
2590
|
+
])) : visible.value.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_39, toDisplayString(t("empty")), 1)) : createCommentVNode("v-if", true),
|
|
2591
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(rows.value, (node, index) => {
|
|
2592
|
+
return openBlock(), createElementBlock(Fragment, { key: isMore(node) ? `more:${node.key}` : node.path }, [isMore(node) ? (openBlock(), createElementBlock("div", {
|
|
2593
|
+
key: 0,
|
|
2594
|
+
class: "fl-row fl-more",
|
|
2595
|
+
style: normalizeStyle({ "--fl-depth": node.depth })
|
|
2596
|
+
}, [_cache[9] || (_cache[9] = createElementVNode("span", { class: "fl-cell fl-cell-check" }, null, -1)), createElementVNode("span", _hoisted_40, [
|
|
2597
|
+
_cache[8] || (_cache[8] = createElementVNode("span", {
|
|
2598
|
+
class: "fl-indent",
|
|
2599
|
+
"aria-hidden": "true"
|
|
2600
|
+
}, null, -1)),
|
|
2601
|
+
createElementVNode("span", _hoisted_41, toDisplayString(t("moreRemaining", { count: node.remaining })), 1),
|
|
2602
|
+
node.remaining > (__props.pageSize || 0) ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [createElementVNode("button", {
|
|
2603
|
+
class: "fl-more-btn",
|
|
2604
|
+
type: "button",
|
|
2605
|
+
onClick: ($event) => showMore(node, false)
|
|
2606
|
+
}, [createTextVNode(toDisplayString(t("showMore")), 1), createElementVNode("span", _hoisted_43, toDisplayString(` ${t("folderItems", { count: __props.pageSize })}`), 1)], 8, _hoisted_42), createElementVNode("button", {
|
|
2607
|
+
class: "fl-more-btn fl-more-all",
|
|
2608
|
+
type: "button",
|
|
2609
|
+
onClick: ($event) => showMore(node, true)
|
|
2610
|
+
}, toDisplayString(t("showAll")), 9, _hoisted_44)], 64)) : (openBlock(), createElementBlock("button", {
|
|
2611
|
+
key: 1,
|
|
2612
|
+
class: "fl-more-btn",
|
|
2613
|
+
type: "button",
|
|
2614
|
+
onClick: ($event) => showMore(node, true)
|
|
2615
|
+
}, toDisplayString(t("showRest", { count: node.remaining })), 9, _hoisted_45))
|
|
2616
|
+
])], 4)) : (openBlock(), createElementBlock("div", {
|
|
2617
|
+
key: 1,
|
|
2289
2618
|
class: normalizeClass(["fl-row", {
|
|
2290
2619
|
"fl-row-dir": node.is_dir,
|
|
2291
2620
|
"fl-row-root": node.isRoot,
|
|
@@ -2296,19 +2625,19 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
2296
2625
|
}]),
|
|
2297
2626
|
style: normalizeStyle({ "--fl-depth": node.depth })
|
|
2298
2627
|
}, [
|
|
2299
|
-
createElementVNode("label",
|
|
2628
|
+
createElementVNode("label", _hoisted_46, [createElementVNode("input", {
|
|
2300
2629
|
type: "checkbox",
|
|
2301
|
-
disabled: !!node.lock,
|
|
2630
|
+
disabled: !!node.lock || batchBusy.value,
|
|
2302
2631
|
"aria-label": t("selectItem", { name: node.name }),
|
|
2303
2632
|
checked: isChecked(node),
|
|
2304
2633
|
".indeterminate": isIndeterminate(node),
|
|
2305
2634
|
onChange: ($event) => toggleCheck(node, $event)
|
|
2306
|
-
}, null, 40,
|
|
2635
|
+
}, null, 40, _hoisted_47)]),
|
|
2307
2636
|
createElementVNode("span", {
|
|
2308
2637
|
class: "fl-cell fl-cell-name",
|
|
2309
2638
|
title: node.isRoot ? node.path : void 0
|
|
2310
2639
|
}, [
|
|
2311
|
-
_cache[
|
|
2640
|
+
_cache[11] || (_cache[11] = createElementVNode("span", {
|
|
2312
2641
|
class: "fl-indent",
|
|
2313
2642
|
"aria-hidden": "true"
|
|
2314
2643
|
}, null, -1)),
|
|
@@ -2322,7 +2651,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
2322
2651
|
}, [createVNode(_sfc_main$2, {
|
|
2323
2652
|
name: "lock",
|
|
2324
2653
|
size: 14
|
|
2325
|
-
})], 8,
|
|
2654
|
+
})], 8, _hoisted_49)) : node.is_dir ? (openBlock(), createElementBlock("button", {
|
|
2326
2655
|
key: 1,
|
|
2327
2656
|
class: normalizeClass(["fl-arrow", { "fl-arrow-open": node.expanded }]),
|
|
2328
2657
|
type: "button",
|
|
@@ -2332,24 +2661,24 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
2332
2661
|
}, [createVNode(_sfc_main$2, {
|
|
2333
2662
|
name: "next",
|
|
2334
2663
|
size: 14
|
|
2335
|
-
})], 10,
|
|
2336
|
-
node.is_dir ? (openBlock(), createElementBlock("svg",
|
|
2664
|
+
})], 10, _hoisted_50)) : (openBlock(), createElementBlock("span", _hoisted_51)),
|
|
2665
|
+
node.is_dir ? (openBlock(), createElementBlock("svg", _hoisted_52, [..._cache[10] || (_cache[10] = [createElementVNode("path", { d: "M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" }, null, -1)])])) : (openBlock(), createElementBlock("span", {
|
|
2337
2666
|
key: 4,
|
|
2338
2667
|
class: "fl-type",
|
|
2339
2668
|
"data-kind": unref(fileKind)(node.name),
|
|
2340
2669
|
"aria-hidden": "true"
|
|
2341
|
-
}, toDisplayString(unref(extOf)(node.name) || "FILE"), 9,
|
|
2342
|
-
createElementVNode("span",
|
|
2670
|
+
}, toDisplayString(unref(extOf)(node.name) || "FILE"), 9, _hoisted_53)),
|
|
2671
|
+
createElementVNode("span", _hoisted_54, [createElementVNode("span", {
|
|
2343
2672
|
class: normalizeClass(["fl-name", { "fl-name-dir": node.is_dir }]),
|
|
2344
2673
|
onClick: ($event) => node.lock || node.is_dir ? toggleExpand(node) : download(node)
|
|
2345
|
-
}, toDisplayString(node.name), 11,
|
|
2346
|
-
node.is_dir && node.loaded ? (openBlock(), createElementBlock("span",
|
|
2674
|
+
}, toDisplayString(node.name), 11, _hoisted_55), createElementVNode("span", _hoisted_56, [!node.is_dir ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [createTextVNode(toDisplayString(unref(formatSize)(node.size)) + " · " + toDisplayString(unref(formatDate)(node.modified)), 1)], 64)) : node.loaded ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [createTextVNode(toDisplayString(t("folderItems", { count: statsOf(node).files })) + " · " + toDisplayString(unref(formatSize)(statsOf(node).bytes)), 1)], 64)) : createCommentVNode("v-if", true)])]),
|
|
2675
|
+
node.is_dir && node.loaded ? (openBlock(), createElementBlock("span", _hoisted_57, toDisplayString(t("folderItems", { count: statsOf(node).files })), 1)) : createCommentVNode("v-if", true),
|
|
2347
2676
|
node.lock?.prompting && node.lock.error ? (openBlock(), createElementBlock("span", {
|
|
2348
2677
|
key: 6,
|
|
2349
2678
|
id: `${unref(uid)}-error-${index}`,
|
|
2350
2679
|
class: "fl-unlock-message",
|
|
2351
2680
|
role: "alert"
|
|
2352
|
-
}, toDisplayString(unlockErrorText(node.lock.error)), 9,
|
|
2681
|
+
}, toDisplayString(unlockErrorText(node.lock.error)), 9, _hoisted_58)) : createCommentVNode("v-if", true),
|
|
2353
2682
|
!node.lock && unref(remembered).has(node.path) ? (openBlock(), createElementBlock("button", {
|
|
2354
2683
|
key: 7,
|
|
2355
2684
|
class: "fl-remembered",
|
|
@@ -2360,9 +2689,9 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
2360
2689
|
}, [createVNode(_sfc_main$2, {
|
|
2361
2690
|
name: "key",
|
|
2362
2691
|
size: 11
|
|
2363
|
-
}), createTextVNode(" " + toDisplayString(t("remembered")) + " · " + toDisplayString(t("forgetPassword")), 1)], 8,
|
|
2364
|
-
node.loading ? (openBlock(), createElementBlock("span",
|
|
2365
|
-
], 8,
|
|
2692
|
+
}), createTextVNode(" " + toDisplayString(t("remembered")) + " · " + toDisplayString(t("forgetPassword")), 1)], 8, _hoisted_59)) : createCommentVNode("v-if", true),
|
|
2693
|
+
node.loading ? (openBlock(), createElementBlock("span", _hoisted_60, "…")) : createCommentVNode("v-if", true)
|
|
2694
|
+
], 8, _hoisted_48),
|
|
2366
2695
|
node.lock?.prompting ? (openBlock(), createElementBlock("form", {
|
|
2367
2696
|
key: 0,
|
|
2368
2697
|
class: "fl-unlock fl-unlock-row",
|
|
@@ -2383,7 +2712,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
2383
2712
|
"aria-label": t("passwordFor", { name: node.name }),
|
|
2384
2713
|
"aria-invalid": !!node.lock.error,
|
|
2385
2714
|
"aria-describedby": node.lock.error ? `${unref(uid)}-error-${index}` : void 0
|
|
2386
|
-
}, null, 8,
|
|
2715
|
+
}, null, 8, _hoisted_62), [[vModelText, node.lock.input]]),
|
|
2387
2716
|
canRemember.value ? (openBlock(), createElementBlock("button", {
|
|
2388
2717
|
key: 0,
|
|
2389
2718
|
class: "fl-unlock-remember",
|
|
@@ -2392,12 +2721,12 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
2392
2721
|
"aria-label": t("rememberPassword"),
|
|
2393
2722
|
title: t("rememberPassword"),
|
|
2394
2723
|
onClick: ($event) => node.lock.remember = !node.lock.remember
|
|
2395
|
-
}, [createVNode(_sfc_main$2, { name: "key" })], 8,
|
|
2724
|
+
}, [createVNode(_sfc_main$2, { name: "key" })], 8, _hoisted_63)) : createCommentVNode("v-if", true),
|
|
2396
2725
|
createElementVNode("button", {
|
|
2397
2726
|
class: "fl-unlock-submit",
|
|
2398
2727
|
type: "submit",
|
|
2399
2728
|
disabled: node.lock.busy || !node.lock.input
|
|
2400
|
-
}, toDisplayString(t("open")), 9,
|
|
2729
|
+
}, toDisplayString(t("open")), 9, _hoisted_64),
|
|
2401
2730
|
createElementVNode("button", {
|
|
2402
2731
|
class: "fl-unlock-cancel",
|
|
2403
2732
|
type: "button",
|
|
@@ -2407,11 +2736,11 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
2407
2736
|
}, [createVNode(_sfc_main$2, {
|
|
2408
2737
|
name: "close",
|
|
2409
2738
|
size: 14
|
|
2410
|
-
})], 8,
|
|
2411
|
-
], 40,
|
|
2412
|
-
createElementVNode("span",
|
|
2413
|
-
createElementVNode("span",
|
|
2414
|
-
createElementVNode("span",
|
|
2739
|
+
})], 8, _hoisted_65)
|
|
2740
|
+
], 40, _hoisted_61)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
|
|
2741
|
+
createElementVNode("span", _hoisted_66, toDisplayString(node.is_dir ? "—" : unref(formatSize)(node.size)), 1),
|
|
2742
|
+
createElementVNode("span", _hoisted_67, toDisplayString(unref(formatDate)(node.modified)), 1),
|
|
2743
|
+
createElementVNode("span", _hoisted_68, [node.lock ? (openBlock(), createElementBlock("button", {
|
|
2415
2744
|
key: 0,
|
|
2416
2745
|
class: "fl-action fl-arrow-end fl-lock",
|
|
2417
2746
|
type: "button",
|
|
@@ -2420,7 +2749,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
2420
2749
|
}, [createVNode(_sfc_main$2, {
|
|
2421
2750
|
name: "lock",
|
|
2422
2751
|
size: 18
|
|
2423
|
-
})], 8,
|
|
2752
|
+
})], 8, _hoisted_69)) : node.is_dir ? (openBlock(), createElementBlock("button", {
|
|
2424
2753
|
key: 1,
|
|
2425
2754
|
class: normalizeClass(["fl-action fl-arrow-end", { "fl-arrow-open": node.expanded }]),
|
|
2426
2755
|
type: "button",
|
|
@@ -2430,25 +2759,42 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
2430
2759
|
}, [createVNode(_sfc_main$2, {
|
|
2431
2760
|
name: "next",
|
|
2432
2761
|
size: 18
|
|
2433
|
-
})], 10,
|
|
2762
|
+
})], 10, _hoisted_70)) : (openBlock(), createElementBlock(Fragment, { key: 2 }, [canPreview(node) ? (openBlock(), createElementBlock("button", {
|
|
2434
2763
|
key: 0,
|
|
2435
2764
|
class: "fl-action fl-preview-btn",
|
|
2436
2765
|
type: "button",
|
|
2437
2766
|
"aria-label": `${t("preview")} ${node.name}`,
|
|
2438
2767
|
title: t("preview"),
|
|
2439
2768
|
onClick: ($event) => preview(node)
|
|
2440
|
-
}, [createVNode(_sfc_main$2, { name: "eye" })], 8,
|
|
2769
|
+
}, [createVNode(_sfc_main$2, { name: "eye" })], 8, _hoisted_71)) : createCommentVNode("v-if", true), createElementVNode("button", {
|
|
2441
2770
|
class: "fl-action fl-download",
|
|
2442
2771
|
type: "button",
|
|
2443
2772
|
"aria-label": `${t("download")} ${node.name}`,
|
|
2444
2773
|
title: t("download"),
|
|
2445
2774
|
onClick: ($event) => download(node)
|
|
2446
|
-
}, [createVNode(_sfc_main$2, { name: "download" })], 8,
|
|
2775
|
+
}, [createVNode(_sfc_main$2, { name: "download" })], 8, _hoisted_72)], 64))])
|
|
2447
2776
|
], 64))
|
|
2448
|
-
], 6);
|
|
2777
|
+
], 6))], 64);
|
|
2449
2778
|
}), 128)),
|
|
2450
|
-
createElementVNode("div",
|
|
2451
|
-
toast.value ? (openBlock(), createElementBlock("div",
|
|
2779
|
+
createElementVNode("div", _hoisted_73, [createElementVNode("span", null, toDisplayString(t("loaded", { count: allFiles.value.length })) + " · " + toDisplayString(t("totalSize", { size: unref(formatSize)(unref(totalSize)(allFiles.value)) })), 1)]),
|
|
2780
|
+
toast.value ? (openBlock(), createElementBlock("div", _hoisted_74, toDisplayString(toast.value), 1)) : createCommentVNode("v-if", true),
|
|
2781
|
+
createVNode(_sfc_main$3, {
|
|
2782
|
+
open: !!zipNotice.value,
|
|
2783
|
+
title: zipNotice.value ? t(zipNotice.value.kind === "warn" ? "zipWarnTitle" : "zipBlockTitle", { size: unref(formatSize)(zipNotice.value.size) }) : "",
|
|
2784
|
+
text: zipNotice.value ? t(zipNotice.value.kind === "warn" ? "zipWarnText" : "zipBlockText", { limit: unref(formatSize)(zipNotice.value.limit) }) : "",
|
|
2785
|
+
tip: zipTip.value,
|
|
2786
|
+
"confirm-label": zipNotice.value?.kind === "warn" ? t("zipContinue") : void 0,
|
|
2787
|
+
"cancel-label": zipNotice.value?.kind === "warn" ? t("cancel") : t("gotIt"),
|
|
2788
|
+
onConfirm: confirmZip,
|
|
2789
|
+
onClose: _cache[4] || (_cache[4] = ($event) => zipNotice.value = null)
|
|
2790
|
+
}, null, 8, [
|
|
2791
|
+
"open",
|
|
2792
|
+
"title",
|
|
2793
|
+
"text",
|
|
2794
|
+
"tip",
|
|
2795
|
+
"confirm-label",
|
|
2796
|
+
"cancel-label"
|
|
2797
|
+
]),
|
|
2452
2798
|
createVNode(_sfc_main$1, {
|
|
2453
2799
|
open: !!previewNode.value,
|
|
2454
2800
|
file: previewNode.value,
|
|
@@ -2461,9 +2807,9 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
2461
2807
|
position: previewPosition.value,
|
|
2462
2808
|
total: previewPosition.value ? previewList.value.length : 0,
|
|
2463
2809
|
onClose: closePreview,
|
|
2464
|
-
onPrev: _cache[
|
|
2465
|
-
onNext: _cache[
|
|
2466
|
-
onDownload: _cache[
|
|
2810
|
+
onPrev: _cache[5] || (_cache[5] = ($event) => stepPreview(-1)),
|
|
2811
|
+
onNext: _cache[6] || (_cache[6] = ($event) => stepPreview(1)),
|
|
2812
|
+
onDownload: _cache[7] || (_cache[7] = ($event) => previewNode.value && download(previewNode.value))
|
|
2467
2813
|
}, null, 8, [
|
|
2468
2814
|
"open",
|
|
2469
2815
|
"file",
|