mirror of
https://github.com/9001/copyparty.git
synced 2025-08-17 09:02:15 -06:00
hook up the multiselect ui
This commit is contained in:
parent
b36f905eab
commit
5752b6db48
19
README.md
19
README.md
|
@ -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
|
||||
|
||||

|
||||
|
||||
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
|
||||
```
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue