From 904748317ce067be83997c31f910fffcf343c675 Mon Sep 17 00:00:00 2001 From: Mark Powers Date: Wed, 28 Aug 2024 22:44:32 -0500 Subject: [PATCH 1/5] Add border in calendar around days with notes This adds a border on calendar days that have notes. This works by setting an attribute on a form element, similar to how settings are passed into the calendar script. Currently, this implementation only will check for notes over the last year. --- src/calendar.ts | 7 +++++++ src/index.ts | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/calendar.ts b/src/calendar.ts index 976ca22..ebb56ad 100644 --- a/src/calendar.ts +++ b/src/calendar.ts @@ -25,6 +25,8 @@ const monday_first = date_ele.getAttribute('iso8601') === 'true' const timeFmt:any = parseInt(date_ele.getAttribute('timeFmt'),10) const theme:any = date_ele.getAttribute('theme') const enableWeekNum = date_ele.getAttribute('weekNum') === 'true' +const days_with_notes_ele = document.getElementById('days_with_notes') + const calendar = new VanillaCalendar('#datepicker', { actions: { clickDay(e, dates) { @@ -39,6 +41,11 @@ const calendar = new VanillaCalendar('#datepicker', { console.log(`Vanilla Calendar: hour: ${hours} minutes: ${minutes}`) console.log(`Vanilla Calendar: keeping: ${keeping}`) }, + getDays(day, date, HTMLElement, HTMLButtonElement) { + if(days_with_notes_ele.getAttribute(date)){ + HTMLButtonElement.style["border"] = "1px solid rgb(112, 112, 255)" + } + }, }, settings: { iso8601: monday_first, diff --git a/src/index.ts b/src/index.ts index 1a0ff73..f65c6a0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -222,7 +222,6 @@ async function createNoteByDate(d) { return note; } - joplin.plugins.register({ onStart: async function () { console.info('joplin-plugin-journal started!'); @@ -244,7 +243,38 @@ joplin.plugins.register({ const theme = await joplin.settings.value('Theme') || "light" const enableWeekNum = await joplin.settings.value('WeekNum') || false - await dialogs.setHtml(dialog, `
`); + // Iterate over year of dates + let now = new Date(new Date().getTime() - new Date().getTimezoneOffset()*60*1000) + let start = new Date(new Date().getTime() - new Date().getTimezoneOffset()*60*1000) + start.setDate(start.getDate() - 365) + let daysWithNotes = [] + for (var d = start; d <= now; d.setDate(d.getDate() + 1)) { + // Get the name of a note for this day + let noteName = await makeNoteName(d); + let parts = noteName.split("/") + + // Look for a note with that name + const paths = parts.slice(0, -1) + const noteTitle = parts[parts.length - 1] + async function traverse(parent_id, depth){ + if(depth == -1){ + return true + } + let folder = await joplin.data.get(['folders', parent_id]); + if(folder.title == paths[depth]){ + return await traverse(folder.parent_id, depth-1) + } + return false + } + let notes = await joplin.data.get(["search"], { query: noteTitle, type: "note" }) + for(const note of notes.items){ + if(await traverse(note.parent_id, paths.length - 1)){ + daysWithNotes.push(d.toISOString().substring(0, 10)) + } + } + } + + await dialogs.setHtml(dialog, `
`); const ret = await dialogs.open(dialog); if (ret.id == "ok") { From b2680f4bbf1fdd1f73f9f7ee0a1c2ee8131bd26d Mon Sep 17 00:00:00 2001 From: Mark Powers Date: Thu, 29 Aug 2024 08:10:47 -0500 Subject: [PATCH 2/5] Move getting days with notes to background timer --- src/index.ts | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/index.ts b/src/index.ts index f65c6a0..1db86e4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -237,16 +237,12 @@ joplin.plugins.register({ { id: "cancel", title: "Cancel" }, ]); - async function getDateByDialog() { - const iso8601 = await joplin.settings.value('iso8601'); - const timeFmt = await joplin.settings.value('TimeFmt') || 0; - const theme = await joplin.settings.value('Theme') || "light" - const enableWeekNum = await joplin.settings.value('WeekNum') || false - + async function getDatesWithNotes() { // Iterate over year of dates let now = new Date(new Date().getTime() - new Date().getTimezoneOffset()*60*1000) let start = new Date(new Date().getTime() - new Date().getTimezoneOffset()*60*1000) start.setDate(start.getDate() - 365) + let daysWithNotes = [] for (var d = start; d <= now; d.setDate(d.getDate() + 1)) { // Get the name of a note for this day @@ -273,6 +269,21 @@ joplin.plugins.register({ } } } + return daysWithNotes + } + + let daysWithNotes = [] + setTimeout(async () => { // Update cached list every 10 minutes + daysWithNotes = await getDatesWithNotes() + }, 5000); + setInterval(async () => { // Update cached list every 10 minutes + daysWithNotes = await getDatesWithNotes() + }, 60 * 10 * 1000); + async function getDateByDialog() { + const iso8601 = await joplin.settings.value('iso8601'); + const timeFmt = await joplin.settings.value('TimeFmt') || 0; + const theme = await joplin.settings.value('Theme') || "light" + const enableWeekNum = await joplin.settings.value('WeekNum') || false await dialogs.setHtml(dialog, `
`); const ret = await dialogs.open(dialog); From 849219c8567e456c8f90f58e9d1378af0f8ec16b Mon Sep 17 00:00:00 2001 From: Mark Powers Date: Sat, 31 Aug 2024 12:11:35 -0500 Subject: [PATCH 3/5] Add settings to configure calendar highlight --- src/calendar.ts | 4 +++- src/index.ts | 64 ++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 59 insertions(+), 9 deletions(-) diff --git a/src/calendar.ts b/src/calendar.ts index ebb56ad..ce97d2c 100644 --- a/src/calendar.ts +++ b/src/calendar.ts @@ -26,6 +26,7 @@ const timeFmt:any = parseInt(date_ele.getAttribute('timeFmt'),10) const theme:any = date_ele.getAttribute('theme') const enableWeekNum = date_ele.getAttribute('weekNum') === 'true' const days_with_notes_ele = document.getElementById('days_with_notes') +const calendarHighlightColor = days_with_notes_ele.getAttribute('calendarHighlightColor') const calendar = new VanillaCalendar('#datepicker', { actions: { @@ -43,7 +44,8 @@ const calendar = new VanillaCalendar('#datepicker', { }, getDays(day, date, HTMLElement, HTMLButtonElement) { if(days_with_notes_ele.getAttribute(date)){ - HTMLButtonElement.style["border"] = "1px solid rgb(112, 112, 255)" + HTMLButtonElement.style["border"] = `1px solid ${calendarHighlightColor}` + HTMLButtonElement.style["margin"] = "1px" } }, }, diff --git a/src/index.ts b/src/index.ts index 1db86e4..85afc06 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,6 @@ import joplin from 'api'; import { SettingItemType } from 'api/types'; +import { clearInterval } from 'timers'; const defaultNoteName = 'Journal/{{year}}/{{monthName}}/{{year}}-{{month}}-{{day}}'; const defaultMonthName = '01-Jan,02-Feb,03-Mar,04-Apr,05-May,06-Jun,07-Jul,08-Aug,09-Sep,10-Oct,11-Nov,12-Dec'; @@ -273,19 +274,37 @@ joplin.plugins.register({ } let daysWithNotes = [] - setTimeout(async () => { // Update cached list every 10 minutes - daysWithNotes = await getDatesWithNotes() - }, 5000); - setInterval(async () => { // Update cached list every 10 minutes - daysWithNotes = await getDatesWithNotes() - }, 60 * 10 * 1000); + let highlightInterval = undefined + async function updateCalendarInterval(){ + if(await joplin.settings.value("HighlightCalendar")){ + if(!highlightInterval){ + // Run now to get initial data + setTimeout(async () => { + daysWithNotes = await getDatesWithNotes() + }, 2000); + + let intervalMinutes = await joplin.settings.value("HighlightCalendarInterval") || 10; + highlightInterval = setInterval(async () => { // Update cached list every 10 minutes + daysWithNotes = await getDatesWithNotes() + }, 60 * 1000 * intervalMinutes); + } + } else if(highlightInterval) { + clearInterval(highlightInterval) + highlightInterval = undefined + daysWithNotes = [] + } + } + async function getDateByDialog() { const iso8601 = await joplin.settings.value('iso8601'); const timeFmt = await joplin.settings.value('TimeFmt') || 0; const theme = await joplin.settings.value('Theme') || "light" const enableWeekNum = await joplin.settings.value('WeekNum') || false - - await dialogs.setHtml(dialog, `
`); + const calendarHighlightColor = await joplin.settings.value('HighlightCalendarColor') + updateCalendarInterval() // Check settings on calendar + const enableCalendarHighlight = await joplin.settings.value("HighlightCalendar") + let calendarHighlightHtml = `
el+"=true").join(" ") : ""}>
` + await dialogs.setHtml(dialog, `
${calendarHighlightHtml}
`); const ret = await dialogs.open(dialog); if (ret.id == "ok") { @@ -463,6 +482,33 @@ joplin.plugins.register({ label: 'Tag Names', description: "Custom tag names, each value is separated by ','. eg", }, + 'HighlightCalendar': { + value: false, + type: SettingItemType.Bool, + section: 'Journal', + public: true, + advanced: true, + label: 'Enable Calendar Highlights', + description: "Highlight days with notes on the calendar", + }, + 'HighlightCalendarInterval': { + value: 10, + type: SettingItemType.Int, + section: 'Journal', + public: true, + advanced: true, + label: 'Calendar Update Period', + description: "How often in minutes to update calendar highlights", + }, + 'HighlightCalendarColor': { + value: "#7070ff", + type: SettingItemType.String, + section: 'Journal', + public: true, + advanced: true, + label: 'Calendar Highlight Color', + description: "CSS color of calendar highlight", + }, }); await joplin.commands.register({ @@ -539,5 +585,7 @@ joplin.plugins.register({ await joplin.commands.execute('openTodayNote'); }, 2000); } + + updateCalendarInterval() // Check the calendar highlight settings }, }); From 7480a5ce8aec6e32858fb3b3d39ca4b6d3ce6437 Mon Sep 17 00:00:00 2001 From: Mark Powers Date: Mon, 2 Sep 2024 09:58:15 -0500 Subject: [PATCH 4/5] Switch from interval to message for calendar highlight --- src/calendar.ts | 16 +++++--- src/index.ts | 103 +++++++++++++++--------------------------------- 2 files changed, 42 insertions(+), 77 deletions(-) diff --git a/src/calendar.ts b/src/calendar.ts index ce97d2c..501fdaa 100644 --- a/src/calendar.ts +++ b/src/calendar.ts @@ -3,6 +3,8 @@ import VanillaCalendar from '@uvarov.frontend/vanilla-calendar'; //import '@uvarov.frontend/vanilla-calendar/build/themes/light.min.css'; //import '@uvarov.frontend/vanilla-calendar/build/themes/dark.min.css'; +declare const webviewApi: any; + function padding(v) { return ('0' + v).slice(-2) } @@ -25,8 +27,8 @@ const monday_first = date_ele.getAttribute('iso8601') === 'true' const timeFmt:any = parseInt(date_ele.getAttribute('timeFmt'),10) const theme:any = date_ele.getAttribute('theme') const enableWeekNum = date_ele.getAttribute('weekNum') === 'true' -const days_with_notes_ele = document.getElementById('days_with_notes') -const calendarHighlightColor = days_with_notes_ele.getAttribute('calendarHighlightColor') +const calendarHighlightColor = date_ele.getAttribute('calendarHighlightColor') +const enableCalendarHighlight = date_ele.getAttribute('enableCalendarHighlight') === "true" const calendar = new VanillaCalendar('#datepicker', { actions: { @@ -43,9 +45,13 @@ const calendar = new VanillaCalendar('#datepicker', { console.log(`Vanilla Calendar: keeping: ${keeping}`) }, getDays(day, date, HTMLElement, HTMLButtonElement) { - if(days_with_notes_ele.getAttribute(date)){ - HTMLButtonElement.style["border"] = `1px solid ${calendarHighlightColor}` - HTMLButtonElement.style["margin"] = "1px" + if(enableCalendarHighlight){ + webviewApi.postMessage({"type": "noteExists", "date": date}).then(res => { + if(res){ + HTMLButtonElement.style["border"] = `1px solid ${calendarHighlightColor}` + HTMLButtonElement.style["margin"] = "1px" + } + }) } }, }, diff --git a/src/index.ts b/src/index.ts index 85afc06..d76099a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,5 @@ import joplin from 'api'; import { SettingItemType } from 'api/types'; -import { clearInterval } from 'timers'; const defaultNoteName = 'Journal/{{year}}/{{monthName}}/{{year}}-{{month}}-{{day}}'; const defaultMonthName = '01-Jan,02-Feb,03-Mar,04-Apr,05-May,06-Jun,07-Jul,08-Aug,09-Sep,10-Oct,11-Nov,12-Dec'; @@ -223,6 +222,7 @@ async function createNoteByDate(d) { return note; } + joplin.plugins.register({ onStart: async function () { console.info('joplin-plugin-journal started!'); @@ -238,73 +238,43 @@ joplin.plugins.register({ { id: "cancel", title: "Cancel" }, ]); - async function getDatesWithNotes() { - // Iterate over year of dates - let now = new Date(new Date().getTime() - new Date().getTimezoneOffset()*60*1000) - let start = new Date(new Date().getTime() - new Date().getTimezoneOffset()*60*1000) - start.setDate(start.getDate() - 365) - - let daysWithNotes = [] - for (var d = start; d <= now; d.setDate(d.getDate() + 1)) { - // Get the name of a note for this day - let noteName = await makeNoteName(d); - let parts = noteName.split("/") - - // Look for a note with that name - const paths = parts.slice(0, -1) - const noteTitle = parts[parts.length - 1] - async function traverse(parent_id, depth){ - if(depth == -1){ - return true - } - let folder = await joplin.data.get(['folders', parent_id]); - if(folder.title == paths[depth]){ - return await traverse(folder.parent_id, depth-1) - } - return false - } - let notes = await joplin.data.get(["search"], { query: noteTitle, type: "note" }) - for(const note of notes.items){ - if(await traverse(note.parent_id, paths.length - 1)){ - daysWithNotes.push(d.toISOString().substring(0, 10)) - } - } - } - return daysWithNotes - } - - let daysWithNotes = [] - let highlightInterval = undefined - async function updateCalendarInterval(){ - if(await joplin.settings.value("HighlightCalendar")){ - if(!highlightInterval){ - // Run now to get initial data - setTimeout(async () => { - daysWithNotes = await getDatesWithNotes() - }, 2000); - - let intervalMinutes = await joplin.settings.value("HighlightCalendarInterval") || 10; - highlightInterval = setInterval(async () => { // Update cached list every 10 minutes - daysWithNotes = await getDatesWithNotes() - }, 60 * 1000 * intervalMinutes); - } - } else if(highlightInterval) { - clearInterval(highlightInterval) - highlightInterval = undefined - daysWithNotes = [] - } - } - async function getDateByDialog() { const iso8601 = await joplin.settings.value('iso8601'); const timeFmt = await joplin.settings.value('TimeFmt') || 0; const theme = await joplin.settings.value('Theme') || "light" const enableWeekNum = await joplin.settings.value('WeekNum') || false const calendarHighlightColor = await joplin.settings.value('HighlightCalendarColor') - updateCalendarInterval() // Check settings on calendar const enableCalendarHighlight = await joplin.settings.value("HighlightCalendar") - let calendarHighlightHtml = `
el+"=true").join(" ") : ""}>
` - await dialogs.setHtml(dialog, `
${calendarHighlightHtml}
`); + await dialogs.setHtml(dialog, `
`); + joplin.views.panels.onMessage(dialog, async (msg) => { + if(msg.type == "noteExists"){ + // Convert the date to local time + const d = new Date(new Date(msg.date).getTime() + new Date().getTimezoneOffset()*60*1000) + let noteName = await makeNoteName(d); + let parts = noteName.split("/") + + // Look for a note with that name + const paths = parts.slice(0, -1) + const noteTitle = parts[parts.length - 1] + async function traverse(parent_id, depth){ + if(depth == -1){ + return true + } + let folder = await joplin.data.get(['folders', parent_id]); + if(folder.title == paths[depth]){ + return await traverse(folder.parent_id, depth-1) + } + return false + } + let notes = await joplin.data.get(["search"], { query: noteTitle, type: "note" }) + for(const note of notes.items){ + if(await traverse(note.parent_id, paths.length - 1)){ + return true + } + } + return false + } + }); const ret = await dialogs.open(dialog); if (ret.id == "ok") { @@ -491,15 +461,6 @@ joplin.plugins.register({ label: 'Enable Calendar Highlights', description: "Highlight days with notes on the calendar", }, - 'HighlightCalendarInterval': { - value: 10, - type: SettingItemType.Int, - section: 'Journal', - public: true, - advanced: true, - label: 'Calendar Update Period', - description: "How often in minutes to update calendar highlights", - }, 'HighlightCalendarColor': { value: "#7070ff", type: SettingItemType.String, @@ -585,7 +546,5 @@ joplin.plugins.register({ await joplin.commands.execute('openTodayNote'); }, 2000); } - - updateCalendarInterval() // Check the calendar highlight settings }, }); From 361e17230803f196194dbf5d998eea7be69a9be4 Mon Sep 17 00:00:00 2001 From: leenzhu Date: Tue, 3 Sep 2024 09:28:45 +0800 Subject: [PATCH 5/5] mark the day with dot that has a note entry --- src/calendar.ts | 4 +--- src/index.ts | 13 ++----------- src/vnilla-calendar-ext.css | 9 +++++++++ 3 files changed, 12 insertions(+), 14 deletions(-) create mode 100644 src/vnilla-calendar-ext.css diff --git a/src/calendar.ts b/src/calendar.ts index 501fdaa..b864b7e 100644 --- a/src/calendar.ts +++ b/src/calendar.ts @@ -27,7 +27,6 @@ const monday_first = date_ele.getAttribute('iso8601') === 'true' const timeFmt:any = parseInt(date_ele.getAttribute('timeFmt'),10) const theme:any = date_ele.getAttribute('theme') const enableWeekNum = date_ele.getAttribute('weekNum') === 'true' -const calendarHighlightColor = date_ele.getAttribute('calendarHighlightColor') const enableCalendarHighlight = date_ele.getAttribute('enableCalendarHighlight') === "true" const calendar = new VanillaCalendar('#datepicker', { @@ -48,8 +47,7 @@ const calendar = new VanillaCalendar('#datepicker', { if(enableCalendarHighlight){ webviewApi.postMessage({"type": "noteExists", "date": date}).then(res => { if(res){ - HTMLButtonElement.style["border"] = `1px solid ${calendarHighlightColor}` - HTMLButtonElement.style["margin"] = "1px" + HTMLButtonElement.classList.add("vanilla-calendar-day_noted"); } }) } diff --git a/src/index.ts b/src/index.ts index d76099a..6013eba 100644 --- a/src/index.ts +++ b/src/index.ts @@ -232,6 +232,7 @@ joplin.plugins.register({ await dialogs.addScript(dialog, "./vanilla-calendar.min.css"); await dialogs.addScript(dialog, "./light.min.css"); await dialogs.addScript(dialog, "./dark.min.css"); + await dialogs.addScript(dialog, "vnilla-calendar-ext.css"); await dialogs.addScript(dialog, "./calendar.js"); await dialogs.setButtons(dialog, [ { id: "ok", title: "OK" }, @@ -243,9 +244,8 @@ joplin.plugins.register({ const timeFmt = await joplin.settings.value('TimeFmt') || 0; const theme = await joplin.settings.value('Theme') || "light" const enableWeekNum = await joplin.settings.value('WeekNum') || false - const calendarHighlightColor = await joplin.settings.value('HighlightCalendarColor') const enableCalendarHighlight = await joplin.settings.value("HighlightCalendar") - await dialogs.setHtml(dialog, `
`); + await dialogs.setHtml(dialog, `
`); joplin.views.panels.onMessage(dialog, async (msg) => { if(msg.type == "noteExists"){ // Convert the date to local time @@ -461,15 +461,6 @@ joplin.plugins.register({ label: 'Enable Calendar Highlights', description: "Highlight days with notes on the calendar", }, - 'HighlightCalendarColor': { - value: "#7070ff", - type: SettingItemType.String, - section: 'Journal', - public: true, - advanced: true, - label: 'Calendar Highlight Color', - description: "CSS color of calendar highlight", - }, }); await joplin.commands.register({ diff --git a/src/vnilla-calendar-ext.css b/src/vnilla-calendar-ext.css new file mode 100644 index 0000000..65a8f88 --- /dev/null +++ b/src/vnilla-calendar-ext.css @@ -0,0 +1,9 @@ +.vanilla-calendar-day_noted::after { + content: ''; + position: absolute; + bottom: 0px; + width: 6px; + height: 6px; + border-radius: 3px; + background-color: gray; +}