120 lines
4.8 KiB
JavaScript
120 lines
4.8 KiB
JavaScript
(function (root, factory) {
|
|
if (typeof module === 'object' && module.exports) module.exports = factory;
|
|
else root.createProgressiveMobileDock = factory;
|
|
})(typeof self !== 'undefined' ? self : this, function createProgressiveMobileDock(options) {
|
|
const document = options.document;
|
|
const myWork = options.myWork;
|
|
const work = document.querySelector('[data-mobile-task="work"]');
|
|
const queues = document.querySelector('[data-mobile-task="queues"]');
|
|
const sheet = document.querySelector('#mobile-queue-sheet');
|
|
const close = document.querySelector('#close-mobile-queues');
|
|
const next = document.querySelector('#mobile-queue-next-action');
|
|
const rows = Object.fromEntries(Array.from(document.querySelectorAll('[data-mobile-queue]'))
|
|
.map(row => [row.dataset.mobileQueue, row]));
|
|
const countElements = Object.fromEntries(Array.from(document.querySelectorAll('[data-mobile-queue-count]'))
|
|
.map(element => [element.dataset.mobileQueueCount, element]));
|
|
const originalDescriptions = Object.fromEntries(Object.entries(rows)
|
|
.map(([name, row]) => [name, row.querySelector?.('small')?.textContent || '']));
|
|
const originalCounts = Object.fromEntries(Object.entries(countElements)
|
|
.map(([name, element]) => [name, element.textContent]));
|
|
const supported = new Set(['all', 'attention', 'filed', 'authored', 'issue', 'pull', 'review', 'update']);
|
|
const listeners = [];
|
|
let started = false;
|
|
let lastTask = null;
|
|
let unsubscribe = null;
|
|
|
|
function listen(element, name, listener) {
|
|
if (!element) return;
|
|
element.addEventListener(name, listener);
|
|
listeners.push([element, name, listener]);
|
|
}
|
|
|
|
function render() {
|
|
const counts = myWork?.counts?.() || {};
|
|
Object.entries(rows).forEach(([name, row]) => {
|
|
const count = Math.max(0, Number(counts[name]) || 0);
|
|
const countElement = countElements[name];
|
|
if (supported.has(name)) {
|
|
row.removeAttribute('data-unavailable');
|
|
row.removeAttribute('data-progressive-loading');
|
|
if (countElement) countElement.textContent = String(count);
|
|
return;
|
|
}
|
|
row.setAttribute('data-unavailable', 'true');
|
|
row.setAttribute('data-progressive-loading', 'true');
|
|
const description = row.querySelector?.('small');
|
|
if (description) description.textContent = 'Still loading';
|
|
if (countElement) countElement.textContent = '…';
|
|
});
|
|
const actionable = ['attention', 'filed', 'authored', 'review', 'update']
|
|
.find(name => Number(counts[name]) > 0);
|
|
if (next) {
|
|
if (actionable) {
|
|
next.textContent = 'Open ' + (actionable === 'authored' ? 'My PRs' : actionable[0].toUpperCase() + actionable.slice(1))
|
|
+ ' (' + counts[actionable] + ')';
|
|
next.dataset.queue = actionable;
|
|
next.removeAttribute('data-unavailable');
|
|
} else {
|
|
next.textContent = Number(counts.all) > 0 ? 'Open assigned work (' + counts.all + ')' : 'Assigned work is still loading';
|
|
next.dataset.queue = 'all';
|
|
if (!Number(counts.all)) next.setAttribute('data-unavailable', 'true');
|
|
}
|
|
}
|
|
}
|
|
|
|
function openSheet() {
|
|
lastTask = 'queues';
|
|
render();
|
|
if (sheet && !sheet.open) sheet.showModal();
|
|
}
|
|
|
|
function openQueue(name) {
|
|
if (!supported.has(name)) return false;
|
|
lastTask = 'work';
|
|
if (sheet?.open) sheet.close();
|
|
myWork?.selectQueue?.(name, {openFirst:true});
|
|
return true;
|
|
}
|
|
|
|
function start() {
|
|
if (started) return false;
|
|
started = true;
|
|
listen(work, 'click', () => { lastTask = 'work'; myWork?.openFirst?.(); });
|
|
listen(queues, 'click', openSheet);
|
|
listen(close, 'click', () => sheet?.open && sheet.close());
|
|
Object.entries(rows).forEach(([name, row]) => listen(row, 'click', () => openQueue(name)));
|
|
listen(next, 'click', () => openQueue(next.dataset.queue || 'all'));
|
|
unsubscribe = myWork?.subscribe?.(render) || null;
|
|
render();
|
|
return true;
|
|
}
|
|
|
|
function handoff() {
|
|
return {queueSheetOpen:Boolean(sheet?.open), lastTask};
|
|
}
|
|
|
|
function stop() {
|
|
listeners.splice(0).forEach(([element, name, listener]) => element.removeEventListener(name, listener));
|
|
unsubscribe?.();
|
|
unsubscribe = null;
|
|
Object.entries(rows).forEach(([name, row]) => {
|
|
row.removeAttribute('data-unavailable');
|
|
row.removeAttribute('data-progressive-loading');
|
|
const description = row.querySelector?.('small');
|
|
if (description) description.textContent = originalDescriptions[name];
|
|
if (countElements[name]) countElements[name].textContent = originalCounts[name];
|
|
});
|
|
started = false;
|
|
}
|
|
|
|
return {start, stop, handoff, render, openQueue};
|
|
});
|
|
|
|
if (typeof window !== 'undefined' && typeof document !== 'undefined') {
|
|
window.stackchainProgressiveMobileDock = createProgressiveMobileDock({
|
|
document,
|
|
myWork:window.stackchainProgressiveMyWork,
|
|
});
|
|
window.stackchainProgressiveMobileDock.start();
|
|
}
|