feat: rename a file in place from its row in the file manager

This commit is contained in:
redtea committed 2026-10-14 15:25:50 +03:00
1 parent 225b7ecfcc
commit 10b8995041
1 file changed
+14 -2
+14 -2
View File
@@ -29,7 +29,7 @@
.act { display:flex; gap:6px; justify-content:flex-end; }
table.fm .c-sz { width:120px; }
table.fm .c-mt { width:160px; }
table.fm .c-act { width:160px; }
table.fm .c-act { width:200px; }
.fm .nm { overflow-wrap:anywhere; }
/* Phones: no date column, and the row buttons only as wide as they are. */
@media (max-width: 640px) {
@@ -128,6 +128,7 @@
// Monochrome inline icons (inherit button color via currentColor).
const SVG = '<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">';
const ICON_DL = SVG + '<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>';
const ICON_REN = SVG + '<path d="M12 20h9"/><path d="M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4 12.5-12.5z"/></svg>';
const ICON_MV = SVG + '<polyline points="5 9 2 12 5 15"/><polyline points="9 5 12 2 15 5"/><polyline points="15 19 12 22 9 19"/><polyline points="19 9 22 12 19 15"/><line x1="2" y1="12" x2="22" y2="12"/><line x1="12" y1="2" x2="12" y2="22"/></svg>';
const ICON_DEL = SVG + '<path d="M3 6h18"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/><line x1="10" y1="11" x2="10" y2="17"/><line x1="14" y1="11" x2="14" y2="17"/></svg>';
let cwd = '/';
@@ -175,13 +176,15 @@
'<td><div class="act">' +
(isZip?'<button class="btn ghost small" data-act="unzip">unzip</button>':'') +
(e.is_dir?'':'<a class="btn ghost small icon" title="Скачать" href="'+dlHref+'" download>'+ICON_DL+'</a>') +
'<button class="btn ghost small icon" data-act="ren" title="Переместить / переименовать">'+ICON_MV+'</button>' +
'<button class="btn ghost small icon" data-act="name" title="Переименовать">'+ICON_REN+'</button>' +
'<button class="btn ghost small icon" data-act="ren" title="Переместить">'+ICON_MV+'</button>' +
'<button class="btn danger small icon" data-act="del" title="Удалить">'+ICON_DEL+'</button>' +
'</div></td>';
const nm = tr.querySelector('.nm');
nm.onclick = () => e.is_dir ? load(join(cwd, e.name)) : view(e);
tr.querySelector('.ck').onchange = ev => { const n=e.name; ev.target.checked?selected.add(n):selected.delete(n); updateSel(); };
tr.querySelector('[data-act="del"]').onclick = () => del(e);
tr.querySelector('[data-act="name"]').onclick = () => rename(e);
tr.querySelector('[data-act="ren"]').onclick = () => move(e);
const uz = tr.querySelector('[data-act="unzip"]'); if (uz) uz.onclick = () => unzip(e);
tb.appendChild(tr);
@@ -239,6 +242,15 @@
r.ok ? (toast('перемещено'), load(cwd)) : toast(r.error||'ошибка', true);
}
// Rename in place: only the name is asked for, the folder stays.
async function rename(e) {
const n = prompt('Новое имя:', e.name);
if (!n || n === e.name) return;
if (n.includes('/')) { toast('имя без "/" - чтобы перенести в другую папку, есть кнопка «Переместить»', true); return; }
const r = await api('move', {src: join(cwd, e.name), dst: join(cwd, n)});
r.ok ? (toast('переименовано'), load(cwd)) : toast(r.error||'ошибка', true);
}
async function unzip(e) {
const r = await api('unzip', {path: join(cwd, e.name), dest: cwd});
r.ok ? (toast('распаковано'), load(cwd)) : toast(r.error||'ошибка', true);