/** * GoingsOn - Snooze Module * Snooze functionality for tasks, emails, and events */ (function() { 'use strict'; const esc = GoingsOn.utils.escapeHtml; const escAttr = GoingsOn.utils.escapeAttr; const ITEM_LABEL = { task: 'Task', email: 'Email', event: 'Event' }; function apiFor(itemType) { if (itemType === 'task') return GoingsOn.api.tasks; if (itemType === 'email') return GoingsOn.api.emails; return GoingsOn.api.events; } function reloadFor(itemType) { if (itemType === 'task') return GoingsOn.tasks.load(); if (itemType === 'email') return GoingsOn.emails.load(); return GoingsOn.events.load(); } // ============ Snooze Functions ============ /** * Open the snooze modal with pre-computed time options. * @param {string} itemType - 'task', 'email', or 'event' * @param {string} id - Item ID to snooze */ async function openSnoozeModal(itemType, id) { // Get pre-computed snooze options from backend const response = await GoingsOn.api.snooze.getOptions(); const options = response.options; let optionsHtml = '
`; const label = ITEM_LABEL[itemType] || 'Item'; const hintHtml = `Hide this ${label.toLowerCase()} and bring it back at the chosen time.
`; GoingsOn.ui.openModal(`Snooze ${label}`, hintHtml + optionsHtml); } /** * Format an ISO datetime string as a short human-readable snooze time. * @param {string} isoString - ISO 8601 datetime string * @returns {string} Formatted date (e.g., "Mon, Apr 15, 9:00 AM") */ function formatSnoozeTime(isoString) { const date = new Date(isoString); const options = { weekday: 'short', month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit' }; return date.toLocaleDateString('en-US', options); } /** * Snooze a task, email, or event until the specified time. * @param {string} itemType - 'task', 'email', or 'event' * @param {string} id - Item ID to snooze * @param {string} until - ISO 8601 datetime to snooze until */ async function snoozeItem(itemType, id, until) { const label = ITEM_LABEL[itemType] || 'Item'; try { await apiFor(itemType).snooze(id, until); reloadFor(itemType); GoingsOn.ui.closeModal(); GoingsOn.ui.showToast(`${label} snoozed until ${formatSnoozeTime(until)}`); } catch (err) { GoingsOn.ui.showToast('Failed to snooze: ' + GoingsOn.utils.getErrorMessage(err), 'error'); } } /** * Snooze using the custom datetime-local picker value. * @param {string} itemType - 'task', 'email', or 'event' * @param {string} id - Item ID to snooze */ async function snoozeItemCustom(itemType, id) { const input = document.getElementById('snooze-custom-datetime'); if (!input.value) { GoingsOn.ui.showToast('Please select a date and time', 'error'); return; } // Parse datetime-local value as local time components to avoid UTC misinterpretation const [datePart, timePart] = input.value.split('T'); const [year, month, day] = datePart.split('-').map(Number); const [hours, minutes] = timePart.split(':').map(Number); const dt = new Date(year, month - 1, day, hours, minutes); const until = dt.toISOString(); await snoozeItem(itemType, id, until); } /** * Remove snooze from a task, email, or event. * @param {string} itemType - 'task', 'email', or 'event' * @param {string} id - Item ID to unsnooze */ async function unsnoozeItem(itemType, id) { const label = ITEM_LABEL[itemType] || 'Item'; try { await apiFor(itemType).unsnooze(id); reloadFor(itemType); GoingsOn.ui.closeModal(); GoingsOn.ui.showToast(`${label} unsnoozed`); } catch (err) { GoingsOn.ui.showToast('Failed to unsnooze: ' + GoingsOn.utils.getErrorMessage(err), 'error'); } } // ============ Populate GoingsOn.snooze Namespace ============ GoingsOn.snooze = { openModal: openSnoozeModal, snooze: snoozeItem, snoozeCustom: snoozeItemCustom, unsnooze: unsnoozeItem, formatTime: formatSnoozeTime, }; })();