vitepress-plugin-filelist 0.7.0 → 0.7.2
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 +8 -5
- package/dist/client/browser/index.d.ts +10 -0
- package/dist/client/browser/index.js +284 -189
- package/dist/client/ssr/index.d.ts +10 -0
- package/dist/client/ssr/index.js +145 -36
- package/dist/client/style.css +90 -3
- package/package.json +1 -1
|
@@ -102,6 +102,10 @@ interface FileListLabels {
|
|
|
102
102
|
deepContinue: string;
|
|
103
103
|
deepSkipped: string;
|
|
104
104
|
deepFailed: string;
|
|
105
|
+
/** Beside a locked folder shown in deep search results. */
|
|
106
|
+
deepLocked: string;
|
|
107
|
+
/** The × in the filter box. */
|
|
108
|
+
clearFilter: string;
|
|
105
109
|
/** Markdown / HTML preview: the source / rendered switch. */
|
|
106
110
|
viewMode: string;
|
|
107
111
|
viewSource: string;
|
|
@@ -179,6 +183,11 @@ interface FileListProps {
|
|
|
179
183
|
* Defaults to `500`.
|
|
180
184
|
*/
|
|
181
185
|
deepSearchLimit?: number;
|
|
186
|
+
/**
|
|
187
|
+
* `manual` (default): “Try deep search” starts deep search mode.
|
|
188
|
+
* `auto`: typing a keyword starts it at once (for small mounts).
|
|
189
|
+
*/
|
|
190
|
+
deepSearch?: 'manual' | 'auto';
|
|
182
191
|
/**
|
|
183
192
|
* Browsers that must build the ZIP in memory (Firefox, Safari) ask first above
|
|
184
193
|
* this many MB. Defaults to 500 (200 on touch devices); `0` never asks.
|
|
@@ -216,6 +225,7 @@ declare const _default: import("vue").DefineComponent<FileListProps, {}, {}, {},
|
|
|
216
225
|
rememberPassword: boolean;
|
|
217
226
|
pageSize: number;
|
|
218
227
|
deepSearchLimit: number;
|
|
228
|
+
deepSearch: "manual" | "auto";
|
|
219
229
|
locale: FileListLocale;
|
|
220
230
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
221
231
|
declare global {
|
package/dist/client/ssr/index.js
CHANGED
|
@@ -575,8 +575,8 @@ const _sfc_main$3 = /*@__PURE__*/ defineComponent({
|
|
|
575
575
|
"aria-label": __props.title
|
|
576
576
|
}, _attrs))}>`);
|
|
577
577
|
if (__props.open) {
|
|
578
|
-
_push(`<div class="fl-confirm-panel"><
|
|
579
|
-
if (__props.tip) _push(`<
|
|
578
|
+
_push(`<div class="fl-confirm-panel"><div class="fl-confirm-title">${ssrInterpolate(__props.title)}</div><div class="fl-confirm-text">${ssrInterpolate(__props.text)}</div>`);
|
|
579
|
+
if (__props.tip) _push(`<div class="fl-confirm-text">${ssrInterpolate(__props.tip)}</div>`);
|
|
580
580
|
else _push(`<!---->`);
|
|
581
581
|
_push(`<div class="fl-confirm-actions">`);
|
|
582
582
|
if (__props.confirmLabel) _push(`<button class="fl-btn" type="button">${ssrInterpolate(__props.cancelLabel)}</button>`);
|
|
@@ -869,8 +869,8 @@ const fileListLocales = {
|
|
|
869
869
|
forgetPassword: "忘记",
|
|
870
870
|
unlockFolder: "输入 {name} 的密码",
|
|
871
871
|
networkHint: "可能被跨域拦截:请检查 OpenList 的 cors.allow_origins,或 OpenList-Worker 的 ALLOW_URLS。",
|
|
872
|
-
deepHint: "
|
|
873
|
-
deepSearch: "
|
|
872
|
+
deepHint: "只筛选了已加载的内容,",
|
|
873
|
+
deepSearch: "尝试深度搜索",
|
|
874
874
|
deepRunning: "正在深度搜索 · 已查找 {count} 个文件夹",
|
|
875
875
|
deepStop: "停止",
|
|
876
876
|
deepDone: "已搜索全部 {count} 个文件夹",
|
|
@@ -878,6 +878,8 @@ const fileListLocales = {
|
|
|
878
878
|
deepContinue: "继续",
|
|
879
879
|
deepSkipped: "跳过 {count} 个加密文件夹",
|
|
880
880
|
deepFailed: "{count} 个文件夹读取失败",
|
|
881
|
+
deepLocked: "未搜索(需要密码)",
|
|
882
|
+
clearFilter: "清除筛选",
|
|
881
883
|
viewMode: "显示方式",
|
|
882
884
|
viewSource: "源码",
|
|
883
885
|
viewRendered: "渲染",
|
|
@@ -963,8 +965,8 @@ const fileListLocales = {
|
|
|
963
965
|
forgetPassword: "Forget",
|
|
964
966
|
unlockFolder: "Enter the password for {name}",
|
|
965
967
|
networkHint: "Possibly blocked by CORS: check cors.allow_origins in OpenList, or ALLOW_URLS in OpenList-Worker.",
|
|
966
|
-
deepHint: "Only loaded folders are filtered",
|
|
967
|
-
deepSearch: "
|
|
968
|
+
deepHint: "Only loaded folders are filtered. ",
|
|
969
|
+
deepSearch: "Try deep search",
|
|
968
970
|
deepRunning: "Searching · {count} folders checked",
|
|
969
971
|
deepStop: "Stop",
|
|
970
972
|
deepDone: "Searched all {count} folders",
|
|
@@ -972,6 +974,8 @@ const fileListLocales = {
|
|
|
972
974
|
deepContinue: "Continue",
|
|
973
975
|
deepSkipped: "{count} locked folders skipped",
|
|
974
976
|
deepFailed: "{count} folders could not be read",
|
|
977
|
+
deepLocked: "Not searched (password needed)",
|
|
978
|
+
clearFilter: "Clear filter",
|
|
975
979
|
viewMode: "View",
|
|
976
980
|
viewSource: "Source",
|
|
977
981
|
viewRendered: "Rendered",
|
|
@@ -1315,19 +1319,19 @@ const _sfc_main$1 = /*@__PURE__*/ defineComponent({
|
|
|
1315
1319
|
else if (mode.value === "audio") _push(`<audio class="fl-preview-audio"${ssrRenderAttr("src", __props.src)} controls preload="metadata"></audio>`);
|
|
1316
1320
|
else if (mode.value === "text") {
|
|
1317
1321
|
_push(`<div class="${ssrRenderClass([{ "fl-preview-rendered": renderAs.value && view.value === "rendered" }, "fl-preview-text"])}">`);
|
|
1318
|
-
if (truncated.value) _push(`<
|
|
1322
|
+
if (truncated.value) _push(`<div class="fl-preview-note">${ssrInterpolate(t("textTruncated", { size: unref(formatSize)(__props.maxTextBytes) }))}</div>`);
|
|
1319
1323
|
else _push(`<!---->`);
|
|
1320
1324
|
if (renderAs.value === "markdown" && view.value === "rendered") {
|
|
1321
1325
|
_push(`<!--[--><!-- sanitised by renderMarkdown (DOMPurify) -->`);
|
|
1322
1326
|
if (renderedHtml.value) _push(`<div class="vp-doc fl-md">${renderedHtml.value ?? ""}</div>`);
|
|
1323
1327
|
else _push(`<div class="fl-preview-status" role="status">${ssrInterpolate(t("loading"))}</div>`);
|
|
1324
1328
|
_push(`<!--]-->`);
|
|
1325
|
-
} else if (renderAs.value === "html" && view.value === "rendered") _push(`<!--[--><
|
|
1329
|
+
} else if (renderAs.value === "html" && view.value === "rendered") _push(`<!--[--><div class="fl-preview-note">${ssrInterpolate(t("htmlSandboxNote"))}</div><!-- empty sandbox: no scripts, no forms, no popups, an opaque origin --><iframe class="fl-preview-html" sandbox="" referrerpolicy="no-referrer"${ssrRenderAttr("srcdoc", textContent.value)}${ssrRenderAttr("title", __props.file.name)}></iframe><!--]-->`);
|
|
1326
1330
|
else _push(`<pre>${ssrInterpolate(textContent.value)}</pre>`);
|
|
1327
1331
|
_push(`</div>`);
|
|
1328
1332
|
} else if (mode.value === "pdf") _push(`<iframe class="fl-preview-frame"${ssrRenderAttr("src", __props.viewer || blobUrl.value)}${ssrRenderAttr("title", __props.file.name)}></iframe>`);
|
|
1329
1333
|
else {
|
|
1330
|
-
_push(`<div class="fl-preview-info"><span class="fl-type fl-preview-badge"${ssrRenderAttr("data-kind", unref(fileKind)(__props.file.name))} aria-hidden="true">${ssrInterpolate(unref(extOf)(__props.file.name) || "FILE")}</span><
|
|
1334
|
+
_push(`<div class="fl-preview-info"><span class="fl-type fl-preview-badge"${ssrRenderAttr("data-kind", unref(fileKind)(__props.file.name))} aria-hidden="true">${ssrInterpolate(unref(extOf)(__props.file.name) || "FILE")}</span><div class="fl-preview-message">${ssrInterpolate(infoMessage.value)}</div>`);
|
|
1331
1335
|
if (!__props.demo) {
|
|
1332
1336
|
_push(`<button class="fl-btn fl-btn-primary" type="button">`);
|
|
1333
1337
|
_push(ssrRenderComponent(_sfc_main$2, {
|
|
@@ -1563,6 +1567,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
1563
1567
|
},
|
|
1564
1568
|
pageSize: { default: 200 },
|
|
1565
1569
|
deepSearchLimit: { default: 500 },
|
|
1570
|
+
deepSearch: { default: "manual" },
|
|
1566
1571
|
zipWarnSize: {},
|
|
1567
1572
|
zipMaxSize: {},
|
|
1568
1573
|
locale: { default: "zh-CN" },
|
|
@@ -1722,6 +1727,21 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
1722
1727
|
zipPath: [item.is_dir ? name : item.name || sourceName(path)]
|
|
1723
1728
|
};
|
|
1724
1729
|
}
|
|
1730
|
+
/** Run at most `size` tasks at once. */
|
|
1731
|
+
function concurrency(size) {
|
|
1732
|
+
let active = 0;
|
|
1733
|
+
const waiting = [];
|
|
1734
|
+
return async (task) => {
|
|
1735
|
+
if (active >= size) await new Promise((resolve) => waiting.push(resolve));
|
|
1736
|
+
active += 1;
|
|
1737
|
+
try {
|
|
1738
|
+
return await task();
|
|
1739
|
+
} finally {
|
|
1740
|
+
active -= 1;
|
|
1741
|
+
waiting.shift()?.();
|
|
1742
|
+
}
|
|
1743
|
+
};
|
|
1744
|
+
}
|
|
1725
1745
|
class RootLockedError extends Error {
|
|
1726
1746
|
rememberedAt;
|
|
1727
1747
|
constructor(rememberedAt) {
|
|
@@ -1733,7 +1753,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
1733
1753
|
* Build a fresh tree. `expandedPaths` re-opens those folders (refresh keeps
|
|
1734
1754
|
* what was open); without it the configured `expanded` defaults apply.
|
|
1735
1755
|
*/
|
|
1736
|
-
async function buildTree(expandedPaths) {
|
|
1756
|
+
async function buildTree(expandedPaths, loadedPaths) {
|
|
1737
1757
|
let nodes;
|
|
1738
1758
|
if (props.sources.length) nodes = await Promise.all(props.sources.map((source) => loadSourceRoot(source, expandedPaths ? expandedPaths.has(source.path) : source.expanded ?? props.expanded)));
|
|
1739
1759
|
else {
|
|
@@ -1744,13 +1764,16 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
1744
1764
|
throw isPasswordError(error) ? new RootLockedError(rememberedAt) : error;
|
|
1745
1765
|
}
|
|
1746
1766
|
}
|
|
1767
|
+
const limit = concurrency(4);
|
|
1747
1768
|
const open = async (list) => {
|
|
1748
|
-
|
|
1749
|
-
const wanted = node.expanded || expandedPaths?.has(node.path);
|
|
1750
|
-
|
|
1751
|
-
node.
|
|
1752
|
-
|
|
1753
|
-
|
|
1769
|
+
await Promise.all(list.map(async (node) => {
|
|
1770
|
+
const wanted = !!(node.expanded || expandedPaths?.has(node.path));
|
|
1771
|
+
const keep = !!loadedPaths?.has(node.path);
|
|
1772
|
+
if (!node.is_dir || node.lock || !(wanted || keep)) return;
|
|
1773
|
+
const ok = await limit(() => loadChildren(node, wanted ? "show" : false, !wanted));
|
|
1774
|
+
node.expanded = wanted && ok;
|
|
1775
|
+
if (ok && (expandedPaths || loadedPaths)) await open(node.children);
|
|
1776
|
+
}));
|
|
1754
1777
|
};
|
|
1755
1778
|
await open(nodes);
|
|
1756
1779
|
return nodes;
|
|
@@ -1820,7 +1843,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
1820
1843
|
const rows = computed(() => {
|
|
1821
1844
|
const out = [];
|
|
1822
1845
|
const query = keyword.value.trim().toLowerCase();
|
|
1823
|
-
const matches = (node) => !query || node.name.toLowerCase().includes(query) || node.is_dir && node.children.some(matches);
|
|
1846
|
+
const matches = (node) => !query || node.name.toLowerCase().includes(query) || node.is_dir && (node.children.some(matches) || deepMode.value && !!node.lock);
|
|
1824
1847
|
const walk = (nodes, key, depth) => {
|
|
1825
1848
|
const list = nodes.filter(matches);
|
|
1826
1849
|
const limit = query ? list.length : Math.min(list.length, limitOf(key));
|
|
@@ -1874,11 +1897,16 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
1874
1897
|
const deep = reactive({
|
|
1875
1898
|
running: false,
|
|
1876
1899
|
searched: 0,
|
|
1877
|
-
skipped: 0,
|
|
1878
1900
|
failed: 0,
|
|
1879
1901
|
capped: false,
|
|
1880
1902
|
done: false
|
|
1881
1903
|
});
|
|
1904
|
+
/**
|
|
1905
|
+
* Deep search mode: entered by “Try deep search” (or at once with
|
|
1906
|
+
* `deep-search="auto"`), left by clearing the filter. While on, new keywords,
|
|
1907
|
+
* refreshes and newly unlocked folders are searched without asking again.
|
|
1908
|
+
*/
|
|
1909
|
+
const deepMode = ref(false);
|
|
1882
1910
|
let deepSeq = 0;
|
|
1883
1911
|
/** Folders that are known but not loaded yet (locked ones excluded). */
|
|
1884
1912
|
function unloadedFolders() {
|
|
@@ -1898,27 +1926,97 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
1898
1926
|
if (!keyword.value.trim()) return null;
|
|
1899
1927
|
if (deep.running) return "running";
|
|
1900
1928
|
if (deep.capped) return "capped";
|
|
1901
|
-
if (
|
|
1929
|
+
if (!deepMode.value) return hasUnloaded.value ? "idle" : null;
|
|
1902
1930
|
return deep.done ? "done" : null;
|
|
1903
1931
|
});
|
|
1932
|
+
/** “Try deep search”, “Continue”, and the automatic runs of deep search mode. */
|
|
1933
|
+
async function deepSearch() {
|
|
1934
|
+
deepMode.value = true;
|
|
1935
|
+
const seq = ++deepSeq;
|
|
1936
|
+
const limit = Math.max(1, Math.floor(props.deepSearchLimit ?? 500));
|
|
1937
|
+
const runStart = deep.searched;
|
|
1938
|
+
Object.assign(deep, {
|
|
1939
|
+
running: true,
|
|
1940
|
+
capped: false,
|
|
1941
|
+
done: false
|
|
1942
|
+
});
|
|
1943
|
+
let wave = unloadedFolders();
|
|
1944
|
+
while (wave.length && seq === deepSeq) {
|
|
1945
|
+
const next = [];
|
|
1946
|
+
const queue = [...wave];
|
|
1947
|
+
const worker = async () => {
|
|
1948
|
+
for (let node = queue.shift(); node && seq === deepSeq; node = queue.shift()) {
|
|
1949
|
+
if (deep.searched - runStart >= limit) return;
|
|
1950
|
+
deep.searched += 1;
|
|
1951
|
+
if (!await loadChildren(node, false, true)) {
|
|
1952
|
+
if (!node.lock) deep.failed += 1;
|
|
1953
|
+
continue;
|
|
1954
|
+
}
|
|
1955
|
+
for (const child of node.children) if (child.is_dir && !child.loaded && !child.lock) next.push(child);
|
|
1956
|
+
}
|
|
1957
|
+
};
|
|
1958
|
+
await Promise.all(Array.from({ length: Math.min(4, queue.length) }, worker));
|
|
1959
|
+
if (deep.searched - runStart >= limit) break;
|
|
1960
|
+
wave = next;
|
|
1961
|
+
}
|
|
1962
|
+
if (seq !== deepSeq) return;
|
|
1963
|
+
deep.running = false;
|
|
1964
|
+
deep.capped = hasUnloaded.value && deep.searched - runStart >= limit;
|
|
1965
|
+
deep.done = !deep.capped;
|
|
1966
|
+
}
|
|
1967
|
+
/** Pause a run (internal: refresh, reload). */
|
|
1904
1968
|
function stopDeepSearch() {
|
|
1905
1969
|
deepSeq += 1;
|
|
1906
1970
|
deep.running = false;
|
|
1907
1971
|
}
|
|
1908
1972
|
watch(keyword, (value) => {
|
|
1909
|
-
if (value.trim())
|
|
1973
|
+
if (value.trim()) {
|
|
1974
|
+
if (props.deepSearch === "auto") deepMode.value = true;
|
|
1975
|
+
return;
|
|
1976
|
+
}
|
|
1910
1977
|
stopDeepSearch();
|
|
1978
|
+
deepMode.value = false;
|
|
1911
1979
|
Object.assign(deep, {
|
|
1912
1980
|
searched: 0,
|
|
1913
|
-
skipped: 0,
|
|
1914
1981
|
failed: 0,
|
|
1915
1982
|
capped: false,
|
|
1916
1983
|
done: false
|
|
1917
1984
|
});
|
|
1918
1985
|
});
|
|
1986
|
+
watch(() => deepMode.value && hasUnloaded.value && !deep.running && !deep.capped && !refreshing.value, (ready) => {
|
|
1987
|
+
if (ready) deepSearch();
|
|
1988
|
+
});
|
|
1989
|
+
/**
|
|
1990
|
+
* Counted from the tree, so a refresh that re-reads the same folders shows the
|
|
1991
|
+
* same numbers: folders read (or found locked), and the locked ones.
|
|
1992
|
+
*/
|
|
1993
|
+
const folderCounts = computed(() => {
|
|
1994
|
+
const counts = {
|
|
1995
|
+
checked: 0,
|
|
1996
|
+
locked: 0
|
|
1997
|
+
};
|
|
1998
|
+
const walk = (nodes) => {
|
|
1999
|
+
for (const node of nodes) {
|
|
2000
|
+
if (!node.is_dir) continue;
|
|
2001
|
+
if (node.lock) {
|
|
2002
|
+
counts.checked += 1;
|
|
2003
|
+
counts.locked += 1;
|
|
2004
|
+
} else if (node.loaded) {
|
|
2005
|
+
counts.checked += 1;
|
|
2006
|
+
walk(node.children);
|
|
2007
|
+
}
|
|
2008
|
+
}
|
|
2009
|
+
};
|
|
2010
|
+
walk(roots.value);
|
|
2011
|
+
return counts;
|
|
2012
|
+
});
|
|
2013
|
+
const lockedFolders = computed(() => folderCounts.value.locked);
|
|
2014
|
+
function lockedInSearch(node) {
|
|
2015
|
+
return deepMode.value && !!node.lock && !!keyword.value.trim();
|
|
2016
|
+
}
|
|
1919
2017
|
const deepSummary = computed(() => [
|
|
1920
|
-
deepRow.value === "capped" ?
|
|
1921
|
-
|
|
2018
|
+
t(deepRow.value === "capped" ? "deepCapped" : "deepDone", { count: folderCounts.value.checked }),
|
|
2019
|
+
lockedFolders.value ? t("deepSkipped", { count: lockedFolders.value }) : "",
|
|
1922
2020
|
deep.failed ? t("deepFailed", { count: deep.failed }) : ""
|
|
1923
2021
|
].filter(Boolean).join(" · "));
|
|
1924
2022
|
const stats = computed(() => folderStats(roots.value, selected.value));
|
|
@@ -2150,7 +2248,16 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
2150
2248
|
name: "search",
|
|
2151
2249
|
size: 15
|
|
2152
2250
|
}, null, _parent));
|
|
2153
|
-
_push(`<input${ssrRenderAttr("value", keyword.value)} type="text"${ssrRenderAttr("placeholder", t("filter"))}${ssrRenderAttr("aria-label", t("filter"))}
|
|
2251
|
+
_push(`<input${ssrRenderAttr("value", keyword.value)} type="text"${ssrRenderAttr("placeholder", t("filter"))}${ssrRenderAttr("aria-label", t("filter"))}>`);
|
|
2252
|
+
if (keyword.value) {
|
|
2253
|
+
_push(`<button class="fl-search-clear" type="button"${ssrRenderAttr("aria-label", t("clearFilter"))}${ssrRenderAttr("title", t("clearFilter"))}>`);
|
|
2254
|
+
_push(ssrRenderComponent(_sfc_main$2, {
|
|
2255
|
+
name: "close",
|
|
2256
|
+
size: 12
|
|
2257
|
+
}, null, _parent));
|
|
2258
|
+
_push(`</button>`);
|
|
2259
|
+
} else _push(`<!---->`);
|
|
2260
|
+
_push(`</label><button class="${ssrRenderClass([{ "fl-spinning": refreshing.value }, "fl-icon-btn fl-refresh"])}" type="button"${ssrIncludeBooleanAttr(refreshing.value || loadingRoot.value) ? " disabled" : ""}${ssrRenderAttr("aria-label", refreshing.value ? t("refreshing") : t("refresh"))}${ssrRenderAttr("title", refreshing.value ? t("refreshing") : t("refresh"))}>`);
|
|
2154
2261
|
_push(ssrRenderComponent(_sfc_main$2, {
|
|
2155
2262
|
name: "refresh",
|
|
2156
2263
|
size: 15
|
|
@@ -2200,9 +2307,9 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
2200
2307
|
_push(`<button class="fl-unlock-submit" type="submit"${ssrIncludeBooleanAttr(rootLock.value.busy || !rootLock.value.input) ? " disabled" : ""}>${ssrInterpolate(t("open"))}</button></span></form>`);
|
|
2201
2308
|
} else if (errorMsg.value) {
|
|
2202
2309
|
_push(`<div class="fl-status fl-error">${ssrInterpolate(t("loadFailed", { message: errorMsg.value }))} `);
|
|
2203
|
-
if (/guest/i.test(errorMsg.value)) _push(`<
|
|
2310
|
+
if (/guest/i.test(errorMsg.value)) _push(`<div class="fl-hint">${ssrInterpolate(t("guestHint"))}</div>`);
|
|
2204
2311
|
else _push(`<!---->`);
|
|
2205
|
-
if (unref(isNetworkError)(errorMsg.value)) _push(`<
|
|
2312
|
+
if (unref(isNetworkError)(errorMsg.value)) _push(`<div class="fl-hint">${ssrInterpolate(t("corsHint"))}</div>`);
|
|
2206
2313
|
else _push(`<!---->`);
|
|
2207
2314
|
_push(`<button class="fl-btn" type="button">${ssrInterpolate(t("retry"))}</button></div>`);
|
|
2208
2315
|
} else if (visible.value.length === 0) _push(`<div class="fl-status">${ssrInterpolate(t("empty"))}</div>`);
|
|
@@ -2251,8 +2358,11 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
2251
2358
|
_push(`<!--]--></span><span class="fl-meta">`);
|
|
2252
2359
|
if (!node.is_dir) _push(`<!--[-->${ssrInterpolate(unref(formatSize)(node.size))} · ${ssrInterpolate(unref(formatDate)(node.modified))}<!--]-->`);
|
|
2253
2360
|
else if (node.loaded) _push(`<!--[-->${ssrInterpolate(t("folderItems", { count: statsOf(node).files }))} · ${ssrInterpolate(unref(formatSize)(statsOf(node).bytes))}<!--]-->`);
|
|
2361
|
+
else if (lockedInSearch(node)) _push(`<span class="fl-locked-note">${ssrInterpolate(t("deepLocked"))}</span>`);
|
|
2254
2362
|
else _push(`<!---->`);
|
|
2255
2363
|
_push(`</span></span>`);
|
|
2364
|
+
if (lockedInSearch(node) && !node.lock?.prompting) _push(`<span class="fl-locked-note fl-locked-hint">${ssrInterpolate(t("deepLocked"))}</span>`);
|
|
2365
|
+
else _push(`<!---->`);
|
|
2256
2366
|
if (node.is_dir && node.loaded) _push(`<span class="fl-count">${ssrInterpolate(t("folderItems", { count: statsOf(node).files }))}</span>`);
|
|
2257
2367
|
else _push(`<!---->`);
|
|
2258
2368
|
if (node.lock?.prompting && node.lock.error) _push(`<span${ssrRenderAttr("id", `${unref(uid)}-error-${index}`)} class="fl-unlock-message" role="alert">${ssrInterpolate(unlockErrorText(node.lock.error))}</span>`);
|
|
@@ -2322,16 +2432,15 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
2322
2432
|
});
|
|
2323
2433
|
_push(`<!--]-->`);
|
|
2324
2434
|
if (deepRow.value) {
|
|
2325
|
-
_push(`<div class="fl-
|
|
2326
|
-
if (deepRow.value === "running") _push(`<!--[
|
|
2327
|
-
else if (deepRow.value === "idle") _push(`<!--[
|
|
2328
|
-
else {
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
_push(`</span></div>`);
|
|
2435
|
+
_push(`<div class="fl-deep" role="status"><div class="fl-deep-text">`);
|
|
2436
|
+
if (deepRow.value === "running") _push(`<!--[-->${ssrInterpolate(t("deepRunning", { count: folderCounts.value.checked }))} · <button class="fl-deep-link" type="button">${ssrInterpolate(t("deepStop"))}</button><!--]-->`);
|
|
2437
|
+
else if (deepRow.value === "idle") _push(`<!--[-->${ssrInterpolate(t("deepHint"))}<button class="fl-deep-link" type="button">${ssrInterpolate(t("deepSearch"))}</button><!--]-->`);
|
|
2438
|
+
else if (deepRow.value === "capped") _push(`<!--[-->${ssrInterpolate(deepSummary.value)} · <button class="fl-deep-link" type="button">${ssrInterpolate(t("deepContinue"))}</button><!--]-->`);
|
|
2439
|
+
else _push(`<!--[-->${ssrInterpolate(deepSummary.value)}<!--]-->`);
|
|
2440
|
+
_push(`</div>`);
|
|
2441
|
+
if (deepRow.value === "running") _push(`<span class="fl-deep-bar" aria-hidden="true"></span>`);
|
|
2442
|
+
else _push(`<!---->`);
|
|
2443
|
+
_push(`</div>`);
|
|
2335
2444
|
} else _push(`<!---->`);
|
|
2336
2445
|
_push(`<div class="fl-foot"><span>${ssrInterpolate(t("loaded", { count: allFiles.value.length }))} · ${ssrInterpolate(t("totalSize", { size: unref(formatSize)(unref(totalSize)(allFiles.value)) }))}</span></div>`);
|
|
2337
2446
|
if (toast.value) _push(`<div class="fl-toast" role="status">${ssrInterpolate(toast.value)}</div>`);
|
package/dist/client/style.css
CHANGED
|
@@ -771,6 +771,7 @@
|
|
|
771
771
|
.fl-hint {
|
|
772
772
|
margin: 6px 0 0;
|
|
773
773
|
font-size: 12px;
|
|
774
|
+
line-height: 1.5;
|
|
774
775
|
color: var(--vp-c-text-2);
|
|
775
776
|
}
|
|
776
777
|
|
|
@@ -824,8 +825,7 @@
|
|
|
824
825
|
|
|
825
826
|
/* ---------------- long folders ---------------- */
|
|
826
827
|
|
|
827
|
-
.fl-more
|
|
828
|
-
.fl-deep {
|
|
828
|
+
.fl-more {
|
|
829
829
|
background: var(--vp-c-bg-soft);
|
|
830
830
|
}
|
|
831
831
|
|
|
@@ -878,8 +878,69 @@
|
|
|
878
878
|
border-radius: 3px;
|
|
879
879
|
}
|
|
880
880
|
|
|
881
|
+
.fl-search-clear {
|
|
882
|
+
display: inline-flex;
|
|
883
|
+
flex: none;
|
|
884
|
+
align-items: center;
|
|
885
|
+
justify-content: center;
|
|
886
|
+
width: 20px;
|
|
887
|
+
height: 20px;
|
|
888
|
+
padding: 0;
|
|
889
|
+
color: var(--vp-c-text-2);
|
|
890
|
+
cursor: pointer;
|
|
891
|
+
background: var(--vp-c-default-soft);
|
|
892
|
+
border: 0;
|
|
893
|
+
border-radius: 50%;
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
.fl-search-clear:hover {
|
|
897
|
+
color: var(--vp-c-text-1);
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
/* the status line closing a filtered list: centred, wraps, never overflows */
|
|
881
901
|
.fl-deep {
|
|
882
902
|
position: relative;
|
|
903
|
+
display: flex;
|
|
904
|
+
align-items: center;
|
|
905
|
+
justify-content: center;
|
|
906
|
+
box-sizing: border-box;
|
|
907
|
+
min-height: 40px;
|
|
908
|
+
padding: 8px 16px;
|
|
909
|
+
text-align: center;
|
|
910
|
+
background: var(--vp-c-bg-soft);
|
|
911
|
+
border-bottom: 1px solid var(--vp-c-divider);
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
.fl-deep-text {
|
|
915
|
+
font-size: 13px;
|
|
916
|
+
line-height: 1.6;
|
|
917
|
+
color: var(--vp-c-text-2);
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
.fl-deep-link {
|
|
921
|
+
padding: 0;
|
|
922
|
+
font: inherit;
|
|
923
|
+
font-weight: 600;
|
|
924
|
+
color: var(--vp-c-brand-1);
|
|
925
|
+
text-decoration: underline;
|
|
926
|
+
text-underline-offset: 3px;
|
|
927
|
+
cursor: pointer;
|
|
928
|
+
background: none;
|
|
929
|
+
border: 0;
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
.fl-deep-link:hover {
|
|
933
|
+
color: var(--vp-c-brand-2);
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
.fl-locked-note {
|
|
937
|
+
font-size: 12px;
|
|
938
|
+
color: var(--fl-lock-fg);
|
|
939
|
+
white-space: nowrap;
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
.fl-locked-hint {
|
|
943
|
+
margin-left: 8px;
|
|
883
944
|
}
|
|
884
945
|
|
|
885
946
|
.fl-deep-bar {
|
|
@@ -925,6 +986,7 @@
|
|
|
925
986
|
.fl-confirm-title {
|
|
926
987
|
margin: 0 0 10px;
|
|
927
988
|
font-size: 16px;
|
|
989
|
+
line-height: 1.5;
|
|
928
990
|
font-weight: 600;
|
|
929
991
|
}
|
|
930
992
|
|
|
@@ -963,7 +1025,31 @@
|
|
|
963
1025
|
flex: 1 1 auto;
|
|
964
1026
|
width: auto;
|
|
965
1027
|
height: 40px;
|
|
966
|
-
padding: 0 12px;
|
|
1028
|
+
padding: 0 4px 0 12px;
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
.fl-search-clear {
|
|
1032
|
+
width: 36px;
|
|
1033
|
+
height: 36px;
|
|
1034
|
+
background: transparent;
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
.fl-deep {
|
|
1038
|
+
min-height: 48px;
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
.fl-deep-text {
|
|
1042
|
+
font-size: 14px;
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
/* a taller tap target without changing the line */
|
|
1046
|
+
.fl-deep-link {
|
|
1047
|
+
padding: 11px 2px;
|
|
1048
|
+
margin: -11px 0;
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
.fl-locked-hint {
|
|
1052
|
+
display: none;
|
|
967
1053
|
}
|
|
968
1054
|
|
|
969
1055
|
/* 16px keeps iOS Safari from zooming in on focus */
|
|
@@ -1476,6 +1562,7 @@
|
|
|
1476
1562
|
margin: 0;
|
|
1477
1563
|
padding: 8px 20px;
|
|
1478
1564
|
font-size: 12px;
|
|
1565
|
+
line-height: 1.5;
|
|
1479
1566
|
color: var(--vp-c-text-2);
|
|
1480
1567
|
background: var(--vp-c-bg-soft);
|
|
1481
1568
|
border-bottom: 1px solid var(--vp-c-divider);
|
package/package.json
CHANGED