Upload app.js
Browse files- static/app.js +65 -0
static/app.js
CHANGED
|
@@ -145,6 +145,7 @@ function parseSizeStr(str) {
|
|
| 145 |
}
|
| 146 |
var HISTORY_KEY = "voml_search_history";
|
| 147 |
var HISTORY_MAX = 20;
|
|
|
|
| 148 |
|
| 149 |
function getHistory() {
|
| 150 |
try { return JSON.parse(localStorage.getItem(HISTORY_KEY)) || []; }
|
|
@@ -156,6 +157,38 @@ function saveHistory(list) {
|
|
| 156 |
catch (e) {}
|
| 157 |
}
|
| 158 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 159 |
function stableSearchStringify(value) {
|
| 160 |
if (Array.isArray(value)) return '[' + value.map(stableSearchStringify).join(',') + ']';
|
| 161 |
if (value && typeof value === 'object') {
|
|
@@ -881,6 +914,7 @@ function syncStateToURL(replace = true) {
|
|
| 881 |
if (!STATE.searchFolders) params.set("search_folders", "false");
|
| 882 |
if (!STATE.exact) params.set("exact", "0");
|
| 883 |
if (!STATE.recordHistory) params.set("history", "0");
|
|
|
|
| 884 |
const qs = params.toString();
|
| 885 |
const path = STATE.mode === "global" ? "/" : `/${STATE.repo}`;
|
| 886 |
const url = qs ? `${path}?${qs}` : path;
|
|
@@ -928,6 +962,31 @@ function syncURLToState() {
|
|
| 928 |
const searchFolders = params.get("search_folders");
|
| 929 |
STATE.searchFolders = searchFolders !== "false";
|
| 930 |
DOM.searchFoldersToggle.checked = STATE.searchFolders;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 931 |
STATE.exact = params.get("exact") !== "0";
|
| 932 |
DOM.exactSearchToggle.checked = STATE.exact;
|
| 933 |
STATE.recordHistory = params.get("history") !== "0";
|
|
@@ -1966,8 +2025,10 @@ function persistFolderSelection(subtreeSet, selfSet) {
|
|
| 1966 |
selfSet.forEach(path => { if (path) merged.push(path); });
|
| 1967 |
subtreeSet.forEach(path => { if (path && !merged.includes(path)) merged.push(path); });
|
| 1968 |
STATE.filterFolders = merged;
|
|
|
|
| 1969 |
STATE.page = 1;
|
| 1970 |
STATE.results = [];
|
|
|
|
| 1971 |
doSearch();
|
| 1972 |
}
|
| 1973 |
|
|
@@ -2411,6 +2472,7 @@ function setupKeyboard() {
|
|
| 2411 |
function clearAllFilters() {
|
| 2412 |
STATE.filterRepos = []; STATE.filterExtensions = []; STATE.filterFolders = []; STATE.filterFolderSubtrees = []; STATE.filterFolderSelfs = [];
|
| 2413 |
STATE.filterMinSize = null; STATE.filterMaxSize = null;
|
|
|
|
| 2414 |
STATE.page = 1; STATE.results = [];
|
| 2415 |
DOM.filterMinSize.value = ""; DOM.filterMaxSize.value = "";
|
| 2416 |
DOM.filterMinUnit.value = "MB"; DOM.filterMaxUnit.value = "MB";
|
|
@@ -2461,7 +2523,9 @@ function setupResultDelegation() {
|
|
| 2461 |
STATE.filterFolders = folder ? [folder] : [];
|
| 2462 |
STATE.filterFolderSubtrees = [];
|
| 2463 |
STATE.filterFolderSelfs = folder ? [folder] : [];
|
|
|
|
| 2464 |
STATE.page = 1; STATE.results = [];
|
|
|
|
| 2465 |
renderFilters(routeRenderId); doSearch();
|
| 2466 |
}
|
| 2467 |
return;
|
|
@@ -2540,6 +2604,7 @@ async function init() {
|
|
| 2540 |
DOM.historyToggle.addEventListener("change", () => {
|
| 2541 |
STATE.recordHistory = DOM.historyToggle.checked;
|
| 2542 |
if (!STATE.recordHistory) saveHistory([]);
|
|
|
|
| 2543 |
});
|
| 2544 |
if (DOM.mirrorLinksToggle) DOM.mirrorLinksToggle.addEventListener("change", () => {
|
| 2545 |
STATE.useMirrorLinks = DOM.mirrorLinksToggle.checked;
|
|
|
|
| 145 |
}
|
| 146 |
var HISTORY_KEY = "voml_search_history";
|
| 147 |
var HISTORY_MAX = 20;
|
| 148 |
+
var FOLDER_FILTER_STORAGE_PREFIX = "voml_folder_filter:";
|
| 149 |
|
| 150 |
function getHistory() {
|
| 151 |
try { return JSON.parse(localStorage.getItem(HISTORY_KEY)) || []; }
|
|
|
|
| 157 |
catch (e) {}
|
| 158 |
}
|
| 159 |
|
| 160 |
+
function folderFilterStorageKey(repo) {
|
| 161 |
+
return FOLDER_FILTER_STORAGE_PREFIX + (repo || "global");
|
| 162 |
+
}
|
| 163 |
+
|
| 164 |
+
function mergeFolderFilters(selfs, subtrees) {
|
| 165 |
+
return (selfs || []).concat((subtrees || []).filter(path => !(selfs || []).includes(path)));
|
| 166 |
+
}
|
| 167 |
+
|
| 168 |
+
function loadStoredFolderFilters(repo) {
|
| 169 |
+
try {
|
| 170 |
+
const data = JSON.parse(localStorage.getItem(folderFilterStorageKey(repo)) || "{}");
|
| 171 |
+
const selfs = Array.isArray(data.selfs) ? data.selfs.filter(Boolean) : [];
|
| 172 |
+
const subtrees = Array.isArray(data.subtrees) ? data.subtrees.filter(Boolean) : [];
|
| 173 |
+
return { selfs, subtrees, folders: mergeFolderFilters(selfs, subtrees) };
|
| 174 |
+
} catch (e) {
|
| 175 |
+
return { selfs: [], subtrees: [], folders: [] };
|
| 176 |
+
}
|
| 177 |
+
}
|
| 178 |
+
|
| 179 |
+
function saveStoredFolderFilters(repo) {
|
| 180 |
+
if (!repo) return;
|
| 181 |
+
const selfs = (STATE.filterFolderSelfs || []).filter(Boolean);
|
| 182 |
+
const subtrees = (STATE.filterFolderSubtrees || []).filter(Boolean);
|
| 183 |
+
try {
|
| 184 |
+
if (!selfs.length && !subtrees.length) {
|
| 185 |
+
localStorage.removeItem(folderFilterStorageKey(repo));
|
| 186 |
+
} else {
|
| 187 |
+
localStorage.setItem(folderFilterStorageKey(repo), JSON.stringify({ selfs, subtrees }));
|
| 188 |
+
}
|
| 189 |
+
} catch (e) {}
|
| 190 |
+
}
|
| 191 |
+
|
| 192 |
function stableSearchStringify(value) {
|
| 193 |
if (Array.isArray(value)) return '[' + value.map(stableSearchStringify).join(',') + ']';
|
| 194 |
if (value && typeof value === 'object') {
|
|
|
|
| 914 |
if (!STATE.searchFolders) params.set("search_folders", "false");
|
| 915 |
if (!STATE.exact) params.set("exact", "0");
|
| 916 |
if (!STATE.recordHistory) params.set("history", "0");
|
| 917 |
+
if (!STATE.useMirrorLinks) params.set("mirror", "0");
|
| 918 |
const qs = params.toString();
|
| 919 |
const path = STATE.mode === "global" ? "/" : `/${STATE.repo}`;
|
| 920 |
const url = qs ? `${path}?${qs}` : path;
|
|
|
|
| 962 |
const searchFolders = params.get("search_folders");
|
| 963 |
STATE.searchFolders = searchFolders !== "false";
|
| 964 |
DOM.searchFoldersToggle.checked = STATE.searchFolders;
|
| 965 |
+
if (STATE.mode !== "global") {
|
| 966 |
+
const urlSelfs = params.getAll("folder_self").filter(Boolean);
|
| 967 |
+
const urlSubtrees = params.getAll("folder_subtree").filter(Boolean);
|
| 968 |
+
const legacyFolders = params.getAll("folder").filter(Boolean);
|
| 969 |
+
if (urlSelfs.length || urlSubtrees.length || legacyFolders.length) {
|
| 970 |
+
STATE.filterFolderSelfs = urlSelfs.length || urlSubtrees.length ? urlSelfs : legacyFolders.slice();
|
| 971 |
+
STATE.filterFolderSubtrees = urlSubtrees;
|
| 972 |
+
STATE.filterFolders = mergeFolderFilters(STATE.filterFolderSelfs, STATE.filterFolderSubtrees);
|
| 973 |
+
saveStoredFolderFilters(STATE.repo);
|
| 974 |
+
params.delete("folder_self");
|
| 975 |
+
params.delete("folder_subtree");
|
| 976 |
+
params.delete("folder");
|
| 977 |
+
const cleanUrl = params.toString() ? `${window.location.pathname}?${params.toString()}` : window.location.pathname;
|
| 978 |
+
history.replaceState(null, "", cleanUrl);
|
| 979 |
+
} else {
|
| 980 |
+
const stored = loadStoredFolderFilters(STATE.repo);
|
| 981 |
+
STATE.filterFolderSelfs = stored.selfs;
|
| 982 |
+
STATE.filterFolderSubtrees = stored.subtrees;
|
| 983 |
+
STATE.filterFolders = stored.folders;
|
| 984 |
+
}
|
| 985 |
+
} else {
|
| 986 |
+
STATE.filterFolderSelfs = [];
|
| 987 |
+
STATE.filterFolderSubtrees = [];
|
| 988 |
+
STATE.filterFolders = [];
|
| 989 |
+
}
|
| 990 |
STATE.exact = params.get("exact") !== "0";
|
| 991 |
DOM.exactSearchToggle.checked = STATE.exact;
|
| 992 |
STATE.recordHistory = params.get("history") !== "0";
|
|
|
|
| 2025 |
selfSet.forEach(path => { if (path) merged.push(path); });
|
| 2026 |
subtreeSet.forEach(path => { if (path && !merged.includes(path)) merged.push(path); });
|
| 2027 |
STATE.filterFolders = merged;
|
| 2028 |
+
saveStoredFolderFilters(STATE.repo);
|
| 2029 |
STATE.page = 1;
|
| 2030 |
STATE.results = [];
|
| 2031 |
+
syncStateToURL(true);
|
| 2032 |
doSearch();
|
| 2033 |
}
|
| 2034 |
|
|
|
|
| 2472 |
function clearAllFilters() {
|
| 2473 |
STATE.filterRepos = []; STATE.filterExtensions = []; STATE.filterFolders = []; STATE.filterFolderSubtrees = []; STATE.filterFolderSelfs = [];
|
| 2474 |
STATE.filterMinSize = null; STATE.filterMaxSize = null;
|
| 2475 |
+
saveStoredFolderFilters(STATE.repo);
|
| 2476 |
STATE.page = 1; STATE.results = [];
|
| 2477 |
DOM.filterMinSize.value = ""; DOM.filterMaxSize.value = "";
|
| 2478 |
DOM.filterMinUnit.value = "MB"; DOM.filterMaxUnit.value = "MB";
|
|
|
|
| 2523 |
STATE.filterFolders = folder ? [folder] : [];
|
| 2524 |
STATE.filterFolderSubtrees = [];
|
| 2525 |
STATE.filterFolderSelfs = folder ? [folder] : [];
|
| 2526 |
+
saveStoredFolderFilters(STATE.repo);
|
| 2527 |
STATE.page = 1; STATE.results = [];
|
| 2528 |
+
syncStateToURL(true);
|
| 2529 |
renderFilters(routeRenderId); doSearch();
|
| 2530 |
}
|
| 2531 |
return;
|
|
|
|
| 2604 |
DOM.historyToggle.addEventListener("change", () => {
|
| 2605 |
STATE.recordHistory = DOM.historyToggle.checked;
|
| 2606 |
if (!STATE.recordHistory) saveHistory([]);
|
| 2607 |
+
syncStateToURL(true);
|
| 2608 |
});
|
| 2609 |
if (DOM.mirrorLinksToggle) DOM.mirrorLinksToggle.addEventListener("change", () => {
|
| 2610 |
STATE.useMirrorLinks = DOM.mirrorLinksToggle.checked;
|