From 43e40320d50a22501362fd9a92b126ca21cb4b59 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Thu, 2 Apr 2026 18:46:15 +0200 Subject: [PATCH 001/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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/623] 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; From 4ce26d337abb34ed3395430b0216372af741554e Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 19 Jun 2026 22:45:37 +0200 Subject: [PATCH 599/623] PWA: serviceworker wip --- copyparty/httpcli.py | 1 + copyparty/web/sw.js | 45 ++++++++++++++++++++++++++++++++++++-------- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/copyparty/httpcli.py b/copyparty/httpcli.py index dfd7616b..d04ea45c 100644 --- a/copyparty/httpcli.py +++ b/copyparty/httpcli.py @@ -336,6 +336,7 @@ class HttpCli(object): """returns true if connection can be reused""" self.out_headers = { "Cache-Control": "no-store, max-age=0", + "Service-Worker-Allowed": "/", } if self.args.early_ban and self.is_banned(): diff --git a/copyparty/web/sw.js b/copyparty/web/sw.js index 5f8b48f3..cdd012c6 100644 --- a/copyparty/web/sw.js +++ b/copyparty/web/sw.js @@ -1,10 +1,13 @@ // service worker. required for PWAs // https://www.digitalapplied.com/blog/progressive-web-apps-2026-pwa-performance-guide // Register service worker on page load +console.log('sw.js') if ('serviceWorker' in navigator) { + console.log('sw load') self.addEventListener("fetch", (event) => { // Regular requests not related to Web Share Target. if (event.request.method !== "POST" || !event.request.action.has("share-target")) { + console.log('normal response') event.respondWith(fetch(event.request)); return; } @@ -12,15 +15,41 @@ if ('serviceWorker' in navigator) { // Requests related to Web Share Target. event.respondWith( (async () => { - const formData = await event.request.formData(); - const files = formData.get("files") || ""; - const responseUrl = '/'; // (ToDo: remember last upload dir) - // ToDo: keep file references in clipboard - // -> upload on paste - event.respondWith(fetch(event.request)); - alert(files); - return; + const formData = await event.request.formData(); + const files = formData.get("files") || ""; + console.log('sw share:') + console.log(files) + await addResourcesToCache(files) + + // const responseUrl = '/'; // (ToDo: remember last upload dir) + // ToDo: keep file references in clipboard + // (maybe read from cache on page load somehow) + // -> upload on paste + + // Copy existing headers + const headers = new Headers(event.request.headers); + + // Set a new header + var pw = await CookieStore.get('cppwd'); + headers.set('pw', pw); + + headers.delete('origin'); // 99% sure this doesn't work, but hey + + const newRequest = new Request(event.request, { + mode: 'cors', + credentials: 'omit', + headers: headers + }) + return fetch(newRequest) })(), ); }); + self.addEventListener('install', (event) => { + console.log('sw wait skip') + self.skipWaiting(); // insta replace old service workers (helpful for dev) + }); + const addResourcesToCache = async (resources) => { + const cache = await caches.open("files"); + await cache.addAll(resources); + }; } \ No newline at end of file From b2b88830a55e36d82124ccaefcdc6b980e0bdbd0 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 19 Jun 2026 23:12:34 +0200 Subject: [PATCH 600/623] use android share menu when copying a link --- copyparty/web/browser.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index a2807f3a..edc2acb3 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -10917,7 +10917,18 @@ var rcm = (function () { case 'pla': play('f-' + selFile.id); break; case 'txt': showfile.show(selFile.name); break; case 'md': location = selFile.path + (has(selFile.path, '?') ? '&v' : '?v'); break; - case 'cpl': cliptxt(selFile.url, function () { toast.ok(2, L.clipped) }); break; + case 'cpl': + if(navigator.canShare){ + let shareData = { + title: selFile.name, + url: selFile.url, + }; + if(navigator.canShare(shareData)) + navigator.share(shareData) + } + else + cliptxt(selFile.url, function () { toast.ok(2, L.clipped) }); + break; case 'dl': ebi('seldl').click(); break; case 'zip': ebi('selzip').click(); break; case 'del': fileman.delete(); break; From 1bec09cea88ce86ba30ae934028f93a670385a44 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Fri, 19 Jun 2026 23:24:58 +0200 Subject: [PATCH 601/623] full-width selection actions on small screens --- copyparty/web/browser.css | 9 +++++++++ copyparty/web/browser.js | 1 + 2 files changed, 10 insertions(+) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index c19df1a5..2e6be2cf 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -4290,6 +4290,15 @@ html.e #wrap.thin .ghead { #widget { font-size: 1.4em; } + #wtoggle.sel { + display: block; + max-width: 100%; + margin: 0 .1em .1em .1em; + } + #wstack.sel #up_quick, + #wstack.sel #wtico { + display: none; + } #pathBar { display: block; padding: .5em 1em; diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index edc2acb3..4f2d61d5 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -9807,6 +9807,7 @@ var msel = (function () { r.all = null; clmod(ebi('wtoggle'), 'sel', r.getsel().length); + clmod(ebi('wstack'), 'sel', r.getsel().length); thegrid.loadsel(); fileman.render(); showfile.updtree(); From 9ef7d4bb86ab33d8d38e4124da4a73eca9749a48 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Sat, 20 Jun 2026 00:05:19 +0200 Subject: [PATCH 602/623] copy link action in wtoggle --- copyparty/web/browser.css | 7 +++--- copyparty/web/browser.js | 48 +++++++++++++++++++++++++++++---------- 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 2e6be2cf..9f2093cc 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -1466,10 +1466,10 @@ html:not(.e) #ggrid>a.thumbed.dir:before { white-space: nowrap; text-align: center; max-width: 79vw; - max-width: calc(100% - 3.5em); + max-width: calc(100% - 3.4em); overflow-x: auto; overflow-y: hidden; - margin: 0 .1em .1em .2em; + margin: 0 .1em .1em .1em; box-shadow: 0 0 .5em var(--mp-sh); border-radius: 5px; border-radius: var(--radius); @@ -1605,7 +1605,7 @@ html:not(.e):not(.d) #up_quick .btn.on { #wtoggle a { font-size: .5em; padding: .5em .5em; - margin: 0em .1em -.3em .1em; + margin: 0em .1em -.23em .1em; display: inline-block; } #wtoggle #zip1 { @@ -4293,7 +4293,6 @@ html.e #wrap.thin .ghead { #wtoggle.sel { display: block; max-width: 100%; - margin: 0 .1em .1em .1em; } #wstack.sel #up_quick, #wstack.sel #wtico { diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index 4f2d61d5..aa666b7a 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -978,6 +978,7 @@ ebi('widget').innerHTML = ( '×cancel📨share🔗link' + (fun_tgl ? '✏️' : '✎') + 'name🗑️del.' + (fun_tgl ? '✂️' : '✂') + 'cut 1 ? 'Sharing files from ' : 'Sharing a file from ') + + ebi('srv_name').textContent, + url: vps.join('\n'), + }; + if(navigator.canShare && (MOBILE || !FIREFOX)){ + //desktop firefox CAN technically use this, but it sucks :P + // within 2min of testing on KDE i encountered the share being broken until browser restart + // + FF copying the "file", which can't be pasted depending on get perms, with no fallback, + // so for example pasting in discord didn't work ~Til 2026-06-19 + if(navigator.canShare(shareData)) + navigator.share(shareData) + } + else + cliptxt(shareData.url, function () { toast.ok(2, L.clipped) }); + } + r.rename = function (e) { ev(e); var sel = msel.getsel(), @@ -5717,6 +5751,7 @@ var fileman = (function () { bcpy.onclick = r.cpy; bpst.onclick = r.paste; bshr.onclick = r.share; + bcpl.onclick = r.link; bclr.onclick = r.clear; return r; @@ -10918,18 +10953,7 @@ var rcm = (function () { case 'pla': play('f-' + selFile.id); break; case 'txt': showfile.show(selFile.name); break; case 'md': location = selFile.path + (has(selFile.path, '?') ? '&v' : '?v'); break; - case 'cpl': - if(navigator.canShare){ - let shareData = { - title: selFile.name, - url: selFile.url, - }; - if(navigator.canShare(shareData)) - navigator.share(shareData) - } - else - cliptxt(selFile.url, function () { toast.ok(2, L.clipped) }); - break; + case 'cpl': fileman.link(); break; case 'dl': ebi('seldl').click(); break; case 'zip': ebi('selzip').click(); break; case 'del': fileman.delete(); break; From 743b936062a4c979a94b0da9f092242fa81e9d64 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Sat, 20 Jun 2026 13:32:37 +0200 Subject: [PATCH 603/623] wing theme slight rework --- copyparty/web/browser.css | 165 ++++++++++++++++++++++++++++++++------ 1 file changed, 141 insertions(+), 24 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 9f2093cc..776aeed6 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -747,7 +747,7 @@ a:hover { #files .imgcontainer:hover, #files a:hover { color: var(--fg-max); - background: color-mix(in oklab, var(--a) 20%, transparent); + background-color: color-mix(in oklab, var(--a) 20%, transparent); text-decoration: underline; } #files thead th { @@ -1028,11 +1028,11 @@ html.dz #flogout { border-left: .2em solid var(--bg-u5); } #repl { - opacity: .3; + color: color-mix(in srgb, var(--a) 30%, transparent); padding: .33em; } #repl:hover{ - opacity: 1; + color: var(--a); } #files a.doc { color: var(--a-gray); @@ -1244,9 +1244,6 @@ tr.play td:nth-child(1) a { html:not(.e) #ggrid>a.thumbed.dir:before { content: '📂'; } -#ggrid>a.dir>span { - color: var(--g-fg); -} #ggrid>a.au:before { content: '▶'; } @@ -1467,6 +1464,7 @@ html:not(.e) #ggrid>a.thumbed.dir:before { text-align: center; max-width: 79vw; max-width: calc(100% - 3.4em); + min-height: 1.25em; overflow-x: auto; overflow-y: hidden; margin: 0 .1em .1em .1em; @@ -4100,6 +4098,7 @@ html.a #path i { height: 1.5em; margin: -.4em .3em -.4em -1.7em; } +html.fy .ghead, html.dy .ghead, html.a .ghead { background: var(--bg); @@ -4107,7 +4106,7 @@ html.a .ghead { border-bottom: #303337 solid 1px; border-bottom: var(--btn-bb); border-radius: 0; - margin: 0 -.5em 1.5em -.5em; + margin: 0 -.5em 1.5em -.6em; padding-left: .5em; padding-right: .5em; } @@ -4219,6 +4218,11 @@ html:not(.e) #wrap.thin #ghead { html.cz #wrap.thin .ghead{ top: 7.4em; } +html.fy #wrap.thin .ghead { + top: 6.1em; + border-left: none; + border-right: none; +} html.dy #wrap.thin .ghead, html.a #wrap.thin .ghead { top: 6.9em; @@ -5627,11 +5631,11 @@ html.f #ggrid > a.au::before { } html.f #ggrid > a:focus-visible .imgcontainer::before, html.f #ggrid > a:hover .imgcontainer::before { - border-color: var(--g-f-bg) transparent transparent var(--g-f-bg); + border-color: var(--g-f-bg) transparent transparent var(--g-f-bg) !important; } html.f #ggrid > a.sel:focus-visible .imgcontainer::before, html.f #ggrid > a.sel:hover .imgcontainer::before { - border-color: var(--g-fsel-bg) transparent transparent var(--g-fsel-bg); + border-color: var(--g-fsel-bg) transparent transparent var(--g-fsel-bg) !important; } /* #wrap:not(.thin) .ghead::after, */ html.f #ggrid .dir.thumbed .imgcontainer::before, @@ -5655,7 +5659,7 @@ html.f #ggrid > a::before { text-shadow: none !important; } html.f #ggrid > a.sel .imgcontainer::before { - border-color: var(--g-sel-bg) transparent transparent var(--g-sel-bg); + border-color: var(--g-sel-bg) transparent transparent var(--g-sel-bg) !important; } html.f #ggrid > a.sel img { box-shadow: none; @@ -5809,13 +5813,15 @@ html.fz #wfp .btn { } html.fy { - --a: #305797; + --a: #3071b7; + --as: color-mix(in oklab, hsl(from var(--a) h calc(s * 1.5) 50%) 30%, var(--bg)); --fg: #f3f3f3; --fg-weak: var(--a); --a2: hsl(from var(--a) calc(h + 190) calc(s * 1.1) calc(l * .5)); --btn-bg: var(--fg); --scrl-hint: var(--bg-u2); --tree-bg: var(--bg-u2); + --g-f-bg: color-mix(in oklab, var(--bg-u3), var(--bg)); } html.fy * { box-shadow: none !important; @@ -5824,7 +5830,10 @@ html.fy * { } html.fy #wrap:not(.thin) .ghead { - top: 3.4em; + top: 2.8em; + border-bottom-right-radius: var(--radius); + border-top-width: 0; + border-left-width: 0; } html.fy #blogout { color: var(--fg) !important; @@ -5870,10 +5879,15 @@ html.fy #files { } html.fy #path i { border-color: var(--fg); + height: 1.2em; + margin: 0 .3em -.25em -1.7em; + opacity: .4; + transform: none; } html.fy #path a { - padding-top: .7em; + padding: .6em .4em; + height: auto; } html.fy #path a:hover { @@ -5891,6 +5905,7 @@ html.fy #treeToggleBtn { padding: .2em; margin: 0 !important; border: none; + border-radius: 0 0 var(--radius) 0; } html.fy #srv_name { line-height: 1.4em; @@ -5903,14 +5918,14 @@ html.fy .opbox:not(#op_bup) { html.fy #pathBar { padding: 0; } -html.fy #ops, -html.fy #path, html.fy .ghead { border: var(--btn-bb); + border-top: none; + --fg: var(--a); + color: var(--fg); + --scrl-hint: var(--bg); } html.fy #actionsArea, -html.fy #ops, -html.fy #path, html.fy #wfp, html.fy #wfp .btn { margin: 0; @@ -5932,7 +5947,7 @@ html.fy #tth { } html.fy #wrap { background-size: 20px 20px; - background-image: radial-gradient(color-mix(in oklab, var(--bg-u2) 20%, transparent) 1px, transparent 1px); + /* background-image: radial-gradient(color-mix(in oklab, var(--bg-u2) 10%, transparent) 1px, transparent 1px); */ } html.fy .modalheader::after { position: absolute; @@ -5983,17 +5998,50 @@ html.fy #wtoggle, html.fy #wtoggle * { line-height: .99em; } +html.fy #repl::before, +html.fy #files:before, +html.fy #ggrid:before, +html.fy #files:after, +html.fy #ggrid::after, html.fy #wrap:before { + --w: 20px; content: ""; - width: 500px; - height: 500px; - border: var(--a) solid 10px; - border-radius: 100%; + width: 150px; + height: 220px; + border-radius: 10px; position: fixed; z-index: -1; right: 10px; - filter: blur(3px); - opacity: .9; + filter: blur(5px); + background: repeating-linear-gradient(-45deg, var(--as), var(--as) var(--w), transparent var(--w), transparent calc(var(--w) * 2)); + margin: 15vh 15vw; +} +html.fy #repl::before, +html.fy #files:before, +html.fy #ggrid:before{ + width: 100px; + height: 100px; + margin: 33vh 6vw; + --w: 15px; + filter: blur(7px); + opacity: .7; +} +html.fy #files:after, +html.fy #ggrid::after { + width: 300px; + height: 90px; + margin: 0 calc(50vw - 150px); + right: auto; + bottom: -10px; +} +html.fy #repl::before{ + top: 0; + left: var(--nav-sz); + margin: 15vh 8vw; + width: 150px; + height: 130px; + --w: 25px; + opacity: .5; } html.fy #qs_btns a { color: var(--bg-u2); @@ -6008,6 +6056,75 @@ html.fy #doc { html.fy .logue { color: var(--a); } +/* +Source - https://stackoverflow.com/a/61913549 +Posted by Temani Afif, modified by community. See post 'Timeline' for change history +Retrieved 2026-06-20, License - CC BY-SA 4.0 +*/ +html.fy #repl::after, +html.fy a:hover .imgcontainer, +html.fy .imgcontainer:hover, +html.fy *:not(#ggrid)>a:not(.btn):not(.modalheader):hover, +html.fy #wrap:after { + --b: 2px; /* thickness of the border */ + --c: var(--a); /* color of the border */ + --w: 10px; /* width of border */ + + + outline: var(--b) solid #0000; /* space for the border */ + --_g: #0000 90deg,var(--c) 0; + --_p: var(--w) var(--w) border-box no-repeat; + border-radius: 0 !important; + background: + conic-gradient(from 90deg at top var(--b) left var(--b),var(--_g)) 0 0 / var(--_p), + conic-gradient(from 180deg at top var(--b) right var(--b),var(--_g)) 100% 0 / var(--_p), + conic-gradient(from 0deg at bottom var(--b) left var(--b),var(--_g)) 0 100% / var(--_p), + conic-gradient(from -90deg at bottom var(--b) right var(--b),var(--_g)) 100% 100% / var(--_p) !important; +} +html.fy #ggrid>a:hover .imgcontainer { + --b: 3px; + --w: 15px; +} +html.fy #repl::after, +html.fy #wrap:after{ + --b: 10px; + --c: var(--as); + --w: 40px; + + margin: 45vh 15vw; + font-size: 130px; + + position: fixed; + top: 0; + content: "🌐"; + color: transparent; + text-shadow: 0 0 0 var(--as); + height: 165px; + line-height: 145px; + + filter: blur(7px); + z-index: -1; + pointer-events: none; + padding: 10px; +} +html.fy #repl::after{ + --w: 30px; + content: "🎉"; + top: auto; + bottom: 0; + margin: 14vh 60vw; + height: 90px; + line-height: 85px; + font-size: 70px; + filter: blur(5px); + opacity: .6; +} +html.fy #files thead th { + background: transparent; +} +html.fy #files tr:not(.sel) .imgcontainer img { + z-index: -1; +} html.f.unfun #ops a { padding: .5em; From cfdbce96a8983cb442fcbd0ec47e4a45d76b9501 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Sat, 20 Jun 2026 14:47:47 +0200 Subject: [PATCH 604/623] zip folder download svg icon --- copyparty/web/browser.css | 27 +++++++++++++++++++++++---- copyparty/web/browser.js | 3 ++- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 776aeed6..7b378d67 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -1607,10 +1607,12 @@ html:not(.e):not(.d) #up_quick .btn.on { display: inline-block; } #wtoggle #zip1 { - padding: .4em; - margin: 0 .2em; - vertical-align: top; + padding: .2em .4em; + position: relative; white-space: nowrap; + width: 2em; + height: 2em; + vertical-align: top; } #wm3u a { margin: -.2em .1em; @@ -1630,10 +1632,24 @@ html:not(.e):not(.d) #up_quick .btn.on { font-size: .7em; display: block; } +#zip1:hover { + --fg: var(--a); +} +#zip1 span { + text-shadow: none; + background: var(--fg); + color: var(--bg-max); + border-radius: 2px; + padding: 1px 3px; + position: absolute; + z-index: 1; + top: 1.4em; + font-size: .6em; + margin-left: .2em; +} .unfun #wfm span, .unfun #wm3u span, -.unfun #zip1 span, .unfun #wnp span { font-size: 1em; } @@ -6125,6 +6141,9 @@ html.fy #files thead th { html.fy #files tr:not(.sel) .imgcontainer img { z-index: -1; } +html.fy #zip1 { + --bg-max: var(--bg-u2); +} html.f.unfun #ops a { padding: .5em; diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index aa666b7a..0942ec59 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -969,6 +969,7 @@ var svg_next = svg_box + '' var svg_pause = svg_box + '' var svg_vol = svg_box + '' +var svg_dlzip = svg_box + ' ' ebi('widget').innerHTML = ( '
      ' + @@ -985,7 +986,7 @@ ebi('widget').innerHTML = ( ' href="#" id="fcpy" tt="' + L.wt_cpy + '">⧉copy📋paste' + '' + (fun_tgl ? '⬇️📦' : 'download') + 'zip' + + ' href="#" id="zip1" tt="' + L.wt_zip1 + '">' + svg_dlzip + 'zip' + '' + (fun_tgl ? '✅
      sel. ' : 'sel.
      ') + 'all' + (fun_tgl ? '🔛
      sel. ' : 'sel.
      ') + 'inv. Date: Sat, 20 Jun 2026 15:36:12 +0200 Subject: [PATCH 605/623] install + about copyparty button in account popup --- copyparty/web/browser.css | 14 ++++++++++---- copyparty/web/browser.html | 5 ++++- copyparty/web/browser.js | 2 +- copyparty/web/util.js | 18 ++++++++++++++++++ 4 files changed, 33 insertions(+), 6 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 7b378d67..21d5b677 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -5542,6 +5542,13 @@ html.by #spaceUsed_bar { text-align: right; left: auto; } +#op_acc a:not(.btn), +#op_acc input { + font-size: 1.2em; + display: block; + cursor: pointer; + justify-self: end; +} #opa_acc label { cursor: pointer !important; } @@ -5769,10 +5776,6 @@ html.f #u2c3t span { html.f #u2cards span { font-size: .8em; } -html.f #blogout, -html.f #goh { - font-size: 1.2em; -} html.f #gridzoom a, html.f #gridchop a, html.f #twig, html.f #twobytwo, @@ -6010,6 +6013,9 @@ html.fy #wtico { line-height: 1.1em; border-radius: 0; } +html.fy #wstack #wtico:hover{ + background: var(--bg-u2) !important; +} html.fy #wtoggle, html.fy #wtoggle * { line-height: .99em; diff --git a/copyparty/web/browser.html b/copyparty/web/browser.html index c99d7178..61d352c1 100644 --- a/copyparty/web/browser.html +++ b/copyparty/web/browser.html @@ -77,11 +77,14 @@

      Login

      {{ srv_info }}
      - control-panel
      + control-panel +
      + + about copyparty
      diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index 0942ec59..e31ffdfd 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -266,7 +266,7 @@ if (1) "cl_themes": "theme", "cl_accent": "accent color (keep empty for default)$Nsupports any css color, like rgba(255, 210, 0, 1)", "cl_radius": "corner radius in pixels (keep empty for default)", - "cl_fun": "enables or disables the FUN 🎉🚀👽🐹🥳❗ (reload the page after changing this setting)", + "cl_fun": "enables or disables the FUN (hides most emojis) 🎉🚀👽🐹🥳❗$Nreload the page after changing this setting.", "cl_langs": "language", "cl_ziptype": "folder download", "cl_uopts": "upload", diff --git a/copyparty/web/util.js b/copyparty/web/util.js index 0ef81497..5c566a8a 100644 --- a/copyparty/web/util.js +++ b/copyparty/web/util.js @@ -2442,4 +2442,22 @@ window.addEventListener('load', async () => { } }); +if(ebi('inst')){ + var installPrompt = null; + window.addEventListener("beforeinstallprompt", function(e) { + e.preventDefault(); + installPrompt = e; + ebi('inst').removeAttribute("hidden"); + }); + ebi('inst').onclick = async function(){ + if (!installPrompt) { + return; + } + const result = await installPrompt.prompt(); + console.log(`Install prompt was: ${result.outcome}`); + installPrompt = null; + ebi('inst').setAttribute("hidden", ""); + } +} + J_UTL = 2; From 641371152d057116a16b6f6d4179d8ddaaff713d Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Sat, 20 Jun 2026 15:38:30 +0200 Subject: [PATCH 606/623] reduce stroke width of new zip dl icon --- 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 e31ffdfd..a3a018e3 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -969,7 +969,7 @@ var svg_next = svg_box + '' var svg_pause = svg_box + '' var svg_vol = svg_box + '' -var svg_dlzip = svg_box + ' ' +var svg_dlzip = svg_box + ' ' ebi('widget').innerHTML = ( '
      ' + From 72ca118e82b405b7ea1e9586c01e38d9eb8378f7 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Sat, 20 Jun 2026 15:42:16 +0200 Subject: [PATCH 607/623] small alignment fix --- 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 21d5b677..e7994e3a 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -1017,6 +1017,7 @@ html.y #path a:hover { } #flogout { display: inline; + direction: rtl; } html.dz #flogout { margin-left: 1em; @@ -5547,7 +5548,6 @@ html.by #spaceUsed_bar { font-size: 1.2em; display: block; cursor: pointer; - justify-self: end; } #opa_acc label { cursor: pointer !important; From c2bd3b9754584c737a2bd612a184ac2ca9e1ae47 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Sat, 20 Jun 2026 15:50:14 +0200 Subject: [PATCH 608/623] fix hiding install button --- copyparty/web/browser.css | 4 ++-- copyparty/web/util.js | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index e7994e3a..044a098c 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -5543,8 +5543,8 @@ html.by #spaceUsed_bar { text-align: right; left: auto; } -#op_acc a:not(.btn), -#op_acc input { +#op_acc a:not([hidden]):not(.btn), +#op_acc input:not([hidden]) { font-size: 1.2em; display: block; cursor: pointer; diff --git a/copyparty/web/util.js b/copyparty/web/util.js index 5c566a8a..5a6c24be 100644 --- a/copyparty/web/util.js +++ b/copyparty/web/util.js @@ -2445,9 +2445,9 @@ window.addEventListener('load', async () => { if(ebi('inst')){ var installPrompt = null; window.addEventListener("beforeinstallprompt", function(e) { - e.preventDefault(); - installPrompt = e; - ebi('inst').removeAttribute("hidden"); + e.preventDefault(); + installPrompt = e; + ebi('inst').removeAttribute("hidden"); }); ebi('inst').onclick = async function(){ if (!installPrompt) { From cf650af42e0b8f4cb7f73b1af28b173978b5d2aa Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Sat, 20 Jun 2026 18:34:51 +0200 Subject: [PATCH 609/623] fix hiding ui elements via volflags --- copyparty/web/browser.css | 28 +++++++++++++++++----------- copyparty/web/browser.html | 4 ++-- copyparty/web/browser.js | 13 ++++++++----- 3 files changed, 27 insertions(+), 18 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 044a098c..edfe322f 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -624,8 +624,8 @@ html .ayjump:focus-visible { top: 0; margin: 0 -.6em; } -#wfp.shifted { - margin-left: 2em; +#pathBar.shifted { + padding-left: 3.7em; } #path { position: relative; @@ -4204,8 +4204,8 @@ html.d #treepar { #pathBar.thin #path a { padding-top: .45em; } -#pathBar.thin #wfp.shifted { - margin-left: 2.5em; +#pathBar.thin.shifted { + padding-left: 3.5em; } #pathBar.thin #actionsArea { position: fixed; @@ -4413,11 +4413,11 @@ html.e #wrap.thin .ghead { padding: .5em; padding-right: 2em; } - #wfp, - #wfp.shifted, - #pathBar.thin #wfp, - #pathBar.thin #wfp.shifted { - margin-left: 2em; + #pathBar, + #pathBar.shifted, + #pathBar.thin, + #pathBar.thin.shifted { + padding-left: 3em; } #wrap.thin .ghead { top: 7em; @@ -5316,6 +5316,9 @@ html.e #pathBar { top: 0; background: var(--ttlbar); } +html.e #pathBar.shifted { + padding-left: 2.5em; +} html.e #pathBar.thin #actionsArea { top: 0 !important; } @@ -5950,8 +5953,11 @@ html.fy #wfp .btn { margin: 0; border: none; } -html.fy #wfp.shifted { - margin-left: 2.5em; +html.fy #actionsArea { + margin-left: auto; +} +html.fy #pathBar.shifted { + padding-left: 3.5em; } html.fy #wfp .btn { padding: .3em; diff --git a/copyparty/web/browser.html b/copyparty/web/browser.html index 61d352c1..9ce3aaeb 100644 --- a/copyparty/web/browser.html +++ b/copyparty/web/browser.html @@ -45,8 +45,8 @@
      -
      -

      +
      +

      diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index a3a018e3..457f2b85 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -1852,16 +1852,18 @@ var ACtx = !IPHONE && (window.AudioContext || window.webkitAudioContext), var x = ''; if (!fullui) { if (window.ui_nombar || /[?&]nombar\b/.exec(sloc0)) x += '#ops,'; - if (window.ui_noacci || /[?&]noacci\b/.exec(sloc0)) x += '#acc_info,'; - if (window.ui_nosrvi || /[?&]nosrvi\b/.exec(sloc0)) x += '#srv_info,#srv_info2,'; + if (window.ui_noacci || /[?&]noacci\b/.exec(sloc0)) x += '#acc_info,#opa_acc,'; + if (window.ui_nosrvi || /[?&]nosrvi\b/.exec(sloc0)) x += '#srv_info,#srv_info2,#tree_footer'; if (window.ui_nocpla || /[?&]nocpla\b/.exec(sloc0)) x += '#goh,'; if (window.ui_nolbar || /[?&]nolbar\b/.exec(sloc0)) x += '#wfp,'; + if (nonav) x += '#path,'; if (window.ui_noctxb || /[?&]noctxb\b/.exec(sloc0)) x += '#wtoggle,'; if (window.ui_norepl || /[?&]norepl\b/.exec(sloc0)) x += '#repl,'; } if (x) document.head.appendChild(mknod('style', '', x.slice(0, -1) + '{display:none!important}')); +if(nonav) if (location.pathname.indexOf('//') === 0) hist_replace(location.pathname.replace(/^\/+/, '/')); @@ -7978,14 +7980,13 @@ var treectl = (function () { r.show = function (instant) { r.hidden = false; if (!entreed) { - ebi('path').style.display = nonav ? 'none' : 'inline-block'; return; } var tree = ebi('tree') tree.style.display = 'block'; tree.style.width = 0; - clmod(ebi('wfp'), 'shifted', false); + clmod(ebi('pathBar'), 'shifted', false); window.addEventListener('scroll', onscroll); window.addEventListener('resize', onresize); @@ -8034,7 +8035,7 @@ var treectl = (function () { ebi('tree_footer').style.display = 'none'; ebi('widget').style.marginLeft = '0'; ebi('wrap').style.marginLeft = ''; - clmod(ebi('wfp'), 'shifted', true); + clmod(ebi('pathBar'), 'shifted', true); window.removeEventListener('resize', onresize); window.removeEventListener('scroll', onscroll); aligngriditems(); @@ -8949,6 +8950,8 @@ var treectl = (function () { if (notree) { cs = 'na'; r.detree(null, 1); + ebi('treeToggleBtn').style.display = 'none'; + clmod(ebi('pathBar'), 'shifted', false); } if (cs == 'tree' || (cs != 'na' && vw >= 60)) From 04151dc7c9a2eff761502604efa721ff02902eaa Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Sat, 20 Jun 2026 18:39:37 +0200 Subject: [PATCH 610/623] use tcolor as default accent --- copyparty/web/browser.html | 1 + copyparty/web/browser.js | 2 ++ 2 files changed, 3 insertions(+) diff --git a/copyparty/web/browser.html b/copyparty/web/browser.html index 9ce3aaeb..14792e08 100644 --- a/copyparty/web/browser.html +++ b/copyparty/web/browser.html @@ -296,6 +296,7 @@ CGV = {{ cgv|tojson }}, TS = "{{ ts }}", dtheme = "{{ dtheme }}", + tcolor = "#{{ tcolor }}" lang = "{{ lang }}", dfavico = "{{ favico }}", have_tags_idx = {{ have_tags_idx }}, diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index 457f2b85..4a7e583b 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -1517,6 +1517,8 @@ ebi('accent').oninput = ebi('accent_picker').oninput = function () { }, 100); } var accent = sread('accent'); +if(!accent || accent.length <= 3) + accent = window.tcolor; if(accent && accent.length > 3){ console.log('read accent color from settings: ' + accent); document.documentElement.style.setProperty('--a', parseColor(accent)); From 37f393d8e4fcb6be9334d7ee9fea3d3539f88a99 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Sat, 20 Jun 2026 20:29:01 +0200 Subject: [PATCH 611/623] fix tcolor link to accent color --- copyparty/web/browser.html | 1 - copyparty/web/browser.js | 23 ----------------------- copyparty/web/util.js | 29 +++++++++++++++++++++++++++++ 3 files changed, 29 insertions(+), 24 deletions(-) diff --git a/copyparty/web/browser.html b/copyparty/web/browser.html index 14792e08..9ce3aaeb 100644 --- a/copyparty/web/browser.html +++ b/copyparty/web/browser.html @@ -296,7 +296,6 @@ CGV = {{ cgv|tojson }}, TS = "{{ ts }}", dtheme = "{{ dtheme }}", - tcolor = "#{{ tcolor }}" lang = "{{ lang }}", dfavico = "{{ favico }}", have_tags_idx = {{ have_tags_idx }}, diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index 4a7e583b..c29aea67 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -1480,21 +1480,6 @@ if(sread('cfg_lgcy') == 'true') ebi('reloc_cfg').click(); // accent color -function parseColor (strColor) { - var s = new Option().style; - s.color = strColor; - return s.color !== '' ? s.color : ''; -} -function setColor (color) { - accent = color; - swrite('accent', accent); - var a = accent || ''; - console.log('accent color set to: ' + a); - document.documentElement.style.setProperty('--a', a); - pbar.drawbuf(); - pbar.drawpos(); - vbar.draw(); -} ebi('accent').oninput = ebi('accent_picker').oninput = function () { var validcolor = parseColor(this.value); console.log(this.value); @@ -1516,14 +1501,6 @@ ebi('accent').oninput = ebi('accent_picker').oninput = function () { setColor(validcolor); }, 100); } -var accent = sread('accent'); -if(!accent || accent.length <= 3) - accent = window.tcolor; -if(accent && accent.length > 3){ - console.log('read accent color from settings: ' + accent); - document.documentElement.style.setProperty('--a', parseColor(accent)); - ebi('accent').value = ebi('accent_picker').value = accent; -} // corner radius ebi('radius').oninput = function () { diff --git a/copyparty/web/util.js b/copyparty/web/util.js index 5a6c24be..ee6fa110 100644 --- a/copyparty/web/util.js +++ b/copyparty/web/util.js @@ -2346,6 +2346,35 @@ function cprop(name) { return getComputedStyle(document.documentElement).getPropertyValue(name); } +// read accent / theme color +function parseColor (strColor) { + var s = new Option().style; + s.color = strColor; + return s.color !== '' ? s.color : ''; +} +function setColor (color) { + accent = color; + swrite('accent', accent); + var a = accent || ''; + console.log('accent color set to: ' + a); + document.documentElement.style.setProperty('--a', a); + pbar.drawbuf(); + pbar.drawpos(); + vbar.draw(); +} +var accent = sread('accent'); +var tcolor = QS('meta[name=theme-color]'); +if(tcolor) + tcolor = tcolor.content; +if((!accent || accent.length <= 3) && tcolor != "#333333") + accent = tcolor; +var thing = QS('meta[name=theme-color]'); +if(accent && accent.length > 3){ + console.log('read accent color from settings: ' + accent); + document.documentElement.style.setProperty('--a', parseColor(accent)); + if(ebi('accent')) + ebi('accent').value = ebi('accent_picker').value = accent; +} function bchrome() { var v, o = QS('meta[name=theme-color]'); From d064ba930d268ecf98c372d03451f908ecd95924 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Sat, 20 Jun 2026 20:43:41 +0200 Subject: [PATCH 612/623] fix reading accent color in settings --- copyparty/web/browser.js | 3 +++ copyparty/web/util.js | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index c29aea67..e9086e7f 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -1501,6 +1501,9 @@ ebi('accent').oninput = ebi('accent_picker').oninput = function () { setColor(validcolor); }, 100); } +if(accent && accent.length > 3){ + ebi('accent').value = ebi('accent_picker').value = accent; +} // corner radius ebi('radius').oninput = function () { diff --git a/copyparty/web/util.js b/copyparty/web/util.js index ee6fa110..f4b661ab 100644 --- a/copyparty/web/util.js +++ b/copyparty/web/util.js @@ -2372,8 +2372,6 @@ var thing = QS('meta[name=theme-color]'); if(accent && accent.length > 3){ console.log('read accent color from settings: ' + accent); document.documentElement.style.setProperty('--a', parseColor(accent)); - if(ebi('accent')) - ebi('accent').value = ebi('accent_picker').value = accent; } function bchrome() { From 48342c6dc8c66dd77c4c7176fe262f1567afe910 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Sat, 20 Jun 2026 21:15:26 +0200 Subject: [PATCH 613/623] changed poison theme bg hue, hide reszbar when tree disabled --- copyparty/web/browser.css | 2 +- copyparty/web/browser.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index edfe322f..86c69ade 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -5802,7 +5802,7 @@ html.f .th_ext .inner { html.fz { --bg: #2e258c; - --bg: hsl(from var(--a) calc(h * 2.5 + 85) calc(s * .6) calc(l * .7)); + --bg: hsl(from var(--a) calc(h * 2.5 + 55) calc(s * .6) calc(l * .7)); --a2: hsl(from var(--bg) calc(h - 40) calc(s * 1.2) calc(l * 1.4)); } html.fz #wrap::before { diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index e9086e7f..bbda5591 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -969,7 +969,7 @@ var svg_next = svg_box + '' var svg_pause = svg_box + '' var svg_vol = svg_box + '' -var svg_dlzip = svg_box + ' ' +var svg_dlzip = svg_box + ' ' ebi('widget').innerHTML = ( '
      ' + @@ -8932,7 +8932,7 @@ var treectl = (function () { if (notree) { cs = 'na'; r.detree(null, 1); - ebi('treeToggleBtn').style.display = 'none'; + ebi('treeToggleBtn').style.display = ebi('reszbar').style.display = 'none'; clmod(ebi('pathBar'), 'shifted', false); } From 5769b53154dc6c432cd3388171cae5446646024d Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Sat, 20 Jun 2026 21:25:05 +0200 Subject: [PATCH 614/623] unfun theme alignment fixes --- copyparty/web/browser.css | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 86c69ade..d7e11174 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -1649,16 +1649,6 @@ html:not(.e):not(.d) #up_quick .btn.on { margin-left: .2em; } -.unfun #wfm span, -.unfun #wm3u span, -.unfun #wnp span { - font-size: 1em; -} - -.unfun #wtoggle a { - font-size: .45em; -} - .unfun #up_quick_more a:after { content: "+" } @@ -1944,6 +1934,7 @@ html.b #mu_outer { } .unfun #ops a { font-size: 1.2em; + padding-top: .35em; } .unfun #srchfolder_div { left: 5.2em; From 4b95cf6accb78ff03297cfe08f85df8e5a486d0a Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Sat, 20 Jun 2026 21:59:25 +0200 Subject: [PATCH 615/623] move shuffle and loop buttons to music widget on small screens, re-add shuffle option button to settings --- copyparty/web/browser.js | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index bbda5591..e83370a5 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -1030,8 +1030,10 @@ ebi('widget').innerHTML = ( ' ' + ' 0:00' + '
      ' + - ' 🔁' + - ' 🔀' + + '
      ' + + ' 🔁' + + ' 🔀' + + '
      ' + '
      ' + svg_vol + '
      ' + '

      ' + '

      '+ @@ -1208,6 +1210,7 @@ var musicSettings = ( '

      🎧 ' + L.cl_opts + '

      ' + '🔂' + + '🔀' + '\n' + ' \n' + - ' \n' + + ' \n' + '
      \n' + '
      \n' + @@ -1908,7 +1911,9 @@ var mpl = (function () { }); bcfg_bind(r, 'shuf', 'au_shuf', false, function () { mp.read_order(); // don't bind + ebi('au_shuf2').classList = ebi('au_shuf').classList; }); + ebi('au_shuf2').onclick = ebi('au_shuf').onclick; bcfg_bind(r, 'aplay', 'au_aplay', true); bcfg_bind(r, 'afade', 'au_afade', true); bcfg_bind(r, 'preload', 'au_preload', true); @@ -7824,6 +7829,8 @@ function onwidgetresize(){ var pb_container = ebi('mu_pbb'); pb_container.appendChild(ebi('progbar')); pb_container.appendChild(ebi('altprogbar')); + ebi('mu_toggles').appendChild(ebi('cyclebtn_loopmode')); + ebi('mu_toggles').appendChild(ebi('au_shuf')); ebi('altprogbar').maxWidth = ''; ebi('mu_vol').appendChild(ebi('pvolbg')); pbar.onresize(); @@ -7845,6 +7852,7 @@ function onwidgetresize(){ //wide ebi('trackname').after(ebi('progbar')); ebi('trackname').after(ebi('altprogbar')); + bar.style.paddingTop = '0'; } catch (e) { @@ -7867,6 +7875,15 @@ function onwidgetresize(){ if(ebi('mu_vol').children.length > 0){ bar.appendChild(ebi('pvolbg')); } + var inmu = ebi('mu_toggles').children.length + if(!thin && inmu){ + ebi('au_tgls').appendChild(ebi('cyclebtn_loopmode')); + ebi('au_tgls').appendChild(ebi('au_shuf')); + } + else if(thin && !inmu){ + ebi('mu_toggles').appendChild(ebi('cyclebtn_loopmode')); + ebi('mu_toggles').appendChild(ebi('au_shuf')); + } pbar.onresize(); From 539c915a13295c8d87969c2ae5ece5fe5b39986d Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Sun, 21 Jun 2026 09:42:31 +0200 Subject: [PATCH 616/623] @mechabubba 's patch --- copyparty/web/browser.css | 20 ++++++++++---------- copyparty/web/browser.html | 8 ++++---- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index d7e11174..7eb39c32 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -625,7 +625,7 @@ html .ayjump:focus-visible { margin: 0 -.6em; } #pathBar.shifted { - padding-left: 3.7em; + padding-left: 3.75em; } #path { position: relative; @@ -635,7 +635,7 @@ html .ayjump:focus-visible { display: block; margin: 0 .5em 0 0; width: calc(100% - .5em); - padding: 0 .2em; + padding: 0 .25em; font-size: 1.2em; white-space: nowrap; overflow-x: auto; @@ -2195,17 +2195,17 @@ input.ssconf_v { } #wfp{ - margin: 0 .3em 0 0; + margin: 0 .0em 0 0; white-space: nowrap; display: flex; } #wfp .btn { - min-width: 1.3em; - width: 1.3em; - height: 1.3em; + min-width: 2em; + width: 2em; + height: 2em; font-size: 1em; - padding: .15em; - margin: 0 .1em 0 0; + padding: .2em; + margin: 0 .6em 0 0; } #files td div:not(.imgcontainer) span { @@ -4196,7 +4196,7 @@ html.d #treepar { padding-top: .45em; } #pathBar.thin.shifted { - padding-left: 3.5em; + padding-left: 3.75em; } #pathBar.thin #actionsArea { position: fixed; @@ -4408,7 +4408,7 @@ html.e #wrap.thin .ghead { #pathBar.shifted, #pathBar.thin, #pathBar.thin.shifted { - padding-left: 3em; + padding-left: 3.95em; } #wrap.thin .ghead { top: 7em; diff --git a/copyparty/web/browser.html b/copyparty/web/browser.html index 9ce3aaeb..fdf65c41 100644 --- a/copyparty/web/browser.html +++ b/copyparty/web/browser.html @@ -46,16 +46,16 @@
      -

      +
      -

      -

      +

      +
      {%- for n in vpnodes %} {{ n[1] }} {%- endfor %} - +
      From 3788b9b132ea5553b37a9ca562b34aea49115f4b Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Sun, 21 Jun 2026 10:23:06 +0200 Subject: [PATCH 617/623] change pathbar alignment method to placeholder element --- copyparty/web/browser.css | 36 ++++++++++++++++++------------------ copyparty/web/browser.html | 2 +- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 7eb39c32..edc5ddcc 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -624,8 +624,8 @@ html .ayjump:focus-visible { top: 0; margin: 0 -.6em; } -#pathBar.shifted { - padding-left: 3.75em; +#pathBar.shifted #hspace { + min-width: 3.2em; } #path { position: relative; @@ -2194,10 +2194,13 @@ input.ssconf_v { display: block; } +#hspace { + display: inline-block; +} #wfp{ - margin: 0 .0em 0 0; + margin: 0 .3em 0 0; white-space: nowrap; - display: flex; + display: inline-block; } #wfp .btn { min-width: 2em; @@ -2205,7 +2208,7 @@ input.ssconf_v { height: 2em; font-size: 1em; padding: .2em; - margin: 0 .6em 0 0; + margin: 0 .3em 0 0; } #files td div:not(.imgcontainer) span { @@ -4195,8 +4198,8 @@ html.d #treepar { #pathBar.thin #path a { padding-top: .45em; } -#pathBar.thin.shifted { - padding-left: 3.75em; +#pathBar.thin.shifted #hspace { + min-width: 0; } #pathBar.thin #actionsArea { position: fixed; @@ -4404,11 +4407,8 @@ html.e #wrap.thin .ghead { padding: .5em; padding-right: 2em; } - #pathBar, - #pathBar.shifted, - #pathBar.thin, - #pathBar.thin.shifted { - padding-left: 3.95em; + html:not(.e) #hspace { + min-width: 3em !important; } #wrap.thin .ghead { top: 7em; @@ -5307,8 +5307,8 @@ html.e #pathBar { top: 0; background: var(--ttlbar); } -html.e #pathBar.shifted { - padding-left: 2.5em; +html.e #pathBar.shifted #hspace { + min-width: 2.5em; } html.e #pathBar.thin #actionsArea { top: 0 !important; @@ -5822,7 +5822,7 @@ html.fz .ghead { margin-left: -1px; } html.fz #wfp .btn { - padding: .2em .4em; + padding: .25em .4em; } html.fy { @@ -5947,11 +5947,11 @@ html.fy #wfp .btn { html.fy #actionsArea { margin-left: auto; } -html.fy #pathBar.shifted { - padding-left: 3.5em; +html.fy #pathBar.shifted #hspace { + min-width: 3.5em; } html.fy #wfp .btn { - padding: .3em; + padding: .45em; } html.fy #bbox-overlay #bbox-next .btn, html.fy #bbox-overlay #bbox-prev .btn, diff --git a/copyparty/web/browser.html b/copyparty/web/browser.html index fdf65c41..2247d2c7 100644 --- a/copyparty/web/browser.html +++ b/copyparty/web/browser.html @@ -46,7 +46,7 @@
      -
      +
      From 5a33c4cd8a5350802d28373658d033193ab5c616 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Sun, 21 Jun 2026 10:39:49 +0200 Subject: [PATCH 618/623] IE fixes --- copyparty/web/browser.js | 3 +- copyparty/web/sw.js | 92 ++++++++++++++++++++-------------------- copyparty/web/util.js | 83 +++++++++++++++++++----------------- 3 files changed, 91 insertions(+), 87 deletions(-) diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index e83370a5..c8f7a01f 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -33,7 +33,8 @@ function jsldp(a, b) { } loadScript('baguettebox', "J_BBX"); loadScript('up2k', "J_U2K"); -loadScript('sw'); +if (navigator.serviceWorker) + loadScript('sw'); // disables emojis diff --git a/copyparty/web/sw.js b/copyparty/web/sw.js index cdd012c6..6a1d85fa 100644 --- a/copyparty/web/sw.js +++ b/copyparty/web/sw.js @@ -1,55 +1,53 @@ // service worker. required for PWAs // https://www.digitalapplied.com/blog/progressive-web-apps-2026-pwa-performance-guide // Register service worker on page load -console.log('sw.js') -if ('serviceWorker' in navigator) { - console.log('sw load') - self.addEventListener("fetch", (event) => { - // Regular requests not related to Web Share Target. - if (event.request.method !== "POST" || !event.request.action.has("share-target")) { - console.log('normal response') - event.respondWith(fetch(event.request)); - return; - } +// modern syntax allowed here, only supported browsers load this file +console.log('sw load') +self.addEventListener("fetch", (event) => { + // Regular requests not related to Web Share Target. + if (event.request.method !== "POST" || !event.request.action.has("share-target")) { + console.log('normal response') + event.respondWith(fetch(event.request)); + return; + } - // Requests related to Web Share Target. - event.respondWith( - (async () => { - const formData = await event.request.formData(); - const files = formData.get("files") || ""; - console.log('sw share:') - console.log(files) - await addResourcesToCache(files) + // Requests related to Web Share Target. + event.respondWith( + (async () => { + const formData = await event.request.formData(); + const files = formData.get("files") || ""; + console.log('sw share:') + console.log(files) + await addResourcesToCache(files) - // const responseUrl = '/'; // (ToDo: remember last upload dir) - // ToDo: keep file references in clipboard - // (maybe read from cache on page load somehow) - // -> upload on paste + // const responseUrl = '/'; // (ToDo: remember last upload dir) + // ToDo: keep file references in clipboard + // (maybe read from cache on page load somehow) + // -> upload on paste - // Copy existing headers - const headers = new Headers(event.request.headers); + // Copy existing headers + const headers = new Headers(event.request.headers); - // Set a new header - var pw = await CookieStore.get('cppwd'); - headers.set('pw', pw); - - headers.delete('origin'); // 99% sure this doesn't work, but hey + // Set a new header + var pw = await CookieStore.get('cppwd'); + headers.set('pw', pw); + + headers.delete('origin'); // 99% sure this doesn't work, but hey - const newRequest = new Request(event.request, { - mode: 'cors', - credentials: 'omit', - headers: headers - }) - return fetch(newRequest) - })(), - ); - }); - self.addEventListener('install', (event) => { - console.log('sw wait skip') - self.skipWaiting(); // insta replace old service workers (helpful for dev) - }); - const addResourcesToCache = async (resources) => { - const cache = await caches.open("files"); - await cache.addAll(resources); - }; -} \ No newline at end of file + const newRequest = new Request(event.request, { + mode: 'cors', + credentials: 'omit', + headers: headers + }) + return fetch(newRequest) + })(), + ); +}); +self.addEventListener('install', (event) => { + console.log('sw wait skip') + self.skipWaiting(); // insta replace old service workers (helpful for dev) +}); +const addResourcesToCache = async (resources) => { + const cache = await caches.open("files"); + await cache.addAll(resources); +}; \ No newline at end of file diff --git a/copyparty/web/util.js b/copyparty/web/util.js index f4b661ab..7fd6b765 100644 --- a/copyparty/web/util.js +++ b/copyparty/web/util.js @@ -2362,16 +2362,19 @@ function setColor (color) { pbar.drawpos(); vbar.draw(); } -var accent = sread('accent'); + +var accent = ""; +if(sread != undefined) + accent = sread('accent'); var tcolor = QS('meta[name=theme-color]'); if(tcolor) tcolor = tcolor.content; if((!accent || accent.length <= 3) && tcolor != "#333333") - accent = tcolor; + accent = tcolor; var thing = QS('meta[name=theme-color]'); if(accent && accent.length > 3){ - console.log('read accent color from settings: ' + accent); - document.documentElement.style.setProperty('--a', parseColor(accent)); + console.log('read accent color from settings: ' + accent); + document.documentElement.style.setProperty('--a', parseColor(accent)); } function bchrome() { @@ -2448,42 +2451,44 @@ 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}`); - } -}); - -if(ebi('inst')){ - var installPrompt = null; - window.addEventListener("beforeinstallprompt", function(e) { - e.preventDefault(); - installPrompt = e; - ebi('inst').removeAttribute("hidden"); - }); - ebi('inst').onclick = async function(){ - if (!installPrompt) { - return; +if (navigator.serviceWorker){ + // 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', function() { + try { + var registration = 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); + } + }); + + if(ebi('inst')){ + var installPrompt = null; + window.addEventListener("beforeinstallprompt", function(e) { + e.preventDefault(); + installPrompt = e; + ebi('inst').removeAttribute("hidden"); + }); + ebi('inst').onclick = function(){ + if (!installPrompt) { + return; + } + var result = installPrompt.prompt(); + console.log("Install prompt was: " + result.outcome); + installPrompt = null; + ebi('inst').setAttribute("hidden", ""); } - const result = await installPrompt.prompt(); - console.log(`Install prompt was: ${result.outcome}`); - installPrompt = null; - ebi('inst').setAttribute("hidden", ""); } } From 0d1f4298389ff02a88bd9c76f14ae9bc3da27a69 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Sun, 21 Jun 2026 10:42:22 +0200 Subject: [PATCH 619/623] 3ds fix --- 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 c8f7a01f..4915e181 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -4902,7 +4902,7 @@ var fileman = (function () { ev(e); - let shareData = { + var shareData = { title: (sel.length > 1 ? 'Sharing files from ' : 'Sharing a file from ') + ebi('srv_name').textContent, url: vps.join('\n'), From ed6faf6f33b622cbbc63e350eaa64813581b6cd3 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Sun, 21 Jun 2026 10:51:07 +0200 Subject: [PATCH 620/623] 3DS MouseEvent polyfill --- copyparty/web/util.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/copyparty/web/util.js b/copyparty/web/util.js index 7fd6b765..e957b870 100644 --- a/copyparty/web/util.js +++ b/copyparty/web/util.js @@ -2451,6 +2451,15 @@ function xhrchk(xhr, prefix, e404, lvl, tag) { return fun(0, prefix + xhr.status + ": " + errtxt, tag); } +// polyfill for 3DS (IE11 can do this natively) +var MouseEvent = function (eventType, params) { + params = params || { bubbles: false, cancelable: false }; + var mouseEvent = document.createEvent('MouseEvent'); + mouseEvent.initMouseEvent(eventType, params.bubbles, params.cancelable, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); + + return mouseEvent; +}; + if (navigator.serviceWorker){ // register service worker // ToDo: set http header: Service-Worker-Allowed: / From d2763d9abd353141cbfae28a6165411ca0ef872c Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Sun, 21 Jun 2026 11:13:44 +0200 Subject: [PATCH 621/623] re-add u2err (fix for commit f7eab354ef12af64d816bd441811aed0bdba8def) --- copyparty/web/browser.html | 1 + 1 file changed, 1 insertion(+) diff --git a/copyparty/web/browser.html b/copyparty/web/browser.html index 2247d2c7..2254d488 100644 --- a/copyparty/web/browser.html +++ b/copyparty/web/browser.html @@ -115,6 +115,7 @@
      +

      From 19a12f3b2a7541e5be387477f62220a911ad66e6 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Sun, 21 Jun 2026 15:12:03 +0200 Subject: [PATCH 622/623] margin adjustments --- copyparty/web/browser.css | 56 ++++++++++++++++++++++++-------------- copyparty/web/browser.html | 6 ++-- 2 files changed, 38 insertions(+), 24 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index edc5ddcc..3b4916cc 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -2198,7 +2198,7 @@ input.ssconf_v { display: inline-block; } #wfp{ - margin: 0 .3em 0 0; + margin: 0; white-space: nowrap; display: inline-block; } @@ -2208,7 +2208,7 @@ input.ssconf_v { height: 2em; font-size: 1em; padding: .2em; - margin: 0 .3em 0 0; + margin: 0 .6em 0 0; } #files td div:not(.imgcontainer) span { @@ -4021,6 +4021,16 @@ html.by #u2etas { box-shadow: 0 4px 4px rgba(0, 0, 0, 0.4); background: var(--bottom-glow), var(--btn-bg); } +html.by #path { + margin-right: .1em; +} +html.by #wfp a { + margin-right: .3em; +} +html.fy #pathBar.shifted #hspace, +html.by #pathBar.shifted #hspace{ + margin-right: -.3em; +} html.by #up_quick_more a, html.by #spaceTotal_bar, html.by #ops>a { @@ -4333,10 +4343,6 @@ html.e #wrap.thin .ghead { #pathBar.thin .popup { position: relative; } - html.fy #actionsArea, - html.fy #pathBar.thin #actionsArea { - right: 0; - } #folder_search { margin: .5em 1em 0 .2em; } @@ -4835,6 +4841,12 @@ html.e input[type="submit"] { background: var(--bg); border: 0; } +html.e #wfp a { + margin: 0; +} +html.e #pathBar.shifted #hspace{ + margin-right: -.4em; +} html.e #ops { background: transparent; } @@ -4975,15 +4987,14 @@ html.e #u2btn { } html.e #ops { /*HC*/ - gap: 0.6em; font-size: larger; padding: 0; height: 2em; } html.e #srchfolder_div { - left: 2em; - top: -.1em; - bottom: 0; + left: 2.5em; + top: -.2em; + bottom: -.2em; } html.e #qs_btns { top: .3em; @@ -5004,8 +5015,7 @@ html.e #ops a { } html.e #ops a { text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.5); - height: 1.4em; - padding: 0; + height: 1.3em; box-shadow: var(--shadow-outset); background: var(--bg); justify-content: center; @@ -5391,9 +5401,6 @@ html.e #detree { html.e #wtc { margin: -.2em 0 -.5em .1em; } -html.e #actionsArea { - margin-right: .5em; -} #rcm { position: fixed; @@ -5539,7 +5546,7 @@ html.by #spaceUsed_bar { } #op_acc a:not([hidden]):not(.btn), #op_acc input:not([hidden]) { - font-size: 1.2em; + font-size: 1.1em; display: block; cursor: pointer; } @@ -5663,7 +5670,7 @@ html.f #ggrid .au.thumbed:not(.play) .imgcontainer::before { border: var(--bg-u2) solid; z-index: 3; border-width: 4em 4em 0 0; - border-color: var(--bg-u2) transparent transparent var(--bg-u2); + border-color: var(--g-bfbg) transparent transparent var(--g-bfbg); margin: 0 2px; } html.f #ggrid > a.play::before { @@ -5795,6 +5802,7 @@ html.fz { --bg: #2e258c; --bg: hsl(from var(--a) calc(h * 2.5 + 55) calc(s * .6) calc(l * .7)); --a2: hsl(from var(--bg) calc(h - 40) calc(s * 1.2) calc(l * 1.4)); + --g-bfbg: var(--bg-u2); } html.fz #wrap::before { content: ''; @@ -5819,10 +5827,15 @@ html.fz #ops { border: var(--btn-bb); } html.fz .ghead { - margin-left: -1px; + margin-top: -.2em; + top: 3.6em; } html.fz #wfp .btn { padding: .25em .4em; + margin-right: .3em; +} +html.fz #path{ + margin-right: .3em; } html.fy { @@ -5835,6 +5848,10 @@ html.fy { --scrl-hint: var(--bg-u2); --tree-bg: var(--bg-u2); --g-f-bg: color-mix(in oklab, var(--bg-u3), var(--bg)); + --g-fg: var(--bg-u2); + --g-bg: color-mix(var(--bg-u2) 5%, transparent); + --g-g1: color-mix(var(--bg-u2) 5%, transparent); + --g-bfbg: color-mix(in oklab, var(--bg-max) 95%, var(--fg-max)); } html.fy * { box-shadow: none !important; @@ -5947,9 +5964,6 @@ html.fy #wfp .btn { html.fy #actionsArea { margin-left: auto; } -html.fy #pathBar.shifted #hspace { - min-width: 3.5em; -} html.fy #wfp .btn { padding: .45em; } diff --git a/copyparty/web/browser.html b/copyparty/web/browser.html index 2254d488..a6cf4b9d 100644 --- a/copyparty/web/browser.html +++ b/copyparty/web/browser.html @@ -47,9 +47,9 @@
      - - - +
      {%- for n in vpnodes %} From 021bdab910e958215cbb3adc2053f333cbd9151b Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Sun, 21 Jun 2026 16:07:09 +0200 Subject: [PATCH 623/623] minor css fixes --- copyparty/web/browser.css | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 3b4916cc..803b8dfd 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -634,7 +634,7 @@ html .ayjump:focus-visible { font-weight: normal; display: block; margin: 0 .5em 0 0; - width: calc(100% - .5em); + width: calc(100% - .6em); padding: 0 .25em; font-size: 1.2em; white-space: nowrap; @@ -1833,7 +1833,7 @@ html:not(.e):not(.d) #up_quick .btn.on { } html.f #mu_outer, html.b #mu_outer { - background: color-mix(in oklab, var(--bg-u2) 70%, transparent); + background: color-mix(in oklab, var(--a) 10%, var(--bg-u2) 10%, transparent); backdrop-filter: blur(32px); } #h_music { @@ -1860,6 +1860,8 @@ html.b #mu_outer { } #mu_th svg { margin: 0 auto; + min-width: 100%; + height: 100%; } #mu_th span { font-size: 8vh; @@ -4362,6 +4364,10 @@ html.e #wrap.thin .ghead { .modalheader { padding: .8em 3em .8em .7em; } + html.f .modalheader { + padding-top: .6em; + padding-bottom: .6em; + } .modalsplit { display: block; overflow-y: auto; @@ -5671,7 +5677,7 @@ html.f #ggrid .au.thumbed:not(.play) .imgcontainer::before { z-index: 3; border-width: 4em 4em 0 0; border-color: var(--g-bfbg) transparent transparent var(--g-bfbg); - margin: 0 2px; + margin: 0 3px; } html.f #ggrid > a.play::before { background: var(--a);