ui-option to force-download files (closes #1058);

* button "dl" in settings UI (always takes precedence)
* global-option and/or volflag "dlni"
* url-parameter ?dlni or ?dlni=0

the preference is applied per-volume when navigating between folders,
unless the settings-button has been toggled, which overrides that
This commit is contained in:
ed 2025-12-01 19:02:03 +00:00
parent fcc1bdfbf5
commit a9174e5dee
4 changed files with 22 additions and 1 deletions

View file

@ -1793,6 +1793,7 @@ def add_ui(ap, retry: int):
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("--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("--favico", metavar="TXT", type=u, default="c 000 none" if retry else "🎉 000 none", help="\033[33mfavicon-text\033[0m [ \033[33mforeground\033[0m [ \033[33mbackground\033[0m ] ], set blank to disable")
ap2.add_argument("--ufavico", metavar="TXT", type=u, default="", help="URL to .ico/png/gif/svg file; \033[33m--favico\033[0m takes precedence unless disabled (volflag=ufavico)")

View file

@ -3049,6 +3049,8 @@ class AuthSrv(object):
vn.js_ls = {
"idx": "e2d" in vf,
"itag": "e2t" in vf,
"dlni": "dlni" in vf,
"dgrid": "grid" in vf,
"dnsort": "nsort" in vf,
"dhsortn": vf["hsortn"],
"dsort": vf["sort"],
@ -3091,7 +3093,8 @@ class AuthSrv(object):
"unlist0": vf.get("unlist") or "",
"see_dots": self.args.see_dots,
"dqdel": self.args.qdel,
"dgrid": "grid" in vf,
"dlni": vn.js_ls["dlni"],
"dgrid": vn.js_ls["dgrid"],
"dgsel": "gsel" in vf,
"dnsort": "nsort" in vf,
"dhsortn": vf["hsortn"],

View file

@ -30,6 +30,7 @@ def vf_bmap() -> dict[str, str]:
}
for k in (
"dedup",
"dlni",
"dotsrch",
"e2d",
"e2ds",
@ -318,6 +319,7 @@ flagcats = {
"hsortn": "number of sort-rules to add to media URLs",
"ufavico=URL": "per-volume favicon (.ico/png/gif/svg)",
"unlist": "dont list files matching REGEX",
"dlni": "force-download (no-inline) files on click",
"html_head=TXT": "includes TXT in the <head>, or @PATH for file at PATH",
"html_head_s=TXT": "additional static text in the html <head>",
"tcolor=#fc0": "theme color (a hint for webbrowsers, discord, etc.)",

View file

@ -226,6 +226,7 @@ if (1)
"ct_ttips": '◔ ◡ ◔"> tooltips',
"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_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',
"ct_qdel": 'when deleting files, only ask for confirmation once">qdel',
@ -878,6 +879,7 @@ ebi('op_cfg').innerHTML = (
' <a id="griden" class="tgl btn" href="#" tt="' + L.wt_grid + '">' + L.ct_grid + '</a>\n' +
' <a id="thumbs" class="tgl btn" href="#" tt="' + L.ct_thumb + '</a>\n' +
' <a id="csel" class="tgl btn" href="#" tt="' + L.ct_csel + '</a>\n' +
' <a id="dlni" class="tgl btn" href="#" tt="' + L.ct_dl + '</a>\n' +
' <a id="ihop" class="tgl btn" href="#" tt="' + L.ct_ihop + '</a>\n' +
' <a id="dotfiles" class="tgl btn" href="#" tt="' + L.ct_dots + '</a>\n' +
' <a id="qdel" class="tgl btn" href="#" tt="' + L.ct_qdel + '</a>\n' +
@ -6603,6 +6605,9 @@ var treectl = (function () {
mentered = null,
treesz = clamp(icfg_get('treesz', 16), 10, 50);
if (/[?&]dlni\b/.exec(sloc0))
swrite('dlni', /[?&]dlni=0\b/.exec(sloc0) ? 0 : 1);
var resort = function () {
ENATSORT = NATSORT && clgot(ebi('nsort'), 'on');
treectl.gentab(get_evpath(), treectl.lsc);
@ -6611,6 +6616,7 @@ var treectl = (function () {
bcfg_bind(r, 'idxh', 'idxh', idxh, setidxh);
bcfg_bind(r, 'dyn', 'dyntree', true, onresize);
bcfg_bind(r, 'csel', 'csel', dgsel);
bcfg_bind(r, 'dlni', 'dlni', dlni, resort);
bcfg_bind(r, 'dots', 'dotfiles', see_dots, function (v) {
r.goto();
setck('dots=' + (v ? 'y' : ''));
@ -7160,6 +7166,10 @@ var treectl = (function () {
dth3x = res.dth3x;
dk = res.dk;
dlni = res.dlni;
if (!sread('dlni'))
clmod(ebi('dlni'), 'on', treectl.dlni = dlni);
srvinf = res.srvinf;
if (rtt !== null)
srvinf += (srvinf ? '</span> // <span>rtt: ' : 'rtt: ') + rtt;
@ -7346,6 +7356,11 @@ var treectl = (function () {
html.push('</tbody>');
html = html.join('\n');
set_files_html(html);
if (r.dlni) {
var o = QSA('#files a[id]');
for (var a = 0, aa = o.length; a < aa; a++)
o[a].setAttribute('download', '');
}
if (r.trunc) {
r.setlazy(plain);
if (!r.ask) {