'use strict'; // ---- File actions const PREVIEW = { img: 'jpg jpeg png gif webp svg bmp heic', pdf: 'pdf', video: 'mp4 mov m4v webm', audio: 'mp3 m4a wav flac ogg aac' }; 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); try { const url = (await fileUrl(repo, path)) + '?hubinline=1', kind = previewKind(name); const media = kind === 'img' ? `${esc(name)}` : kind === 'pdf' ? `` : kind === 'video' ? `` : ``; const el = openSheet(name, '', `${media}
${icon('dl')}Open
`); el.querySelector('.sheet').classList.add('wide'); el.querySelector('#sx').onclick = closeSheet; } catch (e) { toast(e.message); } } async function shareLink(repo, path, isDir) { const p = isDir ? path.replace(/\/?$/, '/') : path; try { let link; try { link = (await sf.req('/api/v2.1/share-links/', { method: 'POST', headers: FORM, body: new URLSearchParams({ repo_id: repo, path: p }) })).link; } catch { link = (await sf.req(`/api/v2.1/share-links/?repo_id=${encodeURIComponent(repo)}&path=${encodeURIComponent(p)}`))[0]?.link; } if (!link) throw new Error('Could not create a share link'); const el = openSheet('Share link', p.split('/').filter(Boolean).pop() || '', `
${navigator.share ? '' : ''}
`); el.querySelector('#cp1').onclick = async () => { try { await navigator.clipboard.writeText(link); toast('Link copied'); closeSheet(); } catch { el.querySelector('#sl').select(); toast('Press copy on the selected link'); } }; const sh = el.querySelector('#sh1'); if (sh) sh.onclick = () => navigator.share({ url: link }).catch(() => {}); } catch (e) { toast(e.message); } } 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) }, ...(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]) }]), ]); }