build-container / build (push) Successful in 20m19s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
64 lines
5.0 KiB
JavaScript
64 lines
5.0 KiB
JavaScript
'use strict';
|
|
// ---- File actions
|
|
const PREVIEW = { img: 'jpg jpeg png gif webp svg bmp heic avif', pdf: 'pdf', video: 'mp4 mov m4v webm', audio: 'mp3 m4a wav flac ogg aac opus', text: 'txt md markdown json csv tsv log xml yml yaml ini conf cfg toml js ts css html htm py sh sql env gitignore' };
|
|
const previewKind = n => Object.keys(PREVIEW).find(k => PREVIEW[k].split(' ').includes(ext(n)));
|
|
const FORM = { 'Content-Type': 'application/x-www-form-urlencoded' };
|
|
const encP = p => p.split('/').map(encodeURIComponent).join('/');
|
|
const fileUrl = async (repo, path) => { const u = new URL(await sf.req(`/api2/repos/${encodeURIComponent(repo)}/file/?p=${encodeURIComponent(path)}&reuse=1`), cfg.seafile); return '/sf' + u.pathname; };
|
|
|
|
// Recently opened files, shown on Home (kept in this browser only).
|
|
function addRecent(repo, path, name) {
|
|
const r = store.get('recents', []).filter(x => !(x.repo === repo && x.path === path));
|
|
r.unshift({ repo, path, name, t: Date.now() }); store.set('recents', r.slice(0, 12));
|
|
}
|
|
|
|
// Default tap on a file: edit documents, preview media, otherwise show the actions.
|
|
function openFile(repo, path, name, dir) {
|
|
if (cfg.editor && EDIT_EXT.has(ext(name)) && ext(name) !== 'txt') { addRecent(repo, path, name); location.hash = '#/edit/' + encodeURIComponent(repo) + path.split('/').filter(Boolean).map(s => '/' + encodeURIComponent(s)).join(''); }
|
|
else if (previewKind(name)) previewFile(repo, path, name);
|
|
else fileSheet(repo, path, name, dir);
|
|
}
|
|
|
|
async function previewFile(repo, path, name) {
|
|
addRecent(repo, path, name);
|
|
if (previewKind(name) === 'text') return textPreview(repo, path, name).catch(e => toast(e.message));
|
|
try {
|
|
const url = (await fileUrl(repo, path)) + '?hubinline=1', kind = previewKind(name);
|
|
const media = kind === 'img' ? `<img src="${url}" alt="${esc(name)}" style="max-width:100%;max-height:70dvh;border-radius:12px;display:block;margin:8px auto">`
|
|
: kind === 'pdf' ? `<iframe src="${url}" title="${esc(name)}" style="width:100%;height:70dvh;border:0;border-radius:12px;background:#fff"></iframe>`
|
|
: kind === 'video' ? `<video src="${url}" controls playsinline style="width:100%;max-height:70dvh;border-radius:12px;background:#000"></video>`
|
|
: `<audio src="${url}" controls style="width:100%;margin:12px 0"></audio>`;
|
|
const el = openSheet(name, '', `${media}<div class="bar"><a class="btn ghost" href="${url.replace('?hubinline=1', '')}" target="_blank" rel="noopener">${icon('dl')}Open</a><button class="btn ghost" id="sx">Close</button></div>`);
|
|
el.querySelector('.sheet').classList.add('wide'); el.querySelector('#sx').onclick = closeSheet;
|
|
} catch (e) { toast(e.message); }
|
|
}
|
|
|
|
const shareLink = (repo, path, isDir) => shareSheet(repo, path, isDir);
|
|
|
|
function fileSheet(repo, path, name, dir) {
|
|
const enc = encodeURIComponent, acts = [], ro = libPerm[repo] === 'r', it = { name, type: 'file' };
|
|
if (previewKind(name)) acts.push({ label: 'Preview', icon: 'doc', run: () => previewFile(repo, path, name) });
|
|
if (cfg.editor && EDIT_EXT.has(ext(name)) && !ro) acts.push({ label: 'Edit here', icon: 'edit', run: () => { addRecent(repo, path, name); location.hash = '#/edit/' + enc(repo) + path.split('/').filter(Boolean).map(s => '/' + enc(s)).join(''); } });
|
|
if (OFFICE_EXT.has(ext(name))) acts.push({ label: 'Open in Seafile', icon: 'doc', run: () => window.open(`${cfg.seafile}/lib/${enc(repo)}/file${path.split('/').map(enc).join('/')}`, '_blank', 'noopener') });
|
|
acts.push({ label: 'Share link', icon: 'copy', run: () => shareLink(repo, path, false) });
|
|
acts.push({ label: 'Download', icon: 'dl', run: () => downloadItem(repo, path) });
|
|
acts.push({ label: 'Version history', icon: 'refresh', run: () => fileHistory(repo, path, name, ro) });
|
|
if (!ro) acts.push({ label: 'Rename', icon: 'edit', run: () => renameItem(repo, path, name, dir, false) });
|
|
if (!ro) acts.push({ label: 'Move to…', icon: 'files', run: () => moveSheet('move', repo, dir, [it]) });
|
|
acts.push({ label: 'Copy to…', icon: 'copy', run: () => moveSheet('copy', repo, dir, [it]) });
|
|
if (!ro) acts.push({ label: 'Delete', icon: 'trash', danger: true, run: () => deleteItems(repo, dir, [it]) });
|
|
actionSheet(name, '', acts);
|
|
}
|
|
|
|
function dirSheet(repo, path, name, dir) {
|
|
const ro = libPerm[repo] === 'r', it = { name, type: 'dir' };
|
|
actionSheet(name, 'Folder', [
|
|
{ label: 'Open', icon: 'files', run: () => { location.hash = '#/files/' + encodeURIComponent(repo) + path.split('/').filter(Boolean).map(s => '/' + encodeURIComponent(s)).join(''); } },
|
|
{ label: 'Share link', icon: 'copy', run: () => shareLink(repo, path, true) },
|
|
{ label: 'Download as zip', icon: 'dl', run: () => zipDownload(repo, dir, [name]) },
|
|
...(ro ? [] : [{ label: 'Rename', icon: 'edit', run: () => renameItem(repo, path, name, dir, true) }, { label: 'Move to…', icon: 'files', run: () => moveSheet('move', repo, dir, [it]) }]),
|
|
{ label: 'Copy to…', icon: 'copy', run: () => moveSheet('copy', repo, dir, [it]) },
|
|
...(ro ? [] : [{ label: 'Delete', icon: 'trash', danger: true, run: () => deleteItems(repo, dir, [it]) }]),
|
|
]);
|
|
}
|