Files
ytplayer/frontend/download-actions.js
2026-10-09 14:28:42 +08:00

60 lines
3.2 KiB
JavaScript

/* One action control for the Downloads page and Settings download manager. */
(function(root) {
'use strict';
// One SVG definition per media concept; every instance inherits its control colour.
const mediaPaths = {
download: '<path d="M12 3v12m-5-5 5 5 5-5M4 17v4h16v-4"/>',
offline: '<circle cx="12" cy="12" r="9"/><path d="m7.5 12 3 3 6-6"/>',
progress: '<path d="M12 3a9 9 0 1 1-9 9"/>'
};
const variants = {
'classic': mediaPaths,
'f7-swipe': {
download: '<path d="M12 3v12m-5-5 5 5 5-5M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2"/>',
offline: '<circle cx="12" cy="12" r="9"/><path d="m8 12 3 3 5-6"/>',
progress: '<path d="M12 3a9 9 0 1 1-9 9"/>'
},
'glass-stage': {
download: '<path d="M12 4v11m-4-4 4 4 4-4M5 20h14"/>',
offline: '<circle cx="12" cy="12" r="8"/><path d="m8.5 12 2.5 2.5 4.5-5"/>',
progress: '<path d="M12 4a8 8 0 1 1-8 8"/>'
},
'bento-hub': {
download: '<path d="M12 4v11m-4-4 4 4 4-4M5 17v3h14v-3"/>',
offline: '<rect x="4" y="4" width="16" height="16" rx="4"/><path d="m8 12 3 3 5-6"/>',
progress: '<path d="M12 4a8 8 0 1 1-8 8"/>'
}
};
const use = kind => `<use href="#media-${kind}"/>`;
const svg = (kind, extra = '') => `<svg class="media-icon ${extra}" data-media-icon="${kind}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${use(kind)}</svg>`;
const media = { paths: mediaPaths, use, svg };
if (root.document) {
const defs = root.document.createElementNS('http://www.w3.org/2000/svg', 'svg');
defs.setAttribute('aria-hidden', 'true'); defs.setAttribute('width', '0'); defs.setAttribute('height', '0');
defs.style.position = 'absolute'; defs.style.pointerEvents = 'none';
defs.innerHTML = '<defs>' + Object.keys(mediaPaths).map(kind => `<g id="media-${kind}">${Object.entries(variants).map(([layout, paths]) => `<g class="media-shape media-shape-${layout}">${paths[kind]}</g>`).join('')}</g>`).join('') + '</defs>';
root.document.body.appendChild(defs);
root.MediaIcons = media;
}
const paths = {
retry: '<path d="M3 11a9 9 0 1 1 2.6 7M3 3v8h8"/>',
cancel: '<path d="m6 6 12 12M6 18 18 6"/>',
pause: '<path d="M8 5v14M16 5v14"/>',
resume: '<path d="m9 5 10 7-10 7z"/>',
};
function create(doc, action, title) {
if (!paths[action]) throw new Error('Unknown download action');
const label = action[0].toUpperCase() + action.slice(1);
const button = doc.createElement('button'); button.type = 'button';
button.className = `dl-act download-action${action === 'cancel' ? ' danger' : ''}`;
button.setAttribute('aria-label', `${label} ${title}`);
const icon = doc.createElementNS('http://www.w3.org/2000/svg', 'svg');
icon.setAttribute('viewBox', '0 0 24 24'); icon.setAttribute('aria-hidden', 'true'); icon.setAttribute('focusable', 'false');
icon.classList.add('download-action-icon'); icon.innerHTML = paths[action];
const text = doc.createElement('span'); text.textContent = label;
button.append(icon, text); return button;
}
const api = { create, media };
if (typeof module !== 'undefined' && module.exports) module.exports = api; else root.DownloadActions = api;
})(globalThis);