From 43e40320d50a22501362fd9a92b126ca21cb4b59 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Thu, 2 Apr 2026 18:46:15 +0200 Subject: [PATCH 001/598] allow key for deleting files in addition to Ctrl + K --- copyparty/web/browser.js | 6 +++--- copyparty/web/tl/chi.js | 2 +- copyparty/web/tl/cze.js | 2 +- copyparty/web/tl/fin.js | 2 +- copyparty/web/tl/fra.js | 2 +- copyparty/web/tl/grc.js | 2 +- copyparty/web/tl/hun.js | 2 +- copyparty/web/tl/ita.js | 2 +- copyparty/web/tl/jpn.js | 2 +- copyparty/web/tl/kor.js | 2 +- copyparty/web/tl/nld.js | 2 +- copyparty/web/tl/nno.js | 2 +- copyparty/web/tl/nor.js | 2 +- copyparty/web/tl/pol.js | 2 +- copyparty/web/tl/por.js | 2 +- copyparty/web/tl/rus.js | 2 +- copyparty/web/tl/spa.js | 2 +- copyparty/web/tl/swe.js | 2 +- copyparty/web/tl/tur.js | 2 +- copyparty/web/tl/ukr.js | 2 +- copyparty/web/tl/vie.js | 2 +- 21 files changed, 23 insertions(+), 23 deletions(-) diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index 72878b20..d14323c0 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -40,7 +40,7 @@ if (1) ["G", "toggle list / grid view"], ["T", "toggle thumbnails / icons"], ["⇧ A/D", "thumbnail size"], - ["ctrl-K", "delete selected"], + ["ctrl-K/Del", "delete selected"], ["ctrl-X", "cut selection to clipboard"], ["ctrl-C", "copy selection to clipboard"], ["ctrl-V", "paste (move/copy) here"], @@ -6244,7 +6244,7 @@ var ahotkeys = function (e) { if (k == '?') return hkhelp(); - if (!sh && ctrl(e)) { + if (!sh && ctrl(e) || k.endsWith('Delete')) { var sel = window.getSelection && window.getSelection() || {}; sel = sel && !sel.isCollapsed && sel.direction != 'none'; @@ -6257,7 +6257,7 @@ var ahotkeys = function (e) { if (kl == 'v') return fileman.d_paste(e); - if (kl == 'k') + if (kl == 'k' || k.endsWith('Delete')) return fileman.delete(e); return; diff --git a/copyparty/web/tl/chi.js b/copyparty/web/tl/chi.js index 99d03681..29d4eeb9 100644 --- a/copyparty/web/tl/chi.js +++ b/copyparty/web/tl/chi.js @@ -33,7 +33,7 @@ Ls.chi = { ["G", "切换列表 / 网格视图"], ["T", "切换缩略图 / 图标"], ["⇧ A/D", "缩略图大小"], - ["ctrl-K", "删除选中项"], + ["ctrl-K/Del", "删除选中项"], ["ctrl-X", "剪切选中项到剪贴板"], ["ctrl-C", "复制选中项到剪贴板"], ["ctrl-V", "粘贴(移动/复制)到此处"], diff --git a/copyparty/web/tl/cze.js b/copyparty/web/tl/cze.js index 07a8035d..3242628a 100644 --- a/copyparty/web/tl/cze.js +++ b/copyparty/web/tl/cze.js @@ -33,7 +33,7 @@ Ls.cze = { ["G", "přepnout seznam / zobrazení mřížky"], ["T", "přepnout náhledy / ikony"], ["⇧ A/D", "velikost náhledů"], - ["ctrl-K", "smazat vybrané"], + ["ctrl-K/Del", "smazat vybrané"], ["ctrl-X", "vyjmout výběr do schránky"], ["ctrl-C", "kopírovat výběr do schránky"], ["ctrl-V", "vložit (přesunout/kopírovat) zde"], diff --git a/copyparty/web/tl/fin.js b/copyparty/web/tl/fin.js index 455d77b5..43bfd032 100644 --- a/copyparty/web/tl/fin.js +++ b/copyparty/web/tl/fin.js @@ -33,7 +33,7 @@ Ls.fin = { ["G", "vaihda lista/kuvanäkymään"], ["T", "vaihda pienoiskuviin/kuvakkeisiin"], ["⇧ A/D", "pienoiskuvien koko"], - ["ctrl-K", "poista valitut"], + ["ctrl-K/Del", "poista valitut"], ["ctrl-X", "siirrä valitut leikepöydälle"], ["ctrl-C", "kopioi valitut leikepöydälle"], ["ctrl-V", "siirrä tai kopioi tähän"], diff --git a/copyparty/web/tl/fra.js b/copyparty/web/tl/fra.js index a1d2f52f..6da1bf60 100644 --- a/copyparty/web/tl/fra.js +++ b/copyparty/web/tl/fra.js @@ -33,7 +33,7 @@ Ls.fra = { ["G", "activer vue en liste / vue en grille"], ["T", "activer les miniatures / icônes"], ["⇧ A/D", "taille des miniatures"], - ["ctrl-K", "suprimer la sélection"], + ["ctrl-K/Del", "suprimer la sélection"], ["ctrl-X", "couper la sélection au presse-papier"], ["ctrl-C", "copier la sélection au presse-papier"], ["ctrl-V", "coller (déplacer/copier) ici"], diff --git a/copyparty/web/tl/grc.js b/copyparty/web/tl/grc.js index 004ade1b..6244e7d0 100644 --- a/copyparty/web/tl/grc.js +++ b/copyparty/web/tl/grc.js @@ -33,7 +33,7 @@ Ls.grc = { ["G", "εναλλαγή λίστας / πλέγματος"], ["T", "εναλλαγή μικρογραφιών / εικονιδίων"], ["⇧ A/D", "μέγεθος μικρογραφιών"], - ["ctrl-K", "διαγραφή επιλεγμένων"], + ["ctrl-K/Del", "διαγραφή επιλεγμένων"], ["ctrl-X", "αποκοπή επιλογής στο πρόχειρο"], ["ctrl-C", "αντιγραφή επιλογής στο πρόχειρο"], ["ctrl-V", "επικόλληση (μετακίνηση/αντιγραφή) εδώ"], diff --git a/copyparty/web/tl/hun.js b/copyparty/web/tl/hun.js index f0db3dd2..cded03b0 100644 --- a/copyparty/web/tl/hun.js +++ b/copyparty/web/tl/hun.js @@ -30,7 +30,7 @@ Ls.hun = { ['G', 'lista / rács nézet'], ['T', 'ikon / indexkép váltás'], ['⇧ A/D', 'méret módosítása'], - ['ctrl-K', 'kijelöltek törlése'], + ['ctrl-K/Del', 'kijelöltek törlése'], ['ctrl-X', 'kivágás vágólapra'], ['ctrl-C', 'másolás vágólapra'], ['ctrl-V', 'beillesztés ide'], diff --git a/copyparty/web/tl/ita.js b/copyparty/web/tl/ita.js index 08fb1e85..bd28018e 100644 --- a/copyparty/web/tl/ita.js +++ b/copyparty/web/tl/ita.js @@ -33,7 +33,7 @@ Ls.ita = { ["G", "alterna vista lista / griglia"], ["T", "alterna miniature / icone"], ["⇧ A/D", "dimensione miniature"], - ["ctrl-K", "elimina selezionati"], + ["ctrl-K/Del", "elimina selezionati"], ["ctrl-X", "taglia selezione negli appunti"], ["ctrl-C", "copia selezione negli appunti"], ["ctrl-V", "incolla (sposta/copia) qui"], diff --git a/copyparty/web/tl/jpn.js b/copyparty/web/tl/jpn.js index 5d1e5889..392156a3 100644 --- a/copyparty/web/tl/jpn.js +++ b/copyparty/web/tl/jpn.js @@ -33,7 +33,7 @@ Ls.jpn = { ["G", "リスト / グリッド表示を切り替える"], ["T", "サムネイル / アイコンを切り替える"], ["⇧ A/D", "サムネイルサイズ"], - ["ctrl-K", "選択した項目を削除"], + ["ctrl-K/Del", "選択した項目を削除"], ["ctrl-X", "選択範囲をクリップボードに切り取る"], ["ctrl-C", "選択範囲をクリップボードにコピー"], ["ctrl-V", "ここに貼り付け(移動/コピー)"], diff --git a/copyparty/web/tl/kor.js b/copyparty/web/tl/kor.js index 98a73ee2..52a959af 100644 --- a/copyparty/web/tl/kor.js +++ b/copyparty/web/tl/kor.js @@ -33,7 +33,7 @@ Ls.kor = { ["G", "목록/그리드 보기 전환"], ["T", "썸네일/아이콘 전환"], ["⇧ A/D", "썸네일 이미지 크기"], - ["ctrl-K", "선택 항목 삭제"], + ["ctrl-K/Del", "선택 항목 삭제"], ["ctrl-X", "선택 항목 잘라내기"], ["ctrl-C", "선택 항목 복사"], ["ctrl-V", "여기에 붙여넣기 (이동/복사)"], diff --git a/copyparty/web/tl/nld.js b/copyparty/web/tl/nld.js index 85eeb0a6..d386a407 100644 --- a/copyparty/web/tl/nld.js +++ b/copyparty/web/tl/nld.js @@ -33,7 +33,7 @@ Ls.nld = { ["G", "Verwissel tussen list / grid weergave"], ["T", "Verwissel tussen miniaturen / iconen"], ["⇧ A/D", "Thumbnail formaat"], - ["ctrl-K", "Verwijder geselecteerde"], + ["ctrl-K/Del", "Verwijder geselecteerde"], ["ctrl-X", "Knip selectie naar klembord"], ["ctrl-C", "Kopieer selectie naar klembord"], ["ctrl-V", "Hier plakken (verplaatsen/kopieëren)"], diff --git a/copyparty/web/tl/nno.js b/copyparty/web/tl/nno.js index c87db519..38172104 100644 --- a/copyparty/web/tl/nno.js +++ b/copyparty/web/tl/nno.js @@ -30,7 +30,7 @@ Ls.nno = { ["G", "listevisning eller ikon"], ["T", "miniatyrbilder på/av"], ["⇧ A/D", "ikonstorleik"], - ["ctrl-K", "slett valde"], + ["ctrl-K/Del", "slett valde"], ["ctrl-X", "klipp ut valde"], ["ctrl-C", "kopiér åt utklippstavle"], ["ctrl-V", "lim inn (flytt/kopiér)"], diff --git a/copyparty/web/tl/nor.js b/copyparty/web/tl/nor.js index e1e191af..e5e65d78 100644 --- a/copyparty/web/tl/nor.js +++ b/copyparty/web/tl/nor.js @@ -30,7 +30,7 @@ Ls.nor = { ["G", "listevisning eller ikoner"], ["T", "miniatyrbilder på/av"], ["⇧ A/D", "ikonstørrelse"], - ["ctrl-K", "slett valgte"], + ["ctrl-K/Del", "slett valgte"], ["ctrl-X", "klipp ut valgte"], ["ctrl-C", "kopiér til utklippstavle"], ["ctrl-V", "lim inn (flytt/kopiér)"], diff --git a/copyparty/web/tl/pol.js b/copyparty/web/tl/pol.js index c1d222e7..15876b49 100644 --- a/copyparty/web/tl/pol.js +++ b/copyparty/web/tl/pol.js @@ -33,7 +33,7 @@ Ls.pol = { ["G", "przełącz widok lista / siatka"], ["T", "przełącz miniaturki / ikony"], ["⇧ A/D", "wielkość miniaturki"], - ["ctrl-K", "usuń zaznaczone"], + ["ctrl-K/Del", "usuń zaznaczone"], ["ctrl-X", "wytnij zaznaczone do schowka"], ["ctrl-C", "skopiuj zaznaczone do schowka"], ["ctrl-V", "wklej (przenieś/skopiuj) tutaj"], diff --git a/copyparty/web/tl/por.js b/copyparty/web/tl/por.js index b98d449d..8fa70ca6 100644 --- a/copyparty/web/tl/por.js +++ b/copyparty/web/tl/por.js @@ -33,7 +33,7 @@ Ls.por = { ["G", "alternar entre visualização de lista / grade"], ["T", "alternar entre miniaturas / ícones"], ["⇧ A/D", "tamanho da miniatura"], - ["ctrl-K", "excluir selecionados"], + ["ctrl-K/Del", "excluir selecionados"], ["ctrl-X", "recortar seleção para a área de transferência"], ["ctrl-C", "copiar seleção para a área de transferência"], ["ctrl-V", "colar (mover/copiar) aqui"], diff --git a/copyparty/web/tl/rus.js b/copyparty/web/tl/rus.js index eff6bd55..683a0e8d 100644 --- a/copyparty/web/tl/rus.js +++ b/copyparty/web/tl/rus.js @@ -33,7 +33,7 @@ Ls.rus = { ["G", "переключиться между списком / плиткой"], ["T", "переключиться между миниатюрами / иконками"], ["⇧ A/D", "размер миниатюры"], - ["ctrl-K", "удалить выделенное"], + ["ctrl-K/Del", "удалить выделенное"], ["ctrl-X", "вырезать выделенное в буфер"], ["ctrl-C", "копировать выделенное в буфер"], ["ctrl-V", "вставить (переместить/копировать) сюда"], diff --git a/copyparty/web/tl/spa.js b/copyparty/web/tl/spa.js index da4f5bb8..1af80eed 100644 --- a/copyparty/web/tl/spa.js +++ b/copyparty/web/tl/spa.js @@ -33,7 +33,7 @@ Ls.spa = { ["G", "alternar vista de lista / cuadrícula"], ["T", "alternar miniaturas / iconos"], ["⇧ A/D", "tamaño de miniatura"], - ["ctrl-K", "eliminar seleccionados"], + ["ctrl-K/Del", "eliminar seleccionados"], ["ctrl-X", "cortar selección al portapapeles"], ["ctrl-C", "copiar selección al portapapeles"], ["ctrl-V", "pegar (mover/copiar) aquí"], diff --git a/copyparty/web/tl/swe.js b/copyparty/web/tl/swe.js index ebb3d5b9..cb9fa49c 100644 --- a/copyparty/web/tl/swe.js +++ b/copyparty/web/tl/swe.js @@ -33,7 +33,7 @@ Ls.swe = { ["G", "växla mellan listvy / rutnät"], ["T", "växla mellan miniatyrer / ikoner"], ["⇧ A/D", "miniatyrstorlek"], - ["ctrl-K", "radera urval"], + ["ctrl-K/Del", "radera urval"], ["ctrl-X", "klipp urval till urklipp"], ["ctrl-C", "kopiera urval till urklipp"], ["ctrl-V", "klistra in (kopiera/flytta) hit"], diff --git a/copyparty/web/tl/tur.js b/copyparty/web/tl/tur.js index 1ec90f49..ca9da1de 100644 --- a/copyparty/web/tl/tur.js +++ b/copyparty/web/tl/tur.js @@ -33,7 +33,7 @@ Ls.tur = { ["G", "liste / ızgara görünümü arasında geçiş yap"], ["T", "küçük resimler / simgeler arasında geçiş yap"], ["⇧ A/D", "küçük resim boyutu"], - ["ctrl-K", "seçileni sil"], + ["ctrl-K/Del", "seçileni sil"], ["ctrl-X", "seçimi panoya kes"], ["ctrl-C", "seçimi panoya kopyala"], ["ctrl-V", "buraya yapıştır (taşı/kopyala)"], diff --git a/copyparty/web/tl/ukr.js b/copyparty/web/tl/ukr.js index fb674ced..ef61bc07 100644 --- a/copyparty/web/tl/ukr.js +++ b/copyparty/web/tl/ukr.js @@ -33,7 +33,7 @@ Ls.ukr = { ["G", "перемкнути список / сітку"], ["T", "перемкнути мініатюри / іконки"], ["⇧ A/D", "розмір мініатюр"], - ["ctrl-K", "видалити вибране"], + ["ctrl-K/Del", "видалити вибране"], ["ctrl-X", "вирізати до буфера"], ["ctrl-C", "копіювати до буфера"], ["ctrl-V", "вставити (перемістити/копіювати) сюди"], diff --git a/copyparty/web/tl/vie.js b/copyparty/web/tl/vie.js index 053b4119..51eabf28 100644 --- a/copyparty/web/tl/vie.js +++ b/copyparty/web/tl/vie.js @@ -30,7 +30,7 @@ Ls.vie = { ["G", "chuyển đổi chế độ xem danh sách / lưới"], ["T", "chuyển đổi ảnh thu nhỏ / biểu tượng"], ["⇧ A/D", "kích thước ảnh thu nhỏ"], - ["ctrl-K", "xoá mục đã chọn"], + ["ctrl-K/Del", "xoá mục đã chọn"], ["ctrl-X", "cắt mục đã chọn vào bảng nhớ tạm"], ["ctrl-C", "sao chép mục đã chọn vào bảng nhớ tạm"], ["ctrl-V", "dán (di chuyển/sao chép) tại đây"], From 32ed65aeb8e3e2f0393b3ad08950f34aa905c931 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 3 Apr 2026 09:32:46 +0200 Subject: [PATCH 002/598] addition to last commit --- scripts/tl.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/tl.js b/scripts/tl.js index cfee97b8..a8b999e0 100644 --- a/scripts/tl.js +++ b/scripts/tl.js @@ -65,7 +65,7 @@ Ls.hmn = { ["G", "toggle list / grid view"], ["T", "toggle thumbnails / icons"], ["⇧ A/D", "thumbnail size"], - ["ctrl-K", "delete selected"], + ["ctrl-K/Del", "delete selected"], ["ctrl-X", "cut selection to clipboard"], ["ctrl-C", "copy selection to clipboard"], ["ctrl-V", "paste (move/copy) here"], From 1d38af57b8e457c8e93843c492e08b2aa27d0d6f Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 3 Apr 2026 09:36:09 +0200 Subject: [PATCH 003/598] swap prev/up/next for emoji buttons --- copyparty/web/browser.js | 10 +++++----- copyparty/web/tl/chi.js | 6 +++--- copyparty/web/tl/cze.js | 6 +++--- copyparty/web/tl/deu.js | 6 +++--- copyparty/web/tl/epo.js | 6 +++--- copyparty/web/tl/fin.js | 6 +++--- copyparty/web/tl/fra.js | 6 +++--- copyparty/web/tl/grc.js | 6 +++--- copyparty/web/tl/hun.js | 6 +++--- copyparty/web/tl/ita.js | 6 +++--- copyparty/web/tl/jpn.js | 6 +++--- copyparty/web/tl/kor.js | 6 +++--- copyparty/web/tl/nld.js | 6 +++--- copyparty/web/tl/nno.js | 6 +++--- copyparty/web/tl/nor.js | 6 +++--- copyparty/web/tl/pol.js | 6 +++--- copyparty/web/tl/por.js | 6 +++--- copyparty/web/tl/rus.js | 6 +++--- copyparty/web/tl/spa.js | 6 +++--- copyparty/web/tl/swe.js | 6 +++--- copyparty/web/tl/tur.js | 6 +++--- copyparty/web/tl/ukr.js | 6 +++--- scripts/tl.js | 6 +++--- 23 files changed, 71 insertions(+), 71 deletions(-) diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index d14323c0..c194a3b7 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -114,9 +114,9 @@ if (1) "ht_and": " and ", "goh": "control-panel", - "gop": 'previous sibling">prev', - "gou": 'parent folder">up', - "gon": 'next folder">next', + "gop": 'previous sibling', + "gou": 'parent folder', + "gon": 'next folder', "logout": "Logout ", "login": "Login", "access": " access", @@ -3585,8 +3585,8 @@ function eval_hash() { document.body.insertBefore(d, ebi('ops')); // folder nav - ebi('goh').parentElement.appendChild(mknod('span', null, - '⬅️➡️⬆️')); ebi('gop').onclick = function () { tree_neigh(-1); } ebi('gon').onclick = function () { tree_neigh(1); } ebi('gou').onclick = function () { tree_up(true); } diff --git a/copyparty/web/tl/chi.js b/copyparty/web/tl/chi.js index 29d4eeb9..1ba909c3 100644 --- a/copyparty/web/tl/chi.js +++ b/copyparty/web/tl/chi.js @@ -107,9 +107,9 @@ Ls.chi = { "ht_and": "又 ", "goh": "控制面板", - "gop": '上一个同级文件夹">前', - "gou": '上一级文件夹">上', - "gon": '下一个文件夹">后', + "gop": '上一个同级文件夹', + "gou": '上一级文件夹', + "gon": '下一个文件夹', "logout": "登出 ", "login": "登录", "access": " 权限", diff --git a/copyparty/web/tl/cze.js b/copyparty/web/tl/cze.js index 3242628a..06d93d20 100644 --- a/copyparty/web/tl/cze.js +++ b/copyparty/web/tl/cze.js @@ -111,9 +111,9 @@ Ls.cze = { "ht_and": " a ", "goh": "ovládací panel", - "gop": 'předchozí sourozenec">předchozí', - "gou": 'nadřazená složka">nahoru', - "gon": 'následující složka">následující', + "gop": 'předchozí sourozenec', + "gou": 'nadřazená složka', + "gon": 'následující složka', "logout": "Odhlásit ", "login": "Přihlásit se", //m "access": " přístup", diff --git a/copyparty/web/tl/deu.js b/copyparty/web/tl/deu.js index 3d9cb9ac..00b51e39 100644 --- a/copyparty/web/tl/deu.js +++ b/copyparty/web/tl/deu.js @@ -107,9 +107,9 @@ Ls.deu = { "ht_and": " und ", "goh": "Einstellungen", - "gop": 'zum vorherigen Ordner springen">vorh.', - "gou": 'zum übergeordneter Ordner springen">hoch', - "gon": 'zum nächsten Ordner springen">nächst.', + "gop": 'zum vorherigen Ordner springen', + "gou": 'zum übergeordneter Ordner springen', + "gon": 'zum nächsten Ordner springen', "logout": "Abmelden ", "login": "Anmelden", "access": " Zugriff", diff --git a/copyparty/web/tl/epo.js b/copyparty/web/tl/epo.js index ea3fcdf6..7c454864 100644 --- a/copyparty/web/tl/epo.js +++ b/copyparty/web/tl/epo.js @@ -107,9 +107,9 @@ Ls.epo = { "ht_and": " kaj ", "goh": "stirpanelo", - "gop": 'malsekva dosierujo">malsekva', - "gou": 'supra dosierujo">supren', - "gon": 'sekva dosierujo">sekva', + "gop": 'malsekva dosierujo', + "gou": 'supra dosierujo', + "gon": 'sekva dosierujo', "logout": "Adiaŭi kiel ", "login": "Ensaluti", "access": " atingo", diff --git a/copyparty/web/tl/fin.js b/copyparty/web/tl/fin.js index 43bfd032..01ac3857 100644 --- a/copyparty/web/tl/fin.js +++ b/copyparty/web/tl/fin.js @@ -107,9 +107,9 @@ Ls.fin = { "ht_and": " ja ", "goh": "hallintapaneeli", - "gop": 'viereinen hakemisto">edell', - "gou": 'ylempi hakemisto">ylös', - "gon": 'seuraava hakemisto">seur', + "gop": 'viereinen hakemisto', + "gou": 'ylempi hakemisto', + "gon": 'seuraava hakemisto', "logout": "Kirjaudu ulos ", "login": "Kirjaudu sisään", "access": " -oikeudet", diff --git a/copyparty/web/tl/fra.js b/copyparty/web/tl/fra.js index 6da1bf60..a9ea2c0c 100644 --- a/copyparty/web/tl/fra.js +++ b/copyparty/web/tl/fra.js @@ -107,9 +107,9 @@ Ls.fra = { "ht_and": " et ", "goh": "panneau-de-commande", - "gop": 'élément "frère" précédent">précédent', - "gou": 'dossier parent">haut', - "gon": 'dossier suivant">suivant', + "gop": 'élément "frère" précédent', + "gou": 'dossier parent', + "gon": 'dossier suivant', "logout": "Déconnexion ", "login": "Se connecter", //m "access": " accès", diff --git a/copyparty/web/tl/grc.js b/copyparty/web/tl/grc.js index 6244e7d0..25a0bd77 100644 --- a/copyparty/web/tl/grc.js +++ b/copyparty/web/tl/grc.js @@ -107,9 +107,9 @@ Ls.grc = { "ht_and": " και ", "goh": "πίνακας ελέγχου", - "gop": 'προηγούμενος φάκελος στο ίδιο επίπεδο">προηγούμενο', - "gou": 'γονικός φάκελος">πάνω', - "gon": 'επόμενος φάκελος">επόμενο', + "gop": 'προηγούμενος φάκελος στο ίδιο επίπεδο', + "gou": 'γονικός φάκελος', + "gon": 'επόμενος φάκελος', "logout": "Αποσύνδεση ", "login": "Σύνδεση", //m "access": " πρόσβαση", diff --git a/copyparty/web/tl/hun.js b/copyparty/web/tl/hun.js index cded03b0..547a8f7e 100644 --- a/copyparty/web/tl/hun.js +++ b/copyparty/web/tl/hun.js @@ -109,9 +109,9 @@ Ls.hun = { "ht_and": ' és ', "goh": 'irányítópult', - "gop": 'előző mappába">előző', - "gou": 'szülőmappa">fel', - "gon": 'következő mappába">következő', + "gop": 'előző mappába', + "gou": 'szülőmappa', + "gon": 'következő mappába', "logout": 'Kilépés ', "login": 'Belépés', "access": ' hozzáférés', diff --git a/copyparty/web/tl/ita.js b/copyparty/web/tl/ita.js index bd28018e..729aca03 100644 --- a/copyparty/web/tl/ita.js +++ b/copyparty/web/tl/ita.js @@ -107,9 +107,9 @@ Ls.ita = { "ht_and": " e ", "goh": "control-panel", - "gop": 'cartella sorella precedente">prec', - "gou": 'cartella genitore">su', - "gon": 'prossima cartella">succ', + "gop": 'cartella sorella precedente', + "gou": 'cartella genitore', + "gon": 'prossima cartella', "logout": "Logout ", "login": "Accedi", //m "access": " accesso", diff --git a/copyparty/web/tl/jpn.js b/copyparty/web/tl/jpn.js index 392156a3..cc1f756a 100644 --- a/copyparty/web/tl/jpn.js +++ b/copyparty/web/tl/jpn.js @@ -107,9 +107,9 @@ Ls.jpn = { "ht_and": " と ", "goh": "コントロールパネル", - "gop": '前のフォルダ">prev', - "gou": '親フォルダ">up', - "gon": '次のフォルダ">next', + "gop": '前のフォルダ', + "gou": '親フォルダ', + "gon": '次のフォルダ', "logout": "ログアウト ", "login": "ログイン", "access": " アクセス", diff --git a/copyparty/web/tl/kor.js b/copyparty/web/tl/kor.js index 52a959af..cdd9e6e9 100644 --- a/copyparty/web/tl/kor.js +++ b/copyparty/web/tl/kor.js @@ -107,9 +107,9 @@ Ls.kor = { "ht_and": " ", "goh": "제어판", - "gop": '이전 형제 폴더">이전', - "gou": '상위 폴더">위로', - "gon": '다음 폴더">다음', + "gop": '이전 형제 폴더', + "gou": '상위 폴더', + "gon": '다음 폴더', "logout": "로그아웃 ", "login": "로그인", //m "access": " 액세스", diff --git a/copyparty/web/tl/nld.js b/copyparty/web/tl/nld.js index d386a407..7acba391 100644 --- a/copyparty/web/tl/nld.js +++ b/copyparty/web/tl/nld.js @@ -107,9 +107,9 @@ Ls.nld = { "ht_and": " en ", "goh": "Beheer-paneel", - "gop": 'Vorige map">Vorige', - "gou": 'Bovenligende map">Omhoog', - "gon": 'Volgende map">Volgende', + "gop": 'Vorige map', + "gou": 'Bovenligende map', + "gon": 'Volgende map', "logout": "Uitloggen ", "login": "Inloggen", //m "access": " Toegang", diff --git a/copyparty/web/tl/nno.js b/copyparty/web/tl/nno.js index 38172104..75b5df95 100644 --- a/copyparty/web/tl/nno.js +++ b/copyparty/web/tl/nno.js @@ -104,9 +104,9 @@ Ls.nno = { "ht_and": " og ", "goh": "kontrollpanel", - "gop": 'navigér åt mappa før den her">forr.', - "gou": 'navigér eitt nivå opp">opp', - "gon": 'navigér åt mappa etter den her">neste', + "gop": 'navigér åt mappa før den her', + "gou": 'navigér eitt nivå opp', + "gon": 'navigér åt mappa etter den her', "logout": "Logg ut ", "login": "Logg inn", "access": " åtgang", diff --git a/copyparty/web/tl/nor.js b/copyparty/web/tl/nor.js index e5e65d78..9da888cd 100644 --- a/copyparty/web/tl/nor.js +++ b/copyparty/web/tl/nor.js @@ -104,9 +104,9 @@ Ls.nor = { "ht_and": " og ", "goh": "kontrollpanel", - "gop": 'naviger til mappen før denne">forr.', - "gou": 'naviger ett nivå opp">opp', - "gon": 'naviger til mappen etter denne">neste', + "gop": 'naviger til mappen før denne', + "gou": 'naviger ett nivå opp', + "gon": 'naviger til mappen etter denne', "logout": "Logg ut ", "login": "Logg inn", "access": " tilgang", diff --git a/copyparty/web/tl/pol.js b/copyparty/web/tl/pol.js index 15876b49..3a8a64ad 100644 --- a/copyparty/web/tl/pol.js +++ b/copyparty/web/tl/pol.js @@ -110,9 +110,9 @@ Ls.pol = { "ht_and": " i ", "goh": "panel sterowania", - "gop": 'poprzedni plik/folder">poprzedni', - "gou": 'nadrzędny folder">w górę', - "gon": 'następny folder">następny', + "gop": 'poprzedni plik/folder', + "gou": 'nadrzędny folder', + "gon": 'następny folder', "logout": "Wyloguj ", "login": "Zaloguj się", //m "access": " dostęp", diff --git a/copyparty/web/tl/por.js b/copyparty/web/tl/por.js index 8fa70ca6..d6966596 100644 --- a/copyparty/web/tl/por.js +++ b/copyparty/web/tl/por.js @@ -107,9 +107,9 @@ Ls.por = { "ht_and": " e ", "goh": "painel de controle", - "gop": 'pai anterior">anterior', - "gou": 'pasta pai">acima', - "gon": 'próxima pasta">próximo', + "gop": 'pai anterior', + "gou": 'pasta pai', + "gon": 'próxima pasta', "logout": "Sair ", "login": "Fazer login", "access": " acesso", diff --git a/copyparty/web/tl/rus.js b/copyparty/web/tl/rus.js index 683a0e8d..7c3bb3fc 100644 --- a/copyparty/web/tl/rus.js +++ b/copyparty/web/tl/rus.js @@ -107,9 +107,9 @@ Ls.rus = { "ht_and": " и ", "goh": "панель управления", - "gop": 'предыдущая папка">пред', - "gou": 'родительская папка">вверх', - "gon": 'следующая папка">след', + "gop": 'предыдущая папка', + "gou": 'родительская папка', + "gon": 'следующая папка', "logout": "Выйти ", "login": "Войти", //m "access": " доступ", diff --git a/copyparty/web/tl/spa.js b/copyparty/web/tl/spa.js index 1af80eed..89a536e1 100644 --- a/copyparty/web/tl/spa.js +++ b/copyparty/web/tl/spa.js @@ -107,9 +107,9 @@ Ls.spa = { "ht_and": " y ", "goh": "panel de control", - "gop": 'hermano anterior">anterior', - "gou": 'carpeta de nivel superior">subir', - "gon": 'siguiente carpeta">siguiente', + "gop": 'hermano anterior', + "gou": 'carpeta de nivel superior', + "gon": 'siguiente carpeta', "logout": "Cerrar sesión ", "login": "Iniciar sesión", //m "access": " acceso", diff --git a/copyparty/web/tl/swe.js b/copyparty/web/tl/swe.js index cb9fa49c..492c86e6 100644 --- a/copyparty/web/tl/swe.js +++ b/copyparty/web/tl/swe.js @@ -107,9 +107,9 @@ Ls.swe = { "ht_and": " och ", "goh": "kontrollpanel", - "gop": 'föregående mapp">föreg.', - "gou": 'överordnad mapp">upp', - "gon": 'nästa mapp">nästa', + "gop": 'föregående mapp', + "gou": 'överordnad mapp', + "gon": 'nästa mapp', "logout": "Logga ut ", "login": "Logga in", //m "access": "-rättighet", diff --git a/copyparty/web/tl/tur.js b/copyparty/web/tl/tur.js index ca9da1de..94308795 100644 --- a/copyparty/web/tl/tur.js +++ b/copyparty/web/tl/tur.js @@ -107,9 +107,9 @@ Ls.tur = { "ht_and": " ve ", "goh": "kontrol paneli", - "gop": 'önceki kardeş">önceki', - "gou": 'üst klasör">üst', - "gon": 'sonraki klasör">sonraki', + "gop": 'önceki kardeş', + "gou": 'üst klasör', + "gon": 'sonraki klasör', "logout": "Çıkış ", "login": "Giriş", "access": " erişim", diff --git a/copyparty/web/tl/ukr.js b/copyparty/web/tl/ukr.js index ef61bc07..17fc9e3a 100644 --- a/copyparty/web/tl/ukr.js +++ b/copyparty/web/tl/ukr.js @@ -107,9 +107,9 @@ Ls.ukr = { "ht_and": " і ", "goh": "панель керування", - "gop": 'попередній сусід">назад', - "gou": 'батьківська папка">вгору', - "gon": 'наступна папка">далі', + "gop": 'попередній сусід', + "gou": 'батьківська папка', + "gon": 'наступна папка', "logout": "Вийти ", "login": "увійти", //m "access": " доступ", diff --git a/scripts/tl.js b/scripts/tl.js index a8b999e0..f5270091 100644 --- a/scripts/tl.js +++ b/scripts/tl.js @@ -139,9 +139,9 @@ Ls.hmn = { "ht_and": " and ", "goh": "control-panel", - "gop": 'previous sibling">prev', - "gou": 'parent folder">up', - "gon": 'next folder">next', + "gop": 'previous sibling', + "gou": 'parent folder', + "gon": 'next folder', "logout": "Logout ", "login": "Login", "access": " access", From d47dd3ec1b84ba3ef2696a60ec004b1d12981576 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 3 Apr 2026 09:36:40 +0200 Subject: [PATCH 004/598] addition to delete hotkey commit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4fd5eea2..d8c88bac 100644 --- a/README.md +++ b/README.md @@ -673,7 +673,7 @@ the browser has the following hotkeys (always qwerty) * `G` toggle list / [grid view](#thumbnails) -- same as `田` bottom-right * `T` toggle thumbnails / icons * `ESC` close various things -* `ctrl-K` delete selected files/folders +* `ctrl-K/Del` delete selected files/folders * `ctrl-X` cut selected files/folders * `ctrl-C` copy selected files/folders to clipboard * `ctrl-V` paste (move/copy) From f72bbce5fc527452d80ee9b6ffe4abdfae53f516 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 3 Apr 2026 09:37:46 +0200 Subject: [PATCH 005/598] addition to swap prev/up/next for emojis --- copyparty/web/tl/vie.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/copyparty/web/tl/vie.js b/copyparty/web/tl/vie.js index 51eabf28..89687d3d 100644 --- a/copyparty/web/tl/vie.js +++ b/copyparty/web/tl/vie.js @@ -102,9 +102,9 @@ Ls.vie = { "ht_and": " và ", "goh": "bảng điều khiển", - "gop": 'thư mục trước">trước', - "gou": 'thư mục cha">lên', - "gon": 'thư mục sau">tiếp', + "gop": 'thư mục trước', + "gou": 'thư mục cha', + "gon": 'thư mục sau', "logout": "Đăng xuất ", "login": "Đăng nhập", "access": "quyền truy cập", From 153be9ae944de8b9f2c936ce45cf6be8086e5fa8 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 3 Apr 2026 09:38:26 +0200 Subject: [PATCH 006/598] yellow default hover color for buttons --- copyparty/web/browser.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index fb3db76a..a9d2cd81 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -41,8 +41,8 @@ --btn-fg: var(--a); --btn-bg: rgba(128,128,128,0.15); --btn-h-fg: var(--a-hil); - --btn-h-bg: #805; - --btn-1-fg: #400; + --btn-h-bg: #850; + --btn-1-fg: rgb(25, 19, 12); --btn-1-bg: var(--a); --btn-h-bs: var(--btn-bs); --btn-h-bb: var(--btn-bb); From f5b95585f661fc6ba5c5f303fc33e2aafea6aede Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 3 Apr 2026 10:50:57 +0200 Subject: [PATCH 007/598] more neutral sorting indicators --- copyparty/web/browser.css | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index a9d2cd81..61e2f342 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -668,13 +668,13 @@ a:hover { } .s0:after, .s1:after { - content: '⌄'; - margin-left: -.15em; + content: '⏷'; + /* margin-left: -.15em; */ } .s0r:after, .s1r:after { - content: '⌃'; - margin-left: -.15em; + content: '⏶'; + /* margin-left: -.15em; */ } .s0:after, .s0r:after { From 465cc2272a62ff164973e0d39a2eb92a701af733 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 3 Apr 2026 16:05:38 +0200 Subject: [PATCH 008/598] add home button to splash, changed some colors --- copyparty/web/splash.css | 23 ++++++++++++++++------- copyparty/web/splash.html | 2 ++ 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/copyparty/web/splash.css b/copyparty/web/splash.css index 832ef566..1bd95084 100644 --- a/copyparty/web/splash.css +++ b/copyparty/web/splash.css @@ -16,7 +16,7 @@ html { } h1 { border-bottom: 1px solid #ccc; - margin: 2em 0 .4em 0; + margin: 1em 0 .4em 0; padding: 0; line-height: 1em; font-weight: normal; @@ -41,8 +41,8 @@ td a { #wb, #w { color: #fff; - background: #940; - border-color: #b70; + background: rgb(54, 153, 0); + border-color: rgb(106, 239, 34); } .af, .logout { @@ -208,8 +208,8 @@ html.z a { html.z .logout, html.z #lo, html.z a.r { - background: #804; - border-color: #c28; + background: rgb(163, 0, 3); + border-color: rgb(214, 27, 27); } html.z a.g { background: #470; @@ -239,8 +239,8 @@ input::placeholder { #x, html.z input { color: #fff; - background: #626; - border-color: #c2c; + background: rgb(39, 130, 204); + border-color: rgb(72, 182, 255); } html.z input::placeholder { color: #fff; @@ -257,3 +257,12 @@ html.bz { html.bz .vols img { filter: sepia(0.8) hue-rotate(180deg); } + +#homebtn { + font-size: x-large; + top: 1em; + left: 1em; + border-radius: .3em; + background: #333; + position: absolute; +} diff --git a/copyparty/web/splash.html b/copyparty/web/splash.html index 47f4d664..38e1fa18 100644 --- a/copyparty/web/splash.html +++ b/copyparty/web/splash.html @@ -12,6 +12,8 @@ {{ html_head }} +🏠 +
{%- if not in_shr %} From 4048f2b1b29f348d4d3bf86dfdb050bfe6c632f3 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 3 Apr 2026 16:06:29 +0200 Subject: [PATCH 009/598] selection box fades out over 1s --- copyparty/web/ui.css | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/copyparty/web/ui.css b/copyparty/web/ui.css index a20b5074..a54684b3 100644 --- a/copyparty/web/ui.css +++ b/copyparty/web/ui.css @@ -371,10 +371,15 @@ html.y #tth { *:focus+label, #pctl *:focus, .btn:focus { - box-shadow: 0 .1em .2em #fc0 inset; - outline: #fc0 solid .1em; + /* box-shadow: 0 .1em .2em #fc0 inset; */ + animation: outline_fadeOut 1s; border-radius: .2em; } +@keyframes outline_fadeOut { +0% {outline: #fc0 solid .1em;} +30% {outline: rgba(255, 204, 0, 0.755) solid .1em;} +100% {outline: transparent solid .1em;} +} html.y *:focus, html.y *:focus+label, html.y #pctl *:focus, From 74a4f351a9c6076e93b1f7c2d345e2223a419ebc Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 3 Apr 2026 16:07:48 +0200 Subject: [PATCH 010/598] folder button: added "+" on top --- copyparty/web/browser.css | 7 +++++++ copyparty/web/browser.js | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 61e2f342..793640d8 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -4188,3 +4188,10 @@ html.e #detree { pointer-events: none; z-index: 99; } + +.overlay_plus{ + position: absolute; + margin: -1.7em 0 0 .8em; + color: var(--fg); +} + diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index c194a3b7..475db6c9 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -751,7 +751,7 @@ ebi('ops').innerHTML = ( (have_del ? '🧯' : '') + '🚀' + '🎈' + - '📂' + + '📂

+

' + '📝' + '📟' + '🎺' + From b7e0d9596cbee29510a9e9df4aee21089e109591 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 3 Apr 2026 16:09:24 +0200 Subject: [PATCH 011/598] remove dependency on "entree" object when generating path --- copyparty/web/browser.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index 475db6c9..77ea07fb 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -9841,12 +9841,10 @@ function reload_browser() { filecols.set_style(); var parts = get_evpath().split('/'), - rm = ebi('entree'), ftab = ebi('files'), link = '', o; - while (rm.nextSibling) - rm.parentNode.removeChild(rm.nextSibling); + ebi('path').innerHTML = ""; for (var a = 0; a < parts.length - 1; a++) { link += parts[a] + '/'; From 8ea1e3b94f252d3921bfd49649f5dc7a64946071 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 3 Apr 2026 16:12:31 +0200 Subject: [PATCH 012/598] add down arrows before download buttons --- copyparty/web/browser.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index 77ea07fb..fe507726 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -773,12 +773,12 @@ ebi('widget').innerHTML = ( ' href="#" id="fcpy" tt="' + L.wt_cpy + '">⧉copy📋paste' + '📦zip' + + ' href="#" id="zip1" tt="' + L.wt_zip1 + '">⬇️📦zip' + 'sel.
allsel.
inv.zipdl' + + ' href="#" id="selzip" class="l1" tt="' + L.wt_selzip + '">⬇️zip⬇️files' + '
📋irc📋txt' + @@ -8548,7 +8548,7 @@ var arcfmt = (function () { o.setAttribute("href", m[1] + arg + m[4]); o.textContent = fmt.split('_')[0]; } - ebi('selzip').textContent = fmt.split('_')[0]; + ebi('selzip').textContent = '⬇️' + fmt.split('_')[0]; ebi('selzip').setAttribute('fmt', arg); QS('#zip1 span').textContent = fmt.split('_')[0]; From 2057902879a4e7e662cfe8ffaf3d90c800c3e144 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 3 Apr 2026 16:20:55 +0200 Subject: [PATCH 013/598] use trash can emoji for delete button --- copyparty/web/browser.js | 92 +++++++++++++++++++++++++++++----------- 1 file changed, 68 insertions(+), 24 deletions(-) diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index fe507726..7876e178 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -746,7 +746,7 @@ modal.load(); // toolbar ebi('ops').innerHTML = ( - '--' + + //'--' + '🔎' + (have_del ? '🧯' : '') + '🚀' + @@ -768,7 +768,7 @@ ebi('widget').innerHTML = ( '📨sharenamedel.🗑️del.cutcopy📋paste' + @@ -786,7 +786,6 @@ ebi('widget').innerHTML = ( ' href="#" id="m3ua" tt="' + L.wt_m3ua + '">📻add📻copy' + '♫' + '
' + '
' + @@ -1014,7 +1013,6 @@ ebi('op_cfg').innerHTML = ( // navpane ebi('tree').innerHTML = ( '
\n' + - ' 🍞...\n' + ' +\n' + ' \n' + ' 🎯\n' + @@ -1029,8 +1027,8 @@ ebi('tree').innerHTML = ( '
    \n' + '
     
    ' ); +ebi('thx_ff').before(ebi('acc_button')); clmod(ebi('tree'), 'sbar', 1); -ebi('entree').setAttribute('tt', L.tt_entree); ebi('goh').textContent = L.goh; QS('#op_mkdir input[type="submit"]').value = L.ab_mkdir; QS('#op_new_md input[type="submit"]').value = L.ab_mkdoc; @@ -1074,6 +1072,7 @@ ebi('rcm').innerHTML = ( if (v) ops[a].href = '#v=' + v; } + ebi('acc_settings').onclick = opclick; })(); @@ -3568,7 +3567,7 @@ function eval_hash() { d.setAttribute('href', '#'); d.setAttribute('class', 'ayjump'); d.innerHTML = a ? L.ay_path : L.ay_files; - document.body.insertBefore(d, ebi('ops')); + document.body.insertBefore(d, ebi('topBar')); d.onclick = function (e) { ev(e); if (a) @@ -3580,10 +3579,6 @@ function eval_hash() { }; })(a); - // account-info label - var d = mknod('div', 'acc_info'); - document.body.insertBefore(d, ebi('ops')); - // folder nav ebi('wfp').appendChild(mknod('span', null, '⬅️➡️⬆️')); @@ -5465,8 +5460,9 @@ var thegrid = (function () { gfiles.style.display = 'none'; gfiles.innerHTML = ( '
    ' + - '' + ' // rtt: ' : 'rtt: ') + rtt; @@ -7819,9 +7849,10 @@ var treectl = (function () { swrite('treesz', treesz); onresize(); } - - ebi('entree').onclick = r.entree; - ebi('detree').onclick = r.detree; + + ebi('treeToggleBtn').tt = L.tt_entree; + + ebi('treeToggleBtn').onclick = r.toggleTree; ebi('visdir').onclick = tree_scrollto; ebi('twig').onclick = scaletree; ebi('twobytwo').onclick = scaletree; @@ -7953,10 +7984,22 @@ function apply_perms(res) { if (idp_login && acct == "*") dst = idp_login.replace(/\{dst\}/g, get_evpath()); - ebi('acc_info').innerHTML = '' + srvinf + - '' + (acct != '*' ? - '
    ' : - '
    ' + L.login + ''); + function goHome(){ + window.location.href = dst; + } + + if(acct != '*'){ + ebi('acc_name').innerHTML = acct; + ebi('acessType').innerHTML = ''; + ebi('blogout').value = L.logout; + ebi('acc_button').onclick = function(){ + ebi('acc_popup').classList.toggle('show'); + } + } + else{ + ebi('acc_name').innerHTML = L.login; + ebi('acc_button').onclick = goHome; + } var o = QSA('#ops>a[data-perm]'); for (var a = 0; a < o.length; a++) { @@ -9852,8 +9895,9 @@ function reload_browser() { o = mknod('a'); o.setAttribute('href', link2); - o.textContent = uricom_dec(parts[a]) || '/'; - ebi('path').appendChild(mknod('i')); + o.textContent = uricom_dec(parts[a]) || '🏠'; + if(a > 0) + ebi('path').appendChild(mknod('i')); ebi('path').appendChild(o); } From 04da181eeb93b3ab712c0f60d80f42a14e352407 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 3 Apr 2026 16:21:59 +0200 Subject: [PATCH 014/598] ui v1.5 ( addition to previous commit) --- copyparty/httpcli.py | 11 ++ copyparty/web/baguettebox.js | 8 +- copyparty/web/browser.css | 347 +++++++++++++++++++++++++++++------ copyparty/web/browser.html | 58 ++++-- copyparty/web/util.js | 3 + 5 files changed, 351 insertions(+), 76 deletions(-) diff --git a/copyparty/httpcli.py b/copyparty/httpcli.py index 8c74664b..6166fc89 100644 --- a/copyparty/httpcli.py +++ b/copyparty/httpcli.py @@ -6976,15 +6976,19 @@ class HttpCli(object): elif not self.can_write: return self.tx_404(True) + srv_name = "" srv_info = [] try: if not self.args.nih: + srv_name = self.args.name_html srv_info.append(self.args.name_html) except: self.log("#wow #whoa") zi = vn.flags["du_iwho"] + h1 = "" + h2 = "" if zi and ( zi == 9 or (zi == 7 and self.uname != "*") @@ -7062,6 +7066,9 @@ class HttpCli(object): "files": [], "taglist": [], "srvinf": srv_infot, + "space_free": float(h1.split()[0]), + "space_total": float(h2.split()[0]), + "space_unit": h2.split()[1], "acct": self.uname, "perms": perms, "cfg": vn.js_ls, @@ -7085,6 +7092,10 @@ class HttpCli(object): "url_suf": url_suf, "title": html_escape("%s %s" % (self.args.bname, self.vpath), crlf=True), "srv_info": srv_infot, + "srv_name": srv_name, + "space_free": float(h1.split()[0]), + "space_total": float(h2.split()[0]), + "space_unit": h2.split()[1], "dtheme": self.args.theme, } diff --git a/copyparty/web/baguettebox.js b/copyparty/web/baguettebox.js index 3bd2a53e..9a78619c 100644 --- a/copyparty/web/baguettebox.js +++ b/copyparty/web/baguettebox.js @@ -577,7 +577,7 @@ window.baguetteBox = (function () { sel = true; ebi('bbox-overlay').style.background = sel ? - 'rgba(153,34,85,0.7)' : ''; + 'rgba(153,85,34,0.7)' : ''; img.style.borderRadius = sel ? '1em' : ''; btnState(btnSel, sel); @@ -585,9 +585,9 @@ window.baguetteBox = (function () { function btnState(btn, sel) { btn.style.color = sel ? '#fff' : ''; - btn.style.background = sel ? '#d48' : ''; - btn.style.textShadow = sel ? '1px 1px 0 #b38' : ''; - btn.style.boxShadow = sel ? '.15em .15em 0 #502' : ''; + btn.style.background = sel ? '#d84' : ''; + btn.style.textShadow = sel ? '1px 1px 0 #b83' : ''; + btn.style.boxShadow = sel ? '.15em .15em 0 #520' : ''; } function keyUpHandler(e) { diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 793640d8..642ba71d 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -25,7 +25,7 @@ --bg-d3: #111; --bg-max: #000; - --tab-alt: #f5a; + --tab-alt: #fa5; --row-alt: #282828; --scroll: #eb0; @@ -71,7 +71,7 @@ --u2-tab-1-b2: #583; --u2-tab-1-sh: #280; --u2-b-fg: #fff; - --u2-b1-bg: #c38; + --u2-b1-bg: #c83; --u2-b2-bg: #d80; --u2-inf-bg: #07a; --u2-inf-b1: #0be; @@ -82,7 +82,7 @@ --ud-b1: #888; --sort-1: #fb0; - --sort-2: #d09; + --sort-2: #d90; --sz-b: #aaa; --sz-k: #4ff; @@ -93,8 +93,8 @@ --srv-1: #aaa; --srv-2: #a73; - --srv-3: #f4c; - --srv-3b: rgba(255,68,204,0.6); + --srv-3: #fc4; + --srv-3b: rgba(255,204,68,0.6); --tree-bg: #2b2b2b; @@ -104,14 +104,14 @@ --g-play-sh: #b83; --g-sel-fg: #fff; - --g-sel-bg: #925; - --g-sel-b1: #e39; - --g-sel-sh: #b36; - --g-fsel-bg: #d39; - --g-fsel-b1: #f4a; - --g-fsel-ts: #804; - --g-dfg: var(--srv-3); - --g-fg: var(--a-hil); + --g-sel-bg: #952; + --g-sel-b1: #e93; + --g-sel-sh: #b63; + --g-fsel-bg: #d93; + --g-fsel-b1: #fa4; + --g-fsel-ts: #840; + --g-dfg: #bbb; + --g-fg: #ccc; --g-bg: var(--bg-u2); --g-b1: var(--bg-u4); --g-b2: var(--bg-u5); @@ -119,7 +119,7 @@ --g-g2: var(--bg-u5); --g-f-bg: var(--bg-u4); --g-f-b1: var(--bg-u5); - --g-f-fg: var(--a-hil); + --g-f-fg: #fff; --g-sh: rgba(0,0,0,0.3); --f-sh1: 0.33; @@ -132,7 +132,7 @@ --f-sel-sh: #fc0; --f-gray: #999; - --fm-off: #f6c; + --fm-off: #fc6; --mp-sh: var(--bg-d3); --mp-b-bg: rgba(0,0,0,0.2); @@ -606,15 +606,28 @@ html .ayjump:focus { #path * { font-size: 1em; } +#pathBar { + display: flex; + margin: 0 0 .5em 0; + align-content: center; + justify-content: space-between; +} #path { color: var(--fg); text-shadow: 1px 1px 0 var(--bg-max); font-weight: normal; - display: inline-block; - padding: .35em .5em .2em .5em; - margin: 1.3em 0 -.2em 0; + display: block; + margin: 0; + /* min-width: 10em; */ + padding: .35em .5em .2em 0; font-size: 1.4em; } +#srch_namev { + font-size: medium; + max-width: 12em; + height: 1.5em; + margin: .2em 0 0 .5em; +} html.y #path { text-shadow: none; } @@ -622,6 +635,8 @@ html.y #path { margin-left: -.7em; } #files { + overflow-x: scroll; + display: block; z-index: 1; top: -.3em; border-spacing: 0; @@ -647,6 +662,7 @@ a, #blogout, #files tbody div a:last-child { } #blogout { margin: -.2em; + text-shadow: 1px 1px 0px var(--bg-max); } #blogout:hover, a:hover { @@ -852,7 +868,7 @@ html.y #path a:hover { .mdo>h1:first-child, .mdo>h2:first-child, .mdo>h3:first-child { - margin-top: 1.5rem; + margin-top: 0.5rem; } .mdo { max-width: 52em; @@ -874,9 +890,9 @@ html.y #path a:hover { } #srv_info, #acc_info { - position: absolute; + position: relative; font-size: .8em; - top: .5em; + bottom: 18.5em; } #srv_info { left: 2em; @@ -891,18 +907,18 @@ html.y #path a:hover { padding: 0; } #srv_info2 { - display: none; + display: block; } #acc_info { - right: 2em; + left: 2em; } #acc_info > span:not([id]) { color: var(--srv-1); - margin-right: .6em; + margin-left: .6em; } #acc_info span.warn { color: var(--srv-3); - border-bottom: 1px solid var(--srv-3b); + border-top: 1px solid var(--srv-3b); } #flogout { display: inline; @@ -917,8 +933,12 @@ html.dz #flogout { border-left: .2em solid var(--bg-u5); } #repl { + opacity: .3; padding: .33em; } +#repl:hover{ + opacity: 1; +} #files a.doc { color: var(--a-gray); } @@ -1110,15 +1130,14 @@ html.dz #flogout { right: 0; bottom: -6em; height: 6em; - width: 100%; - z-index: 3; + z-index: 1; touch-action: none; } #widget.anim { - transition: bottom 0.15s; + transition: bottom 0.15s, margin-left 0.15s; } #widget.open { - box-shadow: 0 0 1em rgba(0,48,64,0.2); + /* box-shadow: 0 0 1em rgba(0,48,64,0.2); */ bottom: 0; } html.y #widget.open { @@ -1131,16 +1150,17 @@ html.y #widget.open { height: 100%; } #fshr, -#wtgrid, +#wtgrid, #wtgrid2, #wtico { position: relative; font-size: .9em; top: -.04em; } -#wtgrid { +#wtgrid, #wtgrid2 { font-size: .75em; padding: .1em; - top: -.12em; + top: -.6em; + display: inline-flex; } #wtico { cursor: pointer; @@ -1170,7 +1190,7 @@ html.y #widget.open { #wtoggle, #widgeti { background: #fff; - background: var(--bg-u3); + background: var(--bg-u2); } #wfs, #wfm, #wzip, #wnp, #wm3u { display: none; @@ -1182,7 +1202,13 @@ html.y #widget.open { border-width: 0 .1em 0 0; } #wzip1 { - margin-right: .2em; + margin-right: 0em; +} +#wzip { + margin-left: 0 !important; + padding-left: 0 !important; + margin-right: 0 !important; + padding-right: 0 !important; } #wfm.act+#wzip1+#wzip, #wfm.act+#wzip1+#wzip+#wnp { @@ -1330,7 +1356,7 @@ html.y #widget.open { font-size: 1.2em; } #widget.cmp #fshr, -#widget.cmp #wtgrid { +#widget.cmp #wtgrid, #widget.cmp #wtgrid2 { display: none; } #widget.cmp #pctl { @@ -1376,6 +1402,8 @@ html.y #widget.open { border-radius: 0 0 .2em .2em; border-bottom: .3em solid var(--a-b); box-shadow: var(--op-aa-sh); + margin: -.2em 0 -.6em 0; + padding-top: .4em; } #ops a svg { width: 1.75em; @@ -1385,9 +1413,41 @@ html.y #widget.open { html.y #ops svg circle { stroke: black; } +#topBar{ + display: flex; + justify-content: space-between; +} +#headerArea{ + display: flex; + margin: .2em; +} +.hamburger_line{ + height: .2em; + width: 1.4em; + margin: .3em; + background: var(--a); + border-radius: .1em; +} +#srv_name{ + font-size: x-large; + margin-top: .2em; +} +#treeToggleBtn{ + padding: .2em; + margin-top: .3em; + cursor: pointer; + + display: block; +} +.on div{ + background: var(--bg-u3); +} #ops { padding: .3em .6em; white-space: nowrap; + display: flex; + max-height: 2.5em; + border-radius: 0 0 0 .3em !important; } #noie { color: #b60; @@ -1407,6 +1467,7 @@ html.y #ops svg circle { #op_cfg input[type=text] { top: -.3em; } +#pathBar input[type=text], .opview select, .opview input[type=text] { color: var(--fg); @@ -1563,7 +1624,7 @@ input.ssconf_v { width: 100%; } #wrap { - margin: 1.8em 1.5em 0 1.5em; + margin: .5em .7em 0 .7em; min-height: 70vh; padding-bottom: 7em; } @@ -1572,12 +1633,13 @@ input.ssconf_v { position: absolute; left: 0; bottom: 0; - top: 7em; overflow-x: hidden; overflow-y: auto; -ms-scroll-chaining: none; overscroll-behavior-y: none; box-shadow: 0 0 1em var(--bg-d2), 0 -1px 0 rgba(128,128,128,0.3); + border: 1px solid var(--bg-u3); + transition: .15s; } #tree, html { @@ -1618,9 +1680,6 @@ html { #tree::-webkit-scrollbar-thumb { background: var(--scroll); } -#tree:hover { - z-index: 2; -} #treeul { position: relative; left: -2.2em; @@ -2473,18 +2532,21 @@ html.y #bbox-overlay figcaption a { } .dropzone { z-index: 80386; - height: 50%; + height: 100%; } #up_dz { - bottom: 50%; + bottom: 12%; } #srch_dz { + display: none; top: 50%; } #up_zd { top: 12%; + bottom: 12%; } #srch_zd { + display: none; bottom: 12%; } .dropdesc span { @@ -2923,7 +2985,7 @@ html.b #u2conf a.b:hover { html.c #path, html.a #path { - border-radius: 0 .3em .3em 0; + border-radius: .3em; } html.c #pctl a, html.a #pctl a { @@ -2938,7 +3000,7 @@ html.b #pctl { html.d #ops, html.c #ops, html.a #ops { - margin: 1.7em 1.5em 0 1.5em; + margin: 0 0 0 1.5em; border-radius: .3em; border-width: 1px 0; } @@ -2976,6 +3038,7 @@ html.a .opbox h3 { html.c #ops, html.c .opbox, html.c #path, +html.c #wfp, html.c #srch_form, html.c .ghead, @@ -3018,7 +3081,7 @@ html.a #op_up2k.srch #u2btn { html.c #u2conf #u2btn, html.a #u2conf #u2btn { padding: .6em 0; - margin-top: -2.6em; + margin-top: .2em; } html.c #u2etas, html.a #u2etas { @@ -3087,7 +3150,7 @@ html.b #srv_info2:after { margin: 0 .4em; } html.b #acc_info { - right: .5em; + left: .5em; } html.b #wtoggle { border-radius: .1em 0 0 0; @@ -3230,7 +3293,34 @@ html.d #treepar { - +/* basically a phone layout */ +@media (max-width: 50em){ + #topBar { + display: block; + } + #ops { + margin: .5em !important; + border-radius: .3em !important; + } + #tree { + z-index: 3; + } + #widget, #wrap { + margin-left: 0 !important; + } + #pathBar { + display: block; + } + #srch_namev { + margin: .5em .5em 0 .5em; + } + #wrap { + margin-right: 0; + } + #wfp { + margin-left: .1em !important; + } +} @media (max-width: 32em) { #u2conf { font-size: .9em; @@ -3287,6 +3377,16 @@ html.d #treepar { display: block; margin-top: 1em; } + + #pathBar { + display: block; + } + #srch_namev { + margin: .5em .5em 0 .5em ; + } + #path { + min-width: auto; + } } @media (max-width: 54em) { html.b #ops { @@ -3332,6 +3432,7 @@ html.d #treepar { #ggrid>a:before, #widget.anim, + #tree, #u2tabw, .dropdesc, .dropdesc b, @@ -3637,7 +3738,7 @@ html.e #acc_info { background: var(--transparent); color: var(--white); height: 2em; - left: 1em; + right: 1em; width: fit-content; } html.e #acc_info, @@ -3689,9 +3790,9 @@ html.e #ops a { color: var(--white); height: fit-content; align-items: center; - top: 3.2em; - right: 1em; - left: auto; + bottom: 9.2em; + left: 1em; + right: auto; display: flex; gap: 0.2em; } @@ -4074,7 +4175,7 @@ html.e #wtico, html.e #zip1 { box-shadow: 0 0 !important; } -html.e #wtgrid { +html.e #wtgrid, #wtgrid2 { top: -0.09em; } html.e #wfs, @@ -4094,15 +4195,6 @@ html.e #barpos { html.e #goh + span { border-left: 0.1em solid var(--bg-u5); } -html.e #wfp { - margin: var(--negative-space); - font-size: 0; - display: inline-block; -} -html.e #wfp a { - font-size: large; - display: inline-block; -} html.e #repl { font-size: large; padding: 0.33em; @@ -4189,9 +4281,142 @@ html.e #detree { z-index: 99; } +#wfp{ + margin: .2em .3em 0 -.3em; +} + +#acc_settings{ + background-color: rgba(0, 0, 0, 0.4); + border-radius: .3em; + margin: .2em .3em; +} +#spaceFree{ + color: var(--fg); + text-align: center; + padding: 2px; + position: absolute; + bottom: 150%; + left: 0%; + font-size: small; + cursor: default; +} +#spaceUsed_bar{ + position: absolute; + left: 0; + bottom: 125%; + /* width: 50%; */ + height: .3em; + border-radius: .3em; + background: var(--btn-1-bg); +} +#spaceTotal_bar{ + position: absolute; + left: 0; + bottom: 125%; + width: 100%; + height: .3em; + border-radius: .3em; + background: var(--btn-h-bg); +} + +.popup_button { + border-radius: .3em; + background: var(--btn-1-bg); + margin: 1em; + position: absolute; + bottom: 0; + left: 0; + cursor: pointer; + height: 2.0em; +} +#acc_btnContent{ + position: absolute; + width: 100%; + height: 100%; + display: flex; + justify-content:space-between; + color: var(--btn-1-fg); + text-align: left; + text-shadow: none; +} +.popup_button p{ + margin: .2em .3em; + align-self: center; +} + +/* Toggle this class - hide and show the popup */ +.popup_button .show { + visibility: visible; + -webkit-animation: fadeIn 1s; + animation: fadeIn 1s; +} + +/* The actual popup */ +.popup { + visibility: hidden; + width: fit-content; + background-color: #555; + color: #fff; + text-align: center; + border-radius: 6px; + padding: 8px; + position: absolute; + display: block; + z-index: 3; + bottom: 125%; + left: 0%; + cursor: default; +} + +/* Popup arrow */ +.popup::after { + content: ""; + position: absolute; + top: 100%; + left: 50%; + margin-left: -5px; + border-width: 5px; + border-style: solid; + border-color: #555 transparent transparent transparent; +} + .overlay_plus{ position: absolute; margin: -1.7em 0 0 .8em; color: var(--fg); } +.gridViewIcon, +.listViewIcon{ + width: 1.7em; + height: 1.7em; +} +.gridViewIcon{ + display: grid; + grid-template-columns: auto auto; + grid-template-rows: auto auto; +} +.listViewIcon{ + display: grid; + grid-template-rows: auto auto ; +} +.gridSquare{ + margin: .1em; + background: var(--a); + border-radius: .1em; +} +.listRow{ + margin: .3em .1em; + margin-left: .8em; + background: var(--a); + border-radius: .1em; +} +.listRow::before{ + position: absolute; + content: '▢'; + text-shadow: none; + font-weight: bold; + font-size: x-small; + margin-left: -1em; + margin-top: -.7em; +} diff --git a/copyparty/web/browser.html b/copyparty/web/browser.html index a5b412b0..2bfc4668 100644 --- a/copyparty/web/browser.html +++ b/copyparty/web/browser.html @@ -16,7 +16,13 @@ -
    +
    + +
    +
    +
    + +
    diff --git a/copyparty/web/util.js b/copyparty/web/util.js index 0476e203..8eb2b068 100644 --- a/copyparty/web/util.js +++ b/copyparty/web/util.js @@ -2270,6 +2270,9 @@ var favico = (function () { fg = dv.length < 2 ? 'fc5' : dv[1].toLowerCase() == 'none' ? '' : dv[1], bg = dv.length < 3 ? '222' : dv[2].toLowerCase() == 'none' ? '' : dv[2]; + if(dv.length > 0) + ebi('srv_name')?.prepend(dv[0] + ' '); + scfg_bind(r, 'txt', 'icot', dv[0], r.upd); scfg_bind(r, 'fg', 'icof', fg, r.upd); scfg_bind(r, 'bg', 'icob', bg, r.upd); From ef6cc41a2429b48e258e9653c398a7492fb10c67 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 3 Apr 2026 17:38:22 +0200 Subject: [PATCH 015/598] use better sorting indicators that are consistent on more platforms --- copyparty/web/browser.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 642ba71d..9aed6aad 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -684,12 +684,12 @@ a:hover { } .s0:after, .s1:after { - content: '⏷'; + content: '▾'; /* margin-left: -.15em; */ } .s0r:after, .s1r:after { - content: '⏶'; + content: '▴'; /* margin-left: -.15em; */ } .s0:after, From c5fd85927879ce9b2386a4c5f1752038e5024652 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 3 Apr 2026 18:12:09 +0200 Subject: [PATCH 016/598] replace list icon unicode with border --- copyparty/web/browser.css | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 9aed6aad..4fa704bc 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -1158,8 +1158,8 @@ html.y #widget.open { } #wtgrid, #wtgrid2 { font-size: .75em; - padding: .1em; - top: -.6em; + padding: 0; + top: -.7em; display: inline-flex; } #wtico { @@ -1439,9 +1439,6 @@ html.y #ops svg circle { display: block; } -.on div{ - background: var(--bg-u3); -} #ops { padding: .3em .6em; white-space: nowrap; @@ -4390,6 +4387,8 @@ html.e #detree { .listViewIcon{ width: 1.7em; height: 1.7em; + padding: .2em; + top: 0; } .gridViewIcon{ display: grid; @@ -4410,13 +4409,23 @@ html.e #detree { margin-left: .8em; background: var(--a); border-radius: .1em; + max-height: .15em; } +.on div{ + background: var(--bg-u3); +} + .listRow::before{ position: absolute; - content: '▢'; - text-shadow: none; - font-weight: bold; - font-size: x-small; - margin-left: -1em; - margin-top: -.7em; + content: ''; + margin-left: -.7em; + margin-top: -.2em; + width: .3em; + height: .3em; + border: var(--a) solid .15em; + border-radius: .1em; } +.on ::before{ + border-color: var(--bg-u3); +} + From 95f87a4c5c60d854d8f55f4beb7b30e191857fe2 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 3 Apr 2026 18:17:33 +0200 Subject: [PATCH 017/598] qdel default -> 1 --- copyparty/__main__.py | 2 +- docs/chungus.conf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/copyparty/__main__.py b/copyparty/__main__.py index e0a46e79..23e37869 100644 --- a/copyparty/__main__.py +++ b/copyparty/__main__.py @@ -1877,7 +1877,7 @@ def add_ui(ap, retry: int): ap2.add_argument("--nsort", action="store_true", help="default-enable natural sort of filenames with leading numbers (volflag=nsort)") ap2.add_argument("--hsortn", metavar="N", type=int, default=2, help="number of sorting rules to include in media URLs by default (volflag=hsortn)") ap2.add_argument("--see-dots", action="store_true", help="default-enable seeing dotfiles; only takes effect if user has the necessary permissions") - ap2.add_argument("--qdel", metavar="LVL", type=int, default=2, help="number of confirmations to show when deleting files (2/1/0)") + ap2.add_argument("--qdel", metavar="LVL", type=int, default=1, help="number of confirmations to show when deleting files (2/1/0)") ap2.add_argument("--dlni", action="store_true", help="force download (don't show inline) when files are clicked (volflag:dlni)") ap2.add_argument("--unlist", metavar="REGEX", type=u, default="", help="don't show files/folders matching \033[33mREGEX\033[0m in file list. WARNING: Purely cosmetic! Does not affect API calls, just the browser. Example: [\033[32m\\.(js|css)$\033[0m] (volflag=unlist)") ap2.add_argument("--dothidden", action="store_true", help="hide specific files in a folder by listing them in a file named .hidden -- WARNING: Mostly cosmetic! Download-as-zip/tar will still download them. Do not rely on this for security (volflag=dothidden)") diff --git a/docs/chungus.conf b/docs/chungus.conf index e2742ca0..6cb39039 100644 --- a/docs/chungus.conf +++ b/docs/chungus.conf @@ -1476,7 +1476,7 @@ see-dots # number of confirmations to show when deleting files (2/1/0) - qdel: 2 # default + qdel: 1 # default # don't show files/folders matching REGEX in file list. WARNING: Purely cosmetic! Does not affect API calls, just the browser. Example: [\.(js|css)$] # 📂 also available as volflag "unlist" From cbd61aad5c13ceff7fc1e270dd7cf9cf5d907f3b Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 3 Apr 2026 18:40:27 +0200 Subject: [PATCH 018/598] files margin adj for new layout --- copyparty/web/browser.css | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 4fa704bc..bf52faba 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -564,6 +564,9 @@ html,body,tr,th,td,#files,a,#blogout { padding: 0; border: none; } +#files { + margin-top: .2em; +} html { color: var(--fg); background: var(--bgg); @@ -3292,6 +3295,9 @@ html.d #treepar { /* basically a phone layout */ @media (max-width: 50em){ + body { + margin: 1em; + } #topBar { display: block; } @@ -3309,7 +3315,7 @@ html.d #treepar { display: block; } #srch_namev { - margin: .5em .5em 0 .5em; + margin: .5em 1em 0 1em; } #wrap { margin-right: 0; From cef757c0b74001cd9faf1e14257d0beb908f8a89 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 3 Apr 2026 18:46:37 +0200 Subject: [PATCH 019/598] remove duplicate https switch hint from login --- copyparty/web/splash.html | 3 --- 1 file changed, 3 deletions(-) diff --git a/copyparty/web/splash.html b/copyparty/web/splash.html index 38e1fa18..ce44a385 100644 --- a/copyparty/web/splash.html +++ b/copyparty/web/splash.html @@ -149,9 +149,6 @@ {%- if chpw %} change password {%- endif %} - {%- if ahttps %} - switch to https - {%- endif %}
    {%- endif %} From c768a854e32f0b9f5f3a439e365068028c60f9ba Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 3 Apr 2026 19:01:37 +0200 Subject: [PATCH 020/598] changed some baguettebox descs --- copyparty/web/baguettebox.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/copyparty/web/baguettebox.js b/copyparty/web/baguettebox.js index 9a78619c..1b4c64a3 100644 --- a/copyparty/web/baguettebox.js +++ b/copyparty/web/baguettebox.js @@ -313,11 +313,11 @@ window.baguetteBox = (function () { '' + '' + '' + - '' + + '' + '' + - '' + + '' + '' + - '' + + '' + '
    ' ); overlay = ctr.firstChild; From c4410c4c46d0276c6447d56a3e6f56474dc75f3a Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 3 Apr 2026 19:06:37 +0200 Subject: [PATCH 021/598] let the gallery grid display up to the edge of the screen --- copyparty/web/browser.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index bf52faba..02dfe13e 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -3399,7 +3399,7 @@ html.d #treepar { @supports (display: grid) and (gap: 1em) { #ggrid { display: grid; - margin: 0em 0.25em; + margin: 0em -0.25em; padding: unset; grid-template-columns: repeat(auto-fit,var(--grid-sz)); justify-content: center; From e413ba7ac614070fd7c25e6038ef85838fe1068d Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 3 Apr 2026 19:10:43 +0200 Subject: [PATCH 022/598] addition to last commit --- copyparty/web/browser.css | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 02dfe13e..a1c2d5e9 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -3323,6 +3323,9 @@ html.d #treepar { #wfp { margin-left: .1em !important; } + #ggrid { + margin: 0em -0.25em !important; + } } @media (max-width: 32em) { #u2conf { @@ -3399,7 +3402,7 @@ html.d #treepar { @supports (display: grid) and (gap: 1em) { #ggrid { display: grid; - margin: 0em -0.25em; + margin: 0; padding: unset; grid-template-columns: repeat(auto-fit,var(--grid-sz)); justify-content: center; From 35c8657e37630a1e0823fd2e615d071d7c4a8ab2 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 3 Apr 2026 21:03:07 +0200 Subject: [PATCH 023/598] fix drop visuals and make drop search work again --- copyparty/web/browser.css | 15 +++++++++------ copyparty/web/up2k.js | 31 ++++++++++++++++++++++++------- 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index a1c2d5e9..d6ac9087 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -2471,7 +2471,7 @@ html.y #bbox-overlay figcaption a { display: table; left: 10%; width: 78%; - height: 26%; + height: 78%; margin: 0; font-size: 3em; font-weight: bold; @@ -2490,7 +2490,7 @@ html.y #bbox-overlay figcaption a { background: rgba(24, 24, 24, 0.7); left: 8%; width: 82%; - height: 32%; + height: 82%; margin: -3vh 0; } .dropdesc.hl.err { @@ -2535,18 +2535,21 @@ html.y #bbox-overlay figcaption a { height: 100%; } #up_dz { - bottom: 12%; + position: absolute; + bottom: 0; } #srch_dz { - display: none; - top: 50%; + position: absolute; + top: 0; } #up_zd { + position: absolute; top: 12%; bottom: 12%; } #srch_zd { - display: none; + position: absolute; + top: 12%; bottom: 12%; } .dropdesc span { diff --git a/copyparty/web/up2k.js b/copyparty/web/up2k.js index 21a6dad0..c54d2a7c 100644 --- a/copyparty/web/up2k.js +++ b/copyparty/web/up2k.js @@ -1054,6 +1054,20 @@ function up2k_init(subtle) { function onoverbtn(e) { return onovercmn(this, e, true); } + function checkDropMode(){ + if(ebi('fsearch')?.checked){ + ebi('srch_zd').style.display = ''; + ebi('up_zd').style.display = 'none'; + ebi('srch_dz').style.display = ''; + ebi('up_dz').style.display = 'none'; + } + else{ + ebi('srch_zd').style.display = 'none'; + ebi('up_zd').style.display = ''; + ebi('srch_dz').style.display = 'none'; + ebi('up_dz').style.display = ''; + } + } function onovercmn(self, e, btn) { try { var ok = false, dt = e.dataTransfer.types; @@ -1087,6 +1101,7 @@ function up2k_init(subtle) { if (btn) return; + checkDropMode(); clmod(ebi('drops'), 'vis', 1); var v = self.getAttribute('v'); if (v) @@ -1100,6 +1115,7 @@ function up2k_init(subtle) { clmod(ebi(v), 'hl'); if (--nenters <= 0) { + checkDropMode(); clmod(ebi('drops'), 'vis'); clmod(ebi('up_dz'), 'hl'); clmod(ebi('srch_dz'), 'hl'); @@ -1158,10 +1174,10 @@ function up2k_init(subtle) { ev(e); nenters = 0; offdrag.call(this); - var dz = this && this.getAttribute('id'); - if (!dz && e && e.clientY) - // cuo2duo fallback - dz = e.clientY < window.innerHeight / 2 ? 'up_dz' : 'srch_dz'; + // var dz = this && this.getAttribute('id'); + // if (!dz && e && e.clientY) + // // cuo2duo fallback + // dz = e.clientY < window.innerHeight / 2 ? 'up_dz' : 'srch_dz'; var err = this.getAttribute('err'); if (err) @@ -1169,10 +1185,11 @@ function up2k_init(subtle) { toast.inf(0, L.u_scan); - if ((dz == 'up_dz' && uc.fsearch) || (dz == 'srch_dz' && !uc.fsearch)) - tgl_fsearch(); + // if ((dz == 'up_dz' && uc.fsearch) || (dz == 'srch_dz' && !uc.fsearch)) + // tgl_fsearch(); - if (!QS('#op_up2k.act')) + //if (!QS('#op_up2k.act')) + if(!uc.fsearch) goto('up2k'); var files, From b55d7b27a021c164b5230468130f4ec4dc40e8a6 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 3 Apr 2026 21:20:34 +0200 Subject: [PATCH 024/598] minor style adjustments --- copyparty/web/browser.css | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index d6ac9087..f790bffb 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -1422,7 +1422,7 @@ html.y #ops svg circle { } #headerArea{ display: flex; - margin: .2em; + margin: .5em .5em -.5em .5em; } .hamburger_line{ height: .2em; @@ -2347,14 +2347,14 @@ html.y #bbox-overlay figcaption a { #bbox-overlay button { cursor: pointer; outline: none; - padding: 0 .3em; - margin: 0 .4em; + padding: 0 .4em; + margin: 0 .2em; border: 0; border-radius: 15%; background: rgba(50, 50, 50, 0.5); color: rgba(255,255,255,0.7); font-size: 1.4em; - line-height: 1.4em; + line-height: 2em; vertical-align: top; font-variant: small-caps; } @@ -2371,7 +2371,7 @@ html.y #bbox-overlay figcaption a { } #bbox-btns { top: .5em; - right: 2%; + right: .5em; position: fixed; } #bbox-halp { @@ -3304,6 +3304,9 @@ html.d #treepar { #topBar { display: block; } + #headerArea { + margin: .2em; + } #ops { margin: .5em !important; border-radius: .3em !important; @@ -3329,6 +3332,9 @@ html.d #treepar { #ggrid { margin: 0em -0.25em !important; } + #ghead { + margin: .5em; + } } @media (max-width: 32em) { #u2conf { From 39918cf8110b5431e8e69064a3b6d6651b5aa0a9 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 3 Apr 2026 21:46:36 +0200 Subject: [PATCH 025/598] fix tree causing scrollbar to appear when it shouldn't --- copyparty/web/browser.css | 3 ++- copyparty/web/browser.js | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index f790bffb..4af12aa0 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -1633,6 +1633,7 @@ input.ssconf_v { position: absolute; left: 0; bottom: 0; + height: auto !important; overflow-x: hidden; overflow-y: auto; -ms-scroll-chaining: none; @@ -1923,7 +1924,7 @@ html.y #tree.nowrap .ntree a+a:hover { border-radius: .3em; padding: .2em .5em; line-height: 2.3em; - margin-bottom: 1.5em; + margin: 0 0 1.5em 0; } #hdoc, #ghead { diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index 7876e178..f8024976 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -7061,12 +7061,12 @@ var treectl = (function () { if (fixedpos && atop >= 0) { tree.style.position = 'absolute'; - tree.style.bottom = ''; + //tree.style.bottom = ''; fixedpos = false; } else if (!fixedpos && atop < 0) { tree.style.position = 'fixed'; - tree.style.height = 'auto'; + //tree.style.height = 'auto'; fixedpos = true; } From ababa893af19324994227da47169f3d19401c10a Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 3 Apr 2026 21:48:03 +0200 Subject: [PATCH 026/598] Revert "fix tree causing scrollbar to appear when it shouldn't" This reverts commit 39918cf8110b5431e8e69064a3b6d6651b5aa0a9. --- copyparty/web/browser.css | 3 +-- copyparty/web/browser.js | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 4af12aa0..f790bffb 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -1633,7 +1633,6 @@ input.ssconf_v { position: absolute; left: 0; bottom: 0; - height: auto !important; overflow-x: hidden; overflow-y: auto; -ms-scroll-chaining: none; @@ -1924,7 +1923,7 @@ html.y #tree.nowrap .ntree a+a:hover { border-radius: .3em; padding: .2em .5em; line-height: 2.3em; - margin: 0 0 1.5em 0; + margin-bottom: 1.5em; } #hdoc, #ghead { diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index f8024976..7876e178 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -7061,12 +7061,12 @@ var treectl = (function () { if (fixedpos && atop >= 0) { tree.style.position = 'absolute'; - //tree.style.bottom = ''; + tree.style.bottom = ''; fixedpos = false; } else if (!fixedpos && atop < 0) { tree.style.position = 'fixed'; - //tree.style.height = 'auto'; + tree.style.height = 'auto'; fixedpos = true; } From 741ad0495c5d49942e93b609326e81ff86746c7b Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 3 Apr 2026 21:56:36 +0200 Subject: [PATCH 027/598] limit transition duration of tree to width --- copyparty/web/browser.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index f790bffb..89fdb675 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -1639,7 +1639,7 @@ input.ssconf_v { overscroll-behavior-y: none; box-shadow: 0 0 1em var(--bg-d2), 0 -1px 0 rgba(128,128,128,0.3); border: 1px solid var(--bg-u3); - transition: .15s; + transition: width 0.15s; } #tree, html { From db864b921d1ded68a27ba27f6b4b2db6ae9b38e7 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 3 Apr 2026 21:59:57 +0200 Subject: [PATCH 028/598] fix tree causing scrollbar to appear when it shouldn't --- copyparty/web/browser.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index 7876e178..fe463433 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -7078,7 +7078,8 @@ var treectl = (function () { treeh = winh - atop; tree.style.top = top + 'px'; - tree.style.height = treeh < 10 ? '' : Math.floor(treeh) + 'px'; + // setting the height causes scrollbars to appear often because it's not exact most of the time + tree.style.height = '';// = treeh < 10 ? '' : Math.floor(treeh) + 'px'; } } timer.add(onscroll2, true); From 06b2ff3e566315b150b7d9d7459e49adbb85b2dd Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Sat, 4 Apr 2026 13:03:58 +0200 Subject: [PATCH 029/598] fix jank implementation of space used progress bar --- copyparty/httpcli.py | 15 +++++++++------ copyparty/web/browser.html | 4 ++-- copyparty/web/browser.js | 4 ++-- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/copyparty/httpcli.py b/copyparty/httpcli.py index 6166fc89..0426ff58 100644 --- a/copyparty/httpcli.py +++ b/copyparty/httpcli.py @@ -6989,6 +6989,7 @@ class HttpCli(object): zi = vn.flags["du_iwho"] h1 = "" h2 = "" + space_used_percent = 0 if zi and ( zi == 9 or (zi == 7 and self.uname != "*") @@ -7016,6 +7017,8 @@ class HttpCli(object): h1 = humansize(free or 0) h2 = humansize(total) srv_info.append("{} free of {}".format(h1, h2)) + if(total > 0) + space_used_percent = (total - (free or 0)) / total * 100 elif zs: self.log("diskfree(%r): %s" % (abspath, zs), 3) @@ -7066,9 +7069,9 @@ class HttpCli(object): "files": [], "taglist": [], "srvinf": srv_infot, - "space_free": float(h1.split()[0]), - "space_total": float(h2.split()[0]), - "space_unit": h2.split()[1], + "space_used_percent": space_used_percent + "space_free": h1, + "space_total": h2, "acct": self.uname, "perms": perms, "cfg": vn.js_ls, @@ -7093,9 +7096,9 @@ class HttpCli(object): "title": html_escape("%s %s" % (self.args.bname, self.vpath), crlf=True), "srv_info": srv_infot, "srv_name": srv_name, - "space_free": float(h1.split()[0]), - "space_total": float(h2.split()[0]), - "space_unit": h2.split()[1], + "space_used_percent": space_used_percent + "space_free": h1, + "space_total": h2, "dtheme": self.args.theme, } diff --git a/copyparty/web/browser.html b/copyparty/web/browser.html index 2bfc4668..be08eb29 100644 --- a/copyparty/web/browser.html +++ b/copyparty/web/browser.html @@ -136,11 +136,11 @@ diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index 715a8254..7befc3d1 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -1027,7 +1027,7 @@ ebi('tree').innerHTML = ( '
      \n' + '
       
      ' ); -ebi('thx_ff').before(ebi('acc_button')); +ebi('thx_ff').before(ebi('tree_footer')); clmod(ebi('tree'), 'sbar', 1); ebi('goh').textContent = L.goh; QS('#op_mkdir input[type="submit"]').value = L.ab_mkdir; @@ -7104,7 +7104,7 @@ var treectl = (function () { setcvar('--nav-sz', w); ebi('tree').style.width = w; - ebi('acc_button').style.width = (iw - 2) + 'em'; + ebi('tree_footer').style.width = (iw - 2) + 'em'; ebi('wrap').style.marginLeft = w2; ebi('widget').style.marginLeft = (iw /1.4) + 'em'; onscroll(); From 493ed5d3aaa3072f4b38d93e75394501084c01ce Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Sat, 4 Apr 2026 13:14:11 +0200 Subject: [PATCH 033/598] add rtt back --- copyparty/web/browser.html | 4 +++- copyparty/web/browser.js | 5 +++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/copyparty/web/browser.html b/copyparty/web/browser.html index edff8a73..3cbabb1e 100644 --- a/copyparty/web/browser.html +++ b/copyparty/web/browser.html @@ -136,7 +136,9 @@ From 85f45841f599969de5f288b971cb0d3fee6940cb Mon Sep 17 00:00:00 2001 From: stackxp <170874486+stackxp@users.noreply.github.com> Date: Tue, 7 Apr 2026 14:23:22 +0200 Subject: [PATCH 038/598] Add moving files into other folders by dragging --- copyparty/web/browser.css | 16 ++++++ copyparty/web/browser.js | 104 +++++++++++++++++++++++++++++++++++++- copyparty/web/up2k.js | 2 +- 3 files changed, 119 insertions(+), 3 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index a1c2d5e9..b4b75f2b 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -634,6 +634,9 @@ html .ayjump:focus { html.y #path { text-shadow: none; } +#path a.dtarget { + text-shadow: var(--f-sel-sh) 0 0 5px; +} #path #entree { margin-left: -.7em; } @@ -787,6 +790,12 @@ html.y #files span.fsz_P { font-weight: bold } #files .srch_hdr a { display: inline; } +#files tr.dtarget { + box-shadow: 0 0 5px 0 var(--f-sel-sh) inset; +} +#files tr.dtarget td { + background: none; +} #path a { padding: 0 .35em; position: relative; @@ -1100,6 +1109,9 @@ html.dz #flogout { scroll-margin-top: 25vh; scroll-margin-bottom: 20vh; } +#ggrid a.dtarget { + box-shadow: 0 0 5px 0 var(--f-sel-sh); +} #files tr.sel a, #files tr.sel a.play { color: var(--fg2-max); @@ -1623,6 +1635,7 @@ input.ssconf_v { border-collapse: collapse; width: 100%; } + #wrap { margin: .5em .7em 0 .7em; min-height: 70vh; @@ -1753,6 +1766,9 @@ html.dz .btn { margin-left: -.25em; z-index: 3; } +#tree li a.dtarget { + box-shadow: 0 0 5px 0 var(--f-sel-sh) inset; +} #tree ul a.sel { background: #000; background: var(--bg-d3); diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index 7876e178..a86a3fa6 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -234,6 +234,7 @@ if (1) "ct_thumb": 'in grid-view, toggle icons or thumbnails$NHotkey: T">🖼️ thumbs', "ct_csel": 'use CTRL and SHIFT for file selection in grid-view">sel', "ct_dsel": 'use drag-selection in grid-view">dsel', + "ct_den": 'use dragging to move files into other folders">mvd', "ct_dl": 'force download (don\'t display inline) when a file is clicked">dl', "ct_ihop": 'when the image viewer is closed, scroll down to the last viewed file">g⮯', "ct_dots": 'show hidden files (if server permits)">dotfiles', @@ -922,6 +923,7 @@ ebi('op_cfg').innerHTML = ( ' 0) ebi('path').appendChild(mknod('i')); ebi('path').appendChild(o); + drag.mktarget(o); } reload_mp(); @@ -9975,7 +10075,7 @@ function reload_browser() { function sel_start(e) { if (e.button !== 0 && e.type !== 'touchstart') return; if (!thegrid.en || !treectl.dsel) return; - if (e.target.closest('#widget,#ops,.opview,.doc')) return; + if (e.target.closest('#widget,#ops,.opview,.doc,#ggrid>a')) return; if (e.target.closest('#gfiles')) ebi('gfiles').style.userSelect = "none" diff --git a/copyparty/web/up2k.js b/copyparty/web/up2k.js index 21a6dad0..43220641 100644 --- a/copyparty/web/up2k.js +++ b/copyparty/web/up2k.js @@ -1066,7 +1066,7 @@ function up2k_init(subtle) { if (toast.txt == L.u_uri) toast.hide(); } - else + else if (!window.drag || !drag.no_warn) return toast.inf(10, L.u_uri) || true; } From 6fd72e2ccf8c94e6d47ec8cc2e189fe593475bf1 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Tue, 7 Apr 2026 20:51:00 +0200 Subject: [PATCH 039/598] settings modal --- copyparty/web/browser.css | 74 +++++++++++++++++++++- copyparty/web/browser.html | 13 ++++ copyparty/web/browser.js | 123 +++++++++++++++++++++++++++---------- 3 files changed, 173 insertions(+), 37 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 393cf01e..53a7a1e6 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -2444,6 +2444,73 @@ html.y #bbox-overlay figcaption a { + +/* settings css */ +#s_content{ + display: grid; + grid-template-rows: auto auto; + margin: 5%; + border-radius: .5em; + border: var(--a) solid 1px; + background: var(--bg-u1); + max-width: 60em; + position: relative; +} +#s_header{ + margin: .5em; +} +#s_hor{ + display: grid; + grid-template-columns: auto auto auto; + min-height: 0; +} +#s_nav, #s_list{ + display: flex; + flex-direction: column; + overflow-y: scroll; + padding: .5em; + padding-top: 0; +} +#s_divider{ + background: var(--a); + width: 1px; + margin: 1em .5em; +} +#s_nav .btn::after{ + position: absolute; + content: ">"; + right: .5em; +} +#s_nav .btn, +#s_list{ + padding-right: 2em; +} +.setting{ + padding: .5em; + border: var(--bg-u5) solid 1px; + border-top: 0; + margin: -1.5em 0 1.5em 0; +} +.setting:hover{ + background: var(--bg-u3); +} +.s_desc{ + margin: .5em 0 0 0; + font-size: medium; + color: var(--fg-weak); +} +#s_list h3{ + background-color: var(--bg-u5); + border-radius: .3em .3em 0 0; + padding: .5em; + margin: 0 0 1.3em 0; +} +#cs_btn{ + position: absolute; + right: 0; + margin: .5em; + color: var(--fg); +} @@ -2453,14 +2520,15 @@ html.y #bbox-overlay figcaption a { #op_up2k { padding: 0 1em 1em 1em; } -#drops { +.overlaybg { display: none; z-index: 3; background: rgba(48, 48, 48, 0.7); } -#drops.vis, +.overlaybg.vis, .dropzone { - display: block; + display: flex; + justify-content: center; position: fixed; top: 0; left: 0; diff --git a/copyparty/web/browser.html b/copyparty/web/browser.html index 22785028..4789283b 100644 --- a/copyparty/web/browser.html +++ b/copyparty/web/browser.html @@ -168,6 +168,19 @@
      + +
      + {%- endif %} - + {%- if js %} diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index f622fbb0..cbccb16e 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -7768,12 +7768,12 @@ var treectl = (function () { swrite('entreed', 'tree'); get_tree("", get_evpath(), true); - r.show(); + r.show(nostore); clmod(ebi('treeToggleBtn'), 'on', true) } - r.show = function () { + r.show = function (instant) { r.hidden = false; if (!entreed) { ebi('path').style.display = nonav ? 'none' : 'inline-block'; @@ -7786,11 +7786,17 @@ var treectl = (function () { window.addEventListener('scroll', onscroll); window.addEventListener('resize', onresize); - // makes animation work by waiting for next frame - setTimeout(function () { + if(!instant){ + // makes animation work by waiting for next frame + setTimeout(function () { + onresize(); + aligngriditems(); + }, 10); + } + else { onresize(); aligngriditems(); - }, 10); + } }; r.detree = function (e, nw) { diff --git a/copyparty/web/util.js b/copyparty/web/util.js index 34cb020c..0b28f17e 100644 --- a/copyparty/web/util.js +++ b/copyparty/web/util.js @@ -2318,8 +2318,7 @@ var favico = (function () { scfg_bind(r, 'bg', 'icob', bg, r.upd); r.upd(); }; - - r.to = setTimeout(r.init, 100); + r.init(); return r; })(); From 26d2c68d4713ca4825873eb44a2d075626e59376 Mon Sep 17 00:00:00 2001 From: Til Date: Sat, 9 May 2026 10:16:30 +0200 Subject: [PATCH 374/598] revert load order change --- copyparty/web/browser.html | 313 +++++++++++++++++++------------------ 1 file changed, 159 insertions(+), 154 deletions(-) diff --git a/copyparty/web/browser.html b/copyparty/web/browser.html index fcf107f4..86e88c45 100644 --- a/copyparty/web/browser.html +++ b/copyparty/web/browser.html @@ -51,182 +51,186 @@ -
      +
      -
      -

      -

      - {%- for n in vpnodes %} - {{ n[1] }} - {%- endfor %} -

      +
      +

      +

      + {%- for n in vpnodes %} + {{ n[1] }} + {%- endfor %} +

      -
      -
      +
      +
      -
      - - - - - -
      - - +
      + + + + + +
      + + +
      -
      - -
      +
      {{ "" if sb_lg else logues[0] }}
      -
      -
      - -
      - -
      -
      switch to basic browser
      -
      - -
      -
      - - 📂 - -
      -
      - -
      -
      - - 📝 - -
      - -
      - -
      -
      - 📟 - -
      -
      - -
      - -
      - - - {%- if doc %} -
      {{ doc|e }}
      - {%- else %} -
      - {%- endif %} - -
      {{ "" if sb_lg else logues[0] }}
      - - diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index 5ff81156..09d68519 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -879,6 +879,15 @@ if(!fun_tgl){ ebi('opa_cfg').innerHTML = 'settings' ebi('acc_pfp').innerHTML = 'account' } +else if(!EMOJI){ + ebi('opa_srch').innerHTML = 's?' + ebi('opa_del').innerHTML = 'un' + ebi('opa_up').innerHTML = 'u▲' + ebi('opa_bup').innerHTML = 'b▲' + ebi('opa_msg').innerHTML = 'msg' + ebi('opa_cfg').innerHTML = '★' + ebi('acc_pfp').innerHTML = 'acc' +} // mkdir + md function mktemp(is_dir) { @@ -939,7 +948,7 @@ function mktemp(is_dir) { if (e.key == "Enter" || e.key == "Escape") { input.onblur = null; if(row.remove) - row.remove(); + row.remove(); else row.style.display = 'none'; ev(e); @@ -996,7 +1005,7 @@ ebi('widget').innerHTML = ( '
      +
      ' + '
      ' + - '' + + '' + (EMOJI ? '♫' : '♪') + '' + '
      ' + @@ -6616,13 +6625,24 @@ window.thegrid = (function () { accent = '#07c'; ihref += '&a=' + parseColor(accent).replace(/ /g, ''); } + + var svg = '' + if(ebi('folder-icon').innerHTML != undefined){ + svg = '' + svg = '' + svg + ''; + } + else{ + // 3DS / unsupported: use fallback + svg = '' + (isdir ? '📁[FOLDER]' : '📄[FILE:' + ext +']') + ''; + } + html.push('' + '
      ' + '' + - '' + + svg + (isdir || ext == 'unk' || ext.startsWith('/') ? '' : '' + ext + '') + @@ -7370,10 +7390,10 @@ var search_ui = (function () { var ms = ebi('moresearch'); if(e){ window.scrollTo(0, 0); - ms.innerHTML = '▴'; + ms.innerHTML = ''; } else{ - ms.innerHTML = '▾'; + ms.innerHTML = ''; } } ebi('moresearch').onclick = function () { @@ -8138,6 +8158,7 @@ var treectl = (function () { if (!entreed || r.hidden){ if(ebi('tree').style.width == '0px') ebi('tree').style.display = 'none'; + ebi('reszbar').style.left = '2px'; setcvar('--nav-sz', 0); return; } @@ -9090,7 +9111,7 @@ function apply_perms(res) { else{ ebi('blogout').style.display = 'none'; ebi('acc_name').innerHTML = L.login; - ebi('acc_pfp').innerHTML = fun_tgl ? '👤' : 'acc'; + ebi('acc_pfp').innerHTML = fun_tgl && EMOJI ? '👤' : 'acc'; } clmod(ebi('acc_pfp'), 'placeholder', acct == '*'); @@ -9177,7 +9198,8 @@ function apply_perms(res) { ebi('reloc_up').innerHTML = up2k_lgcy ? '' : ''; clmod(ebi('up2k'), 'unmodal', up2k_lgcy); } - clmod(ebi('opa_mkd'), 'vis', up_only); + if(EMOJI) + clmod(ebi('opa_mkd'), 'vis', up_only); } function wait_set_fsearch(){ @@ -11168,7 +11190,7 @@ function reload_browser() { o = mknod('a'); o.setAttribute('href', link2); - o.textContent = uricom_dec(parts[a]) || (fun_tgl ? '🏠' : 'home'); + o.textContent = uricom_dec(parts[a]) || (fun_tgl && EMOJI ? '🏠' : 'home'); ebi('path').appendChild(o); ebi('path').appendChild(mknod('i')); drag.mktarget(o); diff --git a/copyparty/web/util.js b/copyparty/web/util.js index 45cb7137..acc49cca 100644 --- a/copyparty/web/util.js +++ b/copyparty/web/util.js @@ -20,6 +20,13 @@ if (window.CGV) Object.assign(window, window.CGV); +function supportsEmoji() { + var ctx = document.createElement('canvas').getContext('2d'); + ctx.canvas.width = ctx.canvas.height = 1; + ctx.fillText('🎉', -4, 4); + return ctx.getImageData(0, 0, 1, 1).data[3] > 0; // Checks if pixels were drawn +} + var wah = '', STG = null, NOAC = 'autocorrect="off" autocapitalize="off"', @@ -35,6 +42,7 @@ var wah = '', VCHROME = CHROME ? 1 : 0, UA = '' + navigator.userAgent, IE = !!document.documentMode, + EMOJI = supportsEmoji(), FIREFOX = ('netscape' in window) && / rv:/.test(UA), IPHONE = TOUCH && /iPhone|iPad|iPod/i.test(UA), LINUX = /Linux/.test(UA), @@ -1823,7 +1831,7 @@ var toast = (function () { setcvar('--tmstep', Math.floor(sec * 20)); html += '
      '; } - obj.innerHTML = html + '
      ' + lf2br(txt) + '
      '; + obj.innerHTML = html + '×
      ' + lf2br(txt) + '
      '; obj.className = cl; sec += obj.offsetWidth; obj.className += ' vis'; From 1712fd85166ff666b30a7e2613a51084d7d79cd7 Mon Sep 17 00:00:00 2001 From: Til Date: Thu, 4 Jun 2026 13:08:33 +0200 Subject: [PATCH 542/598] target 3DS specifically instead of trying to detect svg features (which was false flagging IE11) --- copyparty/web/browser.css | 38 +++++++++++++++++++++++++------------- copyparty/web/browser.js | 19 +++++++++---------- copyparty/web/util.js | 1 + 3 files changed, 35 insertions(+), 23 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 15d31f9c..ad462826 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -1040,9 +1040,12 @@ tr.play td:nth-child(1) a { position: absolute; text-align: center; width: 100%; - width: calc(100% - 8px);; + width: calc(100% - 8px); + left: 4px; + right: 4px; top: 50%; top: calc(55% - .5em); + color: #07c; color: var(--a); text-shadow: none; font-family: monospace; @@ -1303,6 +1306,7 @@ html:not(.e) #ggrid>a.thumbed.dir:before { position: absolute; text-wrap-mode: nowrap; text-wrap: nowrap; + white-space: nowrap; width: 100%; bottom: 100%; right: 0; @@ -1319,7 +1323,9 @@ html:not(.e) #ggrid>a.thumbed.dir:before { display: inline-block; text-wrap-mode: nowrap; text-wrap: nowrap; + white-space: nowrap; text-align: center; + max-width: 79vw; max-width: calc(100% - 3.5em); overflow-x: auto; overflow-y: hidden; @@ -1327,6 +1333,7 @@ html:not(.e) #ggrid>a.thumbed.dir:before { box-shadow: 0 0 .5em var(--mp-sh); border-radius: 5px; border-radius: var(--radius); + overflow-x: auto; } #up_quick { display: inline-block; @@ -1358,6 +1365,7 @@ html:not(.e) #ggrid>a.thumbed.dir:before { margin-bottom: .2em; text-wrap-mode: wrap; text-wrap: nowrap; + white-space: nowrap; } #up_quick_more.vis { display: block; @@ -1365,17 +1373,18 @@ html:not(.e) #ggrid>a.thumbed.dir:before { #up_quick_more a:hover { background: var(--btn-h-bg); } -#up_quick_more a { - position: static; - font-size: large; - display: block; - text-wrap-mode: nowrap; - text-wrap: nowrap; - padding: .5em; - cursor: pointer; - border-radius: 10px; - border-radius: var(--radius); -} + #up_quick_more a { + position: static; + font-size: large; + display: block; + text-wrap-mode: nowrap; + text-wrap: nowrap; + white-space: nowrap; + padding: .5em; + cursor: pointer; + border-radius: 10px; + border-radius: var(--radius); + } #up_quick .overlay_plus { right: .3em; margin-top: -1.5em; @@ -1810,6 +1819,7 @@ html.y #ops svg circle { font-size: x-large; text-wrap-mode: nowrap; text-wrap: nowrap; + white-space: nowrap; display: block; line-height: 1.5em; } @@ -2116,6 +2126,7 @@ html { padding: .3em .5em; text-wrap-mode: nowrap; text-wrap: nowrap; + white-space: nowrap; overflow-x: auto; overflow-y: hidden; } @@ -2166,7 +2177,7 @@ html { .btn { color: #3584e4; color: var(--btn-fg); - background: rgba(70, 73, 77, 0.5); + background: #2f3236; background: var(--btn-bg); box-shadow: var(--btn-bs); border: 1px solid #3a3d41; @@ -3990,6 +4001,7 @@ html:not(.e) #wrap.thin .ghead { html:not(.e) #wrap.thin #ghead { text-wrap-mode: nowrap; text-wrap: nowrap; + white-space: nowrap; overflow-x: auto; overflow-y: hidden; } diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index 09d68519..793b80c8 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -6626,16 +6626,15 @@ window.thegrid = (function () { ihref += '&a=' + parseColor(accent).replace(/ /g, ''); } - var svg = '' - if(ebi('folder-icon').innerHTML != undefined){ - svg = '' - svg = '' + svg + ''; - } - else{ + var svg = ''; + svg = '' + svg + ''; + + if (N3DS){ // 3DS / unsupported: use fallback - svg = '' + (isdir ? '📁[FOLDER]' : '📄[FILE:' + ext +']') + ''; + svg = '' + (isdir ? '📁[FOLDER]' : '📄[FILE:' + ext + ']') + ''; + ext = 'unk'; } html.push(' Date: Thu, 4 Jun 2026 15:20:08 +0200 Subject: [PATCH 545/598] minor splash fix for 3ds --- copyparty/web/splash.css | 2 ++ 1 file changed, 2 insertions(+) diff --git a/copyparty/web/splash.css b/copyparty/web/splash.css index 84453110..011f3b4c 100644 --- a/copyparty/web/splash.css +++ b/copyparty/web/splash.css @@ -172,11 +172,13 @@ a.r:hover, a.r:focus-visible { #pb { opacity: .5; position: fixed; + white-space: nowrap; bottom: .5em; right: .5em; } #pb span { opacity: .6; + pointer-events: none; } #pb a { margin: 0; From ec56e8342fc2c35ab844317c4349c8531c49a188 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Thu, 4 Jun 2026 20:41:56 +0200 Subject: [PATCH 546/598] allow hotkeys when checkboxes are focused --- copyparty/web/browser.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index 793b80c8..51d02f22 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -7054,7 +7054,8 @@ var ahotkeys = function (e) { var k = (e.key || e.code) + '', pos = -1, n, sh = e.shiftKey, ae = document.activeElement, - aet = ae && ae != document.body ? ae.nodeName.toLowerCase() : ''; + aet = ae && ae != document.body ? ae.nodeName.toLowerCase() : '', + aett = aet ? ae.type : ''; if (k.startsWith('Key')) k = k.slice(3); @@ -7125,7 +7126,7 @@ var ahotkeys = function (e) { return ebi('griden').click(); } - if (aet == 'input') + if (aet == 'input' && aett != 'checkbox') return; var in_ftab = (aet == 'tr' || aet == 'td') && ae.closest('#files'); @@ -7178,7 +7179,7 @@ var ahotkeys = function (e) { if (k.endsWith('Enter') && ae && (ae.onclick || ae.hasAttribute('tabIndex'))) return ev(e) && ae.click() || true; - if (aet && aet != 'a' && aet != 'tr' && aet != 'td' && aet != 'div' && aet != 'pre') + if (aet && aet != 'a' && aet != 'tr' && aet != 'td' && aet != 'div' && aet != 'pre' && aett != 'checkbox') return; if (k == '?') From 1789303eb600be7253dfc439446b6c7cb942dd68 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Thu, 4 Jun 2026 20:43:21 +0200 Subject: [PATCH 547/598] cancel button for paste operations --- copyparty/web/browser.css | 4 ++++ copyparty/web/browser.js | 18 +++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index ad462826..d3e42f73 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -1444,6 +1444,10 @@ html:not(.e):not(.d) #up_quick .btn.on { #wfm.act { display: inline-block; } +#wfm .x { + font-size: 1.5em; + line-height: .65em; +} #wtoggle, #wtoggle * { line-height: 1em; diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index 51d02f22..ab754a05 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -974,6 +974,7 @@ ebi('widget').innerHTML = ( '
      ' + '' + '×cancel📨share' + (fun_tgl ? '✏️' : '✎') + 'name🗑️del. Date: Thu, 4 Jun 2026 20:54:55 +0200 Subject: [PATCH 548/598] IE RCM fix --- copyparty/web/browser.css | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index d3e42f73..2a72f114 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -5168,10 +5168,12 @@ html.e #actionsArea { position: fixed; overflow-y: auto; display: none; - background: #fff; + background: #2f3236; background: var(--bg-u2); + border: 1px solid #46494d; border: 1px solid var(--bg-u5); outline: none; + border-radius: 5px; border-radius: var(--radius); box-shadow: 0 0 .3rem var(--bg-d3); z-index: 60; @@ -5198,6 +5200,7 @@ html.e #actionsArea { #rcm > .sep { margin: 0 .2rem; + border-bottom: 1px solid #46494d; border-bottom: 1px solid var(--bg-u5); } From 1368b3b355c7d72ea03636e2782661be6c9265d4 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Thu, 4 Jun 2026 21:17:39 +0200 Subject: [PATCH 549/598] fix issue connected to cross window dragdrop --- copyparty/web/up2k.js | 1 - 1 file changed, 1 deletion(-) diff --git a/copyparty/web/up2k.js b/copyparty/web/up2k.js index c364b9bb..5949456b 100644 --- a/copyparty/web/up2k.js +++ b/copyparty/web/up2k.js @@ -1194,7 +1194,6 @@ function up2k_init(subtle) { function gotfile(e) { ev(e); - console.log(e.dataTransfer.getData("text")) if (e.dataTransfer && e.dataTransfer.getData("text") && e.dataTransfer.getData("text").startsWith(window.location.origin)){ var currLink = e.dataTransfer.getData("text"); console.log("wrap.ondrop: " + currLink); From 2910fc8e5b0886b7ce4ff056ee316002aaf8932f Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 5 Jun 2026 01:00:41 +0200 Subject: [PATCH 550/598] dragdrop code cleanup --- copyparty/web/browser.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index 226620b4..7c3b2825 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -11086,8 +11086,7 @@ var drag = (function() { clmod(current, "sel", true); msel.selui(); } - - e.dataTransfer.setData("text", r.getFilesString()); + r.setDataForTransfer(e); } catch(ex){ console.log(e.target) @@ -11130,8 +11129,7 @@ var drag = (function() { clmod(current, "sel", true); msel.selui(); } - - e.dataTransfer.setData("text", r.getFilesString()); + r.setDataForTransfer(e); } catch(ex){ console.log(e.target) @@ -11146,10 +11144,10 @@ var drag = (function() { r.mktarget(f); } }; - r.getFilesString = function(){ + r.setDataForTransfer = function(e){ var sel = msel.getsel(), vps = []; - + for (var a = 0; a < sel.length; a++) { var link = sel[a].vp; if(!link.startsWith(window.location.origin)) @@ -11157,8 +11155,11 @@ var drag = (function() { vps.push(link); } - return vps.join("\n"); - }; + var payload = vps.join('\n') + e.dataTransfer.setData("text", payload); + e.dataTransfer.setData("text/plain", payload); + e.dataTransfer.setData("text/uri-list", payload); + } return r; })(); From 018268df43e05a95c2fe6af0d1a00cdc21812cd8 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 5 Jun 2026 01:42:31 +0200 Subject: [PATCH 551/598] reorder css rule to fix hover color --- copyparty/web/browser.css | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 2a72f114..903fd29f 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -966,6 +966,9 @@ tr.play td:nth-child(1) a { border-top: 1px solid var(--g-b2); box-shadow: 0 .1em .3em var(--g-sh); } +#ggrid>a:hover { + background: #303337; +} #ggrid>a:focus-visible, #ggrid>a:hover { color: var(--g-f-fg); @@ -973,9 +976,6 @@ tr.play td:nth-child(1) a { border-color: var(--g-f-b1); box-shadow: 0 .1em .3em var(--g-sh); } -#ggrid>a:hover { - background: #303337; -} #ggrid>a:focus-visible .gselchk{ display: block; } From 998a9b86a373c377db269bac94aa8d27406c78da Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 5 Jun 2026 01:57:44 +0200 Subject: [PATCH 552/598] prevent location being just "#" --- copyparty/web/util.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/copyparty/web/util.js b/copyparty/web/util.js index 8646d9bb..2bd9f8d0 100644 --- a/copyparty/web/util.js +++ b/copyparty/web/util.js @@ -1404,7 +1404,7 @@ function hist_replace(url) { function sethash(hv) { if (window.history && history.replaceState) { - hist_replace(location.pathname + location.search + '#' + hv); + hist_replace(location.pathname + location.search + (hv ? '#' : '') + hv); } else { location.hash = hv; From 23683ff9eb2faf4a269fe69fc451d81aaf954c33 Mon Sep 17 00:00:00 2001 From: Til Date: Fri, 5 Jun 2026 10:04:22 +0200 Subject: [PATCH 553/598] minor css fix for html.f --- copyparty/web/browser.css | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 903fd29f..5daefe0e 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -1446,7 +1446,7 @@ html:not(.e):not(.d) #up_quick .btn.on { } #wfm .x { font-size: 1.5em; - line-height: .65em; + line-height: .68em !important; } #wtoggle, #wtoggle * { @@ -3706,6 +3706,7 @@ summary { } .x { font-size: 1.5em; + font-family: initial; } @@ -3990,7 +3991,7 @@ html.d #treepar { right: .6em; z-index: 11; max-width: 80%; - overflow-x: auto; + /*overflow-x: auto;*/ } #pathBar.thin .popup { position: relative; From 929b4d1ee454f50356d3cbbb57a98f8344b4fe95 Mon Sep 17 00:00:00 2001 From: Til Date: Fri, 5 Jun 2026 10:23:11 +0200 Subject: [PATCH 554/598] addition to last commit --- copyparty/web/browser.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 5daefe0e..1f354410 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -4098,7 +4098,7 @@ html.e #wrap.thin .ghead { right: 1em; z-index: 11; max-width: 80%; - overflow-x: auto; + /*overflow-x: auto;*/ } .popup, #pathBar.thin .popup { From 44e0b9ea7d3d4dd6fc46579ebc701d44a9a2aa43 Mon Sep 17 00:00:00 2001 From: Til Date: Fri, 5 Jun 2026 10:53:35 +0200 Subject: [PATCH 555/598] css color fix regarding legacy theming --- copyparty/web/browser.css | 1 - copyparty/web/ui.css | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 1f354410..59f966d6 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -1,6 +1,5 @@ :root { color-scheme: dark; - color: #b9bdc1; --transparent: transparent; --font-mono: monospace; diff --git a/copyparty/web/ui.css b/copyparty/web/ui.css index 685e1bb6..bddf1d87 100644 --- a/copyparty/web/ui.css +++ b/copyparty/web/ui.css @@ -34,6 +34,7 @@ --bgg: var(--bg); background: var(--bg); + color: #b9bdc1; color: var(--fg); } html.y { From 37bd89ebce4f944ef6431354ed03805a63b44aa6 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 5 Jun 2026 17:51:26 +0200 Subject: [PATCH 556/598] dynamic colors for hotdog theme --- copyparty/web/browser.css | 56 ++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 59f966d6..6a5b3f18 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -215,45 +215,48 @@ html.cz { --u2-tab-1-bg: a; } html.cy { + --a: #ff0; + --b: #f00; + --b: hsl(from var(--a) calc(h - 60) s l); + --fg: #fff; --fg-weak: #fff; - --bg: #ff0; - --bg-u2: #f00; - --bg-u3: #f00; + --bg: var(--a); + --bg-u2: var(--b); + --bg-u3: var(--b); --bg-u5: #999; --bg-d3: #f77; - --bg-d2: #ff0; + --bg-d2: var(--a); --sel-bg: #f77; - --a: #fff; --a-hil: #fff; --a-h-bg: #000; - --tab-alt: #f00; + --tab-alt: var(--b); --row-alt: #fff; --btn-bg: #000; - --btn-fg: #ff0; + --btn-fg: var(--a); --btn-h-fg: #fff; - --btn-1-bg: #ff0; + --btn-1-bg: var(--a); --btn-1-fg: #000; - --btn-bs: 0 .25em 0 #f00; + --btn-bs: 0 .25em 0 var(--b); --chk-fg: #fd0; --txt-bg: #000; - --srv-1: #f00; + --srv-1: var(--b); --srv-3: #fff; --op-aa-bg: #fff; - --u2-b1-bg: #f00; - --u2-b2-bg: #f00; + --u2-b1-bg: var(--b); + --u2-b2-bg: var(--b); --g-sel-fg: #fff; --g-sel-bg: #aaa; --g-fsel-bg: #aaa; - --scrl-hint: #f00; + --scrl-hint: var(--b); } html.dz { --fg: #4d4; @@ -3766,7 +3769,7 @@ html.b #ops, html.b #path, html.b #wtoggle, html.b #up_quick_more, -html.b #up_quick_btn:not(:hover):not(.on) +html.b #up_quick_btn:not(:hover):not(.on), html.cz .ghead, html.cz #wfp .btn:not(:hover), @@ -3914,45 +3917,41 @@ html.ay #u2cards a.act { html.cy .pfp { - color: #f00; + color: var(--b); } html.cy #path a:hover { - color: #f00; + color: var(--b); } html.cy .mdo a { - background: #f00; + background: var(--b); } -html.cy #wrap, html.cy #acc_info a, html.cy #files, html.cy #files a, html.cy #files tbody div a:last-child { - color: #f00; + color: var(--b); } html.cy #u2tab a, html.cy #u2cards a { - color: #f00; + color: var(--b); } html.cy #unpost a { - color: #ff0; + color: var(--a); } html.cy #barbuf { filter: hue-rotate(267deg) brightness(0.8) contrast(4); } -html.cy #pvol { - filter: hue-rotate(4deg) contrast(2.2); -} html.cy #path i { background: transparent; } html.cy #up_quick_btn.on:not(:hover) { - background: #f00; + background: var(--b); } html.cy .ghead span { - color: #f00; + color: var(--b); } html.cy #s_list h3 { - background: #ff0; + background: var(--a); color: #000; } @@ -4123,6 +4122,9 @@ html.e #wrap.thin .ghead { #ghead { margin: 0 .5em 1em .5em; } + .modalheader { + padding: .8em 3em .8em .7em; + } .modalsplit { display: block; overflow-y: auto; From 1cdd5ea272efb0f178f0ac00232b836357367d03 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 5 Jun 2026 17:51:34 +0200 Subject: [PATCH 557/598] small IE color adjustment --- copyparty/web/browser.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index 5552ff0d..b6de40be 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -2974,8 +2974,8 @@ var vbar = (function () { style2 = light ? 'color-mix(in oklab, ' + bg + ' 85%, #000 15%' : 'color-mix(in oklab, ' + bg + ' 85%, #fff 15%'; } if(IE){ - style1 = 'rgb(85, 144, 255)'; - style2 = 'rgb(174, 193, 214)' + style1 = 'rgb(60, 126, 248)'; + style2 = 'rgb(75, 78, 82)' } ctx.fillStyle = style2; ctx.fillRect(0, 0, w, h); ctx.fillStyle = style1; ctx.fillRect(0, 0, w * mp.vol, h); From b339056d1aba72ac056ca28265f14f4f30ada962 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 5 Jun 2026 18:03:01 +0200 Subject: [PATCH 558/598] hacker theme accent color support --- copyparty/web/browser.css | 56 ++++++--------------------------------- 1 file changed, 8 insertions(+), 48 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 6a5b3f18..ba1c7b31 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -259,53 +259,11 @@ html.cy { --scrl-hint: var(--b); } html.dz { - --fg: #4d4; - --fg-weak: #2a2; + --a: #32fe32; + --fg-max: rgb(14, 233, 14); + --fg-max: var(--a); - --bg-u5: #050; - --bg-u3: #020; - --bg-u2: #020; - --bg-u1: #020; - --bg: #010; - --bg-d1: #000; - --bg-d2: #020; - --bg-d3: #000; - - --tab-alt: #6f6; - --row-alt: #030; - - --a: #9f9; - --a-hil: #cfc; - --a-dark: #afa; - --a-gray: #2a2; - - --btn-bg: rgba(64,128,64,0.15); - --btn-h-bg: #050; - --btn-1-fg: #000; - --btn-1-bg: #4f4; - --btn-1h-bg: #3f3; - --btn-bs: 0 0 0 .1em #080 inset; - --btn-1-bs: a; - - --u2-btn-b1: var(--fg-weak); - --u2-sbtn-b1: var(--fg-weak); - --u2-tab-b1: var(--fg-weak); - --u2-tab-1-fg: #fff; - --u2-tab-1-bg: linear-gradient(to bottom, #151, var(--bg) 80%); - --u2-b1-bg: #3a3; - --u2-b2-bg: #3a3; - - --sort-1: #fff; - --sort-2: #3f3; - - --srv-1: #3e3; - --srv-2: #1a1; - --srv-3: #0f0; - --srv-3b: #070; - - --tree-bg: #010; - - --f-h-b1: #3b3; + --radius: 0; text-shadow: none; font-family: 'scp', monospace, monospace; @@ -3959,8 +3917,10 @@ html.cy #s_list h3 { -html.dz * { - border-radius: 0 !important; +html.dz #s_nav .btn, +html.dz .btn { + border-width: .1em; + border-color: var(--bg-u5); } html.d #treepar { border-bottom: .2em solid var(--f-h-b1); From ab40892a4f9b38a819ce79a5d2a81b7a5c328cb1 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 5 Jun 2026 19:06:20 +0200 Subject: [PATCH 559/598] theming adjustments --- copyparty/web/browser.css | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index ba1c7b31..12f37efc 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -187,7 +187,6 @@ html.c { --btn-fg: #fff; --btn-bg-a: #9019bf; - --btn-h-bg: #a039ff; --chk-fg: #d90; --op-aa-bg: #f9dd22; @@ -205,6 +204,7 @@ html.cz { --btn-bs: 0 .1em .6em rgba(255,0,185,0.5); --btn-1-bb: .2em solid #e90; --btn-1-bs: 0 .1em .8em rgba(255,205,0,0.9); + --btn-h-bg: #a039ff; --sz-b: #ddd; --sz-k: #c9f; @@ -230,7 +230,7 @@ html.cy { --sel-bg: #f77; - --a-hil: #fff; + --a-hil: var(--b); --a-h-bg: #000; --tab-alt: var(--b); @@ -238,9 +238,9 @@ html.cy { --btn-bg: #000; --btn-fg: var(--a); - --btn-h-fg: #fff; --btn-1-bg: var(--a); --btn-1-fg: #000; + --btn-h-bg: var(--a); --btn-bs: 0 .25em 0 var(--b); --chk-fg: #fd0; @@ -1554,6 +1554,7 @@ html:not(.e):not(.d) #up_quick .btn.on { } #barbuf { background: var(--mp-b-bg); + filter: contrast(1) saturate(1.1) brightness(1.1); } #barpos { box-shadow: -.03em -.03em .7em rgba(0,0,0,0.5) inset; @@ -3896,9 +3897,6 @@ html.cy #u2cards a { html.cy #unpost a { color: var(--a); } -html.cy #barbuf { - filter: hue-rotate(267deg) brightness(0.8) contrast(4); -} html.cy #path i { background: transparent; } From 227ef00a59889dc4f14baf432382539994516116 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 5 Jun 2026 19:16:38 +0200 Subject: [PATCH 560/598] more theme fixes --- copyparty/web/browser.css | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 12f37efc..16e9b34f 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -225,7 +225,6 @@ html.cy { --bg-u2: var(--b); --bg-u3: var(--b); --bg-u5: #999; - --bg-d3: #f77; --bg-d2: var(--a); --sel-bg: #f77; @@ -3523,7 +3522,7 @@ details .setting { border-left: none; border-right: none; } -.c input[type=checkbox] { +.c>input[type=checkbox] { position: absolute; opacity: 0; } From 3794c1e8359298eb9d7c342ccf294a34fa25aabf Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Sat, 6 Jun 2026 10:05:17 +0200 Subject: [PATCH 561/598] prevent auto deselection on items that were selected via long press --- copyparty/web/browser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index b6de40be..aa6c6245 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -10907,7 +10907,7 @@ var rcm = (function () { } var fa = file && file.children[1].querySelector('a[id]'); if (fa && fa.id != 'unsearch') { - selFile.no_dsel = clgot(file, "sel"); + selFile.no_dsel = TOUCH || clgot(file, "sel"); clmod(file, "sel", true); selFile.elem = file; selFile.url = fa.href; From b3b8c3541699edd8a4b4d50c9e4e23c4aad0ea3c Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Mon, 8 Jun 2026 11:14:29 +0200 Subject: [PATCH 562/598] hide disabled contextual buttons completely --- copyparty/web/browser.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index aa6c6245..f5282b79 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -4628,10 +4628,10 @@ var fileman = (function () { encut = nsel, encpy = nsel, enpst = r.clip && r.clip.length, - hren = !(have_mv && has(perms, 'write') && has(perms, 'move')), - hdel = !(have_del && has(perms, 'delete')), - hcut = !(have_mv && has(perms, 'move')), - hpst = !(have_mv && has(perms, 'write')), + hren = !(have_mv && has(perms, 'write') && has(perms, 'move')) || !nsel, + hdel = !(have_del && has(perms, 'delete')) || !nsel, + hcut = !(have_mv && has(perms, 'move')) || !nsel, + hpst = !(have_mv && has(perms, 'write')) || !enpst, hshr = !can_shr || !get_evpath().indexOf(have_shr), enclr = enpst || nsel; @@ -4649,7 +4649,8 @@ var fileman = (function () { clmod(bren, 'hide', hren); clmod(bdel, 'hide', hdel); clmod(bcut, 'hide', hcut); - clmod(bpst, 'hide', hpst); + clmod(bcpy, 'hide', !encpy); + clmod(bpst, 'hide', !enpst); clmod(bshr, 'hide', hshr); clmod(bclr, 'hide', !enclr); From c15a9ac67a4f327572e41eeece8d797597d4e4bb Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Mon, 8 Jun 2026 12:28:28 +0200 Subject: [PATCH 563/598] deselect all on mobile cut or copy to improve navigation --- copyparty/web/browser.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index f5282b79..8e3d7f52 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -5367,6 +5367,9 @@ var fileman = (function () { catch (ex) { toast.warn(30, L.fc_warn.format(sel.length)); } + + if(thegrid.tempsel) + msel.evsel(); }; r.cpy = function (e) { @@ -5427,6 +5430,9 @@ var fileman = (function () { catch (ex) { toast.warn(30, L.fcc_warn.format(sel.length)); } + + if(thegrid.tempsel) + msel.evsel(); }; document.onpaste = function (e) { From 36aaeaacbc1dd43d98dded384bac6075e5f3f8f5 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Mon, 8 Jun 2026 12:33:47 +0200 Subject: [PATCH 564/598] disable special behavior of grid clicks when selection active --- copyparty/web/browser.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index 8e3d7f52..b354c386 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -6456,7 +6456,7 @@ window.thegrid = (function () { return r.loadsel(); clmod(this, 'sel', clgot(tr, 'sel')); } - else if (in_tree && !have_sel) + else if (in_tree) in_tree.click(); else if (oth.hasAttribute('download')) @@ -6465,14 +6465,14 @@ window.thegrid = (function () { else if (aplay && (r.vau || !is_img)) aplay.click(); - else if (is_dir && !have_sel) + else if (is_dir) treectl.reqls(qhref, true); else if (is_txt && !has(['md', 'htm', 'html'], is_txt)) atext.click(); - else if (!is_img && have_sel) - window.open(qhref, '_blank'); + // else if (!is_img && have_sel) + // window.open(qhref, '_blank'); else { if (!dbl){ From 7fb00fb9644a4a87bbd5b5f6914dbf023595fa8a Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Mon, 8 Jun 2026 12:38:29 +0200 Subject: [PATCH 565/598] esc to deselect / clear clipboard --- copyparty/web/browser.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index b354c386..e6126dc3 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -7131,6 +7131,9 @@ var ahotkeys = function (e) { if (QS('#music.vis')) return ebi('cl_mu').click(); + if (!clgot(ebi('fclr'), 'hide')) + return fileman.clear(); + if (QS('.opview.act')) return QS('#ops>a').click(); From 315e7dcc1003e5eea875e33b174892df9248ea88 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Mon, 8 Jun 2026 21:19:58 +0200 Subject: [PATCH 566/598] replaced "fancy light" -> "frutiger" theme --- copyparty/web/browser.css | 139 ++++++++++++++++++++++++++++++++++++-- copyparty/web/browser.js | 2 +- 2 files changed, 133 insertions(+), 8 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 16e9b34f..3dfee30c 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -137,7 +137,118 @@ html.bz { --btn-1-bs: .05em .1em .2em var(--a-dark) inset; } html.by { - --btn-bg: linear-gradient(-5deg, color-mix(in oklab, var(--btn-bg-a)80%, var(--a)), color-mix(in oklab, var(--btn-bg-a) 50%, transparent)); + --radius: 15px; + --a-dark: hsl(from color-mix(in oklab, var(--a) 80%, var(--fg-max) 20%) h calc(s * 1.5) l); + --g-fsel-ts: transparent; + --scrl-hint: transparent; + --glow-intensity: 0.7; + --bottom-glow: radial-gradient( + farthest-corner at bottom center, + color-mix(in srgb, var(--a-hil) 10%, rgba(255, 255, 255, var(--glow-intensity))), + transparent + ); + --btn-bg: linear-gradient( + -5deg, + color-mix(in oklab, var(--btn-bg-a) 30%, var(--a) 20%), + color-mix(in oklab, var(--btn-bg-a) 30%, transparent)); +} +html.by #wtico, +html.by #wtoggle, +html.by #ggrid>a, +html.by #ops a, +html.by #tree ul a.hl, +html.by .btn { + /* OKLCH Color System for accurate colors */ + --hue: 140; + --sat: 0.2; + transition: all .15s; + backdrop-filter: blur(10px); + + /* Color Variables */ + --fg: oklch(15% calc(var(--sat) * 0.5) var(--hue)); + --bg: oklch(75% var(--sat) var(--hue) / 0.8); + --bg-dark: oklch(45% var(--sat) var(--hue) / 0.75); + + background: var(--bottom-glow), var(--btn-bg); + border-radius: var(--radius); + + box-shadow: 0 4px 4px rgba(0, 0, 0, 0.4) !important; +} +html.by #wtico { + border-radius: var(--radius) 0 0 0; +} +html.by #ggrid>a:hover, +html.by #ops a:hover, +html.by .btn:hover { + background: var(--bottom-glow), + linear-gradient( + to bottom, + color-mix(in oklab, transparent, var(--a-dark)), + color-mix(in oklab, transparent, var(--a))); +} +html.by #ggrid>a:active, +html.by .btn:active { + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4) !important; + transform: translateY(2px); +} +html.by, +html.by #ops a.act, +html.by #ggrid>a.sel, +html.by #tree ul a.hl:hover, +html.by #tree ul a.hl, +html.by .tgl.btn.on { + background-color: var(--a); + background: + var(--bottom-glow), + linear-gradient(to bottom, var(--a-dark), var(--a)); + +} +html.by #wtoggle a { + position: relative; +} +html.by #spaceUsed_bar::after, +html.by #wtoggle a:after, +html.by a:not(.play) .imgcontainer::before, +html.by #ops a:after, +html.by #path:after, +html.by #tree ul a.hl:after, +html.by .btn::after { + content: "" !important; + position: absolute; + z-index: 2; + top: 4%; + left: 5px; + width: calc(100% - 10px); + height: 40%; + background: linear-gradient( + -165deg, + rgba(255, 255, 255, 0.7), + rgba(255, 255, 255, 0.1) + ); + border-radius: var(--radius) var(--radius) calc(var(--radius) / 2) calc(var(--radius) / 2); + transition: background 400ms ease; + pointer-events: none; +} +html.by #ops a { + backdrop-filter: blur(10px); + margin-left: 2px; + margin-right: 2px; +} +html.by #srchfolder_div { + left: 3em; +} +html.by #spaceUsed_bar, html.by #spaceTotal_bar { + height: 1.6em; + border: var(--a) solid 1px; +} +html.by #spaceMax { + display: none; +} +html.by #spaceFree { + position: absolute; + z-index: 1; + bottom: 2em; + justify-self: center; } html.a { @@ -2247,6 +2358,7 @@ html.b .btn { color: var(--fg-max); } #tree ul a { + position: relative; border-radius: 5px; border-radius: var(--radius); display: inline-block; @@ -3721,11 +3833,10 @@ html.b .ghead { } html.b .ghead, -html.b #wfp .btn:not(:hover), html.b #treeToggleBtn:not(:hover):not(.on), html.b #ops, html.b #path, -html.b #wtoggle, +html.bz #wtoggle, html.b #up_quick_more, html.b #up_quick_btn:not(:hover):not(.on), @@ -3741,6 +3852,10 @@ html.cz #up_quick_btn:not(:hover):not(.on) { background: var(--btn-bg); } +html.bz #wfp .btn:not(:hover){ + backdrop-filter: blur(10px); +} + html.c .modal .setting:hover { background: color-mix(in oklab, var(--bg-u5) 30%, transparent); } @@ -3761,7 +3876,15 @@ html.c #u2foot:empty, html.b #u2foot:empty { margin-bottom: -1em; } -html.by #ops, +html.by #ops{ + background: none; + backdrop-filter: none; + border: none; + box-shadow: none; + margin: 0 -2px; + padding-left: 0; + padding-right: 0; +} html.by .opbox, html.by #path, html.by #doc, @@ -3769,7 +3892,8 @@ html.by #srch_form, html.by .ghead, html.by #u2etas { border-color: var(--bg-u2); - box-shadow: 0 0 .3em var(--bg-u5); + box-shadow: 0 4px 4px rgba(0, 0, 0, 0.4); + background: var(--bottom-glow), var(--btn-bg); } html.by #tree li, html.by #treepar { @@ -3777,13 +3901,14 @@ html.by #treepar { } html.by #treesuperh, html.by #treepar { - background: var(--bg); + backdrop-filter: blur(10px); + background: color-mix(in srgb, var(--bg) 40%, transparent); border-color: #ddd; } html.by #tree { border-color: #ddd; box-shadow: 0 0 1em #ddd; - background: var(--bg); + background: color-mix(in srgb, var(--bg) 40%, transparent); } diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index aa6c6245..6d1556eb 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -9615,7 +9615,7 @@ var settheme = (function () { var html = [], cb = ebi('themes'), itheme = ax.indexOf(theme[0]) * 2 + (light ? 1 : 0), - names = ['flat dark', 'flat light', 'fancy dark', 'fancy light', 'vice', 'hotdog stand', 'hacker', 'hi-con', 'phi95 dark', 'phi95', 'poison', 'wing', ]; + names = ['flat dark', 'flat light', 'fancy dark', 'frutiger', 'vice', 'hotdog stand', 'hacker', 'hi-con', 'phi95 dark', 'phi95', 'poison', 'wing', ]; for (var a = 0; a < themes; a++) html.push(''.format(a, names[a] || 'custom')); From e443bb8fe441712f97aef5192c121ed1dad16e82 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Mon, 8 Jun 2026 21:45:11 +0200 Subject: [PATCH 567/598] small addition to frutiger theme --- copyparty/web/browser.css | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 3dfee30c..64dd4e80 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -141,6 +141,7 @@ html.by { --a-dark: hsl(from color-mix(in oklab, var(--a) 80%, var(--fg-max) 20%) h calc(s * 1.5) l); --g-fsel-ts: transparent; --scrl-hint: transparent; + --bg-u1: color-mix(in oklab, transparent 92%, var(--fg-max)); --glow-intensity: 0.7; --bottom-glow: radial-gradient( farthest-corner at bottom center, @@ -152,6 +153,7 @@ html.by { color-mix(in oklab, var(--btn-bg-a) 30%, var(--a) 20%), color-mix(in oklab, var(--btn-bg-a) 30%, transparent)); } +html.by #s_list h3, html.by #wtico, html.by #wtoggle, html.by #ggrid>a, @@ -174,6 +176,9 @@ html.by .btn { box-shadow: 0 4px 4px rgba(0, 0, 0, 0.4) !important; } +html.by #s_list h3{ + border-radius: var(--radius) var(--radius) 0 0; +} html.by #wtico { border-radius: var(--radius) 0 0 0; } @@ -206,6 +211,7 @@ html.by .tgl.btn.on { html.by #wtoggle a { position: relative; } +html.by #s_list h3::after, html.by #spaceUsed_bar::after, html.by #wtoggle a:after, html.by a:not(.play) .imgcontainer::before, @@ -237,7 +243,10 @@ html.by #ops a { html.by #srchfolder_div { left: 3em; } -html.by #spaceUsed_bar, html.by #spaceTotal_bar { +html.by #spaceUsed_bar{ + height: 1.6em; +} +html.by #spaceTotal_bar { height: 1.6em; border: var(--a) solid 1px; } @@ -248,7 +257,9 @@ html.by #spaceFree { position: absolute; z-index: 1; bottom: 2em; - justify-self: center; + max-width: stretch; + width: calc(100% - 3em); + text-align: center; } html.a { @@ -3897,7 +3908,7 @@ html.by #u2etas { } html.by #tree li, html.by #treepar { - border-color: var(--bg) var(--bg-max) #ddd var(--bg-max); + border-color: var(--bg-u5) var(--bg-max) transparent var(--bg-max); } html.by #treesuperh, html.by #treepar { From fa92f60aad9e836663283b00861beb7355582676 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Mon, 8 Jun 2026 22:07:09 +0200 Subject: [PATCH 568/598] small addition to frutiger theme --- copyparty/web/browser.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 64dd4e80..d2f48060 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -256,8 +256,8 @@ html.by #spaceMax { html.by #spaceFree { position: absolute; z-index: 1; - bottom: 2em; - max-width: stretch; + bottom: 2.1em; + max-width: initial; width: calc(100% - 3em); text-align: center; } From f4704a4e53f4127e4ef2edcf5164ceb968b99c2d Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Mon, 8 Jun 2026 22:38:32 +0200 Subject: [PATCH 569/598] small addition to frutiger theme --- copyparty/web/browser.css | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index d2f48060..f6e98cda 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -137,11 +137,17 @@ html.bz { --btn-1-bs: .05em .1em .2em var(--a-dark) inset; } html.by { + --a: #139cf1; --radius: 15px; --a-dark: hsl(from color-mix(in oklab, var(--a) 80%, var(--fg-max) 20%) h calc(s * 1.5) l); --g-fsel-ts: transparent; --scrl-hint: transparent; --bg-u1: color-mix(in oklab, transparent 92%, var(--fg-max)); + --w2: color-mix(in srgb, var(--a) 40%, var(--bg)); + --row-alt: color-mix(in srgb, var(--a) 30%, var(--bg)); + --g-sel-bg: var(--a); + + --glow-intensity: 0.7; --bottom-glow: radial-gradient( farthest-corner at bottom center, @@ -176,6 +182,9 @@ html.by .btn { box-shadow: 0 4px 4px rgba(0, 0, 0, 0.4) !important; } +html.by #files thead th { + background: none; +} html.by #s_list h3{ border-radius: var(--radius) var(--radius) 0 0; } @@ -196,6 +205,10 @@ html.by .btn:active { box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4) !important; transform: translateY(2px); } +html.by summary { + color: var(--fg); +} +html.by .modalcontent, html.by, html.by #ops a.act, html.by #ggrid>a.sel, @@ -211,6 +224,7 @@ html.by .tgl.btn.on { html.by #wtoggle a { position: relative; } +html.by #wtico::after, html.by #s_list h3::after, html.by #spaceUsed_bar::after, html.by #wtoggle a:after, @@ -249,6 +263,12 @@ html.by #spaceUsed_bar{ html.by #spaceTotal_bar { height: 1.6em; border: var(--a) solid 1px; + background: transparent; + backdrop-filter: blur(10px); +} +html.by #files tbody tr:hover td, +html.by #files tbody tr:hover td+td { + background: rgba(255, 255, 255, 0.6); } html.by #spaceMax { display: none; @@ -1545,8 +1565,8 @@ html:not(.e):not(.d) #up_quick .btn.on { } #wtoggle a { font-size: .5em; - padding: .7em .5em; - margin: -.3em .1em; + padding: .5em .5em; + margin: 0em .1em -.3em .1em; display: inline-block; } #wtoggle #zip1 { From 04eb6c064020373cf3fbd58c33cc4af6fed95e96 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Mon, 8 Jun 2026 22:45:43 +0200 Subject: [PATCH 570/598] small addition to frutiger theme --- copyparty/web/browser.css | 2 ++ 1 file changed, 2 insertions(+) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index f6e98cda..bad49b3a 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -158,6 +158,8 @@ html.by { -5deg, color-mix(in oklab, var(--btn-bg-a) 30%, var(--a) 20%), color-mix(in oklab, var(--btn-bg-a) 30%, transparent)); + + text-shadow: 0px 0px 4px rgb(255, 255, 255); } html.by #s_list h3, html.by #wtico, From df39302cbc21614388afd5f399d72f45066044e0 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Tue, 9 Jun 2026 07:57:20 +0200 Subject: [PATCH 571/598] reduce amount of blurs in frutiger theme --- copyparty/web/browser.css | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index bad49b3a..038da8d7 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -172,7 +172,6 @@ html.by .btn { --hue: 140; --sat: 0.2; transition: all .15s; - backdrop-filter: blur(10px); /* Color Variables */ --fg: oklch(15% calc(var(--sat) * 0.5) var(--hue)); @@ -189,9 +188,11 @@ html.by #files thead th { } html.by #s_list h3{ border-radius: var(--radius) var(--radius) 0 0; + position: relative; } html.by #wtico { border-radius: var(--radius) 0 0 0; + position: relative; } html.by #ggrid>a:hover, html.by #ops a:hover, @@ -283,6 +284,9 @@ html.by #spaceFree { width: calc(100% - 3em); text-align: center; } +html.by .under { + top: auto; +} html.a { --btn-bs: 0 .05em 0 var(--bg-d3) inset; @@ -3941,7 +3945,7 @@ html.by #treepar { html.by #tree { border-color: #ddd; box-shadow: 0 0 1em #ddd; - background: color-mix(in srgb, var(--bg) 40%, transparent); + background: #88c8f3; } From 5f9a5b0a5d7dd1bf92d2492044514184d5a1244d Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Tue, 9 Jun 2026 09:11:26 +0200 Subject: [PATCH 572/598] addition to last commit --- copyparty/web/browser.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 038da8d7..0fec0a03 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -3945,7 +3945,7 @@ html.by #treepar { html.by #tree { border-color: #ddd; box-shadow: 0 0 1em #ddd; - background: #88c8f3; + background: color-mix(in srgb, var(--bg) 10%, var(--a)); } From 4a45d53b3552f2724d122d235b23d196d60afa2d Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Tue, 9 Jun 2026 09:23:09 +0200 Subject: [PATCH 573/598] fix for overflow reveal on frutiger --- copyparty/web/browser.js | 1 + 1 file changed, 1 insertion(+) diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index 3ce0b7f8..6a8d5d40 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -8414,6 +8414,7 @@ var treectl = (function () { } function mleave(e) { + this.style.top = ''; this.style.position = ''; this.style.minWidth = ''; this.style.width = ''; From d0bc23c38d3d87020d2860e18b23247776165c17 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Tue, 9 Jun 2026 19:28:36 +0200 Subject: [PATCH 574/598] frutiger theme refinements --- copyparty/web/browser.css | 61 ++++++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 23 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 0fec0a03..a53ac01c 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -138,8 +138,10 @@ html.bz { } html.by { --a: #139cf1; + --b: color-mix(in srgb, var(--bg) 20%, var(--a)); --radius: 15px; --a-dark: hsl(from color-mix(in oklab, var(--a) 80%, var(--fg-max) 20%) h calc(s * 1.5) l); + --bg-u3: color-mix(in oklab, var(--bg-max) 70%, var(--b) 30%); --g-fsel-ts: transparent; --scrl-hint: transparent; --bg-u1: color-mix(in oklab, transparent 92%, var(--fg-max)); @@ -157,10 +159,11 @@ html.by { --btn-bg: linear-gradient( -5deg, color-mix(in oklab, var(--btn-bg-a) 30%, var(--a) 20%), - color-mix(in oklab, var(--btn-bg-a) 30%, transparent)); + color-mix(in oklab, var(--btn-bg-a) 30%, var(--b))); text-shadow: 0px 0px 4px rgb(255, 255, 255); } +html.by #spaceTotal_bar, html.by #s_list h3, html.by #wtico, html.by #wtoggle, @@ -168,19 +171,9 @@ html.by #ggrid>a, html.by #ops a, html.by #tree ul a.hl, html.by .btn { - /* OKLCH Color System for accurate colors */ - --hue: 140; - --sat: 0.2; transition: all .15s; - - /* Color Variables */ - --fg: oklch(15% calc(var(--sat) * 0.5) var(--hue)); - --bg: oklch(75% var(--sat) var(--hue) / 0.8); - --bg-dark: oklch(45% var(--sat) var(--hue) / 0.75); - background: var(--bottom-glow), var(--btn-bg); border-radius: var(--radius); - box-shadow: 0 4px 4px rgba(0, 0, 0, 0.4) !important; } html.by #files thead th { @@ -208,6 +201,15 @@ html.by .btn:active { box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4) !important; transform: translateY(2px); } +html.by #widgeti { + background: color-mix(in srgb, var(--bg) 40%, var(--a)); +} +html.by #mu_outer { + background: color-mix(in oklab, var(--b) 50%, transparent); +} +html.by .divider { + display: none; +} html.by summary { color: var(--fg); } @@ -238,7 +240,6 @@ html.by #tree ul a.hl:after, html.by .btn::after { content: "" !important; position: absolute; - z-index: 2; top: 4%; left: 5px; width: calc(100% - 10px); @@ -252,22 +253,20 @@ html.by .btn::after { transition: background 400ms ease; pointer-events: none; } +html.by a:not(.play) .imgcontainer::before{ + z-index: 2; +} html.by #ops a { - backdrop-filter: blur(10px); + position: relative; margin-left: 2px; margin-right: 2px; } html.by #srchfolder_div { left: 3em; } +html.by #spaceTotal_bar, html.by #spaceUsed_bar{ height: 1.6em; -} -html.by #spaceTotal_bar { - height: 1.6em; - border: var(--a) solid 1px; - background: transparent; - backdrop-filter: blur(10px); } html.by #files tbody tr:hover td, html.by #files tbody tr:hover td+td { @@ -2623,6 +2622,12 @@ html.b .btn { #unpost td:nth-child(4) { text-align: right; } +#unpost table { + overflow-x: auto; + display: block; + margin: 0 -1em; + padding: 0 1em; +} #shui, #rui { background: #fff; @@ -3918,7 +3923,7 @@ html.by #ops{ backdrop-filter: none; border: none; box-shadow: none; - margin: 0 -2px; + margin: 0; padding-left: 0; padding-right: 0; } @@ -3928,10 +3933,14 @@ html.by #doc, html.by #srch_form, html.by .ghead, html.by #u2etas { - border-color: var(--bg-u2); + border-color: var(--bg-u3); box-shadow: 0 4px 4px rgba(0, 0, 0, 0.4); background: var(--bottom-glow), var(--btn-bg); } +html.by #spaceTotal_bar, +html.by #ops>a { + border: var(--bg-u3) solid 1px; +} html.by #tree li, html.by #treepar { border-color: var(--bg-u5) var(--bg-max) transparent var(--bg-max); @@ -3945,7 +3954,10 @@ html.by #treepar { html.by #tree { border-color: #ddd; box-shadow: 0 0 1em #ddd; - background: color-mix(in srgb, var(--bg) 10%, var(--a)); + background: var(--b); +} +html.by #tree_footer { + background: linear-gradient(to top, var(--b), color-mix(in oklab, var(--b) 80%, transparent), transparent); } @@ -5374,9 +5386,12 @@ html.e #actionsArea { background: rgb(85, 144, 255); background: var(--a); } -html.b #spaceUsed_bar { +html.bz #spaceUsed_bar { background: linear-gradient(to right, transparent, var(--a-dark), var(--a)); } +html.by #spaceUsed_bar { + background: linear-gradient(to right, var(--a), var(--a-dark)); +} #spaceTotal_bar { position: relative; margin-bottom: .5em; From 999652bde5c7e28fe2b1b70bcff404dfbd965bc9 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Tue, 9 Jun 2026 19:47:50 +0200 Subject: [PATCH 575/598] re-introduce logic to open unsupported formats in new tabs if selection is active --- copyparty/web/baguettebox.js | 4 ++-- copyparty/web/browser.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/copyparty/web/baguettebox.js b/copyparty/web/baguettebox.js index 1f276d13..81b3c6c9 100644 --- a/copyparty/web/baguettebox.js +++ b/copyparty/web/baguettebox.js @@ -37,8 +37,8 @@ window.baguetteBox = (function () { scrollCSS = ['', ''], scrollTimer = 0, re_i = APPLE ? - /^[^?]+\.(a?png|avif|bmp|gif|hei[cf]s?|jfif|jpe?g|jxl|svg|tiff?|webp)(\?|$)/i : - /^[^?]+\.(a?png|avif|bmp|gif|jfif|jpe?g|jxl|svg|tiff?|webp)(\?|$)/i, + /^[^?]+\.(a?png|avif|bmp|gif|hei[cf]s?|jfif|jpe?g|jxl|svg|ico|tiff?|webp)(\?|$)/i : + /^[^?]+\.(a?png|avif|bmp|gif|jfif|jpe?g|jxl|svg|ico|tiff?|webp)(\?|$)/i, re_v = /^[^?]+\.(webm|mkv|mp4|m4v|mov)(\?|$)/i, re_cbz = /^[^?]+\.(cbz)(\?|$)/i, anims = ['slideIn', 'fadeIn', 'none'], diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index 6a8d5d40..289c9de6 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -6471,8 +6471,8 @@ window.thegrid = (function () { else if (is_txt && !has(['md', 'htm', 'html'], is_txt)) atext.click(); - // else if (!is_img && have_sel) - // window.open(qhref, '_blank'); + else if (!is_img && !is_dir && have_sel) + window.open(qhref, '_blank'); else { if (!dbl){ From c01a60d9e59e42b5961c8d4684c8ddcf3fdeae24 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Tue, 9 Jun 2026 19:50:21 +0200 Subject: [PATCH 576/598] frutiger theme cleanup --- copyparty/web/browser.css | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index a53ac01c..ba517769 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -3874,13 +3874,13 @@ html.b .ghead { box-shadow: var(--btn-bs); } -html.b .ghead, -html.b #treeToggleBtn:not(:hover):not(.on), -html.b #ops, -html.b #path, +html.bz .ghead, +html.bz #treeToggleBtn:not(:hover):not(.on), +html.bz #ops, +html.bz #path, html.bz #wtoggle, -html.b #up_quick_more, -html.b #up_quick_btn:not(:hover):not(.on), +html.bz #up_quick_more, +html.bz #up_quick_btn:not(:hover):not(.on), html.cz .ghead, html.cz #wfp .btn:not(:hover), From a4e318568f80297089540b94c92f7059444a7600 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Tue, 9 Jun 2026 20:11:03 +0200 Subject: [PATCH 577/598] frutiger theme additions --- copyparty/web/browser.css | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index ba517769..0b70cd33 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -163,6 +163,7 @@ html.by { text-shadow: 0px 0px 4px rgb(255, 255, 255); } +html.by #up_quick_more a, html.by #spaceTotal_bar, html.by #s_list h3, html.by #wtico, @@ -187,6 +188,7 @@ html.by #wtico { border-radius: var(--radius) 0 0 0; position: relative; } +html.by #up_quick_more a:hover, html.by #ggrid>a:hover, html.by #ops a:hover, html.by .btn:hover { @@ -196,6 +198,7 @@ html.by .btn:hover { color-mix(in oklab, transparent, var(--a-dark)), color-mix(in oklab, transparent, var(--a))); } +html.by #up_quick_more a:active, html.by #ggrid>a:active, html.by .btn:active { box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4) !important; @@ -213,6 +216,9 @@ html.by .divider { html.by summary { color: var(--fg); } +html.by #pvolbg { + color: var(--bg); +} html.by .modalcontent, html.by, html.by #ops a.act, @@ -229,6 +235,15 @@ html.by .tgl.btn.on { html.by #wtoggle a { position: relative; } +html.by #up_quick_more a{ + position: relative; + margin: .5em 0; +} +html.by #up_quick_more{ + background: none; + border: none; +} +html.by #up_quick_more a::after, html.by #wtico::after, html.by #s_list h3::after, html.by #spaceUsed_bar::after, @@ -1575,8 +1590,8 @@ html:not(.e):not(.d) #up_quick .btn.on { display: inline-block; } #wtoggle #zip1 { - padding: .5em; - margin: -.1em .1em; + padding: .4em; + margin: 0 .2em; vertical-align: top; white-space: nowrap; } @@ -3937,6 +3952,7 @@ html.by #u2etas { box-shadow: 0 4px 4px rgba(0, 0, 0, 0.4); background: var(--bottom-glow), var(--btn-bg); } +html.by #up_quick_more a, html.by #spaceTotal_bar, html.by #ops>a { border: var(--bg-u3) solid 1px; From 6ba73b5085e8fbae975467604c2c7d629f008a36 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Tue, 9 Jun 2026 22:30:54 +0200 Subject: [PATCH 578/598] frutiger radius matching --- copyparty/web/browser.css | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 0b70cd33..171f058f 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -264,7 +264,8 @@ html.by .btn::after { rgba(255, 255, 255, 0.7), rgba(255, 255, 255, 0.1) ); - border-radius: var(--radius) var(--radius) calc(var(--radius) / 2) calc(var(--radius) / 2); + --r2: calc(var(--radius) - 3px); + border-radius: var(--r2) var(--r2) calc(var(--r2) / 2) calc(var(--r2) / 2); transition: background 400ms ease; pointer-events: none; } @@ -1113,7 +1114,7 @@ tr.play td:nth-child(1) a { color: #3584e4; z-index: 1; border-radius: 5px; - border-radius: var(--radius); + border-radius: calc(var(--radius) - 2px); max-width: 10em; max-width: calc(var(--grid-sz) - 4px); margin: 0 auto; From 7627bd36f50cc390e3492ea278f74474f8a7a114 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Tue, 9 Jun 2026 23:43:11 +0200 Subject: [PATCH 579/598] theme fixes --- copyparty/web/browser.css | 72 +++++++++++++++++++++++---------------- 1 file changed, 43 insertions(+), 29 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 171f058f..d53fed8f 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -163,6 +163,7 @@ html.by { text-shadow: 0px 0px 4px rgb(255, 255, 255); } +html.by #srchfolder_div, html.by #up_quick_more a, html.by #spaceTotal_bar, html.by #s_list h3, @@ -219,6 +220,7 @@ html.by summary { html.by #pvolbg { color: var(--bg); } +html.by #srchfolder_div, html.by .modalcontent, html.by, html.by #ops a.act, @@ -243,6 +245,7 @@ html.by #up_quick_more{ background: none; border: none; } +html.by #srchfolder_div::after, html.by #up_quick_more a::after, html.by #wtico::after, html.by #s_list h3::after, @@ -278,7 +281,7 @@ html.by #ops a { margin-right: 2px; } html.by #srchfolder_div { - left: 3em; + left: 3.2em; } html.by #spaceTotal_bar, html.by #spaceUsed_bar{ @@ -299,8 +302,10 @@ html.by #spaceFree { width: calc(100% - 3em); text-align: center; } -html.by .under { - top: auto; +html.by #ops a.act { + margin-top: -.15em; + margin-bottom: -.15em; + padding-top: .3em; } html.a { @@ -463,7 +468,7 @@ html.dy { --btn-1h-bg: #555; --chk-fg: a; --txt-sh: a; - --txt-bg: a; + --txt-bg: #fff; --op-a-sh: a; @@ -622,6 +627,7 @@ html .ayjump:focus-visible { margin-left: 2em; } #path { + position: relative; color: var(--fg); text-shadow: 1px 1px 0 var(--bg-max); font-weight: normal; @@ -640,21 +646,26 @@ html .ayjump:focus-visible { } #pathBar #folder_search { margin: 0; - height: calc(100% - .5em); - width: calc(100% - .6em); - right: 0; + display: block; + position: absolute; + right: .2em; + left: .2em; + top: .2em; + bottom: .2em; } #qs_btns { position: absolute; right: .2em; - top: .1em; + top: .2em; font-size: 1.3em; cursor: pointer; + display: flex; } #qs_btns a { background: color-mix(in oklab, var(--txt-bg), transparent); width: 1em; - height: 1.2em; + height: 1em; + line-height: 1em; display: inline-block; text-align: center; border-radius: 5px; @@ -665,7 +676,8 @@ html .ayjump:focus-visible { background: var(--bg); } #qs_btns a .x { - line-height: .75em; + line-height: .6em; + vertical-align: center; } #moresearch span { font-size: .6em; @@ -1677,6 +1689,7 @@ html:not(.e):not(.d) #up_quick .btn.on { margin-left: .3em; padding: 1.2em 0; min-height: 1em; + border-radius: var(--radius); } #progbar { display: none; @@ -1897,6 +1910,7 @@ html.b #mu_outer { border-radius: 5px; min-width: 1em; + border-radius: var(--radius); border: var(--transparent) solid 0px; color: #07c; color: var(--a); @@ -1928,8 +1942,8 @@ html.b #mu_outer { border-radius: 0 0 var(--radius) var(--radius); border-bottom: .3em solid var(--a); box-shadow: var(--op-aa-sh); - margin: -1px 0 -.35em 0; - padding-top: .2em; + margin: 0 0 -.35em 0; + padding-top: calc(.2em - 1px); } #ops a svg { width: 1.75em; @@ -3827,11 +3841,10 @@ summary { #srchfolder_div { display: none; position: absolute; - left: 3.8em; + left: 3.5em; top: 0; right: 0; bottom: 0; - padding: .2em; margin-left: .3em; } .x { @@ -4365,7 +4378,10 @@ html.e #wrap.thin .ghead { padding-right: .25em; } #srchfolder_div { - left: 3.2em; + left: 3em; + } + html.by #srchfolder_div { + left: 2.8em; } } @media (max-width: 37em) { @@ -4703,10 +4719,7 @@ html.e { text-shadow: none; --bg-u1: #0002; --g-sel-fg: #fff; -} -html.e * { --radius: 0; - border-radius: 0 !important; } html.e #ggrid > a.sel { box-shadow: none; @@ -4852,13 +4865,11 @@ html.e #acc_info span.warn, html.e #acc_info a { color: var(--white); } -html.e #flogout:before { - padding-left: 0.2em; - padding-right: 0.4em; - content: " | "; +html.e #accessType { + color: var(--fg); } html.e #blogout { - color: var(--w); + color: var(--fg); box-shadow: none; background: transparent; } @@ -4905,15 +4916,11 @@ html.e #ops { html.e #srchfolder_div { left: 2em; top: -.1em; - bottom: -.6em; + bottom: 0; } html.e #qs_btns { - right: 0.7em; top: .3em; } -html.e .under { - border: var(--fg) solid 1px; -} html.e #srch_form, html.e .opbox { padding-bottom: 1em; @@ -4948,7 +4955,7 @@ html.e #blogout:hover { html.e #ops a.act { border-bottom: 0; - margin-top: -.6em; + margin-top: -.4em; border-top-left-radius: 3px; border-top-right-radius: 3px; box-shadow: var(--shadow-inset-left), var(--shadow-inset-top), @@ -5047,6 +5054,7 @@ html.e #ghead { } html.e #ghead a { margin: 0; + border-radius: var(--radius); } html.e #treeToggleBtn { margin: 0; @@ -5194,6 +5202,8 @@ html.e #treepar { border-bottom: var(--border-dashed-black); margin-left: calc(2.1em - (1em - var(--negative-space))) !important; } +html.e .under, +html.e #up_quick_more, html.e #wtico, html.e #ghead, html.e #op_acc, @@ -5879,6 +5889,10 @@ html.fy .modalheader::after { } html.fy #ops { height: auto; + margin-right: .3em; +} +html.fy #srchfolder_div { + right: .5em; } html.fy #ops a { padding: .29em .4em; From 4fa092d22fb55a2091f3f96d9954d49270b15c6a Mon Sep 17 00:00:00 2001 From: Til Date: Wed, 10 Jun 2026 01:31:17 +0200 Subject: [PATCH 580/598] fix html.f tree visuals --- copyparty/web/browser.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index d53fed8f..e9a20ae4 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -5631,8 +5631,8 @@ html.f #tree .hl { } html.f #tree .hl::after { content: ""; - right: .5em; - left: 0; + right: -2.2em; + left: -1.2em; margin-top: -.3em; margin-bottom: -2px; z-index: -1; From e8f9bbe08d6c5e88380ac2129e1bf89cb4272c40 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Wed, 10 Jun 2026 09:42:41 +0200 Subject: [PATCH 581/598] use number input for corner radius setting --- copyparty/web/browser.css | 1 + copyparty/web/browser.js | 9 ++++----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index e9a20ae4..e49f059b 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -2040,6 +2040,7 @@ html.y #ops svg circle { } #pathBar input[type=text], .opview select, +.opview input[type=number], .opview input[type=text], .opview input[type=color], .opview input[type=date] { diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index 289c9de6..05078e50 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -1314,7 +1314,7 @@ ebi('op_cfg').innerHTML = ( ' ' + ' ' + '
      ' + -' ' + +' ' + ' 🥳\n' + '
      \n' + '
      \n' + @@ -1527,10 +1527,9 @@ ebi('radius').oninput = function () { if(r === radius) return; - if(isNaN(r)) - r = '' - swrite('radius', r); - var setV = this.value == '' ? '' : (r + 'px'); + var usefallback = isNaN(r) || r < 0 || r === ''; + var setV = usefallback ? '' : (r + 'px'); + swrite('radius', !usefallback && r); document.documentElement.style.setProperty('--radius', setV); console.log(setV); } From d11fb558f204b86956be91dfc7bd973d4d65b868 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Thu, 11 Jun 2026 23:53:44 +0200 Subject: [PATCH 582/598] misc css fixes --- copyparty/web/browser.css | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index e49f059b..42d7047e 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -287,8 +287,8 @@ html.by #spaceTotal_bar, html.by #spaceUsed_bar{ height: 1.6em; } -html.by #files tbody tr:hover td, -html.by #files tbody tr:hover td+td { +html.by #files tbody tr:not(.sel):hover td, +html.by #files tbody tr:not(.sel):hover td+td { background: rgba(255, 255, 255, 0.6); } html.by #spaceMax { @@ -675,6 +675,7 @@ html .ayjump:focus-visible { #qs_btns a:hover { background: var(--bg); } +#bbox-btns .x, #qs_btns a .x { line-height: .6em; vertical-align: center; @@ -2304,13 +2305,16 @@ html { width: 10px; opacity: 0; background: #888; + background: var(--a); + border: var(--bg) solid 1px; + border-width: 0 1px; cursor: ew-resize; touch-action: none; user-select: none; transition: opacity .1s; } #reszbar:hover{ - opacity: .3; + opacity: .6; } .resz, .resz * { @@ -3983,13 +3987,14 @@ html.by #treepar { border-color: #ddd; } html.by #tree { - border-color: #ddd; - box-shadow: 0 0 1em #ddd; background: var(--b); } html.by #tree_footer { background: linear-gradient(to top, var(--b), color-mix(in oklab, var(--b) 80%, transparent), transparent); } +html.by #pathBar { + background: linear-gradient(to bottom, var(--a), transparent); +} @@ -5568,6 +5573,7 @@ html.f #ggrid > a:hover::before { } html.f #ggrid > a.au::before { padding: .4em .2em .4em .3em; + margin: 0; } html.f #ggrid > a:focus-visible .imgcontainer::before, html.f #ggrid > a:hover .imgcontainer::before { From 2d487d1427d422680fd1d286c5722009afbb312f Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 12 Jun 2026 23:05:00 +0200 Subject: [PATCH 583/598] bind bbox to file list; pass click event copy from grid to list elements. this enables the bbox in both views --- contrib/plugins/graft-thumbs.js | 8 +- copyparty/web/baguettebox.js | 8 +- copyparty/web/browser.js | 239 +++++++++++++++++--------------- 3 files changed, 138 insertions(+), 117 deletions(-) diff --git a/contrib/plugins/graft-thumbs.js b/contrib/plugins/graft-thumbs.js index 20d5abd4..61ca8f21 100644 --- a/contrib/plugins/graft-thumbs.js +++ b/contrib/plugins/graft-thumbs.js @@ -82,15 +82,15 @@ }; // ...and then the trick! near the end of loadgrid, - // thegrid.bagit is called to initialize the baguettebox + // msel.bagit is called to initialize the baguettebox // (image/video gallery); this is the perfect function to // "hook" (hijack) so we can run our code :^) // need to grab a backup of the original function first, - var orig_func = thegrid.bagit; + var orig_func = msel.bagit; // and then replace it with our own: - thegrid.bagit = function (isrc) { + msel.bagit = function (isrc) { if (isrc !== '#ggrid') // we only want to modify the grid, so @@ -104,7 +104,7 @@ // filenames, so schedule another run: setTimeout(graft_thumbs, 1); - // and finally, call the original thegrid.bagit function + // and finally, call the original msel.bagit function return orig_func(isrc); }; diff --git a/copyparty/web/baguettebox.js b/copyparty/web/baguettebox.js index 81b3c6c9..e9ffdb70 100644 --- a/copyparty/web/baguettebox.js +++ b/copyparty/web/baguettebox.js @@ -288,7 +288,7 @@ window.baguetteBox = (function () { var galleries = data[selector].galleries; [].forEach.call(galleries, function (gallery) { [].forEach.call(gallery, function (imageItem) { - unbind(imageItem.imageElement, 'click', imageItem.eventHandler); + //unbind(imageItem.imageElement, 'click', imageItem.eventHandler); }); if (currentGallery === gallery) @@ -1379,16 +1379,16 @@ window.baguetteBox = (function () { function init(){ - if(thegrid != undefined && thegrid.dirty == false && thegrid.bbox != true){ + if(msel != undefined && msel.bbox != true){ console.log('bbox load') - thegrid.bagit(); + msel.bagit(); } else{ setTimeout(init, 100) } } -console.log('wait for grid init'); +console.log('wait for file list init'); init(); J_BBX = 2; diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index 05078e50..425d08e3 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -6414,86 +6414,15 @@ window.thegrid = (function () { } setsz(); - function gclick1(e) { - if (ctrl(e) && !treectl.csel && !r.sel && !r.tempsel) - return true; - else if (e.altKey){ - ev(e); - return; - } - - return gclick.call(this, e, false); - } - function gclick2(e) { if (ctrl(e) || !r.sel && !r.tempsel) return true; - return gclick.call(this, e, true); - } - - function gclick(e, dbl) { - var oth = ebi(this.getAttribute('ref')), - qhref = this.getAttribute('href'), - href = qhref.split('?')[0], - fid = oth.getAttribute('id'), - aplay = ebi('a' + fid), - atext = ebi('t' + fid), - is_txt = atext && !/\.ts$/.test(href) && showfile.getlang(href), - is_img = img_re.test(href), - is_dir = href.endsWith('/'), - is_srch = !!ebi('unsearch'), - in_tree = is_dir && treectl.find(oth.textContent.slice(0, -1)), - have_sel = QS('#files tr.sel'), - td = oth.closest('td').nextSibling, - tr = td.parentNode; - - if ((r.sel || r.tempsel) && !dbl && !ctrl(e) || treectl.csel && (e.shiftKey || ctrl(e))) { - ev(e); - td.onclick.call(td, e); - if (e.shiftKey) - return r.loadsel(); - clmod(this, 'sel', clgot(tr, 'sel')); - } - else if (in_tree) - in_tree.click(); - - else if (oth.hasAttribute('download')) - oth.click(); - - else if (aplay && (r.vau || !is_img)) - aplay.click(); - - else if (is_dir) - treectl.reqls(qhref, true); - - else if (is_txt && !has(['md', 'htm', 'html'], is_txt)) - atext.click(); - - else if (!is_img && !is_dir && have_sel) - window.open(qhref, '_blank'); - - else { - if (!dbl){ - return true; - } - - setTimeout(function () { - r.sel = true; - }, 1); - r.sel = false; - this.click(); - } - ev(e); + return fclick.call(this, e, true); } r.imshow = function (url) { - var sel = '#ggrid>a' - if (!thegrid.en) { - thegrid.bagit('#files'); - sel = '#files a[id]'; - } - var ims = QSA(sel); + var ims = QSA('#files a[id]'); for (var a = 0, aa = ims.length; a < aa; a++) { var iu = ims[a].getAttribute('href').split('?')[0].split('/').slice(-1)[0]; if (iu == url) @@ -6678,7 +6607,7 @@ window.thegrid = (function () { var ths = QSA('#ggrid>a'); for (var a = 0, aa = ths.length; a < aa; a++) { ths[a].ondblclick = gclick2; - ths[a].onclick = gclick1; + ths[a].onclick = fclick1; } var imgs = QSA('#ggrid>a img'); @@ -6700,46 +6629,11 @@ window.thegrid = (function () { r.dirty = false; r.loadsel(); - if(window.baguetteBox != undefined) - r.bagit(); setTimeout(aligngriditems, 1); setTimeout(r.tippen, 20); drag.initgrid(); } - r.bagit = function (isrc) { - console.log('init image viewer'); - - if (r.bbox) - baguetteBox.destroy(); - - if(!isrc) - isrc = thegrid.en ? '#ggrid' : '#files' - - var br = baguetteBox.run(isrc, { - noScrollbars: true, - duringHide: r.onhide, - afterShow: function () { - r.bbox_opts.refocus = true; - }, - captions: function (g, idx) { - var h = '' + g; - - return '' + (idx + 1) + ' / ' + this.length + ' -- ' + - esc(uricom_dec(h.split('/').pop())) + ''; - }, - onChange: function (i, maxIdx) { - if (this[i].imageElement) { - sethash('g' + this[i].imageElement.getAttribute('ref') + getsort()); - } - } - }); - r.bbox_opts = br[1]; - r.bbox = true; - eval_hash() - }; - r.onhide = function () { afilt.apply(); @@ -10022,6 +9916,13 @@ var msel = (function () { for (var a = 0, aa = tds.length; a < aa; a++) tds[a].onclick = r.seltgl; + var links = QSA('#files a[id]') + for (var a = 0, aa = links.length; a < aa; a++) + links[a].onclick = fclick; + + if(window.baguetteBox != undefined) + r.bagit(); + r.selui(true); arcfmt.render(); fileman.render(); @@ -10030,9 +9931,129 @@ var msel = (function () { ebi('selzip').style.display = zipvis; ebi('zip1').style.display = zipvis; } + + r.bagit = function (isrc) { + console.log('init image viewer'); + + if (r.bbox) + baguetteBox.destroy(); + + if(!isrc) + isrc = '#files' + + var br = baguetteBox.run(isrc, { + noScrollbars: true, + duringHide: r.onhide, + afterShow: function () { + r.bbox_opts.refocus = true; + }, + captions: function (g, idx) { + var h = '' + g; + + return '' + (idx + 1) + ' / ' + this.length + ' -- ' + + esc(uricom_dec(h.split('/').pop())) + ''; + }, + onChange: function (i, maxIdx) { + if (this[i].imageElement) { + sethash('g' + this[i].imageElement.getAttribute('ref') + getsort()); + } + } + }); + r.bbox_opts = br[1]; + r.bbox = true; + eval_hash() + }; + + if(window.baguetteBox != undefined) + r.bagit(); + return r; })(); +function fclick1(e) { + if (ctrl(e) && !treectl.csel && !r.sel && !r.tempsel) + return true; + + e.preventDefault ? e.preventDefault() : e.returnValue = false; + + // pass copy of click event to list entry (can trigger bbox handler) + var link = ebi(this.getAttribute('ref')); + link.dispatchEvent(new MouseEvent('click', { + bubbles: true, + cancelable: true, + clientX: e.clientX, + clientY: e.clientY, + ctrlKey: e.ctrlKey, + shiftKey: e.shiftKey, + altKey: e.altKey, + metaKey: e.metaKey, + })); +} + +function fclick(e, dbl) { + if (e.altKey){ + ev(e); + return; + } + var isInGrid = this.hasAttribute('ref'), + link = this; + if(isInGrid){ + // get table row with file link + link = ebi(this.getAttribute('ref')) + } + var qhref = link.getAttribute('href'), + href = qhref.split('?')[0], + fid = link.getAttribute('id'), + aplay = ebi('a' + fid), + atext = ebi('t' + fid), + is_txt = atext && !/\.ts$/.test(href) && showfile.getlang(href), + is_img = img_re.test(href), + is_dir = href.endsWith('/'), + is_srch = !!ebi('unsearch'), + in_tree = is_dir && treectl.find(link.textContent.slice(0, -1)), + have_sel = QS('#files tr.sel'), + td = link.closest('td').nextSibling, + tr = td.parentNode; + + if ( thegrid.en && (thegrid.sel || thegrid.tempsel) && !dbl && !ctrl(e) || treectl.csel && (e.shiftKey || ctrl(e))) { + ev(e); + msel.seltgl.call(td, e); + if (e.shiftKey) + return thegrid.loadsel(); + clmod(this, 'sel', clgot(tr, 'sel')); + } + else if (in_tree) + in_tree.click(); + + else if (link.hasAttribute('download')) + link.click(); + + else if (thegrid.en && aplay && (thegrid.vau || !is_img)) + aplay.click(); + + else if (is_dir) + treectl.reqls(qhref, true); + + else if (is_txt && !has(['md', 'htm', 'html'], is_txt)) + atext.click(); + + else if (!is_img && !is_dir && have_sel) + window.open(qhref, '_blank'); + + else { + if (!dbl) + return true; + + setTimeout(function () { + thegrid.sel = true; + }, 1); + thegrid.sel = false; + link.click(); + } + ev(e); +} + (function () { if (!FormData) From 0f038122021695a95798e27356dbf366629cdd6c Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Sat, 13 Jun 2026 10:57:39 +0200 Subject: [PATCH 584/598] thumbnails in list view --- copyparty/web/baguettebox.js | 7 +- copyparty/web/browser.css | 64 +++++++-- copyparty/web/browser.js | 242 ++++++++++++++++++----------------- copyparty/web/shares.css | 2 +- copyparty/web/tl/chi.js | 2 +- copyparty/web/tl/cze.js | 2 +- copyparty/web/tl/deu.js | 2 +- copyparty/web/tl/epo.js | 2 +- copyparty/web/tl/fin.js | 2 +- copyparty/web/tl/fra.js | 2 +- copyparty/web/tl/grc.js | 2 +- copyparty/web/tl/hun.js | 2 +- copyparty/web/tl/ita.js | 2 +- copyparty/web/tl/jpn.js | 2 +- copyparty/web/tl/kor.js | 2 +- copyparty/web/tl/nld.js | 2 +- copyparty/web/tl/nor.js | 2 +- copyparty/web/tl/pol.js | 2 +- copyparty/web/tl/por.js | 2 +- copyparty/web/tl/rus.js | 2 +- copyparty/web/tl/spa.js | 2 +- copyparty/web/tl/swe.js | 2 +- copyparty/web/tl/tur.js | 2 +- copyparty/web/tl/ukr.js | 2 +- copyparty/web/tl/vie.js | 2 +- docs/changelog.md | 1 - scripts/tl.js | 2 +- 27 files changed, 204 insertions(+), 156 deletions(-) diff --git a/copyparty/web/baguettebox.js b/copyparty/web/baguettebox.js index e9ffdb70..48301a00 100644 --- a/copyparty/web/baguettebox.js +++ b/copyparty/web/baguettebox.js @@ -288,7 +288,7 @@ window.baguetteBox = (function () { var galleries = data[selector].galleries; [].forEach.call(galleries, function (gallery) { [].forEach.call(gallery, function (imageItem) { - //unbind(imageItem.imageElement, 'click', imageItem.eventHandler); + unbind(imageItem.imageElement, 'click', imageItem.eventHandler); }); if (currentGallery === gallery) @@ -742,7 +742,7 @@ window.baguetteBox = (function () { } function showOverlay(chosenImageIndex) { - clmod(ebi('ggrid'), 'waiting', true); + clmod(ebi('wrap'), 'waiting', true); if (options.noScrollbars) { var a = document.documentElement.style.overflowY, @@ -767,7 +767,7 @@ window.baguetteBox = (function () { loadImage(currentIndex, function () { preloadNext(currentIndex); preloadPrev(currentIndex); - clmod(ebi('ggrid'), 'waiting', false); + clmod(ebi('wrap'), 'waiting', false); }); show_buttons(0); @@ -796,7 +796,6 @@ window.baguetteBox = (function () { function hideOverlay(e, dtor) { ev(e); playvid(false); - removeFromCache('#files'); if (options.noScrollbars) { document.documentElement.style.overflowY = scrollCSS[0]; document.body.style.overflowY = scrollCSS[1]; diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 42d7047e..f24d099c 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -522,6 +522,7 @@ html.dy #files tr.sel a.play { color: #fff; } html.dy tr.play td:nth-child(1) a { + color: #000; background: #fff; border: #000 solid 1px; } @@ -708,6 +709,7 @@ html.y #path { display: block; padding: .5em; scroll-margin-top: 45vh; + border-radius: var(--radius); } #files tr { scroll-margin-top: 25vh; @@ -742,6 +744,7 @@ a:hover { color: var(--a-hil); background: var(--a-h-bg); } +#files .imgcontainer:hover, #files a:hover { color: var(--fg-max); background: color-mix(in oklab, var(--a) 20%, transparent); @@ -786,10 +789,6 @@ a.dir { color: #3584e4; color: var(--a); } -tr.dir td:nth-child(2) a::before { - content: "📁"; - margin: 0 .1em 0 -.2em; -} #files thead th { padding: .3em; background: var(--bg); @@ -844,7 +843,7 @@ html.y #files tr.fade a { border-radius: 0 5px 5px 0; border-radius: 0 var(--radius) var(--radius) 0; } -#files tbody td:nth-child(3) { +#files tbody td:nth-child(4) { font-family: 'scp', monospace, monospace; font-family: var(--font-mono), 'scp', monospace, monospace; text-align: right; @@ -1049,9 +1048,6 @@ tr td:nth-child(1) a { padding: .3em; margin: -.3em; } */ -tr.play td:nth-child(2) a::before { - content: "▶"; -} tr.play td:nth-child(1) a { background: var(--btn-1-bg); color:var(--btn-1-fg); @@ -1118,10 +1114,14 @@ tr.play td:nth-child(1) a { /* separate to allow IE to only use this rule */ display: block; } +#files .play .thumb, +#files .play img, #ggrid>a.play .thumb, #ggrid>a.play img { background: var(--bg-u2); } +.thumb, +.imgcontainer img, #ggrid>a .thumb, #ggrid>a img { color: #3584e4; @@ -1136,6 +1136,7 @@ tr.play td:nth-child(1) a { height: calc(var(--grid-sz) - 2.5em); object-fit: cover; } +.imgcontainer img, #ggrid>a img { position: absolute; opacity: 0; @@ -2197,7 +2198,7 @@ input.ssconf_v { margin: 0 .1em 0 0; } -#files td div span { +#files td div:not(.imgcontainer) span { color: var(--fg-max); padding: 0 .4em; font-weight: bold; @@ -2501,9 +2502,47 @@ html.b .btn { #files td.min { display: none; } -#files td:nth-child(2n) { +#files td:nth-child(3){ color: var(--tab-alt); } +#files td:has(.imgcontainer) { + padding: 0 1px; +} +#files .imgcontainer { + width: 2.3em; + height: 2.3em; + cursor: pointer; + margin: 0; + padding: 0; +} +#files .play .imgcontainer { + margin: -2px 0px; + padding: 2px; +} +#files .thumb, +#files img { + height: 100%; +} +#files tbody tr.sel span.th_ext span, +#files tbody tr.sel span.th_ext { + background: none; +} +#files .dir.thumbed img, +#files .dir .thumbed img { + position: absolute; + opacity: .6; +} +#files .dir.thumbed .thumb, +#files .dir .thumbed .thumb { + display: block !important; + z-index: 2; +} +#files .au .imgcontainer::after { + content: "▶"; + position: absolute; + z-index: 2; + top: .6em; +} #plazy { width: 1px; height: 1px; @@ -2542,7 +2581,6 @@ html.b .btn { padding: 0; } .disabled, -#thumbs, #au_prescan, #au_fullpre, #au_os_seek, @@ -2556,7 +2594,6 @@ html.b .btn { #up_quick.disabled { display: none; } -.setting:has(#griden.on)+.setting #thumbs, .setting:has(#au_preload.on)+.setting #au_prescan, .setting:has(#au_preload.on)+.setting #au_prescan, .setting:has(#au_preload.on)~.setting #au_fullpre, @@ -5237,7 +5274,8 @@ html.e #tree_footer { background: transparent; } html.e #wrap { - padding: 0; + padding-left: 0; + padding-right: 0; } html.e #pathBar { padding: 0; diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index 425d08e3..a6c53ee5 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -282,7 +282,7 @@ if (1) "ct_grid": '田 the grid', "ct_ttips": '◔ ◡ ◔">ℹ️ tooltips', - "ct_thumb": 'in grid-view, toggle icons or thumbnails$NHotkey: T">🖼️ thumbs', + "ct_thumb": 'toggle icons or thumbnails$NHotkey: T">🖼️ thumbs', "ct_csel": 'use CTRL and SHIFT for file selection in grid-view">sel', "ct_dsel": 'use drag-selection in grid-view">dsel', "ct_den": 'use dragging to move files into other folders">mvd', @@ -1261,8 +1261,8 @@ ebi('op_cfg').innerHTML = ( '

      ✅ ' + L.cl_opts + '

      \n' + '
      \n' + ' ' + L.ct_grid + '\n' + ' ' + L.ct_grid + '\n' + ' td:nth-child(2)>a[id]"), + var files = QSA("#files tr>td:nth-child(3)>a[id]"), cover = null; for (var a = 0, aa = files.length; a < aa; a++) { @@ -2304,7 +2304,7 @@ function MPlayer() { for (var a = 0, aa = trs.length; a < aa; a++) { var tds = trs[a].getElementsByTagName('td'), - link = tds[1].getElementsByTagName('a'); + link = tds[2].getElementsByTagName('a'); link = link[link.length - 1]; var url = link.getAttribute('href'), @@ -4245,16 +4245,13 @@ function eval_hash() { } if (mtype == 'g') { - if (!thegrid.en) - ebi('griden').click(); - var t = setInterval(function () { - if (!thegrid.bbox) + if (!msel.bbox || !msel.ready) return; clearInterval(t); baguetteBox.urltime(ts); - var im = QS('#ggrid a[ref="' + id + '"]'); + var im = ebi(id); if (!im) return toast.warn(10, L.im_hnf); @@ -5526,7 +5523,7 @@ var fileman = (function () { f = [], indir = [], srcdir = vsplit(r.clip[0])[0], - links = QSA('#files tbody td:nth-child(2) a'); + links = QSA('#files tbody td:nth-child(3) a'); r.f = f; @@ -6517,88 +6514,21 @@ window.thegrid = (function () { var html = [], svgs = new Set(), max_svgs = CHROME ? 500 : 5000, - need_ext = !r.thumbs || !!ext_th, - use_ext_th = r.thumbs && ext_th, - files = QSA('#files>tbody>tr>td:nth-child(2) a[id]'); + files = QSA('#files>tbody>tr>td:nth-child(3) a[id]'); for (var a = 0, aa = files.length; a < aa; a++) { var ao = files[a], ohref = esc(ao.getAttribute('href')), href = ohref.split('?')[0], - ext = '', - ext0 = '', name = uricom_dec(vsplit(href)[1]), ref = ao.getAttribute('id'), isdir = clgot(ao.parentElement.parentElement, 'dir'), - ac = ao.parentElement.parentElement.classList, - ihref = ohref; - - if (need_ext && href != "#") { - var ar = href.split('.'); - if (ar.length > 1) - ar.shift(); - - ar.reverse(); - ext0 = ar[0]; - for (var b = 0; b < Math.min(2, ar.length); b++) { - ext = ext ? (ar[b] + '.' + ext) : ar[b]; - if (ar[b].length > 2) - break; - } - if (!ext) - ext = 'unk'; - } - - if (use_ext_th && (ext_th[ext] || ext_th[ext0])) { - ihref = ext_th[ext] || ext_th[ext0]; - } - else if (r.thumbs) { - ihref = addq(ihref, 'th=' + ( - have_jxl ? 'x' : - have_webp ? 'w' : - 'j' - )); - if (!r.crop) - ihref += 'f'; - if (r.x3) - ihref += '3'; - if (href == "#") - ihref = SR + '/.cpr/ico/' + (ref == 'moar' ? '++' : 'exit'); - } - else { - ihref = ''; - } - - if(ihref){ - ihref = addq(ihref, 'cache=i&_=' + ACB + TS); - - var accent = getComputedStyle(document.body).getPropertyValue('--a'); - if (!accent) - accent = '#07c'; - ihref += '&a=' + parseColor(accent).replace(/ /g, ''); - } - - var svg = ''; - svg = '' + svg + ''; - - if (N3DS){ - // 3DS / unsupported: use fallback - svg = '' + (isdir ? '📁[FOLDER]' : '📄[FILE:' + ext + ']') + ''; - ext = 'unk'; - } + ac = ao.parentElement.parentElement.classList; html.push('' + - '
      ' + - '' + - svg + - (isdir || ext == 'unk' || ext.startsWith('/') ? '' : - '' + ext + '') + - '
      ' + ao.innerHTML + '
      '); + get_thumb(ohref, ref, isdir, true) + + '' + ao.innerHTML + ''); } ggrid.innerHTML = html.join('\n'); clmod(ggrid, 'crop', r.crop); @@ -6704,7 +6634,10 @@ window.thegrid = (function () { swrite('thumbs', 1); } - bcfg_bind(r, 'thumbs', 'thumbs', true, r.setdirty); + bcfg_bind(r, 'thumbs', 'thumbs', true, function(e){ + r.setdirty(); + msel.render(); + }); bcfg_bind(r, 'ihop', 'ihop', true); bcfg_bind(r, 'vau', 'gridvau', false); bcfg_bind(r, 'crop', 'gridcrop', !dcrop.endsWith('n'), r.set_crop); @@ -6757,6 +6690,85 @@ window.thegrid = (function () { return r; })(); +function get_thumb(ohref, ref, isdir, grid){ + var href = ohref.split('?')[0], + ext = '', + ext0 = '', + name = uricom_dec(vsplit(href)[1]), + need_ext = !thegrid.thumbs || !!ext_th, + use_ext_th = thegrid.thumbs && ext_th, + ihref = ohref; + + if (need_ext && href != "#") { + var ar = href.split('.'); + if (ar.length > 1) + ar.shift(); + + ar.reverse(); + ext0 = ar[0]; + for (var b = 0; b < Math.min(2, ar.length); b++) { + ext = ext ? (ar[b] + '.' + ext) : ar[b]; + if (ar[b].length > 2) + break; + } + if (!ext) + ext = 'unk'; + } + + if (use_ext_th && (ext_th[ext] || ext_th[ext0])) { + ihref = ext_th[ext] || ext_th[ext0]; + } + else if (thegrid.thumbs) { + ihref = addq(ihref, 'th=' + ( + have_jxl ? 'x' : + have_webp ? 'w' : + 'j' + )); + if (grid && !thegrid.crop) + ihref += 'f'; + if (grid && thegrid.x3) + ihref += '3'; + if (href == "#") + ihref = SR + '/.cpr/ico/' + (ref == 'moar' ? '++' : 'exit'); + } + else { + ihref = ''; + } + + if(ihref){ + ihref = addq(ihref, 'cache=i&_=' + ACB + TS); + + var accent = getComputedStyle(document.body).getPropertyValue('--a'); + if (!accent) + accent = '#07c'; + ihref += '&a=' + parseColor(accent).replace(/ /g, ''); + } + + var svg = ''; + svg = '' + svg + ''; + + if (N3DS){ + // 3DS / unsupported: use fallback + svg = '' + (isdir ? '📁[FOLDER]' : '📄[FILE:' + ext + ']') + ''; + ext = 'unk'; + } + + var container = '
      ' + + (grid ? '' : '') + + svg + + (isdir || ext == 'unk' || ext.startsWith('/') ? '' : + '' + ext + '') + + '
      ' + return container; +} + function th_onload(el) { set_loaded(el, true, false) } @@ -8628,8 +8640,9 @@ var treectl = (function () { '" hl="' + id + '" name="' + hname + '">-txt-'; var cl = (/\.PARTIAL$/.exec(fname) ? 'fade ' : '') + (img_re.exec(fname) ? 'img ' : '') + (tn.cls || ''), - ln = ['' + tn.lead + '' + hname + + ln = ['' + tn.lead + '' + + get_thumb(tn.href, id, (/\bdir\b/i).test(cl), false) + + '' + hname + '' + filesizefun(tn.sz)]; for (var b = 0; b < res.taglist.length; b++) { @@ -8736,7 +8749,7 @@ var treectl = (function () { var media = scan_hash(location.hash); if(media && media[0] == 'g') - clmod(ebi('ggrid'), 'waiting', true); + clmod(ebi('wrap'), 'waiting', true); setTimeout(eval_hash, 1); }; @@ -9173,6 +9186,7 @@ function mk_files_header(taglist) { var html = [ '', '!', + 'th', 'File Name', 'Size' ]; @@ -9724,7 +9738,7 @@ var msel = (function () { } r.all = []; - var links = QSA('#files tbody td:nth-child(2) a:last-child'), + var links = QSA('#files tbody td:nth-child(3) a:last-child'), is_srch = !!ebi('unsearch'), vbase = get_evpath(); @@ -9910,16 +9924,25 @@ var msel = (function () { dl_file(sel[a].vp + sel[a].q); }; r.render = function () { - var tds = QSA('#files tbody td+td+td'), + var tds = QSA('#files tbody td+td+td+td'), is_srch = !!ebi('unsearch'); for (var a = 0, aa = tds.length; a < aa; a++) tds[a].onclick = r.seltgl; - var links = QSA('#files a[id]') + var links = QSA('#files td:nth-child(3) a[id]') for (var a = 0, aa = links.length; a < aa; a++) links[a].onclick = fclick; + var thumbs = QSA('#files .imgcontainer') + for (var a = 0, aa = thumbs.length; a < aa; a++) + thumbs[a].onclick = fclick1; + + var imgs = QSA('#files img'); + for (var a = 0, aa = imgs.length; a < aa; a++) { + set_loaded(imgs[a], thegrid.thumbs && imgs[a].complete, true); + } + if(window.baguetteBox != undefined) r.bagit(); @@ -9930,6 +9953,8 @@ var msel = (function () { var zipvis = (is_srch || !have_zip) ? 'none' : ''; ebi('selzip').style.display = zipvis; ebi('zip1').style.display = zipvis; + + r.ready = true; } r.bagit = function (isrc) { @@ -9956,30 +9981,23 @@ var msel = (function () { }, onChange: function (i, maxIdx) { if (this[i].imageElement) { - sethash('g' + this[i].imageElement.getAttribute('ref') + getsort()); + sethash('g' + this[i].imageElement.getAttribute('id') + getsort()); } } }); r.bbox_opts = br[1]; r.bbox = true; - eval_hash() }; - if(window.baguetteBox != undefined) - r.bagit(); - return r; })(); function fclick1(e) { - if (ctrl(e) && !treectl.csel && !r.sel && !r.tempsel) - return true; - e.preventDefault ? e.preventDefault() : e.returnValue = false; // pass copy of click event to list entry (can trigger bbox handler) - var link = ebi(this.getAttribute('ref')); - link.dispatchEvent(new MouseEvent('click', { + var td = ebi(this.getAttribute('ref')); + td.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, clientX: e.clientX, @@ -9996,27 +10014,21 @@ function fclick(e, dbl) { ev(e); return; } - var isInGrid = this.hasAttribute('ref'), - link = this; - if(isInGrid){ - // get table row with file link - link = ebi(this.getAttribute('ref')) - } - var qhref = link.getAttribute('href'), + var qhref = this.getAttribute('href'), href = qhref.split('?')[0], - fid = link.getAttribute('id'), + fid = this.getAttribute('id'), aplay = ebi('a' + fid), atext = ebi('t' + fid), is_txt = atext && !/\.ts$/.test(href) && showfile.getlang(href), is_img = img_re.test(href), is_dir = href.endsWith('/'), is_srch = !!ebi('unsearch'), - in_tree = is_dir && treectl.find(link.textContent.slice(0, -1)), + in_tree = is_dir && treectl.find(this.textContent.slice(0, -1)), have_sel = QS('#files tr.sel'), - td = link.closest('td').nextSibling, + td = this.closest('td').nextSibling, tr = td.parentNode; - if ( thegrid.en && (thegrid.sel || thegrid.tempsel) && !dbl && !ctrl(e) || treectl.csel && (e.shiftKey || ctrl(e))) { + if (thegrid.en && (thegrid.sel || thegrid.tempsel) && !dbl && !ctrl(e) || treectl.csel && (e.shiftKey || ctrl(e))) { ev(e); msel.seltgl.call(td, e); if (e.shiftKey) @@ -10026,10 +10038,10 @@ function fclick(e, dbl) { else if (in_tree) in_tree.click(); - else if (link.hasAttribute('download')) - link.click(); + else if (this.hasAttribute('download')) + this.click(); - else if (thegrid.en && aplay && (thegrid.vau || !is_img)) + else if (aplay && (thegrid.vau || !is_img)) aplay.click(); else if (is_dir) @@ -10049,7 +10061,7 @@ function fclick(e, dbl) { thegrid.sel = true; }, 1); thegrid.sel = false; - link.click(); + this.click(); } ev(e); } @@ -11071,7 +11083,7 @@ var drag = (function() { elem.ondragenter = elem.ondragleave = elem.ondragover = function(e) { if (!r.enabled) return; - var elemHref = basenames((elem.tagName == "A" ? elem : elem.querySelector("td:nth-child(2) a")).href.split("?")[0]) + var elemHref = basenames((elem.tagName == "A" ? elem : elem.querySelector("td:nth-child(3) a")).href.split("?")[0]) if (current == elem || elemHref == get_evpath() || currLink == elemHref) // Prevent folders being dragged into themselves return; ev(e); @@ -11110,7 +11122,7 @@ var drag = (function() { f.draggable = true; f.ondragstart = function(e) { try{ - currLink = basenames(e.target.querySelector("td:nth-child(2) a").href.split("?")); + currLink = basenames(e.target.querySelector("td:nth-child(3) a").href.split("?")); current = e.target; r.no_warn = true; diff --git a/copyparty/web/shares.css b/copyparty/web/shares.css index 0a69260d..755ac2df 100644 --- a/copyparty/web/shares.css +++ b/copyparty/web/shares.css @@ -61,7 +61,7 @@ th { vertical-align: top; white-space: nowrap; } -#wrap td+td+td+td+td+td+td+td { +#wrap td+td+td+td+td+td+td+td+td { font-family: var(--font-mono), monospace, monospace; } #wrap th:first-child, diff --git a/copyparty/web/tl/chi.js b/copyparty/web/tl/chi.js index 6298f8ea..426a97cd 100644 --- a/copyparty/web/tl/chi.js +++ b/copyparty/web/tl/chi.js @@ -225,7 +225,7 @@ Ls.chi = { "ct_grid": '田 网格', "ct_ttips": '◔ ◡ ◔">ℹ️ 提示', - "ct_thumb": '在网格视图中,切换图标或缩略图$N快捷键: T">🖼️ 缩略', + "ct_thumb": '切换图标或缩略图$N快捷键: T">🖼️ 缩略', "ct_csel": '在网格视图中,允许使用 CTRL 和 SHIFT 进行文件选择">选择', "ct_dsel": '在网格视图中,允许拖动选择">拖选', "ct_dl": '点击文件时强制下载(不要就地显示)">下载', diff --git a/copyparty/web/tl/cze.js b/copyparty/web/tl/cze.js index cd94c269..095113a5 100644 --- a/copyparty/web/tl/cze.js +++ b/copyparty/web/tl/cze.js @@ -229,7 +229,7 @@ Ls.cze = { "ct_grid": '田 mřížka', "ct_ttips": '◔ ◡ ◔">ℹ️ nápovědy', - "ct_thumb": 'v zobrazení mřížky přepnout ikony nebo náhledy$NKlávesová zkratka: T">🖼️ náhledy', + "ct_thumb": 'přepnout ikony nebo náhledy$NKlávesová zkratka: T">🖼️ náhledy', "ct_csel": 'použít CTRL a SHIFT pro výběr souborů v zobrazení mřížky">výběr', "ct_dsel": 'použít tažený výběr v zobrazení mřížky">tažení', //m "ct_dl": 'vynutit stažení (nezobrazovat inline) při kliknutí na soubor">dl', //m diff --git a/copyparty/web/tl/deu.js b/copyparty/web/tl/deu.js index 00ccf05f..ffe6ccda 100644 --- a/copyparty/web/tl/deu.js +++ b/copyparty/web/tl/deu.js @@ -225,7 +225,7 @@ Ls.deu = { "ct_grid": '田 Das Raster™', "ct_ttips": '◔ ◡ ◔">ℹ️ Tooltips', - "ct_thumb": 'In Raster-Ansicht, zwischen Icons und Vorschau wechseln$NHotkey: T">🖼️ Vorschaubilder', + "ct_thumb": 'Zwischen Icons und Vorschau wechseln$NHotkey: T">🖼️ Vorschaubilder', "ct_csel": 'Benutze STRG und UMSCHALT für Dateiauswahl in Raster-Ansicht">sel', "ct_dsel": 'Ziehauswahl in Raster-Ansicht verwenden">ziehen', //m "ct_dl": 'Beim Klick auf Dateien sie immer herunterladen (nicht einbetten)">dl', diff --git a/copyparty/web/tl/epo.js b/copyparty/web/tl/epo.js index 1828ab96..962b2be3 100644 --- a/copyparty/web/tl/epo.js +++ b/copyparty/web/tl/epo.js @@ -225,7 +225,7 @@ Ls.epo = { "ct_grid": '田 krado', "ct_ttips": '◔ ◡ ◔">ℹ️ ŝpruchelpiloj', - "ct_thumb": 'dum krado-vido, baskuli montradon de simboloj aŭ bildetoj$NFulmoklavo: T">🖼️ bildetoj', + "ct_thumb": 'baskuli montradon de simboloj aŭ bildetoj$NFulmoklavo: T">🖼️ bildetoj', "ct_csel": 'uzi STIR kaj MAJ por elekti dosierojn en krado-vido">elekto', "ct_dsel": 'uzi tren-elekton en krado-vido">treni', "ct_dl": 'devigi elŝuton (ne montri enkadre), kiam dosiero estas alklakita">elŝuti', diff --git a/copyparty/web/tl/fin.js b/copyparty/web/tl/fin.js index 3d5d074b..2e973d4b 100644 --- a/copyparty/web/tl/fin.js +++ b/copyparty/web/tl/fin.js @@ -225,7 +225,7 @@ Ls.fin = { "ct_grid": '田 kuvanäkymä', "ct_ttips": '◔ ◡ ◔">ℹ️ vihjelaatikot', - "ct_thumb": 'valitse kuvakkeiden / pienoiskuvien välillä kuvanäkymässä $NPikanäppäin: T">🖼️ pienoiskuvat', + "ct_thumb": 'valitse kuvakkeiden / pienoiskuvien välillä $NPikanäppäin: T">🖼️ pienoiskuvat', "ct_csel": 'käytä CTRL ja SHIFT tiedostojen valintaan kuvanäkymässä">valitse', "ct_dsel": 'käytä aluevalintaa tiedostojen valintaan kuvanäkymässä">aluevalinta', "ct_dl": 'pakota lataus (älä näytä upotettuna), kun tiedostoa klikataan">dl', diff --git a/copyparty/web/tl/fra.js b/copyparty/web/tl/fra.js index bdb05b46..04a323f7 100644 --- a/copyparty/web/tl/fra.js +++ b/copyparty/web/tl/fra.js @@ -225,7 +225,7 @@ Ls.fra = { "ct_grid": '田 grille', "ct_ttips": '◔ ◡ ◔">ℹ️ infobulles', - "ct_thumb": 'vue en grille, activer les icônes ou les miniatures$NHotkey: T">🖼️ minia', + "ct_thumb": 'activer les icônes ou les miniatures$NHotkey: T">🖼️ minia', "ct_csel": 'utiliser CTRL et MAJ pour selectioner des fichiers en vue en grille">sel', "ct_dsel": 'utiliser la sélection par glisser en vue en grille">glisser', //m "ct_dl": 'forcer le téléchargement (ne pas afficher en ligne) lorsqu’un fichier est cliqué">dl', //m diff --git a/copyparty/web/tl/grc.js b/copyparty/web/tl/grc.js index 7000176c..79e26e66 100644 --- a/copyparty/web/tl/grc.js +++ b/copyparty/web/tl/grc.js @@ -225,7 +225,7 @@ Ls.grc = { "ct_grid": '田 το πλέγμα', "ct_ttips": '◔ ◡ ◔">ℹ️ συμβουλές εργαλείων', - "ct_thumb": 'σε προβολή πλέγματος, εναλλαγή εικονιδίων ή μικρογραφιών$NΠλήκτρο συντόμευσης: T">🖼️ μικρογραφίες', + "ct_thumb": 'εναλλαγή εικονιδίων ή μικρογραφιών$NΠλήκτρο συντόμευσης: T">🖼️ μικρογραφίες', "ct_csel": 'χρησιμοποίησε CTRL και SHIFT για επιλογή αρχείων σε προβολή πλέγματος">επιλογή', "ct_dsel": 'χρησιμοποίησε επιλογή με σύρσιμο σε προβολή πλέγματος">σύρσιμο', //m "ct_dl": 'εξαναγκασμός λήψης (να μην εμφανίζεται ενσωματωμένα) όταν γίνεται κλικ σε ένα αρχείο">dl', //m diff --git a/copyparty/web/tl/hun.js b/copyparty/web/tl/hun.js index b9404c82..9f2ada68 100644 --- a/copyparty/web/tl/hun.js +++ b/copyparty/web/tl/hun.js @@ -226,7 +226,7 @@ Ls.hun = { "ct_grid": '田 rács nézet', "ct_ttips": '◔ ◡ ◔">ℹ️ segítő szövegek', - "ct_thumb": 'rács nézetben ikonok/indexképek váltása$Ngyorsbillentyű: T">🖼️ képek', + "ct_thumb": 'ikonok/indexképek váltása$Ngyorsbillentyű: T">🖼️ képek', "ct_csel": 'kijelölés CTRL és SHIFT gombokkal rács nézetben">kijelölés', "ct_dsel": 'kijelölés egérhúzással rács nézetben">húzás', "ct_dl": 'azonnali letöltés (beágyazás helyett)">letöltés', diff --git a/copyparty/web/tl/ita.js b/copyparty/web/tl/ita.js index 86639777..88266276 100644 --- a/copyparty/web/tl/ita.js +++ b/copyparty/web/tl/ita.js @@ -225,7 +225,7 @@ Ls.ita = { "ct_grid": '田 griglia', "ct_ttips": '◔ ◡ ◔">ℹ️ tooltip', - "ct_thumb": 'nella vista griglia, alterna icone o miniature$NTasto rapido: T">🖼️ miniature', + "ct_thumb": 'alterna icone o miniature$NTasto rapido: T">🖼️ miniature', "ct_csel": 'usa CTRL e SHIFT per la selezione file nella vista griglia">sel', "ct_dsel": 'usa la selezione tramite trascinamento nella vista griglia">trascina', //m "ct_dl": 'forza il download (non visualizzare inline) quando si clicca su un file">dl', //m diff --git a/copyparty/web/tl/jpn.js b/copyparty/web/tl/jpn.js index 5d616c33..d3305679 100644 --- a/copyparty/web/tl/jpn.js +++ b/copyparty/web/tl/jpn.js @@ -225,7 +225,7 @@ Ls.jpn = { "ct_grid": '田 グリッド', "ct_ttips": '◔ ◡ ◔">ℹ️ ツールチップ', - "ct_thumb": 'グリッドビューではアイコンまたはサムネイルを切り替える$Nホットキー: T">🖼️ サムネイル', + "ct_thumb": 'アイコンまたはサムネイルを切り替える$Nホットキー: T">🖼️ サムネイル', "ct_csel": 'グリッドビューでファイルを選択するにはCtrlとShiftを使用する。">選択', "ct_dsel": 'グリッドビューでドラッグ選択を使用する。">ドラッグ', //m "ct_dl": 'ファイルをクリックしたときに強制的にダウンロードする(インラインで表示しない)">dl', diff --git a/copyparty/web/tl/kor.js b/copyparty/web/tl/kor.js index cfc1f510..b1a8eb4f 100644 --- a/copyparty/web/tl/kor.js +++ b/copyparty/web/tl/kor.js @@ -225,7 +225,7 @@ Ls.kor = { "ct_grid": "田 그리드", "ct_ttips": '◔ ◡ ◔">ℹ️ 도움말', - "ct_thumb": '그리드 보기에서 아이콘 또는 미리보기 이미지 전환$N단축키: T">🖼️ 미리보기', + "ct_thumb": '아이콘 또는 미리보기 이미지 전환$N단축키: T">🖼️ 미리보기', "ct_csel": '그리드 보기에서 CTRL과 SHIFT를 사용하여 파일 선택">선택', "ct_dsel": '그리드 보기에서 드래그 선택 사용">드래그', //m "ct_dl": '파일을 클릭하면 다운로드를 강제로 수행 (인라인으로 표시하지 않음)">dl', //m diff --git a/copyparty/web/tl/nld.js b/copyparty/web/tl/nld.js index 0a6d1186..9f9197d7 100644 --- a/copyparty/web/tl/nld.js +++ b/copyparty/web/tl/nld.js @@ -225,7 +225,7 @@ Ls.nld = { "ct_grid": '田 grid', "ct_ttips": '◔ ◡ ◔">ℹ️ tooltips', - "ct_thumb": 'In grid-overzicht, wissel tussen iconen of thumbnails$NHotkey: T">🖼️ thumbs', + "ct_thumb": 'wissel tussen iconen of thumbnails$NHotkey: T">🖼️ thumbs', "ct_csel": 'Gebruik CTRL en SHIFT voor de bestand selectie in grid-overzicht>sel', "ct_dsel": 'Gebruik slepen om te selecteren in grid-overzicht>slepen', //m "ct_dl": 'download afdwingen (niet inline weergeven) wanneer op een bestand wordt geklikt">dl', //m diff --git a/copyparty/web/tl/nor.js b/copyparty/web/tl/nor.js index c550de47..7dd25ea8 100644 --- a/copyparty/web/tl/nor.js +++ b/copyparty/web/tl/nor.js @@ -222,7 +222,7 @@ Ls.nor = { "ct_grid": '田 ikoner', "ct_ttips": 'vis hjelpetekst ved å holde musen over ting">ℹ️ tips', - "ct_thumb": 'vis miniatyrbilder istedenfor ikoner$NSnarvei: T">🖼️ bilder', + "ct_thumb": 'vis miniatyrbilder isteden for ikoner$NSnarvei: T">🖼️ bilder', "ct_csel": 'bruk tastene CTRL og SHIFT for markering av filer i ikonvisning">merk', "ct_dsel": 'marker filer med klikk-og-dra i ikonvisning">dsel', "ct_dl": 'last ned filer (ikke vis i nettleseren)">dl', diff --git a/copyparty/web/tl/pol.js b/copyparty/web/tl/pol.js index 949a0640..4725bb1e 100644 --- a/copyparty/web/tl/pol.js +++ b/copyparty/web/tl/pol.js @@ -228,7 +228,7 @@ Ls.pol = { "ct_grid": '田 siatka', "ct_ttips": '◔ ◡ ◔">ℹ️ podpowiedzi', - "ct_thumb": 'w widoku siatki, przełącz ikony i miniaturki$NSkrót: T">🖼️ miniaturki', + "ct_thumb": 'przełącz ikony i miniaturki$NSkrót: T">🖼️ miniaturki', "ct_csel": 'użyj CTRL i SHIFT do wybierania plików w widoku siatki">wybierz', "ct_dsel": 'użyj zaznaczania przez przeciąganie w widoku siatki">przeciągnij', //m "ct_dl": 'wymuś pobieranie (nie wyświetlaj inline) po kliknięciu pliku">dl', //m diff --git a/copyparty/web/tl/por.js b/copyparty/web/tl/por.js index 99515fff..a061318b 100644 --- a/copyparty/web/tl/por.js +++ b/copyparty/web/tl/por.js @@ -225,7 +225,7 @@ Ls.por = { "ct_grid": '田 a grade', "ct_ttips": '◔ ◡ ◔">ℹ️ dicas de ferramentas', - "ct_thumb": 'na visualização de grade, alternar entre ícones ou miniaturas$NHotkey: T">🖼️ miniaturas', + "ct_thumb": 'alternar entre ícones ou miniaturas$NHotkey: T">🖼️ miniaturas', "ct_csel": 'usar CTRL e SHIFT para seleção de arquivo na visualização de grade">sel', "ct_dsel": 'usar seleção por arrasto na visualização de grade">arrastar', "ct_dl": 'forçar download (não exibir na página) ao clicar em um arquivo">dl', diff --git a/copyparty/web/tl/rus.js b/copyparty/web/tl/rus.js index d59aeaa1..3768899a 100644 --- a/copyparty/web/tl/rus.js +++ b/copyparty/web/tl/rus.js @@ -225,7 +225,7 @@ Ls.rus = { "ct_grid": '田 сетка', "ct_ttips": '◔ ◡ ◔">ℹ️ подсказки', - "ct_thumb": 'переключение между иконками и миниатюрами в режиме сетки$NГорячая клавиша: T">🖼️ миниат.', + "ct_thumb": 'переключение между иконками и миниатюрами$NГорячая клавиша: T">🖼️ миниат.', "ct_csel": 'держите CTRL или SHIFT для выделения файлов в режиме сетки">выбор', "ct_dsel": 'использовать выделение перетаскиванием в режиме сетки">перетащить', //m "ct_dl": 'принудительная загрузка (не показывать встроенно) при щелчке по файлу">dl', //m diff --git a/copyparty/web/tl/spa.js b/copyparty/web/tl/spa.js index 8590b675..182cff33 100644 --- a/copyparty/web/tl/spa.js +++ b/copyparty/web/tl/spa.js @@ -224,7 +224,7 @@ Ls.spa = { "ct_grid": '田 cuadrícula', "ct_ttips": '◔ ◡ ◔">ℹ️ tooltips', - "ct_thumb": 'en vista de cuadrícula, alternar iconos o miniaturas$NAtajo: T">🖼️ miniaturas', + "ct_thumb": 'alternar iconos o miniaturas$NAtajo: T">🖼️ miniaturas', "ct_csel": 'usa CTRL y SHIFT para seleccionar archivos en la vista de cuadrícula">sel', "ct_dsel": 'usa la selección por arrastre en la vista de cuadrícula">arrastrar', //m "ct_dl": 'forzar descarga (no mostrar en línea) al hacer clic en un archivo">dl', //m diff --git a/copyparty/web/tl/swe.js b/copyparty/web/tl/swe.js index 0b2fcfd1..4b96e2d0 100644 --- a/copyparty/web/tl/swe.js +++ b/copyparty/web/tl/swe.js @@ -225,7 +225,7 @@ Ls.swe = { "ct_grid": '田 rutnätet', "ct_ttips": '◔ ◡ ◔">ℹ️ tips', - "ct_thumb": 'växla mellan miniatyrer och ikoner i rutnätsvyn$NSnabbtangent: T">🖼️ miniatyrer', + "ct_thumb": 'växla mellan miniatyrer och ikoner$NSnabbtangent: T">🖼️ miniatyrer', "ct_csel": 'använd CTRL och SKIFT för urval av filer i rutnätsvyn">val', "ct_dsel": 'använd dra-urval i rutnätsvyn">dra', //m "ct_dl": 'tvinga nedladdning (visa inte inline) när en fil klickas">dl', //m diff --git a/copyparty/web/tl/tur.js b/copyparty/web/tl/tur.js index 7fc3d468..4c7723f0 100644 --- a/copyparty/web/tl/tur.js +++ b/copyparty/web/tl/tur.js @@ -225,7 +225,7 @@ Ls.tur = { "ct_grid": '田 ızgara', "ct_ttips": '◔ ◡ ◔">ℹ️ ipuçları', - "ct_thumb": 'ızgara görünümünde, simgeler ve küçük resimler arasında geçiş yapın$NKısayol: T">🖼️ küçük resimler', + "ct_thumb": 'simgeler ve küçük resimler arasında geçiş yapın$NKısayol: T">🖼️ küçük resimler', "ct_csel": 'ızgara görünümünde dosya seçimi için CTRL ve SHIFT tuşlarını kullanın">seç', "ct_dsel": 'ızgara görünümünde sürükleyerek seçimi kullanın">sürükle', //m "ct_dl": 'dosyaya tıklandığında indirmeyi zorla (satır içinde görüntüleme)">dl', //m diff --git a/copyparty/web/tl/ukr.js b/copyparty/web/tl/ukr.js index 4ca0cdec..4b0fc1a1 100644 --- a/copyparty/web/tl/ukr.js +++ b/copyparty/web/tl/ukr.js @@ -225,7 +225,7 @@ Ls.ukr = { "ct_grid": '田 сітка', "ct_ttips": '◔ ◡ ◔">ℹ️ підказки', - "ct_thumb": 'у режимі сітки, перемкнути іконки або мініатюри$NГаряча клавіша: T">🖼️ мініатюри', + "ct_thumb": 'перемкнути іконки або мініатюри$NГаряча клавіша: T">🖼️ мініатюри', "ct_csel": 'використовувати CTRL і SHIFT для вибору файлів у режимі сітки">вибір', "ct_dsel": 'використовувати вибір перетягуванням у режимі сітки">перетягнути', //m "ct_dl": 'примусове завантаження (не показувати вбудовано) під час натискання на файл">dl', //m diff --git a/copyparty/web/tl/vie.js b/copyparty/web/tl/vie.js index 476fbcda..f6575e0b 100644 --- a/copyparty/web/tl/vie.js +++ b/copyparty/web/tl/vie.js @@ -226,7 +226,7 @@ Ls.vie = { // settings / tuỳ chọn "ct_grid": '田 chế độ lưới', "ct_ttips": '༼ ◕_◕ ༽">ℹ️ tooltips', - "ct_thumb": 'ở chế độ lưới, chuyển biểu tượng hoặc hình thu nhỏ$NPhím tắt: T">🖼️ ảnh thu nhỏ', + "ct_thumb": 'chuyển biểu tượng hoặc hình thu nhỏ$NPhím tắt: T">🖼️ ảnh thu nhỏ', "ct_csel": 'dùng CTRL và SHIFT để chọn tệp trong chế độ lưới">sel', "ct_dsel": 'dùng chọn bằng cách kéo trong chế độ lưới">kéo', //m "ct_dl": 'cưỡng chế tải xuống (không hiện thị trong dòng) khi nhấp vào tệp">dl', diff --git a/docs/changelog.md b/docs/changelog.md index f9da092d..4ceeaa29 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -62,7 +62,6 @@ * more consistent areas for clicking to navigate left / right in the image viewer (they don't depend on image fill mode anymore) * "folder up" / "next sibling" / "previous sibling" are now icon buttons at the top * new look for the login screen -* file list makes it easier to identify folders via an added folder emoji to folder names. to disable this, add the following style: `tr:has(a.dir) td:nth-child(2) a::before { display: none; }` * pm-monokai theme has become "flat dark" ## 🌠 fun facts diff --git a/scripts/tl.js b/scripts/tl.js index 06013c0a..f78faf4b 100644 --- a/scripts/tl.js +++ b/scripts/tl.js @@ -256,7 +256,7 @@ Ls.hmn = { "ct_grid": '田 the grid', "ct_ttips": '◔ ◡ ◔">ℹ️ tooltips', - "ct_thumb": 'in grid-view, toggle icons or thumbnails$NHotkey: T">🖼️ thumbs', + "ct_thumb": 'toggle icons or thumbnails$NHotkey: T">🖼️ thumbs', "ct_csel": 'use CTRL and SHIFT for file selection in grid-view">sel', "ct_dsel": 'use drag-selection in grid-view">dsel', "ct_dl": 'force download (don\'t display inline) when a file is clicked">dl', From 6360f471c06d2a77cd9dc001cde5f19b31af4abb Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Sat, 13 Jun 2026 13:06:47 +0200 Subject: [PATCH 585/598] thumbnails in list view --- copyparty/web/browser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index a6c53ee5..9a9f4522 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -10948,7 +10948,7 @@ var rcm = (function () { var ref = ebi(target.getAttribute('ref')); file = ref && ref.closest('#files tbody tr'); } - var fa = file && file.children[1].querySelector('a[id]'); + var fa = file && file.children[2].querySelector('a[id]'); if (fa && fa.id != 'unsearch') { selFile.no_dsel = TOUCH || clgot(file, "sel"); clmod(file, "sel", true); From 173d258493e1fccc1cfb2fc5cfacfe3c720f08d5 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Sat, 13 Jun 2026 13:16:47 +0200 Subject: [PATCH 586/598] thumbnails in list view --- copyparty/web/browser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index 9a9f4522..83d2e2b0 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -9153,7 +9153,7 @@ function wait_set_fsearch(){ function tr2id(tr) { try { - return tr.cells[1].querySelector('a[id]').getAttribute('id'); + return tr.cells[2].querySelector('a[id]').getAttribute('id'); } catch (ex) { return null; From 164ae0039a24d62429c67532a3a89dac34adfea2 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Sat, 13 Jun 2026 22:37:55 +0200 Subject: [PATCH 587/598] thumbnails in list view --- copyparty/web/browser.css | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index f24d099c..045dab03 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -709,7 +709,6 @@ html.y #path { display: block; padding: .5em; scroll-margin-top: 45vh; - border-radius: var(--radius); } #files tr { scroll-margin-top: 25vh; @@ -1171,6 +1170,10 @@ tr.play td:nth-child(1) a { padding: 4px 3px; justify-content: center; } +#files .imgcontainer img, +#files .imgcontainer { + border-radius: 0; +} .th_ext { z-index: 2; position: absolute; @@ -5622,8 +5625,8 @@ html.f #ggrid > a.sel:hover .imgcontainer::before { border-color: var(--g-fsel-bg) transparent transparent var(--g-fsel-bg); } /* #wrap:not(.thin) .ghead::after, */ -html.f .dir.thumbed .imgcontainer::before, -html.f .au.thumbed:not(.play) .imgcontainer::before { +html.f #ggrid .dir.thumbed .imgcontainer::before, +html.f #ggrid .au.thumbed:not(.play) .imgcontainer::before { content: ""; position: absolute; left: 0; From 99df50d43b2370ac229396b1ae9cae53a08a5d0e Mon Sep 17 00:00:00 2001 From: Til Date: Wed, 17 Jun 2026 07:28:49 +0200 Subject: [PATCH 588/598] fix search after list thumbs commit --- copyparty/web/browser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index 83d2e2b0..8e6f375c 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -2304,7 +2304,7 @@ function MPlayer() { for (var a = 0, aa = trs.length; a < aa; a++) { var tds = trs[a].getElementsByTagName('td'), - link = tds[2].getElementsByTagName('a'); + link = tds[3].getElementsByTagName('a'); link = link[link.length - 1]; var url = link.getAttribute('href'), From 8ca21978f46acecec6cfbc985cf38cc0ad1c329b Mon Sep 17 00:00:00 2001 From: Til Date: Wed, 17 Jun 2026 08:14:51 +0200 Subject: [PATCH 589/598] fix search after list thumbs commit --- copyparty/web/browser.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index 8e6f375c..734812b0 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -2300,13 +2300,13 @@ function MPlayer() { r.cd_pause = 0; var re_audio = have_acode && mpl.ac_oth ? re_au_all : re_au_native, - trs = QSA('#files tbody tr'); + trs = QSA('#files tbody tr'), + links = QSA('#files tbody a[id]'); for (var a = 0, aa = trs.length; a < aa; a++) { - var tds = trs[a].getElementsByTagName('td'), - link = tds[3].getElementsByTagName('a'); + var tds = trs[a].getElementsByTagName('td'); + var link = links[a]; - link = link[link.length - 1]; var url = link.getAttribute('href'), fn = url.split('?')[0]; @@ -6514,7 +6514,7 @@ window.thegrid = (function () { var html = [], svgs = new Set(), max_svgs = CHROME ? 500 : 5000, - files = QSA('#files>tbody>tr>td:nth-child(3) a[id]'); + files = QSA('#files>tbody>tr>td a[id]'); for (var a = 0, aa = files.length; a < aa; a++) { var ao = files[a], From ab78858469affcd73e5bb4dad6faf2f6ffa2208f Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Wed, 17 Jun 2026 09:55:47 +0200 Subject: [PATCH 590/598] rework file list logic to work with class "flink" (file link) instead of fixed index --- copyparty/web/baguettebox.js | 7 +- copyparty/web/browser.css | 71 +++++++--- copyparty/web/browser.html | 2 +- copyparty/web/browser.js | 248 ++++++++++++++++++----------------- copyparty/web/shares.css | 2 +- copyparty/web/tl/chi.js | 2 +- copyparty/web/tl/cze.js | 2 +- copyparty/web/tl/deu.js | 2 +- copyparty/web/tl/epo.js | 2 +- copyparty/web/tl/fin.js | 2 +- copyparty/web/tl/fra.js | 2 +- copyparty/web/tl/grc.js | 2 +- copyparty/web/tl/hun.js | 2 +- copyparty/web/tl/ita.js | 2 +- copyparty/web/tl/jpn.js | 2 +- copyparty/web/tl/kor.js | 2 +- copyparty/web/tl/nld.js | 2 +- copyparty/web/tl/nor.js | 2 +- copyparty/web/tl/pol.js | 2 +- copyparty/web/tl/por.js | 2 +- copyparty/web/tl/rus.js | 2 +- copyparty/web/tl/spa.js | 2 +- copyparty/web/tl/swe.js | 2 +- copyparty/web/tl/tur.js | 2 +- copyparty/web/tl/ukr.js | 2 +- copyparty/web/tl/vie.js | 2 +- docs/changelog.md | 1 - scripts/tl.js | 2 +- 28 files changed, 213 insertions(+), 162 deletions(-) diff --git a/copyparty/web/baguettebox.js b/copyparty/web/baguettebox.js index e9ffdb70..48301a00 100644 --- a/copyparty/web/baguettebox.js +++ b/copyparty/web/baguettebox.js @@ -288,7 +288,7 @@ window.baguetteBox = (function () { var galleries = data[selector].galleries; [].forEach.call(galleries, function (gallery) { [].forEach.call(gallery, function (imageItem) { - //unbind(imageItem.imageElement, 'click', imageItem.eventHandler); + unbind(imageItem.imageElement, 'click', imageItem.eventHandler); }); if (currentGallery === gallery) @@ -742,7 +742,7 @@ window.baguetteBox = (function () { } function showOverlay(chosenImageIndex) { - clmod(ebi('ggrid'), 'waiting', true); + clmod(ebi('wrap'), 'waiting', true); if (options.noScrollbars) { var a = document.documentElement.style.overflowY, @@ -767,7 +767,7 @@ window.baguetteBox = (function () { loadImage(currentIndex, function () { preloadNext(currentIndex); preloadPrev(currentIndex); - clmod(ebi('ggrid'), 'waiting', false); + clmod(ebi('wrap'), 'waiting', false); }); show_buttons(0); @@ -796,7 +796,6 @@ window.baguetteBox = (function () { function hideOverlay(e, dtor) { ev(e); playvid(false); - removeFromCache('#files'); if (options.noScrollbars) { document.documentElement.style.overflowY = scrollCSS[0]; document.body.style.overflowY = scrollCSS[1]; diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 42d7047e..045dab03 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -522,6 +522,7 @@ html.dy #files tr.sel a.play { color: #fff; } html.dy tr.play td:nth-child(1) a { + color: #000; background: #fff; border: #000 solid 1px; } @@ -742,6 +743,7 @@ a:hover { color: var(--a-hil); background: var(--a-h-bg); } +#files .imgcontainer:hover, #files a:hover { color: var(--fg-max); background: color-mix(in oklab, var(--a) 20%, transparent); @@ -786,10 +788,6 @@ a.dir { color: #3584e4; color: var(--a); } -tr.dir td:nth-child(2) a::before { - content: "📁"; - margin: 0 .1em 0 -.2em; -} #files thead th { padding: .3em; background: var(--bg); @@ -844,7 +842,7 @@ html.y #files tr.fade a { border-radius: 0 5px 5px 0; border-radius: 0 var(--radius) var(--radius) 0; } -#files tbody td:nth-child(3) { +#files tbody td:nth-child(4) { font-family: 'scp', monospace, monospace; font-family: var(--font-mono), 'scp', monospace, monospace; text-align: right; @@ -1049,9 +1047,6 @@ tr td:nth-child(1) a { padding: .3em; margin: -.3em; } */ -tr.play td:nth-child(2) a::before { - content: "▶"; -} tr.play td:nth-child(1) a { background: var(--btn-1-bg); color:var(--btn-1-fg); @@ -1118,10 +1113,14 @@ tr.play td:nth-child(1) a { /* separate to allow IE to only use this rule */ display: block; } +#files .play .thumb, +#files .play img, #ggrid>a.play .thumb, #ggrid>a.play img { background: var(--bg-u2); } +.thumb, +.imgcontainer img, #ggrid>a .thumb, #ggrid>a img { color: #3584e4; @@ -1136,6 +1135,7 @@ tr.play td:nth-child(1) a { height: calc(var(--grid-sz) - 2.5em); object-fit: cover; } +.imgcontainer img, #ggrid>a img { position: absolute; opacity: 0; @@ -1170,6 +1170,10 @@ tr.play td:nth-child(1) a { padding: 4px 3px; justify-content: center; } +#files .imgcontainer img, +#files .imgcontainer { + border-radius: 0; +} .th_ext { z-index: 2; position: absolute; @@ -2197,7 +2201,7 @@ input.ssconf_v { margin: 0 .1em 0 0; } -#files td div span { +#files td div:not(.imgcontainer) span { color: var(--fg-max); padding: 0 .4em; font-weight: bold; @@ -2501,9 +2505,47 @@ html.b .btn { #files td.min { display: none; } -#files td:nth-child(2n) { +#files td:nth-child(3){ color: var(--tab-alt); } +#files td:has(.imgcontainer) { + padding: 0 1px; +} +#files .imgcontainer { + width: 2.3em; + height: 2.3em; + cursor: pointer; + margin: 0; + padding: 0; +} +#files .play .imgcontainer { + margin: -2px 0px; + padding: 2px; +} +#files .thumb, +#files img { + height: 100%; +} +#files tbody tr.sel span.th_ext span, +#files tbody tr.sel span.th_ext { + background: none; +} +#files .dir.thumbed img, +#files .dir .thumbed img { + position: absolute; + opacity: .6; +} +#files .dir.thumbed .thumb, +#files .dir .thumbed .thumb { + display: block !important; + z-index: 2; +} +#files .au .imgcontainer::after { + content: "▶"; + position: absolute; + z-index: 2; + top: .6em; +} #plazy { width: 1px; height: 1px; @@ -2542,7 +2584,6 @@ html.b .btn { padding: 0; } .disabled, -#thumbs, #au_prescan, #au_fullpre, #au_os_seek, @@ -2556,7 +2597,6 @@ html.b .btn { #up_quick.disabled { display: none; } -.setting:has(#griden.on)+.setting #thumbs, .setting:has(#au_preload.on)+.setting #au_prescan, .setting:has(#au_preload.on)+.setting #au_prescan, .setting:has(#au_preload.on)~.setting #au_fullpre, @@ -5237,7 +5277,8 @@ html.e #tree_footer { background: transparent; } html.e #wrap { - padding: 0; + padding-left: 0; + padding-right: 0; } html.e #pathBar { padding: 0; @@ -5584,8 +5625,8 @@ html.f #ggrid > a.sel:hover .imgcontainer::before { border-color: var(--g-fsel-bg) transparent transparent var(--g-fsel-bg); } /* #wrap:not(.thin) .ghead::after, */ -html.f .dir.thumbed .imgcontainer::before, -html.f .au.thumbed:not(.play) .imgcontainer::before { +html.f #ggrid .dir.thumbed .imgcontainer::before, +html.f #ggrid .au.thumbed:not(.play) .imgcontainer::before { content: ""; position: absolute; left: 0; diff --git a/copyparty/web/browser.html b/copyparty/web/browser.html index 0e40b23e..6eda8026 100644 --- a/copyparty/web/browser.html +++ b/copyparty/web/browser.html @@ -259,7 +259,7 @@ {%- for f in files %} {{ f.lead }} - {{ f.name|e }} + {{ f.name|e }} {{ f.sz }} {%- if f.tags is defined %} {%- for k in taglist %} diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index 425d08e3..63ee7d9e 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -282,7 +282,7 @@ if (1) "ct_grid": '田 the grid', "ct_ttips": '◔ ◡ ◔">ℹ️ tooltips', - "ct_thumb": 'in grid-view, toggle icons or thumbnails$NHotkey: T">🖼️ thumbs', + "ct_thumb": 'toggle icons or thumbnails$NHotkey: T">🖼️ thumbs', "ct_csel": 'use CTRL and SHIFT for file selection in grid-view">sel', "ct_dsel": 'use drag-selection in grid-view">dsel', "ct_den": 'use dragging to move files into other folders">mvd', @@ -1261,8 +1261,8 @@ ebi('op_cfg').innerHTML = ( '

      ✅ ' + L.cl_opts + '

      \n' + '
      \n' + ' ' + L.ct_grid + '\n' + ' ' + L.ct_grid + '\n' + ' td:nth-child(2)>a[id]"), + var files = QSA("#files .flink"), cover = null; for (var a = 0, aa = files.length; a < aa; a++) { @@ -2304,7 +2304,7 @@ function MPlayer() { for (var a = 0, aa = trs.length; a < aa; a++) { var tds = trs[a].getElementsByTagName('td'), - link = tds[1].getElementsByTagName('a'); + link = trs[a].querySelectorAll('.flink'); link = link[link.length - 1]; var url = link.getAttribute('href'), @@ -4245,16 +4245,13 @@ function eval_hash() { } if (mtype == 'g') { - if (!thegrid.en) - ebi('griden').click(); - var t = setInterval(function () { - if (!thegrid.bbox) + if (!msel.bbox || !msel.ready) return; clearInterval(t); baguetteBox.urltime(ts); - var im = QS('#ggrid a[ref="' + id + '"]'); + var im = ebi(id); if (!im) return toast.warn(10, L.im_hnf); @@ -5526,7 +5523,7 @@ var fileman = (function () { f = [], indir = [], srcdir = vsplit(r.clip[0])[0], - links = QSA('#files tbody td:nth-child(2) a'); + links = QSA('#files .flink'); r.f = f; @@ -6517,88 +6514,21 @@ window.thegrid = (function () { var html = [], svgs = new Set(), max_svgs = CHROME ? 500 : 5000, - need_ext = !r.thumbs || !!ext_th, - use_ext_th = r.thumbs && ext_th, - files = QSA('#files>tbody>tr>td:nth-child(2) a[id]'); + files = QSA('#files .flink'); for (var a = 0, aa = files.length; a < aa; a++) { var ao = files[a], ohref = esc(ao.getAttribute('href')), href = ohref.split('?')[0], - ext = '', - ext0 = '', name = uricom_dec(vsplit(href)[1]), ref = ao.getAttribute('id'), isdir = clgot(ao.parentElement.parentElement, 'dir'), - ac = ao.parentElement.parentElement.classList, - ihref = ohref; - - if (need_ext && href != "#") { - var ar = href.split('.'); - if (ar.length > 1) - ar.shift(); - - ar.reverse(); - ext0 = ar[0]; - for (var b = 0; b < Math.min(2, ar.length); b++) { - ext = ext ? (ar[b] + '.' + ext) : ar[b]; - if (ar[b].length > 2) - break; - } - if (!ext) - ext = 'unk'; - } - - if (use_ext_th && (ext_th[ext] || ext_th[ext0])) { - ihref = ext_th[ext] || ext_th[ext0]; - } - else if (r.thumbs) { - ihref = addq(ihref, 'th=' + ( - have_jxl ? 'x' : - have_webp ? 'w' : - 'j' - )); - if (!r.crop) - ihref += 'f'; - if (r.x3) - ihref += '3'; - if (href == "#") - ihref = SR + '/.cpr/ico/' + (ref == 'moar' ? '++' : 'exit'); - } - else { - ihref = ''; - } - - if(ihref){ - ihref = addq(ihref, 'cache=i&_=' + ACB + TS); - - var accent = getComputedStyle(document.body).getPropertyValue('--a'); - if (!accent) - accent = '#07c'; - ihref += '&a=' + parseColor(accent).replace(/ /g, ''); - } - - var svg = ''; - svg = '' + svg + ''; - - if (N3DS){ - // 3DS / unsupported: use fallback - svg = '' + (isdir ? '📁[FOLDER]' : '📄[FILE:' + ext + ']') + ''; - ext = 'unk'; - } + ac = ao.parentElement.parentElement.classList; html.push('' + - '
      ' + - '' + - svg + - (isdir || ext == 'unk' || ext.startsWith('/') ? '' : - '' + ext + '') + - '
      ' + ao.innerHTML + '
      '); + '" class="flink ' + ac + '" ttt="' + esc(name) + '">' + + get_thumb(ohref, ref, isdir, true) + + '' + ao.innerHTML + ''); } ggrid.innerHTML = html.join('\n'); clmod(ggrid, 'crop', r.crop); @@ -6704,7 +6634,10 @@ window.thegrid = (function () { swrite('thumbs', 1); } - bcfg_bind(r, 'thumbs', 'thumbs', true, r.setdirty); + bcfg_bind(r, 'thumbs', 'thumbs', true, function(e){ + r.setdirty(); + msel.render(); + }); bcfg_bind(r, 'ihop', 'ihop', true); bcfg_bind(r, 'vau', 'gridvau', false); bcfg_bind(r, 'crop', 'gridcrop', !dcrop.endsWith('n'), r.set_crop); @@ -6757,6 +6690,85 @@ window.thegrid = (function () { return r; })(); +function get_thumb(ohref, ref, isdir, grid){ + var href = ohref.split('?')[0], + ext = '', + ext0 = '', + name = uricom_dec(vsplit(href)[1]), + need_ext = !thegrid.thumbs || !!ext_th, + use_ext_th = thegrid.thumbs && ext_th, + ihref = ohref; + + if (need_ext && href != "#") { + var ar = href.split('.'); + if (ar.length > 1) + ar.shift(); + + ar.reverse(); + ext0 = ar[0]; + for (var b = 0; b < Math.min(2, ar.length); b++) { + ext = ext ? (ar[b] + '.' + ext) : ar[b]; + if (ar[b].length > 2) + break; + } + if (!ext) + ext = 'unk'; + } + + if (use_ext_th && (ext_th[ext] || ext_th[ext0])) { + ihref = ext_th[ext] || ext_th[ext0]; + } + else if (thegrid.thumbs) { + ihref = addq(ihref, 'th=' + ( + have_jxl ? 'x' : + have_webp ? 'w' : + 'j' + )); + if (grid && !thegrid.crop) + ihref += 'f'; + if (grid && thegrid.x3) + ihref += '3'; + if (href == "#") + ihref = SR + '/.cpr/ico/' + (ref == 'moar' ? '++' : 'exit'); + } + else { + ihref = ''; + } + + if(ihref){ + ihref = addq(ihref, 'cache=i&_=' + ACB + TS); + + var accent = getComputedStyle(document.body).getPropertyValue('--a'); + if (!accent) + accent = '#07c'; + ihref += '&a=' + parseColor(accent).replace(/ /g, ''); + } + + var svg = ''; + svg = '' + svg + ''; + + if (N3DS){ + // 3DS / unsupported: use fallback + svg = '' + (isdir ? '📁[FOLDER]' : '📄[FILE:' + ext + ']') + ''; + ext = 'unk'; + } + + var container = '
      ' + + (grid ? '' : '') + + svg + + (isdir || ext == 'unk' || ext.startsWith('/') ? '' : + '' + ext + '') + + '
      ' + return container; +} + function th_onload(el) { set_loaded(el, true, false) } @@ -8628,8 +8640,9 @@ var treectl = (function () { '" hl="' + id + '" name="' + hname + '">-txt-'; var cl = (/\.PARTIAL$/.exec(fname) ? 'fade ' : '') + (img_re.exec(fname) ? 'img ' : '') + (tn.cls || ''), - ln = ['' + tn.lead + '' + hname + + ln = ['' + tn.lead + '' + + get_thumb(tn.href, id, (/\bdir\b/i).test(cl), false) + + '' + hname + '' + filesizefun(tn.sz)]; for (var b = 0; b < res.taglist.length; b++) { @@ -8736,7 +8749,7 @@ var treectl = (function () { var media = scan_hash(location.hash); if(media && media[0] == 'g') - clmod(ebi('ggrid'), 'waiting', true); + clmod(ebi('wrap'), 'waiting', true); setTimeout(eval_hash, 1); }; @@ -9140,7 +9153,7 @@ function wait_set_fsearch(){ function tr2id(tr) { try { - return tr.cells[1].querySelector('a[id]').getAttribute('id'); + return tr.querySelector('.flink').getAttribute('id'); } catch (ex) { return null; @@ -9173,6 +9186,7 @@ function mk_files_header(taglist) { var html = [ '', '!', + 'th', 'File Name', 'Size' ]; @@ -9724,7 +9738,7 @@ var msel = (function () { } r.all = []; - var links = QSA('#files tbody td:nth-child(2) a:last-child'), + var links = QSA('#files .flink'), is_srch = !!ebi('unsearch'), vbase = get_evpath(); @@ -9910,16 +9924,25 @@ var msel = (function () { dl_file(sel[a].vp + sel[a].q); }; r.render = function () { - var tds = QSA('#files tbody td+td+td'), + var tds = QSA('#files tbody td+td+td+td'), is_srch = !!ebi('unsearch'); for (var a = 0, aa = tds.length; a < aa; a++) tds[a].onclick = r.seltgl; - var links = QSA('#files a[id]') + var links = QSA('#files .flink') for (var a = 0, aa = links.length; a < aa; a++) links[a].onclick = fclick; + var thumbs = QSA('#files .imgcontainer') + for (var a = 0, aa = thumbs.length; a < aa; a++) + thumbs[a].onclick = fclick1; + + var imgs = QSA('#files img'); + for (var a = 0, aa = imgs.length; a < aa; a++) { + set_loaded(imgs[a], thegrid.thumbs && imgs[a].complete, true); + } + if(window.baguetteBox != undefined) r.bagit(); @@ -9930,6 +9953,8 @@ var msel = (function () { var zipvis = (is_srch || !have_zip) ? 'none' : ''; ebi('selzip').style.display = zipvis; ebi('zip1').style.display = zipvis; + + r.ready = true; } r.bagit = function (isrc) { @@ -9956,30 +9981,23 @@ var msel = (function () { }, onChange: function (i, maxIdx) { if (this[i].imageElement) { - sethash('g' + this[i].imageElement.getAttribute('ref') + getsort()); + sethash('g' + this[i].imageElement.getAttribute('id') + getsort()); } } }); r.bbox_opts = br[1]; r.bbox = true; - eval_hash() }; - if(window.baguetteBox != undefined) - r.bagit(); - return r; })(); function fclick1(e) { - if (ctrl(e) && !treectl.csel && !r.sel && !r.tempsel) - return true; - e.preventDefault ? e.preventDefault() : e.returnValue = false; // pass copy of click event to list entry (can trigger bbox handler) - var link = ebi(this.getAttribute('ref')); - link.dispatchEvent(new MouseEvent('click', { + var td = ebi(this.getAttribute('ref')); + td.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, clientX: e.clientX, @@ -9996,27 +10014,21 @@ function fclick(e, dbl) { ev(e); return; } - var isInGrid = this.hasAttribute('ref'), - link = this; - if(isInGrid){ - // get table row with file link - link = ebi(this.getAttribute('ref')) - } - var qhref = link.getAttribute('href'), + var qhref = this.getAttribute('href'), href = qhref.split('?')[0], - fid = link.getAttribute('id'), + fid = this.getAttribute('id'), aplay = ebi('a' + fid), atext = ebi('t' + fid), is_txt = atext && !/\.ts$/.test(href) && showfile.getlang(href), is_img = img_re.test(href), is_dir = href.endsWith('/'), is_srch = !!ebi('unsearch'), - in_tree = is_dir && treectl.find(link.textContent.slice(0, -1)), + in_tree = is_dir && treectl.find(this.textContent.slice(0, -1)), have_sel = QS('#files tr.sel'), - td = link.closest('td').nextSibling, + td = this.closest('td').nextSibling, tr = td.parentNode; - if ( thegrid.en && (thegrid.sel || thegrid.tempsel) && !dbl && !ctrl(e) || treectl.csel && (e.shiftKey || ctrl(e))) { + if (thegrid.en && (thegrid.sel || thegrid.tempsel) && !dbl && !ctrl(e) || treectl.csel && (e.shiftKey || ctrl(e))) { ev(e); msel.seltgl.call(td, e); if (e.shiftKey) @@ -10026,10 +10038,10 @@ function fclick(e, dbl) { else if (in_tree) in_tree.click(); - else if (link.hasAttribute('download')) - link.click(); + else if (this.hasAttribute('download')) + this.click(); - else if (thegrid.en && aplay && (thegrid.vau || !is_img)) + else if (aplay && (thegrid.vau || !is_img)) aplay.click(); else if (is_dir) @@ -10049,7 +10061,7 @@ function fclick(e, dbl) { thegrid.sel = true; }, 1); thegrid.sel = false; - link.click(); + this.click(); } ev(e); } @@ -10936,7 +10948,7 @@ var rcm = (function () { var ref = ebi(target.getAttribute('ref')); file = ref && ref.closest('#files tbody tr'); } - var fa = file && file.children[1].querySelector('a[id]'); + var fa = file && file.querySelector('.flink'); if (fa && fa.id != 'unsearch') { selFile.no_dsel = TOUCH || clgot(file, "sel"); clmod(file, "sel", true); @@ -11071,7 +11083,7 @@ var drag = (function() { elem.ondragenter = elem.ondragleave = elem.ondragover = function(e) { if (!r.enabled) return; - var elemHref = basenames((elem.tagName == "A" ? elem : elem.querySelector("td:nth-child(2) a")).href.split("?")[0]) + var elemHref = basenames((elem.tagName == "A" ? elem : elem.querySelector(".flink")).href.split("?")[0]) if (current == elem || elemHref == get_evpath() || currLink == elemHref) // Prevent folders being dragged into themselves return; ev(e); @@ -11110,7 +11122,7 @@ var drag = (function() { f.draggable = true; f.ondragstart = function(e) { try{ - currLink = basenames(e.target.querySelector("td:nth-child(2) a").href.split("?")); + currLink = basenames(e.target.querySelector(".flink").href.split("?")); current = e.target; r.no_warn = true; diff --git a/copyparty/web/shares.css b/copyparty/web/shares.css index 0a69260d..755ac2df 100644 --- a/copyparty/web/shares.css +++ b/copyparty/web/shares.css @@ -61,7 +61,7 @@ th { vertical-align: top; white-space: nowrap; } -#wrap td+td+td+td+td+td+td+td { +#wrap td+td+td+td+td+td+td+td+td { font-family: var(--font-mono), monospace, monospace; } #wrap th:first-child, diff --git a/copyparty/web/tl/chi.js b/copyparty/web/tl/chi.js index 6298f8ea..426a97cd 100644 --- a/copyparty/web/tl/chi.js +++ b/copyparty/web/tl/chi.js @@ -225,7 +225,7 @@ Ls.chi = { "ct_grid": '田 网格', "ct_ttips": '◔ ◡ ◔">ℹ️ 提示', - "ct_thumb": '在网格视图中,切换图标或缩略图$N快捷键: T">🖼️ 缩略', + "ct_thumb": '切换图标或缩略图$N快捷键: T">🖼️ 缩略', "ct_csel": '在网格视图中,允许使用 CTRL 和 SHIFT 进行文件选择">选择', "ct_dsel": '在网格视图中,允许拖动选择">拖选', "ct_dl": '点击文件时强制下载(不要就地显示)">下载', diff --git a/copyparty/web/tl/cze.js b/copyparty/web/tl/cze.js index cd94c269..095113a5 100644 --- a/copyparty/web/tl/cze.js +++ b/copyparty/web/tl/cze.js @@ -229,7 +229,7 @@ Ls.cze = { "ct_grid": '田 mřížka', "ct_ttips": '◔ ◡ ◔">ℹ️ nápovědy', - "ct_thumb": 'v zobrazení mřížky přepnout ikony nebo náhledy$NKlávesová zkratka: T">🖼️ náhledy', + "ct_thumb": 'přepnout ikony nebo náhledy$NKlávesová zkratka: T">🖼️ náhledy', "ct_csel": 'použít CTRL a SHIFT pro výběr souborů v zobrazení mřížky">výběr', "ct_dsel": 'použít tažený výběr v zobrazení mřížky">tažení', //m "ct_dl": 'vynutit stažení (nezobrazovat inline) při kliknutí na soubor">dl', //m diff --git a/copyparty/web/tl/deu.js b/copyparty/web/tl/deu.js index 00ccf05f..ffe6ccda 100644 --- a/copyparty/web/tl/deu.js +++ b/copyparty/web/tl/deu.js @@ -225,7 +225,7 @@ Ls.deu = { "ct_grid": '田 Das Raster™', "ct_ttips": '◔ ◡ ◔">ℹ️ Tooltips', - "ct_thumb": 'In Raster-Ansicht, zwischen Icons und Vorschau wechseln$NHotkey: T">🖼️ Vorschaubilder', + "ct_thumb": 'Zwischen Icons und Vorschau wechseln$NHotkey: T">🖼️ Vorschaubilder', "ct_csel": 'Benutze STRG und UMSCHALT für Dateiauswahl in Raster-Ansicht">sel', "ct_dsel": 'Ziehauswahl in Raster-Ansicht verwenden">ziehen', //m "ct_dl": 'Beim Klick auf Dateien sie immer herunterladen (nicht einbetten)">dl', diff --git a/copyparty/web/tl/epo.js b/copyparty/web/tl/epo.js index 1828ab96..962b2be3 100644 --- a/copyparty/web/tl/epo.js +++ b/copyparty/web/tl/epo.js @@ -225,7 +225,7 @@ Ls.epo = { "ct_grid": '田 krado', "ct_ttips": '◔ ◡ ◔">ℹ️ ŝpruchelpiloj', - "ct_thumb": 'dum krado-vido, baskuli montradon de simboloj aŭ bildetoj$NFulmoklavo: T">🖼️ bildetoj', + "ct_thumb": 'baskuli montradon de simboloj aŭ bildetoj$NFulmoklavo: T">🖼️ bildetoj', "ct_csel": 'uzi STIR kaj MAJ por elekti dosierojn en krado-vido">elekto', "ct_dsel": 'uzi tren-elekton en krado-vido">treni', "ct_dl": 'devigi elŝuton (ne montri enkadre), kiam dosiero estas alklakita">elŝuti', diff --git a/copyparty/web/tl/fin.js b/copyparty/web/tl/fin.js index 3d5d074b..2e973d4b 100644 --- a/copyparty/web/tl/fin.js +++ b/copyparty/web/tl/fin.js @@ -225,7 +225,7 @@ Ls.fin = { "ct_grid": '田 kuvanäkymä', "ct_ttips": '◔ ◡ ◔">ℹ️ vihjelaatikot', - "ct_thumb": 'valitse kuvakkeiden / pienoiskuvien välillä kuvanäkymässä $NPikanäppäin: T">🖼️ pienoiskuvat', + "ct_thumb": 'valitse kuvakkeiden / pienoiskuvien välillä $NPikanäppäin: T">🖼️ pienoiskuvat', "ct_csel": 'käytä CTRL ja SHIFT tiedostojen valintaan kuvanäkymässä">valitse', "ct_dsel": 'käytä aluevalintaa tiedostojen valintaan kuvanäkymässä">aluevalinta', "ct_dl": 'pakota lataus (älä näytä upotettuna), kun tiedostoa klikataan">dl', diff --git a/copyparty/web/tl/fra.js b/copyparty/web/tl/fra.js index bdb05b46..04a323f7 100644 --- a/copyparty/web/tl/fra.js +++ b/copyparty/web/tl/fra.js @@ -225,7 +225,7 @@ Ls.fra = { "ct_grid": '田 grille', "ct_ttips": '◔ ◡ ◔">ℹ️ infobulles', - "ct_thumb": 'vue en grille, activer les icônes ou les miniatures$NHotkey: T">🖼️ minia', + "ct_thumb": 'activer les icônes ou les miniatures$NHotkey: T">🖼️ minia', "ct_csel": 'utiliser CTRL et MAJ pour selectioner des fichiers en vue en grille">sel', "ct_dsel": 'utiliser la sélection par glisser en vue en grille">glisser', //m "ct_dl": 'forcer le téléchargement (ne pas afficher en ligne) lorsqu’un fichier est cliqué">dl', //m diff --git a/copyparty/web/tl/grc.js b/copyparty/web/tl/grc.js index 7000176c..79e26e66 100644 --- a/copyparty/web/tl/grc.js +++ b/copyparty/web/tl/grc.js @@ -225,7 +225,7 @@ Ls.grc = { "ct_grid": '田 το πλέγμα', "ct_ttips": '◔ ◡ ◔">ℹ️ συμβουλές εργαλείων', - "ct_thumb": 'σε προβολή πλέγματος, εναλλαγή εικονιδίων ή μικρογραφιών$NΠλήκτρο συντόμευσης: T">🖼️ μικρογραφίες', + "ct_thumb": 'εναλλαγή εικονιδίων ή μικρογραφιών$NΠλήκτρο συντόμευσης: T">🖼️ μικρογραφίες', "ct_csel": 'χρησιμοποίησε CTRL και SHIFT για επιλογή αρχείων σε προβολή πλέγματος">επιλογή', "ct_dsel": 'χρησιμοποίησε επιλογή με σύρσιμο σε προβολή πλέγματος">σύρσιμο', //m "ct_dl": 'εξαναγκασμός λήψης (να μην εμφανίζεται ενσωματωμένα) όταν γίνεται κλικ σε ένα αρχείο">dl', //m diff --git a/copyparty/web/tl/hun.js b/copyparty/web/tl/hun.js index b9404c82..9f2ada68 100644 --- a/copyparty/web/tl/hun.js +++ b/copyparty/web/tl/hun.js @@ -226,7 +226,7 @@ Ls.hun = { "ct_grid": '田 rács nézet', "ct_ttips": '◔ ◡ ◔">ℹ️ segítő szövegek', - "ct_thumb": 'rács nézetben ikonok/indexképek váltása$Ngyorsbillentyű: T">🖼️ képek', + "ct_thumb": 'ikonok/indexképek váltása$Ngyorsbillentyű: T">🖼️ képek', "ct_csel": 'kijelölés CTRL és SHIFT gombokkal rács nézetben">kijelölés', "ct_dsel": 'kijelölés egérhúzással rács nézetben">húzás', "ct_dl": 'azonnali letöltés (beágyazás helyett)">letöltés', diff --git a/copyparty/web/tl/ita.js b/copyparty/web/tl/ita.js index 86639777..88266276 100644 --- a/copyparty/web/tl/ita.js +++ b/copyparty/web/tl/ita.js @@ -225,7 +225,7 @@ Ls.ita = { "ct_grid": '田 griglia', "ct_ttips": '◔ ◡ ◔">ℹ️ tooltip', - "ct_thumb": 'nella vista griglia, alterna icone o miniature$NTasto rapido: T">🖼️ miniature', + "ct_thumb": 'alterna icone o miniature$NTasto rapido: T">🖼️ miniature', "ct_csel": 'usa CTRL e SHIFT per la selezione file nella vista griglia">sel', "ct_dsel": 'usa la selezione tramite trascinamento nella vista griglia">trascina', //m "ct_dl": 'forza il download (non visualizzare inline) quando si clicca su un file">dl', //m diff --git a/copyparty/web/tl/jpn.js b/copyparty/web/tl/jpn.js index 5d616c33..d3305679 100644 --- a/copyparty/web/tl/jpn.js +++ b/copyparty/web/tl/jpn.js @@ -225,7 +225,7 @@ Ls.jpn = { "ct_grid": '田 グリッド', "ct_ttips": '◔ ◡ ◔">ℹ️ ツールチップ', - "ct_thumb": 'グリッドビューではアイコンまたはサムネイルを切り替える$Nホットキー: T">🖼️ サムネイル', + "ct_thumb": 'アイコンまたはサムネイルを切り替える$Nホットキー: T">🖼️ サムネイル', "ct_csel": 'グリッドビューでファイルを選択するにはCtrlとShiftを使用する。">選択', "ct_dsel": 'グリッドビューでドラッグ選択を使用する。">ドラッグ', //m "ct_dl": 'ファイルをクリックしたときに強制的にダウンロードする(インラインで表示しない)">dl', diff --git a/copyparty/web/tl/kor.js b/copyparty/web/tl/kor.js index cfc1f510..b1a8eb4f 100644 --- a/copyparty/web/tl/kor.js +++ b/copyparty/web/tl/kor.js @@ -225,7 +225,7 @@ Ls.kor = { "ct_grid": "田 그리드", "ct_ttips": '◔ ◡ ◔">ℹ️ 도움말', - "ct_thumb": '그리드 보기에서 아이콘 또는 미리보기 이미지 전환$N단축키: T">🖼️ 미리보기', + "ct_thumb": '아이콘 또는 미리보기 이미지 전환$N단축키: T">🖼️ 미리보기', "ct_csel": '그리드 보기에서 CTRL과 SHIFT를 사용하여 파일 선택">선택', "ct_dsel": '그리드 보기에서 드래그 선택 사용">드래그', //m "ct_dl": '파일을 클릭하면 다운로드를 강제로 수행 (인라인으로 표시하지 않음)">dl', //m diff --git a/copyparty/web/tl/nld.js b/copyparty/web/tl/nld.js index 0a6d1186..9f9197d7 100644 --- a/copyparty/web/tl/nld.js +++ b/copyparty/web/tl/nld.js @@ -225,7 +225,7 @@ Ls.nld = { "ct_grid": '田 grid', "ct_ttips": '◔ ◡ ◔">ℹ️ tooltips', - "ct_thumb": 'In grid-overzicht, wissel tussen iconen of thumbnails$NHotkey: T">🖼️ thumbs', + "ct_thumb": 'wissel tussen iconen of thumbnails$NHotkey: T">🖼️ thumbs', "ct_csel": 'Gebruik CTRL en SHIFT voor de bestand selectie in grid-overzicht>sel', "ct_dsel": 'Gebruik slepen om te selecteren in grid-overzicht>slepen', //m "ct_dl": 'download afdwingen (niet inline weergeven) wanneer op een bestand wordt geklikt">dl', //m diff --git a/copyparty/web/tl/nor.js b/copyparty/web/tl/nor.js index c550de47..7dd25ea8 100644 --- a/copyparty/web/tl/nor.js +++ b/copyparty/web/tl/nor.js @@ -222,7 +222,7 @@ Ls.nor = { "ct_grid": '田 ikoner', "ct_ttips": 'vis hjelpetekst ved å holde musen over ting">ℹ️ tips', - "ct_thumb": 'vis miniatyrbilder istedenfor ikoner$NSnarvei: T">🖼️ bilder', + "ct_thumb": 'vis miniatyrbilder isteden for ikoner$NSnarvei: T">🖼️ bilder', "ct_csel": 'bruk tastene CTRL og SHIFT for markering av filer i ikonvisning">merk', "ct_dsel": 'marker filer med klikk-og-dra i ikonvisning">dsel', "ct_dl": 'last ned filer (ikke vis i nettleseren)">dl', diff --git a/copyparty/web/tl/pol.js b/copyparty/web/tl/pol.js index 949a0640..4725bb1e 100644 --- a/copyparty/web/tl/pol.js +++ b/copyparty/web/tl/pol.js @@ -228,7 +228,7 @@ Ls.pol = { "ct_grid": '田 siatka', "ct_ttips": '◔ ◡ ◔">ℹ️ podpowiedzi', - "ct_thumb": 'w widoku siatki, przełącz ikony i miniaturki$NSkrót: T">🖼️ miniaturki', + "ct_thumb": 'przełącz ikony i miniaturki$NSkrót: T">🖼️ miniaturki', "ct_csel": 'użyj CTRL i SHIFT do wybierania plików w widoku siatki">wybierz', "ct_dsel": 'użyj zaznaczania przez przeciąganie w widoku siatki">przeciągnij', //m "ct_dl": 'wymuś pobieranie (nie wyświetlaj inline) po kliknięciu pliku">dl', //m diff --git a/copyparty/web/tl/por.js b/copyparty/web/tl/por.js index 99515fff..a061318b 100644 --- a/copyparty/web/tl/por.js +++ b/copyparty/web/tl/por.js @@ -225,7 +225,7 @@ Ls.por = { "ct_grid": '田 a grade', "ct_ttips": '◔ ◡ ◔">ℹ️ dicas de ferramentas', - "ct_thumb": 'na visualização de grade, alternar entre ícones ou miniaturas$NHotkey: T">🖼️ miniaturas', + "ct_thumb": 'alternar entre ícones ou miniaturas$NHotkey: T">🖼️ miniaturas', "ct_csel": 'usar CTRL e SHIFT para seleção de arquivo na visualização de grade">sel', "ct_dsel": 'usar seleção por arrasto na visualização de grade">arrastar', "ct_dl": 'forçar download (não exibir na página) ao clicar em um arquivo">dl', diff --git a/copyparty/web/tl/rus.js b/copyparty/web/tl/rus.js index d59aeaa1..3768899a 100644 --- a/copyparty/web/tl/rus.js +++ b/copyparty/web/tl/rus.js @@ -225,7 +225,7 @@ Ls.rus = { "ct_grid": '田 сетка', "ct_ttips": '◔ ◡ ◔">ℹ️ подсказки', - "ct_thumb": 'переключение между иконками и миниатюрами в режиме сетки$NГорячая клавиша: T">🖼️ миниат.', + "ct_thumb": 'переключение между иконками и миниатюрами$NГорячая клавиша: T">🖼️ миниат.', "ct_csel": 'держите CTRL или SHIFT для выделения файлов в режиме сетки">выбор', "ct_dsel": 'использовать выделение перетаскиванием в режиме сетки">перетащить', //m "ct_dl": 'принудительная загрузка (не показывать встроенно) при щелчке по файлу">dl', //m diff --git a/copyparty/web/tl/spa.js b/copyparty/web/tl/spa.js index 8590b675..182cff33 100644 --- a/copyparty/web/tl/spa.js +++ b/copyparty/web/tl/spa.js @@ -224,7 +224,7 @@ Ls.spa = { "ct_grid": '田 cuadrícula', "ct_ttips": '◔ ◡ ◔">ℹ️ tooltips', - "ct_thumb": 'en vista de cuadrícula, alternar iconos o miniaturas$NAtajo: T">🖼️ miniaturas', + "ct_thumb": 'alternar iconos o miniaturas$NAtajo: T">🖼️ miniaturas', "ct_csel": 'usa CTRL y SHIFT para seleccionar archivos en la vista de cuadrícula">sel', "ct_dsel": 'usa la selección por arrastre en la vista de cuadrícula">arrastrar', //m "ct_dl": 'forzar descarga (no mostrar en línea) al hacer clic en un archivo">dl', //m diff --git a/copyparty/web/tl/swe.js b/copyparty/web/tl/swe.js index 0b2fcfd1..4b96e2d0 100644 --- a/copyparty/web/tl/swe.js +++ b/copyparty/web/tl/swe.js @@ -225,7 +225,7 @@ Ls.swe = { "ct_grid": '田 rutnätet', "ct_ttips": '◔ ◡ ◔">ℹ️ tips', - "ct_thumb": 'växla mellan miniatyrer och ikoner i rutnätsvyn$NSnabbtangent: T">🖼️ miniatyrer', + "ct_thumb": 'växla mellan miniatyrer och ikoner$NSnabbtangent: T">🖼️ miniatyrer', "ct_csel": 'använd CTRL och SKIFT för urval av filer i rutnätsvyn">val', "ct_dsel": 'använd dra-urval i rutnätsvyn">dra', //m "ct_dl": 'tvinga nedladdning (visa inte inline) när en fil klickas">dl', //m diff --git a/copyparty/web/tl/tur.js b/copyparty/web/tl/tur.js index 7fc3d468..4c7723f0 100644 --- a/copyparty/web/tl/tur.js +++ b/copyparty/web/tl/tur.js @@ -225,7 +225,7 @@ Ls.tur = { "ct_grid": '田 ızgara', "ct_ttips": '◔ ◡ ◔">ℹ️ ipuçları', - "ct_thumb": 'ızgara görünümünde, simgeler ve küçük resimler arasında geçiş yapın$NKısayol: T">🖼️ küçük resimler', + "ct_thumb": 'simgeler ve küçük resimler arasında geçiş yapın$NKısayol: T">🖼️ küçük resimler', "ct_csel": 'ızgara görünümünde dosya seçimi için CTRL ve SHIFT tuşlarını kullanın">seç', "ct_dsel": 'ızgara görünümünde sürükleyerek seçimi kullanın">sürükle', //m "ct_dl": 'dosyaya tıklandığında indirmeyi zorla (satır içinde görüntüleme)">dl', //m diff --git a/copyparty/web/tl/ukr.js b/copyparty/web/tl/ukr.js index 4ca0cdec..4b0fc1a1 100644 --- a/copyparty/web/tl/ukr.js +++ b/copyparty/web/tl/ukr.js @@ -225,7 +225,7 @@ Ls.ukr = { "ct_grid": '田 сітка', "ct_ttips": '◔ ◡ ◔">ℹ️ підказки', - "ct_thumb": 'у режимі сітки, перемкнути іконки або мініатюри$NГаряча клавіша: T">🖼️ мініатюри', + "ct_thumb": 'перемкнути іконки або мініатюри$NГаряча клавіша: T">🖼️ мініатюри', "ct_csel": 'використовувати CTRL і SHIFT для вибору файлів у режимі сітки">вибір', "ct_dsel": 'використовувати вибір перетягуванням у режимі сітки">перетягнути', //m "ct_dl": 'примусове завантаження (не показувати вбудовано) під час натискання на файл">dl', //m diff --git a/copyparty/web/tl/vie.js b/copyparty/web/tl/vie.js index 476fbcda..f6575e0b 100644 --- a/copyparty/web/tl/vie.js +++ b/copyparty/web/tl/vie.js @@ -226,7 +226,7 @@ Ls.vie = { // settings / tuỳ chọn "ct_grid": '田 chế độ lưới', "ct_ttips": '༼ ◕_◕ ༽">ℹ️ tooltips', - "ct_thumb": 'ở chế độ lưới, chuyển biểu tượng hoặc hình thu nhỏ$NPhím tắt: T">🖼️ ảnh thu nhỏ', + "ct_thumb": 'chuyển biểu tượng hoặc hình thu nhỏ$NPhím tắt: T">🖼️ ảnh thu nhỏ', "ct_csel": 'dùng CTRL và SHIFT để chọn tệp trong chế độ lưới">sel', "ct_dsel": 'dùng chọn bằng cách kéo trong chế độ lưới">kéo', //m "ct_dl": 'cưỡng chế tải xuống (không hiện thị trong dòng) khi nhấp vào tệp">dl', diff --git a/docs/changelog.md b/docs/changelog.md index f9da092d..4ceeaa29 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -62,7 +62,6 @@ * more consistent areas for clicking to navigate left / right in the image viewer (they don't depend on image fill mode anymore) * "folder up" / "next sibling" / "previous sibling" are now icon buttons at the top * new look for the login screen -* file list makes it easier to identify folders via an added folder emoji to folder names. to disable this, add the following style: `tr:has(a.dir) td:nth-child(2) a::before { display: none; }` * pm-monokai theme has become "flat dark" ## 🌠 fun facts diff --git a/scripts/tl.js b/scripts/tl.js index 06013c0a..f78faf4b 100644 --- a/scripts/tl.js +++ b/scripts/tl.js @@ -256,7 +256,7 @@ Ls.hmn = { "ct_grid": '田 the grid', "ct_ttips": '◔ ◡ ◔">ℹ️ tooltips', - "ct_thumb": 'in grid-view, toggle icons or thumbnails$NHotkey: T">🖼️ thumbs', + "ct_thumb": 'toggle icons or thumbnails$NHotkey: T">🖼️ thumbs', "ct_csel": 'use CTRL and SHIFT for file selection in grid-view">sel', "ct_dsel": 'use drag-selection in grid-view">dsel', "ct_dl": 'force download (don\'t display inline) when a file is clicked">dl', From 6b513bf65fa1db68614e026cc5e82cbfdb21f8bb Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Wed, 17 Jun 2026 11:31:44 +0200 Subject: [PATCH 591/598] fix for grid mode search after ab78858469affcd73e5bb4dad6faf2f6ffa2208f broke it --- copyparty/web/browser.js | 6 +++--- copyparty/web/util.js | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index 63ee7d9e..d4af1ca7 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -7574,7 +7574,7 @@ var search_ui = (function () { var html = mk_files_header(tagord), seen = {}; html.push(''); - html.push('-[❌] ' + L.sl_close + ' -- ' + L.sl_hits.format(res.hits.length) + (res.trunc ? ' -- ' + L.sl_moar + '' : '') + ''); + html.push('-[❌] ' + L.sl_close + ' -- ' + L.sl_hits.format(res.hits.length) + (res.trunc ? ' -- ' + L.sl_moar + '' : '') + ''); for (var a = 0; a < res.hits.length; a++) { var r = res.hits[a], @@ -7592,8 +7592,8 @@ var search_ui = (function () { if (ext.length > 8) ext = '%'; - var links = linksplit(r.rp + '', null, id).join('/'), - nodes = ['-
      ' + links + + var links = linksplit(r.rp + '', null, id, true).join('/'), + nodes = ['-
      ' + links + '
      ' + hsz]; for (var b = 0; b < tagord.length; b++) { diff --git a/copyparty/web/util.js b/copyparty/web/util.js index 2bd9f8d0..2c7c7a71 100644 --- a/copyparty/web/util.js +++ b/copyparty/web/util.js @@ -779,7 +779,7 @@ function assert_vp(path) { } -function linksplit(rp, base, id) { +function linksplit(rp, base, id, flink) { var ret = [], apath = base || '/', q = null; @@ -816,7 +816,7 @@ function linksplit(rp, base, id) { link += '" id="' + id; } - ret.push('' + vlink + ''); + ret.push('' + vlink + ''); apath += link; } return ret; From 948426168ec3959f016d06fd29d9d6b4453b1696 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Wed, 17 Jun 2026 13:23:41 +0200 Subject: [PATCH 592/598] fix default border radius setting --- copyparty/web/browser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index d4af1ca7..10b1cb27 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -1529,7 +1529,7 @@ ebi('radius').oninput = function () { var usefallback = isNaN(r) || r < 0 || r === ''; var setV = usefallback ? '' : (r + 'px'); - swrite('radius', !usefallback && r); + swrite('radius', !usefallback ? r : ''); document.documentElement.style.setProperty('--radius', setV); console.log(setV); } From 87b0888d0c25369df3e0a9061e2c37eef2346fcc Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Thu, 18 Jun 2026 09:51:25 +0200 Subject: [PATCH 593/598] pwa support (wip) --- copyparty/__init__.py | 3 ++ copyparty/web/browser.css | 3 +- copyparty/web/browser.html | 1 + copyparty/web/browser.js | 4 ++- copyparty/web/copyparty.png | Bin 0 -> 1585 bytes copyparty/web/idp.html | 1 + copyparty/web/manifest.json | 33 ++++++++++++++++++++++ copyparty/web/md.html | 1 + copyparty/web/mde.html | 1 + copyparty/web/msg.html | 1 + copyparty/web/rups.html | 1 + copyparty/web/shares.html | 1 + copyparty/web/splash.html | 1 + copyparty/web/svcs.html | 1 + copyparty/web/sw.js | 54 ++++++++++++++++++++++++++++++++++++ scripts/sfx.ls | 3 ++ 16 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 copyparty/web/copyparty.png create mode 100644 copyparty/web/manifest.json create mode 100644 copyparty/web/sw.js diff --git a/copyparty/__init__.py b/copyparty/__init__.py index 6430e655..23ec8eae 100644 --- a/copyparty/__init__.py +++ b/copyparty/__init__.py @@ -73,6 +73,7 @@ web/browser.js web/browser2.html web/cf.html web/copyparty.gif +web/copyparty.png web/deps/busy.mp3 web/deps/easymde.css web/deps/easymde.js @@ -89,6 +90,7 @@ web/deps/sha512.ac.js web/deps/sha512.hw.js web/idp.html web/iiam.gif +web/manifest.json web/md.css web/md.html web/md.js @@ -110,6 +112,7 @@ web/splash.html web/splash.js web/svcs.html web/svcs.js +web/sw.js web/tl/chi.js web/tl/cze.js web/tl/deu.js diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 045dab03..c19df1a5 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -679,7 +679,8 @@ html .ayjump:focus-visible { #bbox-btns .x, #qs_btns a .x { line-height: .6em; - vertical-align: center; + vertical-align: middle; + vertical-align: center; } #moresearch span { font-size: .6em; diff --git a/copyparty/web/browser.html b/copyparty/web/browser.html index 6eda8026..c99d7178 100644 --- a/copyparty/web/browser.html +++ b/copyparty/web/browser.html @@ -7,6 +7,7 @@ + {{ html_head }} diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index 10b1cb27..a2807f3a 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -15,7 +15,8 @@ function loadScript(name, id) { this.readyState === "loaded" || this.readyState === "complete") ) { done = true; - jsldp(id, name); + if(id) + jsldp(id, name); // Handle memory leak in IE s.onload = s.onreadystatechange = null; @@ -32,6 +33,7 @@ function jsldp(a, b) { } loadScript('baguettebox', "J_BBX"); loadScript('up2k', "J_U2K"); +loadScript('sw'); // disables emojis diff --git a/copyparty/web/copyparty.png b/copyparty/web/copyparty.png new file mode 100644 index 0000000000000000000000000000000000000000..8a17b717093d9f494341e9a34fc33747b7011a19 GIT binary patch literal 1585 zcmbVMc}&xH6o2inw5$bM1Q7}d$Yq8I0)a9NRD?jCvI2rb1!{`SS#_W=L5}`F!f-N+ zh;odhPG*@313VDCembNeibMgK95!;;QBI|REzlM8znNv(%QtzSm+#9b@5uX{U+{@+Q9PW+=(0Ii1*|a_39Y!3s_JzG|0O>g|RDm z{P(rz9+K92GFQCfw^$ev<_JN72lRX`Sh-f8cpjsMP8Hk*3qcjUjo`~dX#K5P`}+_v zdpNMOmQ+hhaA++il&(+bh7DVTq-Jwr$Wwe`rRoTEw{t&~?E+?-Otn7el|prg0+2JM z@cM44%Vv2b?w*Dke6)>=O+5!i4{^OSy@Cj|uBQ!YN2+J#{5zUOaHuYuK!<)OxQUZO z^PUA&B=QvMc7-nS{2x1XoX?0q)!#*)HYOo}O*(mgAxBApk3wBWVYQ{IG;63>Z6->~$Z zOMBx+JPc&HCX(s6V|^KJ>2EGfj(6daF1JR^W6EP)2T7$Dfq+hh9j)n_I=*nsx zw9UPZ%r3{@q!tV?(njcBGaAe_XuG!Kh^t}M6jy|o77j4b(i$^jB#qO2(q)8RkqJKP z{W)4QJ1LV57^Y^#uT^)%2B`K%l>@rNES!!*^6K3t630a*b9pT}mRLLmcBrwHl2L5J z*`~4xvQfAgMiUID%}%WXm?6>Nim7n4WU#;?JEJ=7cdaKBT9;;wiWpNe(K>)YZc1XZ zAH+wQZMJbYkkCD55~b6t@P@PYPJPEk_ym1v;b1XP`8S9;nnIS!7iVjWy(RS6q%Z^F9*WDI0P&Pe)p2kI<8DJLIK#X_ zLebs=2|3F&>04Bgng3Uh4I}e#(WOjngS*rSk;dFayu#@Tw_yLmPh77td!Qg4_Qvwr zA;o*1dw8VS)AdwJgo$vo++t^xvX{WeK4?2d9 zUBZ>a*8ska7QYuL6(MO^}^KwrW=X$)8f@Mslh@K&oBFHYcsC>;=lSfw~@ ze8GbXw;QQ&1}Sf#W|xe|0n7D%eS{wNn(#(9Si_Nm&JW4>1&U|)hPLM7BIi^Oa4sMu`?={}9wfh7MYce}#!qo|tes@3gfAxI>LQpIS4Zl4E?L^Q14GFZf^O4oO(8StGLu|!E&hM> A(*OVf literal 0 HcmV?d00001 diff --git a/copyparty/web/idp.html b/copyparty/web/idp.html index 13360181..2ac37489 100644 --- a/copyparty/web/idp.html +++ b/copyparty/web/idp.html @@ -8,6 +8,7 @@ + {{ html_head }} diff --git a/copyparty/web/manifest.json b/copyparty/web/manifest.json new file mode 100644 index 00000000..b68258ce --- /dev/null +++ b/copyparty/web/manifest.json @@ -0,0 +1,33 @@ +{ + "short_name": "copyparty", + "name": "copyparty", + "description": "the all in one file server", + "icons": [ + { + "src": "/.cpr/copyparty.png", + "sizes": "512x512", + "type": "image/svg+xml" + } + ], + "start_url": "/?utm_medium=PWA&utm_source=launcher", + "display": "minimal-ui", + "orientation": "any", + "theme_color": "#fc5", + "background_color": "#222", + "share_target": { + "action": "/?utm_medium=PWA&utm_source=share-target&share-target", + "method": "POST", + "enctype": "multipart/form-data", + "params": { + "title": "name", + "text": "description", + "url": "link", + "files": [ + { + "name": "files", + "accept": ["*/*"] + } + ] + } + } + } \ No newline at end of file diff --git a/copyparty/web/md.html b/copyparty/web/md.html index e2d1a9e6..fa6e0bc5 100644 --- a/copyparty/web/md.html +++ b/copyparty/web/md.html @@ -7,6 +7,7 @@ + {%- if edit %} diff --git a/copyparty/web/mde.html b/copyparty/web/mde.html index 042d1357..47bba37c 100644 --- a/copyparty/web/mde.html +++ b/copyparty/web/mde.html @@ -7,6 +7,7 @@ + diff --git a/copyparty/web/msg.html b/copyparty/web/msg.html index 30f53d55..891d0a1d 100644 --- a/copyparty/web/msg.html +++ b/copyparty/web/msg.html @@ -7,6 +7,7 @@ + diff --git a/copyparty/web/sw.js b/copyparty/web/sw.js new file mode 100644 index 00000000..7103a254 --- /dev/null +++ b/copyparty/web/sw.js @@ -0,0 +1,54 @@ +// service worker. required for PWAs +// https://www.digitalapplied.com/blog/progressive-web-apps-2026-pwa-performance-guide +// Register service worker on page load +if ('serviceWorker' in navigator) { + self.addEventListener("fetch", (event) => { + // Regular requests not related to Web Share Target. + if (event.request.method !== "POST" || !event.request.enctype.has("share-target")) { + event.respondWith(fetch(event.request)); + return; + } + + // Requests related to Web Share Target. + event.respondWith( + (async () => { + const formData = await event.request.formData(); + const link = formData.get("link") || ""; + // Instead of the original URL `/save-bookmark/`, redirect + // the user to a URL returned by the `saveBookmark()` + // function, for example, `/`. + const responseUrl = await saveBookmark(link); + return Response.redirect(responseUrl, 303); + })(), + ); + }); + window.addEventListener('load', async () => { + try { + const registration = await navigator.serviceWorker.register( + '/service-worker.js', + { scope: '/' } + ); + console.log('SW registered:', registration.scope); + + // Check for waiting update + if (registration.waiting) { + notifyUserOfUpdate(registration); + } + + // Listen for future updates + registration.addEventListener('updatefound', () => { + const newWorker = registration.installing; + newWorker?.addEventListener('statechange', () => { + if ( + newWorker.state === 'installed' && + navigator.serviceWorker.controller + ) { + notifyUserOfUpdate(registration); + } + }); + }); + } catch (error) { + console.error('SW registration failed:', error); + } + }); +} \ No newline at end of file diff --git a/scripts/sfx.ls b/scripts/sfx.ls index 7578b96b..02355b36 100644 --- a/scripts/sfx.ls +++ b/scripts/sfx.ls @@ -75,6 +75,7 @@ copyparty/web/browser.js, copyparty/web/browser2.html, copyparty/web/cf.html, copyparty/web/copyparty.gif, +copyparty/web/copyparty.png, copyparty/web/deps, copyparty/web/deps/__init__.py, copyparty/web/deps/busy.mp3, @@ -93,6 +94,7 @@ copyparty/web/deps/sha512.ac.js, copyparty/web/deps/sha512.hw.js, copyparty/web/idp.html, copyparty/web/iiam.gif, +copyparty/web/manifest.json, copyparty/web/md.css, copyparty/web/md.html, copyparty/web/md.js, @@ -115,6 +117,7 @@ copyparty/web/splash.html, copyparty/web/splash.js, copyparty/web/svcs.html, copyparty/web/svcs.js, +copyparty/web/sw.js, copyparty/web/tl, copyparty/web/tl/chi.js, copyparty/web/tl/cze.js, From 4f02ee941c8481c8c5cba326fb65c0ef51277dbe Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Thu, 18 Jun 2026 10:47:44 +0200 Subject: [PATCH 594/598] changed PWA icon --- copyparty/__init__.py | 1 + copyparty/web/copyparty.svg | 1 + copyparty/web/manifest.json | 2 +- scripts/sfx.ls | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 copyparty/web/copyparty.svg diff --git a/copyparty/__init__.py b/copyparty/__init__.py index 23ec8eae..19d6a1b1 100644 --- a/copyparty/__init__.py +++ b/copyparty/__init__.py @@ -74,6 +74,7 @@ web/browser2.html web/cf.html web/copyparty.gif web/copyparty.png +web/copyparty.svg web/deps/busy.mp3 web/deps/easymde.css web/deps/easymde.js diff --git a/copyparty/web/copyparty.svg b/copyparty/web/copyparty.svg new file mode 100644 index 00000000..8f101f27 --- /dev/null +++ b/copyparty/web/copyparty.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/copyparty/web/manifest.json b/copyparty/web/manifest.json index b68258ce..084538de 100644 --- a/copyparty/web/manifest.json +++ b/copyparty/web/manifest.json @@ -4,7 +4,7 @@ "description": "the all in one file server", "icons": [ { - "src": "/.cpr/copyparty.png", + "src": "/.cpr/copyparty.svg", "sizes": "512x512", "type": "image/svg+xml" } diff --git a/scripts/sfx.ls b/scripts/sfx.ls index 02355b36..4762b219 100644 --- a/scripts/sfx.ls +++ b/scripts/sfx.ls @@ -76,6 +76,7 @@ copyparty/web/browser2.html, copyparty/web/cf.html, copyparty/web/copyparty.gif, copyparty/web/copyparty.png, +copyparty/web/copyparty.svg, copyparty/web/deps, copyparty/web/deps/__init__.py, copyparty/web/deps/busy.mp3, From 3b916d415f9b28a548f06280b8941abd20e1b524 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Thu, 18 Jun 2026 12:19:53 +0200 Subject: [PATCH 595/598] set PWA border to accent color --- copyparty/web/manifest.json | 2 +- copyparty/web/util.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/copyparty/web/manifest.json b/copyparty/web/manifest.json index 084538de..c752af05 100644 --- a/copyparty/web/manifest.json +++ b/copyparty/web/manifest.json @@ -12,7 +12,7 @@ "start_url": "/?utm_medium=PWA&utm_source=launcher", "display": "minimal-ui", "orientation": "any", - "theme_color": "#fc5", + "theme_color": "#222", "background_color": "#222", "share_target": { "action": "/?utm_medium=PWA&utm_source=share-target&share-target", diff --git a/copyparty/web/util.js b/copyparty/web/util.js index 2c7c7a71..f64381d5 100644 --- a/copyparty/web/util.js +++ b/copyparty/web/util.js @@ -2353,7 +2353,7 @@ function bchrome() { return; try { - v = cprop('--bg-u3'); + v = cprop('--a'); } catch (ex) { } o.setAttribute('content', v ? v : document.documentElement.className.indexOf('y') + 1 ? '#eee' : '#333'); From d4c05393e540218a122683810300303ee5ade51e Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Thu, 18 Jun 2026 12:48:18 +0200 Subject: [PATCH 596/598] PWA: serviceworker prep / wip --- copyparty/web/manifest.json | 6 ++--- copyparty/web/sw.js | 44 ++++++++++++++----------------------- 2 files changed, 19 insertions(+), 31 deletions(-) diff --git a/copyparty/web/manifest.json b/copyparty/web/manifest.json index c752af05..3202cc40 100644 --- a/copyparty/web/manifest.json +++ b/copyparty/web/manifest.json @@ -19,9 +19,9 @@ "method": "POST", "enctype": "multipart/form-data", "params": { - "title": "name", - "text": "description", - "url": "link", + "title": "share", + "text": "upload", + "url": "/", "files": [ { "name": "files", diff --git a/copyparty/web/sw.js b/copyparty/web/sw.js index 7103a254..b94a5582 100644 --- a/copyparty/web/sw.js +++ b/copyparty/web/sw.js @@ -13,42 +13,30 @@ if ('serviceWorker' in navigator) { event.respondWith( (async () => { const formData = await event.request.formData(); - const link = formData.get("link") || ""; - // Instead of the original URL `/save-bookmark/`, redirect - // the user to a URL returned by the `saveBookmark()` - // function, for example, `/`. - const responseUrl = await saveBookmark(link); + const files = formData.get("files") || ""; + const responseUrl = '/'; // (ToDo: remember last upload dir) + // ToDo: keep file references in clipboard + // -> upload on paste + alert(files) return Response.redirect(responseUrl, 303); })(), ); }); + window.addEventListener('load', async () => { try { - const registration = await navigator.serviceWorker.register( - '/service-worker.js', - { scope: '/' } - ); - console.log('SW registered:', registration.scope); - - // Check for waiting update - if (registration.waiting) { - notifyUserOfUpdate(registration); - } - - // Listen for future updates - registration.addEventListener('updatefound', () => { - const newWorker = registration.installing; - newWorker?.addEventListener('statechange', () => { - if ( - newWorker.state === 'installed' && - navigator.serviceWorker.controller - ) { - notifyUserOfUpdate(registration); - } + const registration = await navigator.serviceWorker.register("/.cpr/w/sw.js", { + scope: "/", }); - }); + if (registration.installing) { + console.log("Service worker installing"); + } else if (registration.waiting) { + console.log("Service worker installed"); + } else if (registration.active) { + console.log("Service worker active"); + } } catch (error) { - console.error('SW registration failed:', error); + console.error(`Registration failed with ${error}`); } }); } \ No newline at end of file From 0135a925d94b362c564b431ea1bb344d9bb63146 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Thu, 18 Jun 2026 12:55:21 +0200 Subject: [PATCH 597/598] PWA: remove broken serviceworker redirect --- copyparty/web/sw.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/copyparty/web/sw.js b/copyparty/web/sw.js index b94a5582..d6b30825 100644 --- a/copyparty/web/sw.js +++ b/copyparty/web/sw.js @@ -17,8 +17,9 @@ if ('serviceWorker' in navigator) { const responseUrl = '/'; // (ToDo: remember last upload dir) // ToDo: keep file references in clipboard // -> upload on paste - alert(files) - return Response.redirect(responseUrl, 303); + event.respondWith(fetch(event.request)); + alert(files); + return; })(), ); }); From d80f3b76c5e6757c40a04428b50759cac75196b5 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Thu, 18 Jun 2026 14:00:39 +0200 Subject: [PATCH 598/598] PWA: wip service worker registration --- copyparty/web/sw.js | 19 +------------------ copyparty/web/util.js | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/copyparty/web/sw.js b/copyparty/web/sw.js index d6b30825..5f8b48f3 100644 --- a/copyparty/web/sw.js +++ b/copyparty/web/sw.js @@ -4,7 +4,7 @@ if ('serviceWorker' in navigator) { self.addEventListener("fetch", (event) => { // Regular requests not related to Web Share Target. - if (event.request.method !== "POST" || !event.request.enctype.has("share-target")) { + if (event.request.method !== "POST" || !event.request.action.has("share-target")) { event.respondWith(fetch(event.request)); return; } @@ -23,21 +23,4 @@ if ('serviceWorker' in navigator) { })(), ); }); - - window.addEventListener('load', async () => { - try { - const registration = await navigator.serviceWorker.register("/.cpr/w/sw.js", { - scope: "/", - }); - if (registration.installing) { - console.log("Service worker installing"); - } else if (registration.waiting) { - console.log("Service worker installed"); - } else if (registration.active) { - console.log("Service worker active"); - } - } catch (error) { - console.error(`Registration failed with ${error}`); - } - }); } \ No newline at end of file diff --git a/copyparty/web/util.js b/copyparty/web/util.js index f64381d5..0ef81497 100644 --- a/copyparty/web/util.js +++ b/copyparty/web/util.js @@ -2421,4 +2421,25 @@ function xhrchk(xhr, prefix, e404, lvl, tag) { return fun(0, prefix + xhr.status + ": " + errtxt, tag); } +// register service worker +// ToDo: set http header: Service-Worker-Allowed: / +// otherwise it will fail to register +// https://stackoverflow.com/questions/49084718/how-exactly-add-service-worker-allowed-to-register-service-worker-scope-in-upp +window.addEventListener('load', async () => { + try { + const registration = await navigator.serviceWorker.register("/.cpr/w/sw.js", { + scope: "/", + }); + if (registration.installing) { + console.log("Service worker installing"); + } else if (registration.waiting) { + console.log("Service worker installed"); + } else if (registration.active) { + console.log("Service worker active"); + } + } catch (error) { + console.error(`Registration failed with ${error}`); + } +}); + J_UTL = 2;