hook up the multiselect ui

This commit is contained in:
ed 2021-05-26 00:47:43 +02:00
parent b36f905eab
commit 5752b6db48
4 changed files with 79 additions and 11 deletions

View file

@ -13,7 +13,7 @@ turn your phone or raspi into a portable file server with resumable uploads/down
* *resumable* uploads need `firefox 34+` / `chrome 41+` / `safari 7+` for full speed
* code standard: `black`
📷 screenshots: [browser](#the-browser) // [upload](#uploading) // [md-viewer](#markdown-viewer) // [search](#searching) // [fsearch](#file-search) // [zip-DL](#zip-downloads) // [ie4](#browser-support)
📷 **screenshots:** [browser](#the-browser) // [upload](#uploading) // [thumbnails](#thumbnails) // [md-viewer](#markdown-viewer) // [search](#searching) // [fsearch](#file-search) // [zip-DL](#zip-downloads) // [ie4](#browser-support)
## readme toc
@ -29,6 +29,7 @@ turn your phone or raspi into a portable file server with resumable uploads/down
* [tabs](#tabs)
* [hotkeys](#hotkeys)
* [tree-mode](#tree-mode)
* [thumbnails](#thumbnails)
* [zip downloads](#zip-downloads)
* [uploading](#uploading)
* [file-search](#file-search)
@ -43,6 +44,8 @@ turn your phone or raspi into a portable file server with resumable uploads/down
* [client examples](#client-examples)
* [up2k](#up2k)
* [dependencies](#dependencies)
* [optional dependencies](#optional-dependencies)
* [install recommended deps](#install-recommended-deps)
* [optional gpl stuff](#optional-gpl-stuff)
* [sfx](#sfx)
* [sfx repack](#sfx-repack)
@ -148,11 +151,16 @@ summary: it works!
the browser has the following hotkeys
* `I/K` prev/next folder
* `P` parent folder
* `G` toggle list / grid view
* `T` toggle thumbnails / icons
* when playing audio:
* `0..9` jump to 10%..90%
* `U/O` skip 10sec back/forward
* `J/L` prev/next song
* `J` also starts playing the folder
* in the grid view:
* `S` toggle multiselect
* `A/D` zoom
## tree-mode
@ -162,6 +170,13 @@ by default there's a breadcrumbs path; you can replace this with a tree-browser
click `[-]` and `[+]` to adjust the size, and the `[a]` toggles if the tree should widen dynamically as you go deeper or stay fixed-size
## thumbnails
![copyparty-thumbs-fs8](https://user-images.githubusercontent.com/241032/119577189-6d490200-bdba-11eb-81a6-7b2ef7bc1128.png)
it does static images with Pillow and uses FFmpeg for video files, so you may want to `--no-thumb` or maybe just `--no-vthumb` depending on how destructive your users are
## zip downloads
the `zip` link next to folders can produce various types of zip/tar files using these alternatives in the browser settings tab:
@ -421,7 +436,7 @@ enable reading HEIF pictures:
* `pyheif-pillow-opener` (requires Linux or a C compiler)
## install recommended dependencies
## install recommended deps
```
python -m pip install --user -U jinja2 mutagen Pillow
```

View file

@ -25,7 +25,8 @@ class Ico(object):
<?xml version="1.0" encoding="UTF-8"?>
<svg version="1.1" viewBox="0 0 100 30" xmlns="http://www.w3.org/2000/svg"><g>
<rect width="100%" height="100%" fill="#{}" />
<text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" fill="#{}" font-family="sans-serif" font-size="16px" xml:space="preserve">{}</text>
<text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" xml:space="preserve"
fill="#{}" font-family="monospace" font-size="14px" style="letter-spacing:.5px">{}</text>
</g></svg>
"""
svg = svg.format(c[:6], c[6:], ext).encode("utf-8")

View file

@ -67,6 +67,11 @@ a, #files tbody div a:last-child {
background: #161616;
text-decoration: underline;
}
#files thead {
background: #333;
position: sticky;
top: 0;
}
#files thead a {
color: #999;
font-weight: normal;
@ -183,11 +188,21 @@ a, #files tbody div a:last-child {
color: #840;
text-shadow: 0 0 .3em #b80;
}
#files tbody tr.sel td {
#files tbody tr.sel td,
#ggrid a.sel {
color: #fff;
background: #925;
border-color: #c37;
}
#files tbody tr.sel:hover td,
#ggrid a.sel:hover {
color: #fff;
background: #a36;
border-color: #d48;
}
#ggrid a.sel {
box-shadow: 0 .1em .7em #b36;
}
#files tr.sel a {
color: #fff;
}
@ -719,7 +734,9 @@ input[type="checkbox"]:checked+label {
border: 1px solid #444;
border-radius: .3em;
padding: .5em;
margin: 0 1.5em 0 .4em;
margin: 0 1.5em 1em .4em;
position: sticky;
top: 0;
}
#ghead .btn {
position: relative;

View file

@ -745,7 +745,7 @@ var thegrid = (function () {
}
};
var click = function (e) {
var btnclick = function (e) {
ev(e);
var s = this.getAttribute('s'),
z = this.getAttribute('z');
@ -765,12 +765,13 @@ var thegrid = (function () {
var links = QSA('#ghead>a');
for (var a = 0; a < links.length; a++)
links[a].onclick = click;
links[a].onclick = btnclick;
ebi('gridsel').onclick = function (e) {
ev(e);
r.sel = !r.sel;
bcfg_set('gridsel', r.sel);
r.loadsel();
};
r.setvis = function (vis) {
@ -793,15 +794,34 @@ var thegrid = (function () {
}
setsz();
function seltgl(e) {
ev(e);
var oth = ebi(this.getAttribute('ref')),
td = oth.parentNode.nextSibling,
tr = td.parentNode;
td.click();
this.setAttribute('class', tr.getAttribute('class'));
}
r.loadsel = function () {
var ths = QSA('#ggrid>a');
for (var a = 0, aa = ths.length; a < aa; a++) {
ths[a].onclick = r.sel ? seltgl : null;
ths[a].setAttribute('class', ebi(ths[a].getAttribute('ref')).parentNode.parentNode.getAttribute('class'));
}
}
function loadgrid() {
if (!r.dirty)
return;
return r.loadsel();
var html = [];
var tr = lfiles.tBodies[0].rows;
for (var a = 0; a < tr.length; a++) {
var ao = tr[a].cells[1].firstChild,
href = esc(ao.getAttribute('href')),
ref = ao.getAttribute('id'),
isdir = href.split('?')[0].slice(-1)[0] == '/',
ihref = href;
@ -830,13 +850,13 @@ var thegrid = (function () {
ihref = '/.cpr/ico/' + ihref.slice(0, -1);
}
html.push('<a href="' + href +
'"><img src="' + ihref + '"><span>' +
ao.innerHTML + '</span></a>');
html.push('<a href="' + href + '" ref="' + ref + '"><img src="' +
ihref + '" /><span>' + ao.innerHTML + '</span></a>');
}
lfiles.style.display = 'none';
gfiles.style.display = 'block';
ebi('ggrid').innerHTML = html.join('\n');
r.loadsel();
}
if (r.en) {
@ -920,6 +940,19 @@ document.onkeydown = function (e) {
if (k == 'KeyT')
return ebi('thumbs').click();
if (window['thegrid'] && thegrid.en) {
if (k == 'KeyS')
return ebi('gridsel').click();
if (k == 'KeyA')
return QSA('#ghead>a[z]')[0].click();
if (k == 'KeyD')
return QSA('#ghead>a[z]')[1].click();
}
};
@ -1943,6 +1976,8 @@ var msel = (function () {
}
function selui() {
clmod(ebi('wtoggle'), 'sel', getsel().length);
if (window['thegrid'])
thegrid.loadsel();
}
function seltgl(e) {
ev(e);