From dc1dac6ae7639fddaa1cddef1efc3e051fa857eb Mon Sep 17 00:00:00 2001 From: Rudo Triton Date: Sun, 7 Nov 2021 17:03:30 +0200 Subject: [PATCH] filtering, eventCircle settings (#26) * filter calendars, alldayevents with calCircles - allow filtering calendars - let disable all-day events from counting towards eventCircle color - change "flipped" to also use widget parameter --- README.md | 3 +++ calendar.js | 34 ++++++++++++++++++++++++++++++---- src/buildCalendarView.ts | 3 ++- src/countEvents.ts | 30 ++++++++++++++++++++++++++++-- src/getEvents.ts | 6 ++++++ src/settings.ts | 8 +++++++- tsconfig.json | 2 +- 7 files changed, 77 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 0660b4b..f50aabb 100644 --- a/README.md +++ b/README.md @@ -25,11 +25,13 @@ calendar app. - `calendarApp` - Tapping on the widget launches a calendar app (as long as `debug: false`), by default it launches the iOS Calendar app, however it can be changed to anything as long as the app supports callback URLs. Changing the `calshow` to something else would open other apps. E.g. for Google Calendar it is `googlecalendar`, for Fantastical it is `x-fantastical3`. - `backgroundImage` - Image path to use as the widget background, which is taken either from the widget parameters, from the `params` variable at the top, or just replace `params.bg` with the image path. To get an image that can then be used to have a "transparent" widget background use [this](https://gist.github.com/mzeryck/3a97ccd1e059b3afa3c6666d27a496c9#gistcomment-3468585) script and save it to the _Scriptable_ folder on iCloud. Then set either the widget parameter (long press on the widget -> edit widget -> parameter) to `{ "bg": "my-image.jpg"}` where `my-image` is the name of your transparent background **OR** change the line which has `{ bg: "1121.jpg" }` to include your image name. +- `calFilter` - Optionally an array of calendars to show, shows all calendars if empty. Can be supplied as a widget parameter to only affect that particular widget. - `widgetBackgroundColor` - In case of no background image, what color to use. - `todayTextColor` - color of today's date - `markToday` - show a circle around today or not - `todayCircleColor` - if we mark days, then in what color - `showEventCircles` - adds colored background for all days that have an event. The color intensity is based roughly on how many events take place that day. +- `discountAllDayEvents` - if true, all-day events don't count towards eventCircle intensity value - `eventCircleColor` - if showing event circles, then in what color - `weekdayTextColor` - color of weekdays - `weekendLetters` - color of the letters in the top row @@ -48,6 +50,7 @@ - `showPrevMonth` - would show days from the previous month if they fit into the calendar view. - `showNextMonth` - would show days from the next month if they fit into the calendar view. - `individualDateTargets` - would allow tapping on a date to open that specific day in the calendar set by the `calendarApp` setting. (atm, supports default iOS calendar and Fantastical callback urls, should be possible to add more). +- `flipped` - the layout for the medium-sized widget can be either the default, `events - calendar`, or a flipped, `calendar - events` layout. This setting can also be given as a widget parameter (something like: `{ "flipped": true }`) to just affect that particular widget. ## Small Widgets diff --git a/calendar.js b/calendar.js index 5385cec..8ce2259 100644 --- a/calendar.js +++ b/calendar.js @@ -4,11 +4,13 @@ var settings = { debug: false, calendarApp: "calshow", backgroundImage: params.bg ? params.bg : "transparent.jpg", + calFilter: params.calFilter ? params.calFilter : [], widgetBackgroundColor: "#000000", todayTextColor: "#000000", markToday: true, todayCircleColor: "#FFB800", showEventCircles: true, + discountAllDayEvents: false, eventCircleColor: "#1E5C7B", weekdayTextColor: "#ffffff", weekendLetters: "#FFB800", @@ -27,7 +29,7 @@ var settings = { showPrevMonth: true, showNextMonth: true, individualDateTargets: false, - flipped: false, + flipped: params.flipped ? params.flipped : false, }; var settings_default = settings; @@ -196,14 +198,20 @@ function buildCalendar( var buildCalendar_default = buildCalendar; // src/countEvents.ts -async function countEvents(date, extendToPrev = 0, extendToNext = 0) { +async function countEvents( + date, + extendToPrev = 0, + extendToNext = 0, + settings2 +) { const { firstOfMonth } = getMonthBoundaries_default(date); const { startDate, endDate } = extendBoundaries( firstOfMonth, extendToPrev, extendToNext ); - const events = await CalendarEvent.between(startDate, endDate); + let events = await CalendarEvent.between(startDate, endDate); + events = trimEvents(events, settings2); const eventCounts = new Map(); events.forEach((event) => { if (event.isAllDay) { @@ -219,6 +227,18 @@ async function countEvents(date, extendToPrev = 0, extendToNext = 0) { const intensity = calculateIntensity(eventCounts); return { eventCounts, intensity }; } +function trimEvents(events, settings2) { + let trimmedEvents = events; + if (settings2.calFilter.length) { + trimmedEvents = events.filter((event) => + settings2.calFilter.includes(event.calendar.title) + ); + } + if (settings2.discountAllDayEvents || !settings2.showAllDayEvents) { + trimmedEvents = trimmedEvents.filter((event) => !event.isAllDay); + } + return trimmedEvents; +} function extendBoundaries(first, extendToPrev, extendToNext) { const startDate = new Date( first.getFullYear(), @@ -368,7 +388,8 @@ async function buildCalendarView(date, stack, settings2) { const { eventCounts, intensity } = await countEvents_default( date, daysFromPrevMonth, - daysFromNextMonth + daysFromNextMonth, + settings2 ); for (let i = 0; i < calendar.length; i += 1) { const weekdayStack = calendarStack.addStack(); @@ -571,6 +592,11 @@ async function getEvents(date, settings2) { dateLimit.setDate(dateLimit.getDate() + settings2.nextNumOfDays); events = await CalendarEvent.between(date, dateLimit); } + if (settings2.calFilter.length) { + events = events.filter((event) => + settings2.calFilter.includes(event.calendar.title) + ); + } const futureEvents = []; for (const event of events) { if ( diff --git a/src/buildCalendarView.ts b/src/buildCalendarView.ts index a3817d4..31232c6 100644 --- a/src/buildCalendarView.ts +++ b/src/buildCalendarView.ts @@ -47,7 +47,8 @@ async function buildCalendarView( const { eventCounts, intensity } = await countEvents( date, daysFromPrevMonth, - daysFromNextMonth + daysFromNextMonth, + settings ); for (let i = 0; i < calendar.length; i += 1) { diff --git a/src/countEvents.ts b/src/countEvents.ts index 7f0d757..a473543 100644 --- a/src/countEvents.ts +++ b/src/countEvents.ts @@ -1,3 +1,4 @@ +import { Settings } from "settings"; import getMonthBoundaries from "./getMonthBoundaries"; /** @@ -8,7 +9,8 @@ import getMonthBoundaries from "./getMonthBoundaries"; async function countEvents( date: Date, extendToPrev = 0, - extendToNext = 0 + extendToNext = 0, + settings: Settings ): Promise { const { firstOfMonth } = getMonthBoundaries(date); const { startDate, endDate } = extendBoundaries( @@ -16,8 +18,12 @@ async function countEvents( extendToPrev, extendToNext ); - const events = await CalendarEvent.between(startDate, endDate); + let events = await CalendarEvent.between(startDate, endDate); + + events = trimEvents(events, settings); + const eventCounts: EventCounts = new Map(); + events.forEach((event) => { if (event.isAllDay) { const date = event.startDate; @@ -35,6 +41,26 @@ async function countEvents( return { eventCounts, intensity }; } +/** + * Remove events that we don't care about from the array, so that they won't + * affect the intensity of the eventCircles + */ +function trimEvents(events: CalendarEvent[], settings: Settings) { + let trimmedEvents = events; + + if (settings.calFilter.length) { + trimmedEvents = events.filter((event) => + settings.calFilter.includes(event.calendar.title) + ); + } + + if (settings.discountAllDayEvents || !settings.showAllDayEvents) { + trimmedEvents = trimmedEvents.filter((event) => !event.isAllDay); + } + + return trimmedEvents; +} + /** * Find the boundaries between which the events are counted, when showing the * previous and/or the next month then the boundaries are wider than just the diff --git a/src/getEvents.ts b/src/getEvents.ts index 9b4ea56..5737d75 100644 --- a/src/getEvents.ts +++ b/src/getEvents.ts @@ -13,6 +13,12 @@ async function getEvents( events = await CalendarEvent.between(date, dateLimit); } + if (settings.calFilter.length) { + events = events.filter((event) => + settings.calFilter.includes(event.calendar.title) + ); + } + const futureEvents: CalendarEvent[] = []; // if we show events for the whole week, then we need to filter allDay events diff --git a/src/settings.ts b/src/settings.ts index f880994..072d1d1 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -14,6 +14,8 @@ const settings: Settings = { // parameter config would look like this: // { "bg": "2111.jpg", "view": "events" } backgroundImage: params.bg ? params.bg : "transparent.jpg", + // what calendars to show, all if empty or something like: ["Work"] + calFilter: params.calFilter ? params.calFilter : [], widgetBackgroundColor: "#000000", todayTextColor: "#000000", markToday: true, @@ -22,6 +24,8 @@ const settings: Settings = { // background for all other days, only applicable if showEventCircles is true // show a circle behind each date that has an event then showEventCircles: true, + // if true, all-day events don't count towards eventCircle intensity value + discountAllDayEvents: false, eventCircleColor: "#1E5C7B", // color of all the other dates weekdayTextColor: "#ffffff", @@ -59,19 +63,21 @@ const settings: Settings = { // tapping on a date opens that specific one individualDateTargets: false, // events-calendar OR a flipped calendar-events type of view for medium widget - flipped: false, + flipped: params.flipped ? params.flipped : false, }; export interface Settings { debug: boolean; calendarApp: string; backgroundImage: string; + calFilter: string[]; widgetBackgroundColor: string; todayTextColor: string; markToday: boolean; todayCircleColor: string; weekdayTextColor: string; showEventCircles: boolean; + discountAllDayEvents: boolean; eventCircleColor: string; locale: string; weekendLetters: string; diff --git a/tsconfig.json b/tsconfig.json index 98f935c..e67be85 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,6 +3,6 @@ "target": "es2017", "module": "commonjs", // ts-node breaks if this is something else "baseUrl": "src", - "lib": ["ES6"] + "lib": ["es2017"] } }