Skip to content

Commit

Permalink
Fix the duplicate calendar events bug
Browse files Browse the repository at this point in the history
  • Loading branch information
JacE070 committed Nov 30, 2023
1 parent c3c24cc commit 12db2db
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 41 deletions.
75 changes: 37 additions & 38 deletions apps/antalmanac/src/lib/download.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,9 @@ export function getRRule(bydays: string[], quarter: string) {
return `FREQ=WEEKLY;BYDAY=${bydays.toString()};INTERVAL=1;COUNT=${count}`;
}

export function getEventsFromCourses(events = AppStore.getEventsInCalendar()): EventAttributes[] {
export function getEventsFromCourses(
events = [...AppStore.getEventsInCalendar(), ...AppStore.getFinalEventsInCalendar()]
): EventAttributes[] {
const calendarEvents = events.flatMap((event) => {
if (event.isCustomEvent) {
// FIXME: We don't have a way to get the term for custom events,
Expand Down Expand Up @@ -281,45 +283,42 @@ export function getEventsFromCourses(events = AppStore.getEventsInCalendar()): E
if (location.days === undefined) return null;
const days = getByDays(location.days);

const classStartDate = getClassStartDate(term, days);

const [firstClassStart, firstClassEnd] = getFirstClass(
classStartDate,
{ hour: start.getHours(), minute: start.getMinutes() },
{ hour: end.getHours(), minute: end.getMinutes() }
);

const rrule = getRRule(days, getQuarter(term));

// Add VEvent to events array.
return {
productId: 'antalmanac/ics',
startOutputType: 'local' as const,
endOutputType: 'local' as const,
title: `${title} ${sectionType}`,
description: `${courseTitle}\nTaught by ${instructors.join('/')}`,
location: `${location.building} ${location.room}`,
start: firstClassStart,
end: firstClassEnd,
recurrenceRule: rrule,
};
if (sectionType === 'Fin') {
return {
productId: 'antalmanac/ics',
startOutputType: 'local' as const,
endOutputType: 'local' as const,
title: `${title} Final Exam`,
description: `Final Exam for ${courseTitle}`,
start: getExamTime(finalExam, getYear(term))[0]!,
end: getExamTime(finalExam, getYear(term))[1]!,
};
} else {
const classStartDate = getClassStartDate(term, days);

const [firstClassStart, firstClassEnd] = getFirstClass(
classStartDate,
{ hour: start.getHours(), minute: start.getMinutes() },
{ hour: end.getHours(), minute: end.getMinutes() }
);

const rrule = getRRule(days, getQuarter(term));

// Add VEvent to events array.
return {
productId: 'antalmanac/ics',
startOutputType: 'local' as const,
endOutputType: 'local' as const,
title: `${title} ${sectionType}`,
description: `${courseTitle}\nTaught by ${instructors.join('/')}`,
location: `${location.building} ${location.room}`,
start: firstClassStart,
end: firstClassEnd,
recurrenceRule: rrule,
};
}
})
.filter(notNull);

// Add final to events.
if (finalExam.examStatus === 'SCHEDULED_FINAL') {
if (finalExam.startTime && finalExam.endTime) {
courseEvents.push({
productId: 'antalmanac/ics',
startOutputType: 'local' as const,
endOutputType: 'local' as const,
title: `${title} Final Exam`,
description: `Final Exam for ${sectionType} ${courseTitle}`,
start: getExamTime(finalExam, getYear(term))[0]!,
end: getExamTime(finalExam, getYear(term))[1]!,
});
}
}
return courseEvents;
}
});
Expand Down
14 changes: 12 additions & 2 deletions apps/antalmanac/src/stores/calendarizeHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@ export function calendarizeCourseEvents(currentCourses: ScheduleCourse[] = []):
title: `${course.deptCode} ${course.courseNumber}`,
courseTitle: course.courseTitle,
locations: meeting.bldg.map(getLocation).map((location: Location) => {
return { ...location, days: meeting.days === null ? undefined : meeting.days };
return {
...location,
days: meeting.days === null ? undefined : COURSE_WEEK_DAYS[dayIndex],
};
}),
showLocationInfo: false,
instructors: course.section.instructors,
Expand Down Expand Up @@ -99,12 +102,19 @@ export function calendarizeFinals(currentCourses: ScheduleCourse[] = []): Course
*/
const dayIndicesOcurring = weekdaysOccurring.map((day, index) => (day ? index : undefined)).filter(notNull);

const locationsWithNoDays = bldg ? bldg.map(getLocation) : course.section.meetings[0].bldg.map(getLocation);

return dayIndicesOcurring.map((dayIndex) => ({
color: course.section.color,
term: course.term,
title: `${course.deptCode} ${course.courseNumber}`,
courseTitle: course.courseTitle,
locations: bldg ? bldg.map(getLocation) : course.section.meetings[0].bldg.map(getLocation),
locations: locationsWithNoDays.map((location: Location) => {
return {
...location,
days: COURSE_WEEK_DAYS[dayIndex],
};
}),
showLocationInfo: true,
instructors: course.section.instructors,
sectionCode: course.section.sectionCode,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Taught by placeholderInstructor1/placeholderInstructor2",
"title": "placeholderDeptCode placeholderCourseNumber placeholderSectionType",
},
{
"description": "Final Exam for placeholderSectionType placeholderCourseTitle",
"description": "Final Exam for placeholderCourseTitle",
"end": [
2023,
3,
Expand Down
33 changes: 33 additions & 0 deletions apps/antalmanac/tests/download-ics.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ describe('download-ics', () => {
title: 'placeholderDeptCode placeholderCourseNumber',
locations: [{ building: 'placeholderLocation', room: 'placeholderRoom', days: 'MWF' }],
showLocationInfo: true,
// We don't use finalExam anymore for calendar file export,
// instead, FinalExamEvent is used
finalExam: {
examStatus: 'SCHEDULED_FINAL',
dayOfWeek: 'Mon',
Expand All @@ -37,6 +39,36 @@ describe('download-ics', () => {
sectionType: 'placeholderSectionType',
term: '2023 Fall', // Cannot be a random placeholder; it has to be in `quarterStartDates` otherwise it'll be undefined
},
// FinalExamEvent
{
color: 'placeholderColor',
start: new Date(2023, 9, 29, 1, 2),
end: new Date(2023, 9, 29, 3, 4),
title: 'placeholderDeptCode placeholderCourseNumber',
locations: [{ building: 'placeholderLocation', room: 'placeholderRoom', days: 'MWF' }],
showLocationInfo: true,
finalExam: {
examStatus: 'SCHEDULED_FINAL',
dayOfWeek: 'Mon',
month: 2,
day: 3,
startTime: {
hour: 1,
minute: 2,
},
endTime: {
hour: 3,
minute: 4,
},
locations: [{ building: 'placeholderFinalLocation', room: 'placeholderFinalRoom' }],
},
courseTitle: 'placeholderCourseTitle',
instructors: ['placeholderInstructor1', 'placeholderInstructor2'],
isCustomEvent: false,
sectionCode: 'placeholderSectionCode',
sectionType: 'Fin',
term: '2023 Fall', // Cannot be a random placeholder; it has to be in `quarterStartDates` otherwise it'll be undefined
},
// CustomEvent
{
color: 'placeholderColor',
Expand All @@ -46,6 +78,7 @@ describe('download-ics', () => {
customEventID: 123,
isCustomEvent: true,
days: ['M', 'W', 'F'],
building: 'placeholderCustomEventBuilding',
},
];

Expand Down

0 comments on commit 12db2db

Please sign in to comment.