diff --git a/index.html b/index.html index 675ef5a..1738a8e 100644 --- a/index.html +++ b/index.html @@ -5,12 +5,11 @@ - Hello World LSPlugin :) + Deadline Countdown LSPlugin :)
- diff --git a/index.js b/index.js index ea7d2ee..ee98281 100644 --- a/index.js +++ b/index.js @@ -1,24 +1,85 @@ -function renderCountdown(el) { - // add a countdown to the element - // change to - const time = el.querySelector("time") - const timeText = time.textContent - - const timeTextParts = timeText.split(" ") - const timeDate = moment(timeTextParts[0]).toDate() - - const now = new Date() - const daysDiff = daysDifference(now, timeDate) - const daysText = daysDiff === 1 ? "day" : "days" - time.textContent = `${timeText} (${daysDiff} ${daysText} left)` +const SETTINGS_SCHEMA = [ + { + key: 'show-future', + type: 'boolean', + title: 'Future', + description: 'Add annotation for events in the future', + default: true, + }, + { + key: 'show-past', + type: 'boolean', + title: 'Past', + description: 'Add annotation for events in the past', + default: true, + }, + { + key: 'minimum-interval', + type: 'enum', + title: 'Minimum interval', + enumPicker: 'select', + enumChoices: ['days', 'hours', 'minutes', 'seconds'], + description: 'If set to hours, the annotation will only be added if the interval is at least an hour. Note: Annotations are only generated when the page loads and do not update in real time.', + default: 'hours', + }, +]; + + +const INTERVALS = [ + ['d', 86400], + ['h', 3600], + ['m', 60], + ['s', 1], +]; + + +const INTERVALS_LOOKUP = Object.fromEntries(INTERVALS); + + +let cfgShowFuture = true, cfgShowPast = true, cfgMinInterval = 60; + + +function settingsHandler(newSettings, _oldSettings) { + cfgShowFuture = newSettings['show-future'] !== false; + cfgShowPast = newSettings['show-past'] !== false; + cfgMinInterval = INTERVALS_LOOKUP[(newSettings['minimum-interval'] || 'm')[0]]; +} + + + +function prettyTimeDifference(sec, minSec) { + minSec = minSec === undefined ? 60 : minSec; + let result = []; + for (const [label, interval] of INTERVALS) { + if (sec < minSec) break; + if (sec < interval) continue; + const count = Math.trunc(sec / interval); + sec -= interval * count; + result.push(`${count}${label}`); + } + return result.join(' '); } -function daysDifference(d0, d1) { - var diff = d1.setHours(12) - d0.setHours(12); - return Math.round(diff / 8.64e7); + +function renderCountdown(el) { + const time = el.querySelector("time"); + if (!time) return; + const timeText = time.textContent, now = new Date(); + const timeTextParts = timeText.split(' '); + const timePart = timeTextParts[2] && !isNaN(timeTextParts[2][0]) ? timeTextParts[2] : ''; + const then = new Date(timeTextParts[0].concat(' ', timePart)); + if (then < now && !cfgShowPast) return; + if (then > now && !cfgShowFuture) return; + const diff = Math.floor(Math.abs(then - now) / 1000); + const prettyDiff = prettyTimeDifference(diff, cfgMinInterval); + if (prettyDiff === '') return; + time.textContent = `${timeText} (${then >= now ? 'in' : 'past'} ${prettyDiff})`; } + async function main() { + logseq.onSettingsChanged(settingsHandler); + logseq.useSettingsSchema(SETTINGS_SCHEMA); const pluginId = logseq.baseInfo.id console.info(`#${pluginId}: MAIN`) @@ -44,4 +105,4 @@ async function main() { } // bootstrap -logseq.ready(main).catch(console.error); \ No newline at end of file +logseq.ready(main).catch(console.error);