vitepress-plugin-filelist 0.2.2 → 0.3.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 +26 -6
- package/dist/client/browser/index.d.ts +37 -0
- package/dist/client/browser/index.js +540 -131
- package/dist/client/ssr/index.d.ts +37 -0
- package/dist/client/ssr/index.js +264 -35
- package/dist/client/style.css +580 -95
- package/package.json +3 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "../style.css";
|
|
2
|
-
import { Fragment, computed, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, defineComponent, normalizeClass, normalizeStyle, onMounted, openBlock, ref, renderList, toDisplayString, unref, vModelText, withDirectives, withKeys } from "vue";
|
|
2
|
+
import { Fragment, computed, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, defineComponent, normalizeClass, normalizeStyle, onBeforeUnmount, onMounted, openBlock, ref, renderList, toDisplayString, unref, vModelSelect, vModelText, withDirectives, withKeys } from "vue";
|
|
3
3
|
// src/client/locales.ts
|
|
4
4
|
const fileListLocales = {
|
|
5
5
|
"zh-CN": {
|
|
@@ -7,7 +7,7 @@ const fileListLocales = {
|
|
|
7
7
|
demoBadge: "演示数据",
|
|
8
8
|
filter: "筛选文件名",
|
|
9
9
|
refresh: "刷新",
|
|
10
|
-
batch: "
|
|
10
|
+
batch: "下载 ZIP",
|
|
11
11
|
batchCount: "批量下载({count})",
|
|
12
12
|
batching: "打包中 {percent}%",
|
|
13
13
|
passwordPrompt: "该目录受密码保护:",
|
|
@@ -34,7 +34,16 @@ const fileListLocales = {
|
|
|
34
34
|
downloadFailed: "下载失败:{message}",
|
|
35
35
|
previewFailed: "预览失败:{message}",
|
|
36
36
|
batchFailed: "打包失败:{message}",
|
|
37
|
-
defaultZip: "资源"
|
|
37
|
+
defaultZip: "资源",
|
|
38
|
+
clear: "清除",
|
|
39
|
+
clearSelection: "取消选择",
|
|
40
|
+
totalSize: "共 {size}",
|
|
41
|
+
folderItems: "{count} 项",
|
|
42
|
+
sortBy: "排序",
|
|
43
|
+
selectAll: "全选",
|
|
44
|
+
selectItem: "选择 {name}",
|
|
45
|
+
expand: "展开 {name}",
|
|
46
|
+
collapse: "收起 {name}"
|
|
38
47
|
},
|
|
39
48
|
"en-US": {
|
|
40
49
|
allFiles: "All files",
|
|
@@ -68,7 +77,16 @@ const fileListLocales = {
|
|
|
68
77
|
downloadFailed: "Download failed: {message}",
|
|
69
78
|
previewFailed: "Preview failed: {message}",
|
|
70
79
|
batchFailed: "Failed to create ZIP: {message}",
|
|
71
|
-
defaultZip: "resources"
|
|
80
|
+
defaultZip: "resources",
|
|
81
|
+
clear: "Clear",
|
|
82
|
+
clearSelection: "Clear selection",
|
|
83
|
+
totalSize: "{size} total",
|
|
84
|
+
folderItems: "{count} items",
|
|
85
|
+
sortBy: "Sort",
|
|
86
|
+
selectAll: "Select all",
|
|
87
|
+
selectItem: "Select {name}",
|
|
88
|
+
expand: "Expand {name}",
|
|
89
|
+
collapse: "Collapse {name}"
|
|
72
90
|
}
|
|
73
91
|
};
|
|
74
92
|
function formatLabel(template, values = {}) {
|
|
@@ -87,6 +105,41 @@ function joinPath(parent, name) {
|
|
|
87
105
|
function encodePath(path) {
|
|
88
106
|
return path.split("/").map(encodeURIComponent).join("/");
|
|
89
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* Make one path segment safe as a ZIP entry segment: no separators,
|
|
110
|
+
* no `.` / `..` traversal, no empty names.
|
|
111
|
+
*/
|
|
112
|
+
function zipSegment(name) {
|
|
113
|
+
const cleaned = name.replace(/[\\/]/g, "_").trim();
|
|
114
|
+
if (!cleaned || cleaned === "." || cleaned === "..") return "_";
|
|
115
|
+
return cleaned;
|
|
116
|
+
}
|
|
117
|
+
/** Join path segments into a ZIP entry name, sanitising each segment. */
|
|
118
|
+
function zipEntryName(segments) {
|
|
119
|
+
return segments.map(zipSegment).join("/");
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Return `name`, or `name (2)`, `name (3)`... when it is already in `used`.
|
|
123
|
+
* The suffix goes before the extension of the last segment. Adds the result to `used`.
|
|
124
|
+
*/
|
|
125
|
+
function uniqueEntryName(name, used) {
|
|
126
|
+
let candidate = name;
|
|
127
|
+
if (used.has(candidate)) {
|
|
128
|
+
const slash = name.lastIndexOf("/");
|
|
129
|
+
const dir = name.slice(0, slash + 1);
|
|
130
|
+
const base = name.slice(slash + 1);
|
|
131
|
+
const dot = base.lastIndexOf(".");
|
|
132
|
+
const stem = dot > 0 ? base.slice(0, dot) : base;
|
|
133
|
+
const ext = dot > 0 ? base.slice(dot) : "";
|
|
134
|
+
let index = 2;
|
|
135
|
+
do {
|
|
136
|
+
candidate = `${dir}${stem} (${index})${ext}`;
|
|
137
|
+
index += 1;
|
|
138
|
+
} while (used.has(candidate));
|
|
139
|
+
}
|
|
140
|
+
used.add(candidate);
|
|
141
|
+
return candidate;
|
|
142
|
+
}
|
|
90
143
|
function formatSize(size) {
|
|
91
144
|
if (!size || !Number.isFinite(size)) return "-";
|
|
92
145
|
const units = [
|
|
@@ -116,6 +169,97 @@ function extOf(name) {
|
|
|
116
169
|
const match = name.match(/\.([a-z0-9]+)$/i);
|
|
117
170
|
return match ? match[1].toUpperCase() : "";
|
|
118
171
|
}
|
|
172
|
+
const FILE_KINDS = {};
|
|
173
|
+
for (const [kind, exts] of Object.entries({
|
|
174
|
+
doc: [
|
|
175
|
+
"doc",
|
|
176
|
+
"docx",
|
|
177
|
+
"odt",
|
|
178
|
+
"rtf",
|
|
179
|
+
"txt",
|
|
180
|
+
"md",
|
|
181
|
+
"pages",
|
|
182
|
+
"wps"
|
|
183
|
+
],
|
|
184
|
+
sheet: [
|
|
185
|
+
"xls",
|
|
186
|
+
"xlsx",
|
|
187
|
+
"ods",
|
|
188
|
+
"csv",
|
|
189
|
+
"tsv",
|
|
190
|
+
"numbers",
|
|
191
|
+
"et"
|
|
192
|
+
],
|
|
193
|
+
slide: [
|
|
194
|
+
"ppt",
|
|
195
|
+
"pptx",
|
|
196
|
+
"odp",
|
|
197
|
+
"key",
|
|
198
|
+
"dps"
|
|
199
|
+
],
|
|
200
|
+
pdf: ["pdf"],
|
|
201
|
+
image: [
|
|
202
|
+
"png",
|
|
203
|
+
"jpg",
|
|
204
|
+
"jpeg",
|
|
205
|
+
"gif",
|
|
206
|
+
"webp",
|
|
207
|
+
"svg",
|
|
208
|
+
"bmp",
|
|
209
|
+
"ico",
|
|
210
|
+
"avif",
|
|
211
|
+
"heic"
|
|
212
|
+
],
|
|
213
|
+
media: [
|
|
214
|
+
"mp3",
|
|
215
|
+
"wav",
|
|
216
|
+
"flac",
|
|
217
|
+
"aac",
|
|
218
|
+
"ogg",
|
|
219
|
+
"m4a",
|
|
220
|
+
"mp4",
|
|
221
|
+
"webm",
|
|
222
|
+
"mov",
|
|
223
|
+
"mkv",
|
|
224
|
+
"avi"
|
|
225
|
+
],
|
|
226
|
+
archive: [
|
|
227
|
+
"zip",
|
|
228
|
+
"rar",
|
|
229
|
+
"7z",
|
|
230
|
+
"tar",
|
|
231
|
+
"gz",
|
|
232
|
+
"tgz",
|
|
233
|
+
"bz2",
|
|
234
|
+
"xz",
|
|
235
|
+
"iso"
|
|
236
|
+
],
|
|
237
|
+
code: [
|
|
238
|
+
"js",
|
|
239
|
+
"ts",
|
|
240
|
+
"json",
|
|
241
|
+
"html",
|
|
242
|
+
"css",
|
|
243
|
+
"py",
|
|
244
|
+
"java",
|
|
245
|
+
"c",
|
|
246
|
+
"cpp",
|
|
247
|
+
"go",
|
|
248
|
+
"rs",
|
|
249
|
+
"sh",
|
|
250
|
+
"yml",
|
|
251
|
+
"yaml",
|
|
252
|
+
"xml"
|
|
253
|
+
]
|
|
254
|
+
})) for (const ext of exts) FILE_KINDS[ext] = kind;
|
|
255
|
+
/** Rough file family, used to colour the type badge. */
|
|
256
|
+
function fileKind(name) {
|
|
257
|
+
return FILE_KINDS[extOf(name).toLowerCase()] ?? "other";
|
|
258
|
+
}
|
|
259
|
+
/** Sum of the `size` of the given entries, ignoring missing or invalid sizes. */
|
|
260
|
+
function totalSize(items) {
|
|
261
|
+
return items.reduce((sum, item) => sum + (Number.isFinite(item.size) && (item.size ?? 0) > 0 ? item.size : 0), 0);
|
|
262
|
+
}
|
|
119
263
|
function compareNodes(a, b, key, ascending = true) {
|
|
120
264
|
if (a.is_dir !== b.is_dir) return a.is_dir ? -1 : 1;
|
|
121
265
|
let result = 0;
|
|
@@ -125,83 +269,152 @@ function compareNodes(a, b, key, ascending = true) {
|
|
|
125
269
|
return ascending ? result : -result;
|
|
126
270
|
}
|
|
127
271
|
// src/client/FileList.vue
|
|
128
|
-
const _hoisted_1 = { class: "fl-
|
|
129
|
-
const _hoisted_2 = {
|
|
130
|
-
|
|
131
|
-
|
|
272
|
+
const _hoisted_1 = { class: "fl-bar" };
|
|
273
|
+
const _hoisted_2 = {
|
|
274
|
+
key: 0,
|
|
275
|
+
class: "fl-selection",
|
|
276
|
+
role: "status"
|
|
277
|
+
};
|
|
278
|
+
const _hoisted_3 = { class: "fl-selection-count" };
|
|
279
|
+
const _hoisted_4 = { class: "fl-selection-size" };
|
|
132
280
|
const _hoisted_5 = {
|
|
281
|
+
key: 1,
|
|
282
|
+
class: "fl-title"
|
|
283
|
+
};
|
|
284
|
+
const _hoisted_6 = { class: "fl-title-text" };
|
|
285
|
+
const _hoisted_7 = {
|
|
133
286
|
key: 0,
|
|
134
287
|
class: "fl-demo-badge"
|
|
135
288
|
};
|
|
136
|
-
const
|
|
137
|
-
const
|
|
138
|
-
const
|
|
139
|
-
const
|
|
289
|
+
const _hoisted_8 = ["aria-label", "title"];
|
|
290
|
+
const _hoisted_9 = { class: "fl-clear-text" };
|
|
291
|
+
const _hoisted_10 = { class: "fl-tools" };
|
|
292
|
+
const _hoisted_11 = { class: "fl-search" };
|
|
293
|
+
const _hoisted_12 = ["placeholder", "aria-label"];
|
|
294
|
+
const _hoisted_13 = ["aria-label", "title"];
|
|
295
|
+
const _hoisted_14 = ["disabled"];
|
|
296
|
+
const _hoisted_15 = {
|
|
140
297
|
key: 0,
|
|
141
298
|
class: "fl-password"
|
|
142
299
|
};
|
|
143
|
-
const
|
|
144
|
-
const
|
|
145
|
-
const
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
300
|
+
const _hoisted_16 = ["placeholder", "aria-label"];
|
|
301
|
+
const _hoisted_17 = { class: "fl-row fl-head" };
|
|
302
|
+
const _hoisted_18 = { class: "fl-cell fl-cell-check" };
|
|
303
|
+
const _hoisted_19 = [
|
|
304
|
+
"aria-label",
|
|
305
|
+
"checked",
|
|
306
|
+
".indeterminate"
|
|
307
|
+
];
|
|
308
|
+
const _hoisted_20 = { class: "fl-cell fl-cell-name" };
|
|
309
|
+
const _hoisted_21 = ["aria-sort"];
|
|
310
|
+
const _hoisted_22 = {
|
|
311
|
+
class: "fl-sort",
|
|
312
|
+
"aria-hidden": "true"
|
|
313
|
+
};
|
|
314
|
+
const _hoisted_23 = { class: "fl-cell fl-cell-size" };
|
|
315
|
+
const _hoisted_24 = {
|
|
316
|
+
class: "fl-sort",
|
|
317
|
+
"aria-hidden": "true"
|
|
318
|
+
};
|
|
319
|
+
const _hoisted_25 = { class: "fl-cell fl-cell-date" };
|
|
320
|
+
const _hoisted_26 = {
|
|
321
|
+
class: "fl-sort",
|
|
322
|
+
"aria-hidden": "true"
|
|
323
|
+
};
|
|
324
|
+
const _hoisted_27 = { class: "fl-cell fl-cell-op" };
|
|
325
|
+
const _hoisted_28 = { class: "fl-sort-select" };
|
|
326
|
+
const _hoisted_29 = {
|
|
327
|
+
class: "fl-sort-current",
|
|
328
|
+
"aria-hidden": "true"
|
|
329
|
+
};
|
|
330
|
+
const _hoisted_30 = ["aria-label"];
|
|
331
|
+
const _hoisted_31 = ["value"];
|
|
332
|
+
const _hoisted_32 = {
|
|
151
333
|
key: 1,
|
|
152
334
|
class: "fl-status"
|
|
153
335
|
};
|
|
154
|
-
const
|
|
336
|
+
const _hoisted_33 = {
|
|
155
337
|
key: 2,
|
|
156
338
|
class: "fl-status fl-error"
|
|
157
339
|
};
|
|
158
|
-
const
|
|
340
|
+
const _hoisted_34 = {
|
|
159
341
|
key: 0,
|
|
160
342
|
class: "fl-hint"
|
|
161
343
|
};
|
|
162
|
-
const
|
|
344
|
+
const _hoisted_35 = {
|
|
163
345
|
key: 1,
|
|
164
346
|
class: "fl-hint"
|
|
165
347
|
};
|
|
166
|
-
const
|
|
348
|
+
const _hoisted_36 = {
|
|
167
349
|
key: 3,
|
|
168
350
|
class: "fl-status"
|
|
169
351
|
};
|
|
170
|
-
const
|
|
171
|
-
const
|
|
352
|
+
const _hoisted_37 = { class: "fl-cell fl-cell-check" };
|
|
353
|
+
const _hoisted_38 = [
|
|
354
|
+
"aria-label",
|
|
172
355
|
"checked",
|
|
173
356
|
".indeterminate",
|
|
174
357
|
"onChange"
|
|
175
358
|
];
|
|
176
|
-
const
|
|
177
|
-
const
|
|
178
|
-
|
|
359
|
+
const _hoisted_39 = ["title"];
|
|
360
|
+
const _hoisted_40 = [
|
|
361
|
+
"aria-label",
|
|
362
|
+
"aria-expanded",
|
|
363
|
+
"onClick"
|
|
364
|
+
];
|
|
365
|
+
const _hoisted_41 = {
|
|
179
366
|
key: 1,
|
|
180
|
-
class: "fl-arrow-placeholder"
|
|
367
|
+
class: "fl-arrow-placeholder",
|
|
368
|
+
"aria-hidden": "true"
|
|
181
369
|
};
|
|
182
|
-
const
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
370
|
+
const _hoisted_42 = {
|
|
371
|
+
key: 2,
|
|
372
|
+
class: "fl-folder-icon",
|
|
373
|
+
viewBox: "0 0 24 24",
|
|
374
|
+
width: "18",
|
|
375
|
+
height: "18",
|
|
376
|
+
"aria-hidden": "true"
|
|
186
377
|
};
|
|
187
|
-
const
|
|
188
|
-
|
|
189
|
-
|
|
378
|
+
const _hoisted_43 = ["data-kind"];
|
|
379
|
+
const _hoisted_44 = { class: "fl-label" };
|
|
380
|
+
const _hoisted_45 = ["onClick"];
|
|
381
|
+
const _hoisted_46 = { class: "fl-meta" };
|
|
382
|
+
const _hoisted_47 = {
|
|
383
|
+
key: 4,
|
|
384
|
+
class: "fl-count"
|
|
190
385
|
};
|
|
191
|
-
const
|
|
192
|
-
key:
|
|
193
|
-
class: "fl-loading"
|
|
386
|
+
const _hoisted_48 = {
|
|
387
|
+
key: 5,
|
|
388
|
+
class: "fl-loading",
|
|
389
|
+
"aria-hidden": "true"
|
|
194
390
|
};
|
|
195
|
-
const
|
|
196
|
-
const
|
|
197
|
-
const
|
|
198
|
-
const
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
391
|
+
const _hoisted_49 = { class: "fl-cell fl-cell-size" };
|
|
392
|
+
const _hoisted_50 = { class: "fl-cell fl-cell-date" };
|
|
393
|
+
const _hoisted_51 = { class: "fl-cell fl-cell-op" };
|
|
394
|
+
const _hoisted_52 = [
|
|
395
|
+
"aria-label",
|
|
396
|
+
"aria-expanded",
|
|
397
|
+
"onClick"
|
|
398
|
+
];
|
|
399
|
+
const _hoisted_53 = [
|
|
400
|
+
"aria-label",
|
|
401
|
+
"title",
|
|
402
|
+
"onClick"
|
|
403
|
+
];
|
|
404
|
+
const _hoisted_54 = [
|
|
405
|
+
"aria-label",
|
|
406
|
+
"title",
|
|
407
|
+
"onClick"
|
|
408
|
+
];
|
|
409
|
+
const _hoisted_55 = { class: "fl-foot" };
|
|
410
|
+
const _hoisted_56 = {
|
|
411
|
+
key: 0,
|
|
412
|
+
class: "fl-foot-hint"
|
|
413
|
+
};
|
|
414
|
+
const _hoisted_57 = {
|
|
203
415
|
key: 4,
|
|
204
|
-
class: "fl-toast"
|
|
416
|
+
class: "fl-toast",
|
|
417
|
+
role: "status"
|
|
205
418
|
};
|
|
206
419
|
const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
207
420
|
__name: "FileList",
|
|
@@ -258,6 +471,9 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
258
471
|
function errorText(error) {
|
|
259
472
|
return error instanceof Error ? error.message : String(error);
|
|
260
473
|
}
|
|
474
|
+
function isPasswordError(error) {
|
|
475
|
+
return /password|密码/i.test(errorText(error));
|
|
476
|
+
}
|
|
261
477
|
const DEMO_TREE = {
|
|
262
478
|
"/": [
|
|
263
479
|
{
|
|
@@ -472,7 +688,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
472
688
|
nodes.sort((a, b) => compareNodes(a, b, sortKey.value, sortAsc.value));
|
|
473
689
|
for (const node of nodes) if (node.children.length) sortTree(node.children);
|
|
474
690
|
}
|
|
475
|
-
function toNodes(items, parent, depth, password = "") {
|
|
691
|
+
function toNodes(items, parent, depth, password = "", zipParent = []) {
|
|
476
692
|
return items.map((item) => ({
|
|
477
693
|
...item,
|
|
478
694
|
path: joinPath(parent, item.name),
|
|
@@ -481,7 +697,8 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
481
697
|
loaded: false,
|
|
482
698
|
loading: false,
|
|
483
699
|
children: [],
|
|
484
|
-
password
|
|
700
|
+
password,
|
|
701
|
+
zipPath: [...zipParent, item.name]
|
|
485
702
|
}));
|
|
486
703
|
}
|
|
487
704
|
function setSort(key) {
|
|
@@ -490,6 +707,9 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
490
707
|
sortKey.value = key;
|
|
491
708
|
sortAsc.value = true;
|
|
492
709
|
}
|
|
710
|
+
resortAll();
|
|
711
|
+
}
|
|
712
|
+
function resortAll() {
|
|
493
713
|
if (props.sources.length) {
|
|
494
714
|
for (const root of roots.value) if (root.children.length) sortTree(root.children);
|
|
495
715
|
} else sortTree(roots.value);
|
|
@@ -502,11 +722,12 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
502
722
|
if (node.loaded) return true;
|
|
503
723
|
node.loading = true;
|
|
504
724
|
try {
|
|
505
|
-
node.children = toNodes(await listDir(node.path, node.password), node.path, node.depth + 1, node.password);
|
|
725
|
+
node.children = toNodes(await listDir(node.path, node.password || activePassword.value), node.path, node.depth + 1, node.password, node.zipPath);
|
|
506
726
|
sortTree(node.children);
|
|
507
727
|
node.loaded = true;
|
|
508
728
|
return true;
|
|
509
729
|
} catch (error) {
|
|
730
|
+
if (isPasswordError(error)) needsPassword.value = true;
|
|
510
731
|
showToast(t("folderFailed", { message: errorText(error) }));
|
|
511
732
|
return false;
|
|
512
733
|
} finally {
|
|
@@ -531,16 +752,17 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
531
752
|
} else try {
|
|
532
753
|
const data = await request("/api/fs/get", {
|
|
533
754
|
path,
|
|
534
|
-
password
|
|
755
|
+
password: password || activePassword.value
|
|
535
756
|
});
|
|
536
757
|
item = {
|
|
537
758
|
...item,
|
|
538
759
|
...data
|
|
539
760
|
};
|
|
540
761
|
} catch {}
|
|
762
|
+
const name = source.title || item.name || sourceName(path);
|
|
541
763
|
return {
|
|
542
764
|
...item,
|
|
543
|
-
name
|
|
765
|
+
name,
|
|
544
766
|
path,
|
|
545
767
|
depth: 0,
|
|
546
768
|
expanded: source.expanded ?? props.expanded,
|
|
@@ -548,7 +770,8 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
548
770
|
loading: false,
|
|
549
771
|
children: [],
|
|
550
772
|
password,
|
|
551
|
-
isRoot: true
|
|
773
|
+
isRoot: true,
|
|
774
|
+
zipPath: [item.is_dir ? name : item.name || sourceName(path)]
|
|
552
775
|
};
|
|
553
776
|
}
|
|
554
777
|
async function loadRoot() {
|
|
@@ -571,7 +794,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
571
794
|
downloadCache.clear();
|
|
572
795
|
} catch (error) {
|
|
573
796
|
const message = errorText(error);
|
|
574
|
-
if (
|
|
797
|
+
if (isPasswordError(error)) needsPassword.value = true;
|
|
575
798
|
else errorMsg.value = message;
|
|
576
799
|
} finally {
|
|
577
800
|
loadingRoot.value = false;
|
|
@@ -613,10 +836,27 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
613
836
|
const hit = files.filter((file) => selected.value.has(file.path)).length;
|
|
614
837
|
return hit > 0 && hit < files.length;
|
|
615
838
|
}
|
|
616
|
-
|
|
617
|
-
|
|
839
|
+
/** Load a directory and all of its sub-directories. */
|
|
840
|
+
async function loadTree(node) {
|
|
841
|
+
if (!node.is_dir) return true;
|
|
842
|
+
if (!await loadChildren(node)) return false;
|
|
843
|
+
for (const child of node.children) if (child.is_dir && !await loadTree(child)) return false;
|
|
844
|
+
return true;
|
|
845
|
+
}
|
|
846
|
+
async function toggleCheck(node, event) {
|
|
847
|
+
const input = event?.target;
|
|
848
|
+
if (node.is_dir && !isChecked(node)) {
|
|
849
|
+
if (await loadTree(node)) node.expanded = true;
|
|
850
|
+
else {
|
|
851
|
+
if (input) input.checked = isChecked(node);
|
|
852
|
+
return;
|
|
853
|
+
}
|
|
854
|
+
}
|
|
618
855
|
const files = descendantFiles(node);
|
|
619
|
-
if (!files.length)
|
|
856
|
+
if (!files.length) {
|
|
857
|
+
if (input) input.checked = false;
|
|
858
|
+
return;
|
|
859
|
+
}
|
|
620
860
|
const next = new Set(selected.value);
|
|
621
861
|
if (files.every((file) => next.has(file.path))) files.forEach((file) => next.delete(file.path));
|
|
622
862
|
else files.forEach((file) => next.add(file.path));
|
|
@@ -625,6 +865,39 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
625
865
|
const allFiles = computed(() => roots.value.flatMap(descendantFiles));
|
|
626
866
|
const allChecked = computed(() => allFiles.value.length > 0 && allFiles.value.every((file) => selected.value.has(file.path)));
|
|
627
867
|
const someChecked = computed(() => !allChecked.value && allFiles.value.some((file) => selected.value.has(file.path)));
|
|
868
|
+
const selectedFiles = computed(() => allFiles.value.filter((file) => selected.value.has(file.path)));
|
|
869
|
+
const selectedBytes = computed(() => totalSize(selectedFiles.value));
|
|
870
|
+
const loadedBytes = computed(() => totalSize(allFiles.value));
|
|
871
|
+
function clearSelection() {
|
|
872
|
+
selected.value = /* @__PURE__ */ new Set();
|
|
873
|
+
}
|
|
874
|
+
function folderFiles(node) {
|
|
875
|
+
return node.is_dir && node.loaded ? descendantFiles(node) : [];
|
|
876
|
+
}
|
|
877
|
+
/** Compact sort control for narrow containers, where header cells are hidden. */
|
|
878
|
+
const sortOptions = computed(() => [
|
|
879
|
+
"name",
|
|
880
|
+
"size",
|
|
881
|
+
"modified"
|
|
882
|
+
].flatMap((key) => {
|
|
883
|
+
const label = t(key === "name" ? "columnName" : key === "size" ? "columnSize" : "columnDate");
|
|
884
|
+
return [{
|
|
885
|
+
value: `${key}:asc`,
|
|
886
|
+
label: `${label} ↑`
|
|
887
|
+
}, {
|
|
888
|
+
value: `${key}:desc`,
|
|
889
|
+
label: `${label} ↓`
|
|
890
|
+
}];
|
|
891
|
+
}));
|
|
892
|
+
const sortValue = computed({
|
|
893
|
+
get: () => `${sortKey.value}:${sortAsc.value ? "asc" : "desc"}`,
|
|
894
|
+
set: (value) => {
|
|
895
|
+
const [key, direction] = value.split(":");
|
|
896
|
+
sortKey.value = key;
|
|
897
|
+
sortAsc.value = direction !== "desc";
|
|
898
|
+
resortAll();
|
|
899
|
+
}
|
|
900
|
+
});
|
|
628
901
|
function toggleCheckAll() {
|
|
629
902
|
selected.value = allChecked.value ? /* @__PURE__ */ new Set() : new Set(allFiles.value.map((file) => file.path));
|
|
630
903
|
}
|
|
@@ -696,6 +969,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
696
969
|
batchProgress.value = 0;
|
|
697
970
|
try {
|
|
698
971
|
const entries = {};
|
|
972
|
+
const usedNames = /* @__PURE__ */ new Set();
|
|
699
973
|
const queue = [...files];
|
|
700
974
|
let done = 0;
|
|
701
975
|
const worker = async () => {
|
|
@@ -704,7 +978,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
704
978
|
if (!file) break;
|
|
705
979
|
const response = await fetch(await resolveUrl(file));
|
|
706
980
|
if (!response.ok) throw new Error(`${file.name}:HTTP ${response.status}`);
|
|
707
|
-
entries[file.
|
|
981
|
+
entries[uniqueEntryName(zipEntryName(file.zipPath), usedNames)] = new Uint8Array(await response.arrayBuffer());
|
|
708
982
|
done += 1;
|
|
709
983
|
batchProgress.value = Math.round(done / files.length * 90);
|
|
710
984
|
}
|
|
@@ -729,124 +1003,258 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
729
1003
|
loadRoot();
|
|
730
1004
|
}
|
|
731
1005
|
const displayTitle = computed(() => props.title || siteTitle.value || (props.path === "/" ? t("allFiles") : props.path));
|
|
1006
|
+
const stickyTop = ref(0);
|
|
1007
|
+
function measureStickyTop() {
|
|
1008
|
+
if (typeof document === "undefined") return;
|
|
1009
|
+
let top = 0;
|
|
1010
|
+
for (const el of document.querySelectorAll(".VPNav, .VPLocalNav")) {
|
|
1011
|
+
const style = getComputedStyle(el);
|
|
1012
|
+
if (style.display === "none" || style.position !== "fixed" && style.position !== "sticky") continue;
|
|
1013
|
+
top = Math.max(top, (Number.parseFloat(style.top) || 0) + el.offsetHeight);
|
|
1014
|
+
}
|
|
1015
|
+
stickyTop.value = top;
|
|
1016
|
+
}
|
|
732
1017
|
onMounted(() => {
|
|
733
1018
|
loadRoot();
|
|
734
1019
|
loadSiteTitle();
|
|
1020
|
+
measureStickyTop();
|
|
1021
|
+
window.addEventListener("resize", measureStickyTop, { passive: true });
|
|
1022
|
+
});
|
|
1023
|
+
onBeforeUnmount(() => {
|
|
1024
|
+
window.removeEventListener("resize", measureStickyTop);
|
|
1025
|
+
clearTimeout(toastTimer);
|
|
735
1026
|
});
|
|
736
1027
|
return (_ctx, _cache) => {
|
|
737
|
-
return openBlock(), createElementBlock("div",
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
1028
|
+
return openBlock(), createElementBlock("div", {
|
|
1029
|
+
class: normalizeClass(["fl-root", { "fl-selecting": selected.value.size > 0 }]),
|
|
1030
|
+
style: normalizeStyle({ "--fl-sticky-top-auto": `${stickyTop.value}px` })
|
|
1031
|
+
}, [
|
|
1032
|
+
createElementVNode("div", _hoisted_1, [
|
|
1033
|
+
selected.value.size ? (openBlock(), createElementBlock("div", _hoisted_2, [createElementVNode("span", _hoisted_3, toDisplayString(t("selected", { count: selected.value.size })), 1), createElementVNode("span", _hoisted_4, toDisplayString(t("totalSize", { size: unref(formatSize)(selectedBytes.value) })), 1)])) : (openBlock(), createElementBlock("div", _hoisted_5, [createElementVNode("span", _hoisted_6, toDisplayString(displayTitle.value), 1), demo.value ? (openBlock(), createElementBlock("span", _hoisted_7, toDisplayString(t("demoBadge")), 1)) : createCommentVNode("v-if", true)])),
|
|
1034
|
+
selected.value.size ? (openBlock(), createElementBlock("button", {
|
|
1035
|
+
key: 2,
|
|
1036
|
+
class: "fl-clear",
|
|
1037
|
+
type: "button",
|
|
1038
|
+
"aria-label": t("clearSelection"),
|
|
1039
|
+
title: t("clearSelection"),
|
|
1040
|
+
onClick: clearSelection
|
|
1041
|
+
}, [_cache[6] || (_cache[6] = createElementVNode("svg", {
|
|
1042
|
+
class: "fl-clear-icon",
|
|
1043
|
+
viewBox: "0 0 24 24",
|
|
1044
|
+
width: "18",
|
|
1045
|
+
height: "18",
|
|
1046
|
+
fill: "none",
|
|
1047
|
+
stroke: "currentColor",
|
|
1048
|
+
"stroke-width": "2.2",
|
|
1049
|
+
"stroke-linecap": "round",
|
|
1050
|
+
"aria-hidden": "true"
|
|
1051
|
+
}, [createElementVNode("path", { d: "M6 6l12 12" }), createElementVNode("path", { d: "M18 6 6 18" })], -1)), createElementVNode("span", _hoisted_9, toDisplayString(t("clear")), 1)], 8, _hoisted_8)) : createCommentVNode("v-if", true),
|
|
1052
|
+
createElementVNode("div", _hoisted_10, [createElementVNode("label", _hoisted_11, [_cache[7] || (_cache[7] = createElementVNode("svg", {
|
|
1053
|
+
viewBox: "0 0 24 24",
|
|
1054
|
+
width: "15",
|
|
1055
|
+
height: "15",
|
|
1056
|
+
fill: "none",
|
|
1057
|
+
stroke: "currentColor",
|
|
1058
|
+
"stroke-width": "2",
|
|
1059
|
+
"stroke-linecap": "round",
|
|
1060
|
+
"aria-hidden": "true"
|
|
1061
|
+
}, [createElementVNode("circle", {
|
|
1062
|
+
cx: "11",
|
|
1063
|
+
cy: "11",
|
|
1064
|
+
r: "7"
|
|
1065
|
+
}), createElementVNode("path", { d: "m20 20-3.5-3.5" })], -1)), withDirectives(createElementVNode("input", {
|
|
744
1066
|
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => keyword.value = $event),
|
|
745
|
-
class: "fl-search",
|
|
746
1067
|
type: "text",
|
|
747
|
-
placeholder: t("filter")
|
|
748
|
-
|
|
749
|
-
createElementVNode("button", {
|
|
750
|
-
class: "fl-btn",
|
|
1068
|
+
placeholder: t("filter"),
|
|
1069
|
+
"aria-label": t("filter")
|
|
1070
|
+
}, null, 8, _hoisted_12), [[vModelText, keyword.value]])]), createElementVNode("button", {
|
|
1071
|
+
class: "fl-icon-btn",
|
|
751
1072
|
type: "button",
|
|
1073
|
+
"aria-label": t("refresh"),
|
|
1074
|
+
title: t("refresh"),
|
|
752
1075
|
onClick: loadRoot
|
|
753
|
-
},
|
|
754
|
-
|
|
1076
|
+
}, [..._cache[8] || (_cache[8] = [createElementVNode("svg", {
|
|
1077
|
+
viewBox: "0 0 24 24",
|
|
1078
|
+
width: "15",
|
|
1079
|
+
height: "15",
|
|
1080
|
+
fill: "none",
|
|
1081
|
+
stroke: "currentColor",
|
|
1082
|
+
"stroke-width": "2",
|
|
1083
|
+
"stroke-linecap": "round",
|
|
1084
|
+
"stroke-linejoin": "round",
|
|
1085
|
+
"aria-hidden": "true"
|
|
1086
|
+
}, [createElementVNode("path", { d: "M21 12a9 9 0 1 1-3-6.7" }), createElementVNode("path", { d: "M21 4v5h-5" })], -1)])], 8, _hoisted_13)]),
|
|
1087
|
+
selected.value.size ? (openBlock(), createElementBlock("button", {
|
|
1088
|
+
key: 3,
|
|
755
1089
|
class: "fl-btn fl-btn-primary",
|
|
756
1090
|
type: "button",
|
|
757
|
-
disabled:
|
|
1091
|
+
disabled: batchBusy.value,
|
|
758
1092
|
onClick: batchDownload
|
|
759
|
-
},
|
|
760
|
-
|
|
761
|
-
|
|
1093
|
+
}, [_cache[9] || (_cache[9] = createElementVNode("svg", {
|
|
1094
|
+
viewBox: "0 0 24 24",
|
|
1095
|
+
width: "15",
|
|
1096
|
+
height: "15",
|
|
1097
|
+
fill: "none",
|
|
1098
|
+
stroke: "currentColor",
|
|
1099
|
+
"stroke-width": "2.2",
|
|
1100
|
+
"stroke-linecap": "round",
|
|
1101
|
+
"stroke-linejoin": "round",
|
|
1102
|
+
"aria-hidden": "true"
|
|
1103
|
+
}, [
|
|
1104
|
+
createElementVNode("path", { d: "M12 3v12" }),
|
|
1105
|
+
createElementVNode("path", { d: "m7 10 5 5 5-5" }),
|
|
1106
|
+
createElementVNode("path", { d: "M5 21h14" })
|
|
1107
|
+
], -1)), createTextVNode(" " + toDisplayString(batchBusy.value ? t("batching", { percent: batchProgress.value }) : t("batch")), 1)], 8, _hoisted_14)) : createCommentVNode("v-if", true)
|
|
1108
|
+
]),
|
|
1109
|
+
needsPassword.value ? (openBlock(), createElementBlock("div", _hoisted_15, [
|
|
762
1110
|
createElementVNode("span", null, toDisplayString(t("passwordPrompt")), 1),
|
|
763
1111
|
withDirectives(createElementVNode("input", {
|
|
764
1112
|
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => passwordInput.value = $event),
|
|
765
1113
|
type: "password",
|
|
766
1114
|
placeholder: t("passwordPlaceholder"),
|
|
1115
|
+
"aria-label": t("passwordPlaceholder"),
|
|
767
1116
|
onKeyup: withKeys(submitPassword, ["enter"])
|
|
768
|
-
}, null, 40,
|
|
1117
|
+
}, null, 40, _hoisted_16), [[vModelText, passwordInput.value]]),
|
|
769
1118
|
createElementVNode("button", {
|
|
770
1119
|
class: "fl-btn fl-btn-primary",
|
|
771
1120
|
type: "button",
|
|
772
1121
|
onClick: submitPassword
|
|
773
1122
|
}, toDisplayString(t("open")), 1)
|
|
774
1123
|
])) : createCommentVNode("v-if", true),
|
|
775
|
-
createElementVNode("div",
|
|
776
|
-
createElementVNode("
|
|
1124
|
+
createElementVNode("div", _hoisted_17, [
|
|
1125
|
+
createElementVNode("label", _hoisted_18, [createElementVNode("input", {
|
|
777
1126
|
type: "checkbox",
|
|
1127
|
+
"aria-label": t("selectAll"),
|
|
778
1128
|
checked: allChecked.value,
|
|
779
1129
|
".indeterminate": someChecked.value,
|
|
780
1130
|
onChange: toggleCheckAll
|
|
781
|
-
}, null, 40,
|
|
782
|
-
createElementVNode("span", {
|
|
783
|
-
class: "fl-
|
|
1131
|
+
}, null, 40, _hoisted_19)]),
|
|
1132
|
+
createElementVNode("span", _hoisted_20, [createElementVNode("button", {
|
|
1133
|
+
class: "fl-sort-btn",
|
|
1134
|
+
type: "button",
|
|
1135
|
+
"aria-sort": sortKey.value === "name" ? sortAsc.value ? "ascending" : "descending" : void 0,
|
|
784
1136
|
onClick: _cache[2] || (_cache[2] = ($event) => setSort("name"))
|
|
785
|
-
}, [createTextVNode(toDisplayString(t("columnName")), 1), createElementVNode("span",
|
|
786
|
-
createElementVNode("span", {
|
|
787
|
-
class: "fl-
|
|
1137
|
+
}, [createTextVNode(toDisplayString(t("columnName")), 1), createElementVNode("span", _hoisted_22, toDisplayString(sortKey.value === "name" ? sortAsc.value ? "▲" : "▼" : ""), 1)], 8, _hoisted_21)]),
|
|
1138
|
+
createElementVNode("span", _hoisted_23, [createElementVNode("button", {
|
|
1139
|
+
class: "fl-sort-btn",
|
|
1140
|
+
type: "button",
|
|
788
1141
|
onClick: _cache[3] || (_cache[3] = ($event) => setSort("size"))
|
|
789
|
-
}, [createTextVNode(toDisplayString(t("columnSize")), 1), createElementVNode("span",
|
|
790
|
-
createElementVNode("span", {
|
|
791
|
-
class: "fl-
|
|
1142
|
+
}, [createTextVNode(toDisplayString(t("columnSize")), 1), createElementVNode("span", _hoisted_24, toDisplayString(sortKey.value === "size" ? sortAsc.value ? "▲" : "▼" : ""), 1)])]),
|
|
1143
|
+
createElementVNode("span", _hoisted_25, [createElementVNode("button", {
|
|
1144
|
+
class: "fl-sort-btn",
|
|
1145
|
+
type: "button",
|
|
792
1146
|
onClick: _cache[4] || (_cache[4] = ($event) => setSort("modified"))
|
|
793
|
-
}, [createTextVNode(toDisplayString(t("columnDate")), 1), createElementVNode("span",
|
|
794
|
-
|
|
1147
|
+
}, [createTextVNode(toDisplayString(t("columnDate")), 1), createElementVNode("span", _hoisted_26, toDisplayString(sortKey.value === "modified" ? sortAsc.value ? "▲" : "▼" : ""), 1)])]),
|
|
1148
|
+
createElementVNode("span", _hoisted_27, [createElementVNode("label", _hoisted_28, [
|
|
1149
|
+
createElementVNode("span", null, toDisplayString(t("sortBy")), 1),
|
|
1150
|
+
createElementVNode("span", _hoisted_29, toDisplayString(sortOptions.value.find((option) => option.value === sortValue.value)?.label), 1),
|
|
1151
|
+
withDirectives(createElementVNode("select", {
|
|
1152
|
+
"onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => sortValue.value = $event),
|
|
1153
|
+
"aria-label": t("sortBy")
|
|
1154
|
+
}, [(openBlock(true), createElementBlock(Fragment, null, renderList(sortOptions.value, (option) => {
|
|
1155
|
+
return openBlock(), createElementBlock("option", {
|
|
1156
|
+
key: option.value,
|
|
1157
|
+
value: option.value
|
|
1158
|
+
}, toDisplayString(option.label), 9, _hoisted_31);
|
|
1159
|
+
}), 128))], 8, _hoisted_30), [[vModelSelect, sortValue.value]])
|
|
1160
|
+
])])
|
|
795
1161
|
]),
|
|
796
|
-
loadingRoot.value ? (openBlock(), createElementBlock("div",
|
|
1162
|
+
loadingRoot.value ? (openBlock(), createElementBlock("div", _hoisted_32, toDisplayString(t("loading")), 1)) : errorMsg.value ? (openBlock(), createElementBlock("div", _hoisted_33, [
|
|
797
1163
|
createTextVNode(toDisplayString(t("loadFailed", { message: errorMsg.value })) + " ", 1),
|
|
798
|
-
/guest/i.test(errorMsg.value) ? (openBlock(), createElementBlock("p",
|
|
799
|
-
/failed to fetch|networkerror/i.test(errorMsg.value) ? (openBlock(), createElementBlock("p",
|
|
1164
|
+
/guest/i.test(errorMsg.value) ? (openBlock(), createElementBlock("p", _hoisted_34, toDisplayString(t("guestHint")), 1)) : createCommentVNode("v-if", true),
|
|
1165
|
+
/failed to fetch|networkerror/i.test(errorMsg.value) ? (openBlock(), createElementBlock("p", _hoisted_35, toDisplayString(t("corsHint")), 1)) : createCommentVNode("v-if", true),
|
|
800
1166
|
createElementVNode("button", {
|
|
801
1167
|
class: "fl-btn",
|
|
802
1168
|
type: "button",
|
|
803
1169
|
onClick: loadRoot
|
|
804
1170
|
}, toDisplayString(t("retry")), 1)
|
|
805
|
-
])) : visible.value.length === 0 ? (openBlock(), createElementBlock("div",
|
|
1171
|
+
])) : visible.value.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_36, toDisplayString(t("empty")), 1)) : createCommentVNode("v-if", true),
|
|
806
1172
|
(openBlock(true), createElementBlock(Fragment, null, renderList(visible.value, (node) => {
|
|
807
1173
|
return openBlock(), createElementBlock("div", {
|
|
808
1174
|
key: node.path,
|
|
809
1175
|
class: normalizeClass(["fl-row", {
|
|
810
1176
|
"fl-row-dir": node.is_dir,
|
|
811
1177
|
"fl-row-root": node.isRoot,
|
|
812
|
-
"fl-row-selected": selected.value.has(node.path)
|
|
813
|
-
}])
|
|
1178
|
+
"fl-row-selected": !node.is_dir && selected.value.has(node.path)
|
|
1179
|
+
}]),
|
|
1180
|
+
style: normalizeStyle({ "--fl-depth": node.depth })
|
|
814
1181
|
}, [
|
|
815
|
-
createElementVNode("
|
|
1182
|
+
createElementVNode("label", _hoisted_37, [createElementVNode("input", {
|
|
816
1183
|
type: "checkbox",
|
|
1184
|
+
"aria-label": t("selectItem", { name: node.name }),
|
|
817
1185
|
checked: isChecked(node),
|
|
818
1186
|
".indeterminate": isIndeterminate(node),
|
|
819
|
-
onChange: ($event) => toggleCheck(node)
|
|
820
|
-
}, null, 40,
|
|
1187
|
+
onChange: ($event) => toggleCheck(node, $event)
|
|
1188
|
+
}, null, 40, _hoisted_38)]),
|
|
821
1189
|
createElementVNode("span", {
|
|
822
1190
|
class: "fl-cell fl-cell-name",
|
|
823
|
-
title: node.isRoot ? node.path : void 0
|
|
824
|
-
|
|
825
|
-
|
|
1191
|
+
title: node.isRoot ? node.path : void 0
|
|
1192
|
+
}, [
|
|
1193
|
+
_cache[12] || (_cache[12] = createElementVNode("span", {
|
|
1194
|
+
class: "fl-indent",
|
|
1195
|
+
"aria-hidden": "true"
|
|
1196
|
+
}, null, -1)),
|
|
1197
|
+
node.is_dir ? (openBlock(), createElementBlock("button", {
|
|
1198
|
+
key: 0,
|
|
1199
|
+
class: normalizeClass(["fl-arrow", { "fl-arrow-open": node.expanded }]),
|
|
1200
|
+
type: "button",
|
|
1201
|
+
"aria-label": t(node.expanded ? "collapse" : "expand", { name: node.name }),
|
|
1202
|
+
"aria-expanded": node.expanded,
|
|
1203
|
+
onClick: ($event) => toggleExpand(node)
|
|
1204
|
+
}, [..._cache[10] || (_cache[10] = [createElementVNode("svg", {
|
|
1205
|
+
viewBox: "0 0 24 24",
|
|
1206
|
+
width: "14",
|
|
1207
|
+
height: "14",
|
|
1208
|
+
fill: "none",
|
|
1209
|
+
stroke: "currentColor",
|
|
1210
|
+
"stroke-width": "2.4",
|
|
1211
|
+
"stroke-linecap": "round",
|
|
1212
|
+
"stroke-linejoin": "round",
|
|
1213
|
+
"aria-hidden": "true"
|
|
1214
|
+
}, [createElementVNode("path", { d: "m9 6 6 6-6 6" })], -1)])], 10, _hoisted_40)) : (openBlock(), createElementBlock("span", _hoisted_41)),
|
|
1215
|
+
node.is_dir ? (openBlock(), createElementBlock("svg", _hoisted_42, [..._cache[11] || (_cache[11] = [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", {
|
|
1216
|
+
key: 3,
|
|
1217
|
+
class: "fl-type",
|
|
1218
|
+
"data-kind": unref(fileKind)(node.name),
|
|
1219
|
+
"aria-hidden": "true"
|
|
1220
|
+
}, toDisplayString(unref(extOf)(node.name) || "FILE"), 9, _hoisted_43)),
|
|
1221
|
+
createElementVNode("span", _hoisted_44, [createElementVNode("span", {
|
|
1222
|
+
class: normalizeClass(["fl-name", { "fl-name-dir": node.is_dir }]),
|
|
1223
|
+
onClick: ($event) => node.is_dir ? toggleExpand(node) : download(node)
|
|
1224
|
+
}, toDisplayString(node.name), 11, _hoisted_45), createElementVNode("span", _hoisted_46, [node.is_dir ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [node.loaded ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [createTextVNode(toDisplayString(t("folderItems", { count: folderFiles(node).length })) + " · " + toDisplayString(unref(formatSize)(unref(totalSize)(folderFiles(node)))), 1)], 64)) : createCommentVNode("v-if", true)], 64)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [createTextVNode(toDisplayString(unref(formatSize)(node.size)) + " · " + toDisplayString(unref(formatDate)(node.modified)), 1)], 64))])]),
|
|
1225
|
+
node.is_dir && node.loaded ? (openBlock(), createElementBlock("span", _hoisted_47, toDisplayString(t("folderItems", { count: folderFiles(node).length })), 1)) : createCommentVNode("v-if", true),
|
|
1226
|
+
node.loading ? (openBlock(), createElementBlock("span", _hoisted_48, "…")) : createCommentVNode("v-if", true)
|
|
1227
|
+
], 8, _hoisted_39),
|
|
1228
|
+
createElementVNode("span", _hoisted_49, toDisplayString(node.is_dir ? "—" : unref(formatSize)(node.size)), 1),
|
|
1229
|
+
createElementVNode("span", _hoisted_50, toDisplayString(unref(formatDate)(node.modified)), 1),
|
|
1230
|
+
createElementVNode("span", _hoisted_51, [node.is_dir ? (openBlock(), createElementBlock("button", {
|
|
826
1231
|
key: 0,
|
|
827
|
-
class: normalizeClass(["fl-arrow", { "fl-arrow-open": node.expanded }]),
|
|
1232
|
+
class: normalizeClass(["fl-action fl-arrow-end", { "fl-arrow-open": node.expanded }]),
|
|
828
1233
|
type: "button",
|
|
1234
|
+
"aria-label": t(node.expanded ? "collapse" : "expand", { name: node.name }),
|
|
1235
|
+
"aria-expanded": node.expanded,
|
|
829
1236
|
onClick: ($event) => toggleExpand(node)
|
|
830
|
-
},
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
createElementVNode("
|
|
1237
|
+
}, [..._cache[13] || (_cache[13] = [createElementVNode("svg", {
|
|
1238
|
+
viewBox: "0 0 24 24",
|
|
1239
|
+
width: "18",
|
|
1240
|
+
height: "18",
|
|
1241
|
+
fill: "none",
|
|
1242
|
+
stroke: "currentColor",
|
|
1243
|
+
"stroke-width": "2.2",
|
|
1244
|
+
"stroke-linecap": "round",
|
|
1245
|
+
"stroke-linejoin": "round",
|
|
1246
|
+
"aria-hidden": "true"
|
|
1247
|
+
}, [createElementVNode("path", { d: "m9 6 6 6-6 6" })], -1)])], 10, _hoisted_52)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [canPreview(node) ? (openBlock(), createElementBlock("button", {
|
|
841
1248
|
key: 0,
|
|
842
|
-
class: "fl-download",
|
|
1249
|
+
class: "fl-action fl-download",
|
|
843
1250
|
type: "button",
|
|
1251
|
+
"aria-label": `${t("preview")} ${node.name}`,
|
|
844
1252
|
title: t("preview"),
|
|
845
1253
|
onClick: ($event) => preview(node)
|
|
846
|
-
}, [..._cache[
|
|
1254
|
+
}, [..._cache[14] || (_cache[14] = [createElementVNode("svg", {
|
|
847
1255
|
viewBox: "0 0 24 24",
|
|
848
|
-
width: "
|
|
849
|
-
height: "
|
|
1256
|
+
width: "16",
|
|
1257
|
+
height: "16",
|
|
850
1258
|
fill: "none",
|
|
851
1259
|
stroke: "currentColor",
|
|
852
1260
|
"stroke-width": "2",
|
|
@@ -857,15 +1265,16 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
857
1265
|
cx: "12",
|
|
858
1266
|
cy: "12",
|
|
859
1267
|
r: "3"
|
|
860
|
-
})], -1)])], 8,
|
|
861
|
-
class: "fl-download",
|
|
1268
|
+
})], -1)])], 8, _hoisted_53)) : createCommentVNode("v-if", true), createElementVNode("button", {
|
|
1269
|
+
class: "fl-action fl-download",
|
|
862
1270
|
type: "button",
|
|
1271
|
+
"aria-label": `${t("download")} ${node.name}`,
|
|
863
1272
|
title: t("download"),
|
|
864
1273
|
onClick: ($event) => download(node)
|
|
865
|
-
}, [..._cache[
|
|
1274
|
+
}, [..._cache[15] || (_cache[15] = [createElementVNode("svg", {
|
|
866
1275
|
viewBox: "0 0 24 24",
|
|
867
|
-
width: "
|
|
868
|
-
height: "
|
|
1276
|
+
width: "16",
|
|
1277
|
+
height: "16",
|
|
869
1278
|
fill: "none",
|
|
870
1279
|
stroke: "currentColor",
|
|
871
1280
|
"stroke-width": "2",
|
|
@@ -876,12 +1285,12 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
876
1285
|
createElementVNode("path", { d: "M12 3v12" }),
|
|
877
1286
|
createElementVNode("path", { d: "m7 10 5 5 5-5" }),
|
|
878
1287
|
createElementVNode("path", { d: "M5 21h14" })
|
|
879
|
-
], -1)])], 8,
|
|
880
|
-
],
|
|
1288
|
+
], -1)])], 8, _hoisted_54)], 64))])
|
|
1289
|
+
], 6);
|
|
881
1290
|
}), 128)),
|
|
882
|
-
createElementVNode("div",
|
|
883
|
-
toast.value ? (openBlock(), createElementBlock("div",
|
|
884
|
-
]);
|
|
1291
|
+
createElementVNode("div", _hoisted_55, [createElementVNode("span", null, toDisplayString(t("loaded", { count: allFiles.value.length })) + " · " + toDisplayString(t("totalSize", { size: unref(formatSize)(loadedBytes.value) })), 1), unloadedFolders.value ? (openBlock(), createElementBlock("span", _hoisted_56, toDisplayString(t("unloaded", { count: unloadedFolders.value })), 1)) : createCommentVNode("v-if", true)]),
|
|
1292
|
+
toast.value ? (openBlock(), createElementBlock("div", _hoisted_57, toDisplayString(toast.value), 1)) : createCommentVNode("v-if", true)
|
|
1293
|
+
], 6);
|
|
885
1294
|
};
|
|
886
1295
|
}
|
|
887
1296
|
});
|
|
@@ -906,4 +1315,4 @@ function enhanceAppWithFileList({ app }) {
|
|
|
906
1315
|
if (!app._context.components.FileList) app.component("FileList", _sfc_main);
|
|
907
1316
|
if (!app._context.components.VPFileList) app.component("VPFileList", _sfc_main);
|
|
908
1317
|
}
|
|
909
|
-
export { _sfc_main as FileList, _sfc_main as VPFileList, compareNodes, encodePath, enhanceAppWithFileList, extOf, fileListLocales, formatDate, formatLabel, formatSize, joinPath, resolveLabels };
|
|
1318
|
+
export { _sfc_main as FileList, _sfc_main as VPFileList, compareNodes, encodePath, enhanceAppWithFileList, extOf, fileKind, fileListLocales, formatDate, formatLabel, formatSize, joinPath, resolveLabels, totalSize, uniqueEntryName, zipEntryName, zipSegment };
|