Skip to content

Commit 819f5ba

Browse files
committed
feat: add various quick searches
1 parent 77274e9 commit 819f5ba

File tree

2 files changed

+169
-1
lines changed

2 files changed

+169
-1
lines changed

copyparty/web/browser.css

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1343,7 +1343,7 @@ html.y #widget.open {
13431343
color: var(--a);
13441344
text-shadow: 1px 1px 1px var(--op-a-sh);
13451345
font-size: 1.5em;
1346-
padding: .25em .4em;
1346+
padding: 0em .4em;
13471347
margin: 0;
13481348
}
13491349
#ops a.act {
@@ -1366,6 +1366,13 @@ html.y #ops svg circle {
13661366
#ops {
13671367
padding: .3em .6em;
13681368
white-space: nowrap;
1369+
display: flex;
1370+
align-items: center;
1371+
}
1372+
1373+
#opa_filter {
1374+
margin: 0em .4em;
1375+
min-width: 50px;
13691376
}
13701377
#noie {
13711378
color: #b60;

copyparty/web/browser.js

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,10 @@ var Ls = {
232232
"ct_idxh": 'show index.html instead of folder listing">htm',
233233
"ct_sbars": 'show scrollbars">⟊',
234234

235+
"qs_off": 'disable quicksearch, hotkeys will work">off',
236+
"qs_filter": 'typing without a focused item will hide all items that do not start with this text; disables hotkeys">filter',
237+
"qs_jump": 'typing without a focused item will jump to the next item that starts with this text; disables hotkeys">jump',
238+
235239
"cut_umod": "if a file already exists on the server, update the server's last-modified timestamp to match your local file (requires write+delete permissions)\">re📅",
236240

237241
"cut_turbo": "the yolo button, you probably DO NOT want to enable this:$N$Nuse this if you were uploading a huge amount of files and had to restart for some reason, and want to continue the upload ASAP$N$Nthis replaces the hash-check with a simple <em>&quot;does this have the same filesize on the server?&quot;</em> so if the file contents are different it will NOT be uploaded$N$Nyou should turn this off when the upload is done, and then &quot;upload&quot; the same files again to let the client verify them\">turbo",
@@ -856,6 +860,10 @@ var Ls = {
856860
"ct_idxh": 'vis index.html istedenfor fil-liste">htm',
857861
"ct_sbars": 'vis rullgardiner / skrollefelt">⟊',
858862

863+
"qs_off": 'deaktiver hurtigsøk, hurtigtaster vil fungere">av',
864+
"qs_filter": 'skriving uten et fokusert element vil skjule alle elementer som ikke starter med denne teksten; deaktiverer hurtigtaster">filter',
865+
"qs_jump": 'skriving uten et fokusert element vil hoppe til neste element som starter med denne teksten; deaktiverer hurtigtaster">hopp',
866+
859867
"cut_umod": 'i tilfelle en fil du laster opp allerede finnes på serveren, så skal serverens tidsstempel oppdateres slik at det stemmer overens med din lokale fil (krever rettighetene write+delete)">re📅',
860868

861869
"cut_turbo": "forenklet befaring ved opplastning; bør sannsynlig <em>ikke</em> skrus på:$N$Nnyttig dersom du var midt i en svær opplastning som måtte restartes av en eller annen grunn, og du vil komme igang igjen så raskt som overhodet mulig.$N$Nnår denne er skrudd på så forenkles befaringen kraftig; istedenfor å utføre en trygg sjekk på om filene finnes på serveren i god stand, så sjekkes kun om <em>filstørrelsen</em> stemmer. Så dersom en korrupt fil skulle befinne seg på serveren allerede, på samme sted med samme størrelse og navn, så blir det <em>ikke oppdaget</em>.$N$Ndet anbefales å kun benytte denne funksjonen for å komme seg raskt igjennom selve opplastningen, for så å skru den av, og til slutt &quot;laste opp&quot; de samme filene én gang til -- slik at integriteten kan verifiseres\">turbo",
@@ -1480,6 +1488,10 @@ var Ls = {
14801488
"ct_idxh": '显示 index.html 代替文件夹列表">htm',
14811489
"ct_sbars": '显示滚动条">⟊',
14821490

1491+
"qs_off": '禁用快速搜索,热键将正常工作">关闭',
1492+
"qs_filter": '在没有焦点项目时输入将隐藏所有不以此文本开头的项目;禁用热键">过滤',
1493+
"qs_jump": '在没有焦点项目时输入将跳转到下一个以此文本开头的项目;禁用热键">跳转',
1494+
14831495
"cut_umod": "如果文件已存在于服务器上,将服务器的最后修改时间戳更新为与你的本地文件匹配(需要写入和删除权限)\">re📅",
14841496

14851497
"cut_turbo": "YOLO 按钮,你可能不想启用这个:$N$N如果你上传了大量文件并且由于某些原因需要重新启动,$N并且想要尽快继续上传,使用此选项$N$N这会用简单的 <em>&quot;服务器上的文件大小是否相同?&quot;</em> 替代哈希检查,$N因此如果文件内容不同,它将不会被上传$N$N上传完成后,你应该关闭此选项,$N然后重新&quot;上传&quot;相同的文件以让客户端验证它们\">加速",
@@ -1922,6 +1934,7 @@ ebi('ops').innerHTML = (
19221934
'<a href="#" id="opa_msg" data-dest="msg" tt="' + L.ot_msg + '">📟</a>' +
19231935
'<a href="#" id="opa_auc" data-dest="player" tt="' + L.ot_mp + '">🎺</a>' +
19241936
'<a href="#" id="opa_cfg" data-dest="cfg" tt="' + L.ot_cfg + '">⚙️</a>' +
1937+
'<input type="text" id="opa_filter" placeholder="Filter...">' +
19251938
(IE ? '<span id="noie">' + L.ot_noie + '</span>' : '') +
19261939
'<div id="opdesc"></div>'
19271940
);
@@ -2079,6 +2092,119 @@ x.parentNode.insertBefore(mknod('div', null,
20792092
})();
20802093

20812094

2095+
//
2096+
// Quicksearch setting logic
2097+
//
2098+
var qsearch = 0; // 0=off, 1=filter, 2=jump
2099+
var qsearch_str = "";
2100+
var qsearch_timer = null;
2101+
2102+
function set_qsearch_mode(mode) {
2103+
qsearch = mode;
2104+
swrite("qsearch_mode", qsearch);
2105+
set_qsearch_str("");
2106+
clear_qsearch_highlight();
2107+
do_qsearch_filter();
2108+
}
2109+
2110+
function clear_qsearch_highlight() {
2111+
var rows = QSA("#files tbody tr");
2112+
for (var i = 0; i < rows.length; i++) {
2113+
clmod(rows[i], "sel", 0);
2114+
}
2115+
}
2116+
2117+
function do_qsearch_filter() {
2118+
if (!treectl) return;
2119+
var substr = qsearch_str.toLowerCase();
2120+
if (!treectl._originalFiles)
2121+
treectl._originalFiles = treectl.lsc.files.slice();
2122+
if (!treectl._originalDirs)
2123+
treectl._originalDirs = treectl.lsc.dirs.slice();
2124+
2125+
function filter(items) {
2126+
return items.filter(function(item) {
2127+
var name = (item.href || '').split('/').filter(Boolean).pop() || '';
2128+
return name.toLowerCase().startsWith(substr);
2129+
});
2130+
}
2131+
2132+
var filteredDirs = substr ? filter(treectl._originalDirs) : treectl._originalDirs;
2133+
var filteredFiles = substr ? filter(treectl._originalFiles) : treectl._originalFiles;
2134+
2135+
var filteredLsc = Object.assign({}, treectl.lsc, {
2136+
dirs: filteredDirs,
2137+
files: filteredFiles
2138+
});
2139+
2140+
treectl.gentab(get_evpath(), filteredLsc);
2141+
}
2142+
2143+
var opaFilter = ebi('opa_filter')
2144+
2145+
opaFilter.addEventListener('input', function () {
2146+
qsearch_str = this.value
2147+
do_qsearch_filter();
2148+
});
2149+
2150+
function set_qsearch_str(val) {
2151+
qsearch_str = val;
2152+
if (!val || qsearch !== 2) {
2153+
opaFilter.value = val;
2154+
}
2155+
}
2156+
2157+
function do_qsearch_jump() {
2158+
clear_qsearch_highlight();
2159+
var substr = qsearch_str.toLowerCase();
2160+
if (!substr) {
2161+
return;
2162+
}
2163+
var rows = QSA("#files tbody tr");
2164+
for (var i = 0; i < rows.length; i++) {
2165+
var tds = rows[i].getElementsByTagName("td");
2166+
if (tds.length < 2) continue;
2167+
var name = tds[1].textContent.trim().toLowerCase();
2168+
if (name.startsWith(substr)) {
2169+
clmod(rows[i], "sel", 1);
2170+
rows[i].scrollIntoView({ block: "nearest" });
2171+
break;
2172+
}
2173+
}
2174+
}
2175+
2176+
function handle_qsearch_key(e) {
2177+
if (qsearch === 0) return false;
2178+
if (e.ctrlKey || e.altKey || e.metaKey) {
2179+
return false;
2180+
}
2181+
var ch = e.key;
2182+
if (ch.length === 1) {
2183+
set_qsearch_str(qsearch_str + ch);
2184+
if (qsearch === 1) {
2185+
do_qsearch_filter();
2186+
} else if (qsearch === 2) {
2187+
do_qsearch_jump();
2188+
}
2189+
if (qsearch_timer) clearTimeout(qsearch_timer);
2190+
qsearch_timer = setTimeout(function() {
2191+
// reset on next input, don't reset current view
2192+
qsearch_str = "";
2193+
}, 2000);
2194+
return true;
2195+
}
2196+
if (ch === "Backspace") {
2197+
set_qsearch_str("");
2198+
if (qsearch === 1) {
2199+
do_qsearch_filter();
2200+
} else if (qsearch === 2) {
2201+
do_qsearch_jump();
2202+
}
2203+
return true;
2204+
}
2205+
return false;
2206+
}
2207+
20822208
// config panel
20832209
ebi('op_cfg').innerHTML = (
20842210
'<div>\n' +
@@ -2097,6 +2223,12 @@ ebi('op_cfg').innerHTML = (
20972223
' <a id="sbars" class="tgl btn" href="#" tt="' + L.ct_sbars + '</a>\n' +
20982224
' </div>\n' +
20992225
'</div>\n' +
2226+
'<div id="qscfg">\n' +
2227+
' <h3>quicksearch</h3>\n' +
2228+
' <a id="qs_off" class="tgl btn" href="#" tt="' + L.qs_off + '</a>\n' +
2229+
' <a id="qs_filter" class="tgl btn" href="#" tt="' + L.qs_filter + '</a>\n' +
2230+
' <a id="qs_jump" class="tgl btn" href="#" tt="' + L.qs_jump + '</a>\n' +
2231+
'</div>\n' +
21002232
'<div>\n' +
21012233
' <h3>' + L.cl_themes + '</h3>\n' +
21022234
' <div id="themes">\n' +
@@ -2156,6 +2288,33 @@ ebi('op_cfg').innerHTML = (
21562288
'<div><h3>' + L.cl_hiddenc + ' &nbsp;' + (MOBILE ? '<a href="#" id="hcolsh">' + L.cl_hidec + '</a> / ' : '') + '<a href="#" id="hcolsr">' + L.cl_reset + '</a></h3><div id="hcols"></div></div>'
21572289
);
21582290

2291+
// Bind quicksearch setting to UI
2292+
(function() {
2293+
var qs_modes = [
2294+
{ id: "qs_off", mode: 0 },
2295+
{ id: "qs_filter", mode: 1 },
2296+
{ id: "qs_jump", mode: 2 }
2297+
];
2298+
var saved = parseInt(sread("qsearch_mode") || "0", 10);
2299+
if (isNaN(saved) || saved < 0 || saved > 2) saved = 0;
2300+
set_qsearch_mode(saved);
2301+
for (var i = 0; i < qs_modes.length; i++) {
2302+
var btn = ebi(qs_modes[i].id);
2303+
if (!btn) continue;
2304+
btn.onclick = function(e) {
2305+
ev(e);
2306+
for (var j = 0; j < qs_modes.length; j++) {
2307+
clmod(ebi(qs_modes[j].id), "on", 0);
2308+
}
2309+
var idx = qs_modes.findIndex(x => x.id === this.id);
2310+
if (idx >= 0) {
2311+
clmod(this, "on", 1);
2312+
set_qsearch_mode(qs_modes[idx].mode);
2313+
}
2314+
};
2315+
clmod(btn, "on", saved === qs_modes[i].mode);
2316+
}
2317+
})();
21592318

21602319
// navpane
21612320
ebi('tree').innerHTML = (
@@ -7034,6 +7193,8 @@ var ahotkeys = function (e) {
70347193
if (aet && aet != 'a' && aet != 'tr' && aet != 'td' && aet != 'div' && aet != 'pre')
70357194
return;
70367195

7196+
if (handle_qsearch_key(e)) return;
7197+
70377198
if (e.key == '?')
70387199
return hkhelp();
70397200

0 commit comments

Comments
 (0)