aboutsummaryrefslogtreecommitdiff
path: root/modules/ext/webdav.js
diff options
context:
space:
mode:
authorAgando <roduccomm@gmail.com>2026-10-26 15:21:14 +0100
committerAgando <roduccomm@gmail.com>2026-10-26 15:21:14 +0100
commit7904f3e9300a4ee02243728c185e8bfce0953bb1 (patch)
treea4d5b4c0a6038eb360cab61d6cc34d10499ad1c3 /modules/ext/webdav.js
parent0e3d019e8b2dcc335f02a277039368e8b7d36b03 (diff)
fix(newos4): four phone-test defects — no preview close, single-file share, dead-end fullscreen, silent WebDAV move
All four came from the operator's phone pass on v4.6.95 and each collapsed to a line of code. A "No file selected to download": the preview pane had no close control; the only ✕ was the file manager's own, and it calls _closeOverlay() which wipes _multiSelect/_selectedFile/_selectMode. On a phone the preview covers the list, so closing it before pressing Download always emptied the selection. The toolbar now starts with ✕ -> _clearPreview(), which keeps the selection and leaves fullscreen first; Download with no targets names the fix instead of stating a dead end. B share/copy: 🔗 existed only in the preview toolbar and took a single path, and after the Android share sheet there was no copy affordance. Added _sharePaths(paths, mode) used by both the toolbar (1 path, 📋 copy and 🔗 share) and a new action-bar 🔗 Share (whole selection), plus _inlineLinkBox() which renders a selectable input/textarea with all URLs when neither the share sheet nor the clipboard is available. No prompt() anywhere on this path. C fullscreen: requestFullscreen targeted .fm-preview-body, which sits INSIDE the pane but excludes the toolbar, so ⛶ and ✗ disappeared and only the OS back gesture got out. Now fullscreens #filemgr-preview — toolbar, ✕ and ⛶ stay on screen and ⛶ toggles. D webdav move: bulk Move asked for the destination with prompt(), which returns null in iOS standalone PWAs and most Android WebViews, so it silently did nothing and looked unimplemented. Destination is now an inline row in the bulk bar (44px input + "Move here"/"Cancel", prefilled). Verified on the served code: ext bundle md5 5f440c77b6ab5529729aee8019a6c351 (served == local), webdav.js carries wdav-move-dest x2, and a headless browser probe on the real page shows the toolbar as ["✕","⛶","📋","🔗"], closing the preview prints "Preview closed — selection kept" with the selection intact, selecting 3 files and copying yields a textarea with the 3 real WebDAV URLs, and Download with nothing selected explains what to do. 6 PASS on the URL test, no-undef clean, v4.6.99, help 362/362. Not done, deliberately: cut/copy + paste across the VFS/WebDAV border. Recorded as Issue D2 in the plan with the exact insertion points, the upload-then-delete ordering rule and the failure case.
Diffstat (limited to 'modules/ext/webdav.js')
-rw-r--r--modules/ext/webdav.js51
1 files changed, 38 insertions, 13 deletions
diff --git a/modules/ext/webdav.js b/modules/ext/webdav.js
index ed312a5..88f1f59 100644
--- a/modules/ext/webdav.js
+++ b/modules/ext/webdav.js
@@ -1962,19 +1962,44 @@ class WebDAVModule {
document.getElementById('bulk-move')?.addEventListener('click', function() {
const names = Object.entries(self._selected).filter(function(e) { return e[1]; }).map(function(e) { return e[0]; });
if (!names.length) return;
- let target = prompt('Move ' + names.length + ' item(s) to directory:', '/');
- if (!target) return;
- target = target.replace(/\/+$/, '');
- names.forEach(function(name) {
- const oldFull = (path.replace(/\/+$/, '') || '') + '/' + name;
- const newFull = target + '/' + name;
- self._webdavRequest('MOVE', oldFull, { headers: { 'Destination': self._absoluteUrl(newFull) } })
- .then(function(r) {
- if (r.ok || r.status === 201 || r.status === 204) self.terminal.print('Moved: ' + name, 'success');
- else self.terminal.print('Move failed: ' + name + ' (HTTP ' + r.status + ')', 'error');
- });
- });
- setTimeout(function() { self.openWebdavBrowser(path); }, 500);
+ // 2026-10-26 (phone test): prompt() is suppressed in iOS standalone PWAs and most
+ // Android WebViews — it returns null, so "Move" looked like a missing feature.
+ // Ask for the destination inline in the bulk bar instead.
+ const doMove = function(rawTarget) {
+ const target = String(rawTarget || '').trim().replace(/\/+$/, '');
+ if (!target) { self.terminal.print('Move cancelled — no destination', 'error'); return; }
+ names.forEach(function(name) {
+ const oldFull = (path.replace(/\/+$/, '') || '') + '/' + name;
+ const newFull = target + '/' + name;
+ self._webdavRequest('MOVE', oldFull, { headers: { 'Destination': self._absoluteUrl(newFull) } })
+ .then(function(r) {
+ if (r.ok || r.status === 201 || r.status === 204) self.terminal.print('Moved: ' + name + ' → ' + newFull, 'success');
+ else self.terminal.print('Move failed: ' + name + ' (HTTP ' + r.status + ')', 'error');
+ })
+ .catch(function(e) { self.terminal.print('Move failed: ' + name + ' — ' + (e && e.message ? e.message : e), 'error'); });
+ });
+ setTimeout(function() { self.openWebdavBrowser(target); }, 600);
+ };
+ const bar = document.getElementById('wdav-bulk-bar');
+ let row = document.getElementById('wdav-move-row');
+ if (row) { row.remove(); row = null; }
+ if (!bar) { doMove(path || '/'); return; }
+ row = document.createElement('div');
+ row.id = 'wdav-move-row';
+ row.style.cssText = 'display:flex;gap:8px;align-items:center;width:100%;padding-top:8px;flex-wrap:wrap';
+ row.innerHTML = '<span style="font-size:0.9em;color:var(--text-color)">Move ' + names.length +
+ ' to:</span><input id="wdav-move-dest" type="text" aria-label="Destination directory" ' +
+ 'style="flex:1;min-width:120px;min-height:44px;padding:6px 10px;font-size:1em;border-radius:4px;' +
+ 'border:1px solid var(--border);background:var(--bg-primary);color:var(--text-color)">' +
+ '<button class="btn" id="wdav-move-go" style="min-height:44px;padding:0 14px">Move here</button>' +
+ '<button class="btn" id="wdav-move-cancel" style="min-height:44px;padding:0 14px">Cancel</button>';
+ bar.appendChild(row);
+ const dest = row.querySelector('#wdav-move-dest');
+ dest.value = (path || '/').replace(/\/+$/, '') || '/';
+ row.querySelector('#wdav-move-go').onclick = function() { const v = dest.value; row.remove(); doMove(v); };
+ row.querySelector('#wdav-move-cancel').onclick = function() { row.remove(); };
+ dest.focus();
+ dest.select();
});
document.getElementById('bulk-download')?.addEventListener('click', function() {
const names = Object.entries(self._selected).filter(function(e) { return e[1]; }).map(function(e) { return e[0]; });