Skip to content

Commit

Permalink
Merge pull request #138 from cloud-atlas-ai:muness/issue19
Browse files Browse the repository at this point in the history
Skip declined event for recurring events
  • Loading branch information
muness authored Dec 23, 2024
2 parents 2e02f2c + b413e9c commit 3b59e5a
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 13 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/icalUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ function processRecurringRules(event: any, dayToMatch: string, excludedDates: mo

if (moment(clonedEvent.start).isSame(dayToMatch, 'day')) {
console.debug(`Adding recurring event: ${clonedEvent.summary} ${clonedEvent.start} - ${clonedEvent.end}`);
console.debug(clonedEvent);
matchingEvents.push(clonedEvent);
}
});
Expand Down
59 changes: 49 additions & 10 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ export default class ICSPlugin extends Plugin {
].filter(Boolean).join(' ').trim();
}


async getEvents(date: string): Promise<IEvent[]> {
let events: IEvent[] = [];
let errorMessages: string[] = []; // To store error messages
Expand Down Expand Up @@ -96,16 +97,9 @@ export default class ICSPlugin extends Plugin {

// Exception handling for parsing and filtering
try {
dateEvents = filterMatchingEvents(icsArray, date, calendarSetting.format.showOngoing);

// Exclude transparent events
dateEvents = dateEvents.filter(event => {
if (event.transparency && event.transparency.toUpperCase() === "TRANSPARENT") {
console.debug(`Excluding transparent event: ${event.summary}`);
return false;
}
return true;
});
dateEvents = dateEvents = filterMatchingEvents(icsArray, date, calendarSetting.format.showOngoing)
.filter(e => this.excludeTransparentEvents(e, calendarSetting))
.filter(e => this.excludeDeclinedEvents(e, calendarSetting));

} catch (filterError) {
console.error(`Error filtering events for calendar ${calendarSetting.icsName}: ${filterError}`);
Expand Down Expand Up @@ -186,6 +180,51 @@ export default class ICSPlugin extends Plugin {
return;
}

excludeTransparentEvents(event: any, calendarSetting: Calendar): boolean {
// 1. Exclude transparent events
if (
event.transparency &&
event.transparency.toUpperCase() === "TRANSPARENT"
) {
console.debug(`Excluding transparent event: ${event.summary}`);
return false;
}

return true;

}

excludeDeclinedEvents(event: any, calendarSetting: Calendar): boolean {
if (!event.attendees) {
event.attendees = Array.isArray(event.attendee)
? event.attendee
: event.attendee
? [event.attendee]
: [];
}

// 3. Check if the user (calendar owner) declined
const ownerEmail = calendarSetting.ownerEmail?.toLowerCase().trim();
if (ownerEmail) {
const myAttendee = event.attendees.find((att: any) => {
const attEmail = att.val.replace("mailto:", "").toLowerCase().trim();
return attEmail === ownerEmail;
});

if (myAttendee) {
const partStat = myAttendee.params?.PARTSTAT?.toUpperCase();
if (partStat === "DECLINED") {
// The owner of this calendar has declined the event
console.debug(
`Skipping event (“${event.summary}”) for ${ownerEmail} due to DECLINED`
);
return false;
}
}
}
return true;
}

async loadSettings() {
this.data = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
}
Expand Down
7 changes: 7 additions & 0 deletions src/settings/ICSSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ export interface ICSSettings {
export interface Calendar {
icsUrl: string;
icsName: string;

/**
* Optional field for storing the owner email of this calendar.
* Used when checking PARTSTAT=DECLINED for that email.
*/
ownerEmail?: string;

calendarType: 'remote' | 'vdir'; // Add this line
format: {
checkbox: boolean;
Expand Down
17 changes: 16 additions & 1 deletion src/settings/ICSSettingsTab.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ export default class ICSSettingsTab extends PluginSettingTab {
this.plugin.addCalendar({
icsName: modal.icsName,
icsUrl: modal.icsUrl,
ownerEmail: modal.ownerEmail,
format: modal.format,
calendarType: modal.calendarType as 'remote' | 'vdir',
});
Expand Down Expand Up @@ -140,6 +141,7 @@ export default class ICSSettingsTab extends PluginSettingTab {
this.plugin.addCalendar({
icsName: modal.icsName,
icsUrl: modal.icsUrl,
ownerEmail: modal.ownerEmail,
format: modal.format,
calendarType: modal.calendarType as 'remote' | 'vdir',
});
Expand Down Expand Up @@ -204,6 +206,7 @@ class SettingsModal extends Modal {
urlSetting: Setting;
urlText: TextComponent;
urlDropdown: DropdownComponent;
ownerEmail: string = "";

saved: boolean = false;
error: boolean = false;
Expand All @@ -217,7 +220,7 @@ class SettingsModal extends Modal {
location: boolean,
description: boolean,
showAttendees: boolean,
showOngoing: boolean
showOngoing: boolean,
} = DEFAULT_CALENDAR_FORMAT;
calendarType: string;
constructor(app: App, plugin: ICSPlugin, setting?: Calendar) {
Expand All @@ -226,6 +229,7 @@ class SettingsModal extends Modal {
if (setting) {
this.icsName = setting.icsName;
this.icsUrl = setting.icsUrl;
this.ownerEmail = setting.ownerEmail;
this.format = setting.format;
this.calendarType = setting.calendarType || 'remote';
}
Expand Down Expand Up @@ -254,6 +258,17 @@ class SettingsModal extends Modal {
nameText = text;
nameText.setValue(this.icsName).onChange(async (v) => {
this.icsName = v;
this.hasChanges = true;
});
});

const ownerEmailSetting = new Setting(settingDiv)
.setName('Calendar Owner Email (Optional)')
.setDesc('Used to skip declined events')
.addText(text => {
text.setValue(this.ownerEmail).onChange(value => {
this.ownerEmail = value;
this.hasChanges = true;
});
});

Expand Down

0 comments on commit 3b59e5a

Please sign in to comment.