Files
taskdecay/lib/review.js
T

97 lines
4.1 KiB
JavaScript

let items = [];
let doneIds = new Set();
document.addEventListener('DOMContentLoaded', async () => {
const container = document.getElementById('container');
const progress = document.getElementById('progress');
try {
const res = await chrome.runtime.sendMessage({ type: 'getReviewTasks' });
if (res.error) {
container.innerHTML = `<div class="error">${escapeHtml(res.error)}</div>`;
return;
}
items = res.review || [];
render();
}
catch (e) {
container.innerHTML = `<div class="error">${escapeHtml(e.message)}</div>`;
}
function render() {
const remaining = items.filter(i => !doneIds.has(i.task.id));
progress.textContent = `${items.length - remaining.length} / ${items.length} reviewed`;
if (remaining.length === 0) {
container.innerHTML = `
<div class="empty-state">
<h2>All caught up!</h2>
<p>No more decayed tasks to review. Come back next week.</p>
</div>
`;
chrome.runtime.sendMessage({ type: 'setLastReviewDate', date: new Date().toISOString() }).catch(() => { });
return;
}
container.innerHTML = '';
for (const item of remaining) {
container.appendChild(renderCard(item));
}
}
function renderCard(item) {
const card = document.createElement('div');
card.className = 'card';
card.id = `card-${item.task.id}`;
const pillClass = item.score.score >= 70 ? 'score-hot' : item.score.score >= 40 ? 'score-warm' : 'score-cold';
card.innerHTML = `
<div class="card-header">
<div class="title">${escapeHtml(item.task.title)}</div>
<div class="score-pill ${pillClass}">${item.score.score} decay</div>
</div>
<div class="meta">
<span>${escapeHtml(item.task.source)}</span>
${item.task.projectName ? `<span>Project: ${escapeHtml(item.task.projectName)}</span>` : ''}
${item.task.labels.length > 0 ? `<span>Labels: ${escapeHtml(item.task.labels.join(', '))}</span>` : ''}
<span>Age: ${Math.round(item.score.ageDays)} days</span>
</div>
<div class="meta">${escapeHtml(item.score.explanation)}</div>
<div class="actions">
<button class="btn btn-done" data-action="complete" data-id="${item.task.id}">Mark Done</button>
<button class="btn btn-archive" data-action="delete" data-id="${item.task.id}">Delete</button>
<button class="btn btn-dismiss" data-action="dismiss" data-id="${item.task.id}">Dismiss</button>
<a href="${escapeHtml(item.task.url)}" target="_blank" class="btn btn-open">Open</a>
</div>
`;
card.querySelectorAll('button[data-action]').forEach(btn => {
btn.addEventListener('click', async (e) => {
const target = e.currentTarget;
const action = target.getAttribute('data-action');
const id = target.getAttribute('data-id');
target.textContent = '...';
try {
if (action === 'complete') {
await chrome.runtime.sendMessage({ type: 'complete', taskId: id });
}
else if (action === 'delete') {
await chrome.runtime.sendMessage({ type: 'delete', taskId: id });
}
else if (action === 'dismiss') {
await chrome.runtime.sendMessage({ type: 'dismiss', taskId: id });
}
doneIds.add(id);
const c = document.getElementById(`card-${id}`);
if (c) {
c.classList.add('done');
}
setTimeout(render, 300);
}
catch (err) {
target.textContent = 'Error';
}
});
});
return card;
}
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
});
export {};