import { t } from './i18n.js'; import * as platform from './platform.js'; import { groupLinkRoute } from './group-link.js'; /** * "Copy link": the `#/name@owner/path` address of a file or folder * (group-link.js), on this hub, put on the clipboard. * * The hub's origin, never the page's: in the desktop application the page is * `app://meshbay`, and a link that only opens inside one person's application * is not a link. */ /** The full link to `path` inside `group` (`{ name, owner_username }`). */ export function groupItemLink(group, path) { return platform.hubOrigin() + '/#' + groupLinkRoute(group, path); } /** An entry's path inside its group: its folder, root first, then its name. */ export function entryPath(entry, dir = entry.path) { return [dir, entry.name].filter(Boolean).join('/'); } // The async clipboard first; the old command where it is refused — a page // without focus, a WebView without the permission. Neither needs to read // anything back. async function _write(text) { try { await navigator.clipboard.writeText(text); return true; } catch { /* fall through */ } const area = document.createElement('textarea'); area.value = text; area.setAttribute('readonly', ''); area.style.cssText = 'position:fixed;top:0;left:0;opacity:0;pointer-events:none'; document.body.appendChild(area); area.select(); let ok = false; try { ok = document.execCommand('copy'); } catch { ok = false; } area.remove(); return ok; } let _note = null; let _noteTimer = null; // Said once and gone, in the playlists' note (style.css `.playlist-note`). // Appended to the body rather than rendered by a view, because the views that // copy include modals and a context menu that has already closed. function _say(text) { if (!_note) { _note = document.createElement('div'); _note.className = 'playlist-note copy-link-note'; _note.setAttribute('role', 'status'); } _note.textContent = text; document.body.appendChild(_note); clearTimeout(_noteTimer); _noteTimer = setTimeout(() => { if (_note) _note.remove(); }, 2500); } /** Copy `url`, and say whether it worked. The link itself is shown if not. */ export async function copyLink(url) { if (!url) return; const ok = await _write(url); _say(ok ? t('link.copied') : t('link.copy_failed', { url })); }