Skip to content

Commit

Permalink
feat: prevent rerender of SectionTableBody when hovered
Browse files Browse the repository at this point in the history
  • Loading branch information
KevinWu098 committed Dec 8, 2024
1 parent 7e6451a commit 5b4736a
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 45 deletions.
20 changes: 11 additions & 9 deletions apps/antalmanac/src/components/Calendar/CalendarRoot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Box, ClickAwayListener, Popper } from '@material-ui/core';
import moment from 'moment';
import { memo, SyntheticEvent, useCallback, useEffect, useMemo, useState } from 'react';
import { Calendar, DateLocalizer, momentLocalizer, Views } from 'react-big-calendar';
import { shallow } from 'zustand/shallow';

import CalendarToolbar from './CalendarToolbar';
import CourseCalendarEvent, { CalendarEvent, CourseEvent } from './CourseCalendarEvent';
Expand All @@ -29,10 +30,10 @@ export const ScheduleCalendar = memo(() => {
const [scheduleNames, setScheduleNames] = useState(() => AppStore.getScheduleNames());

const { isMilitaryTime } = useTimeFormatStore();
const [hoveredCalendarizedCourses, hoveredCalendarizedFinal] = useHoveredStore((store) => [
store.hoveredCalendarizedCourses,
store.hoveredCalendarizedFinal,
]);
const [hoveredCalendarizedCourses, hoveredCalendarizedFinal] = useHoveredStore(
(state) => [state.hoveredCalendarizedCourses, state.hoveredCalendarizedFinal],
shallow
);

const getEventsForCalendar = useCallback((): CalendarEvent[] => {
if (showFinalsSchedule)
Expand All @@ -49,6 +50,8 @@ export const ScheduleCalendar = memo(() => {
showFinalsSchedule,
]);

const events = useMemo(() => getEventsForCalendar(), [getEventsForCalendar]);

const handleClosePopover = useCallback(() => {
setAnchorEl(null);
}, []);
Expand All @@ -74,9 +77,9 @@ export const ScheduleCalendar = memo(() => {
* @returns A date with the earliest time or 7AM
*/
const getStartTime = useCallback(() => {
const eventStartHours = getEventsForCalendar().map((event) => event.start.getHours());
const eventStartHours = events.map((event) => event.start.getHours());
return new Date(2018, 0, 1, Math.min(7, Math.min(...eventStartHours)));
}, [getEventsForCalendar]);
}, [events]);

const eventStyleGetter = useCallback((event: CalendarEvent) => {
const style = {
Expand Down Expand Up @@ -113,7 +116,6 @@ export const ScheduleCalendar = memo(() => {
return Math.abs(bgBrightness - textBrightness) > minBrightnessDiff;
};

const events = useMemo(() => getEventsForCalendar(), [getEventsForCalendar]);
const hasWeekendCourse = events.some((event) => event.start.getDay() === 0 || event.start.getDay() === 6);

const calendarTimeFormat = isMilitaryTime ? 'HH:mm' : 'h:mm A';
Expand All @@ -124,8 +126,8 @@ export const ScheduleCalendar = memo(() => {
const finalsDate = hoveredCalendarizedFinal
? getFinalsStartDateForTerm(hoveredCalendarizedFinal.term)
: onlyCourseEvents.length > 0
? getFinalsStartDateForTerm(onlyCourseEvents[0].term)
: getDefaultFinalsStartDate();
? getFinalsStartDateForTerm(onlyCourseEvents[0].term)
: getDefaultFinalsStartDate();

const finalsDateFormat = finalsDate ? 'ddd MM/DD' : 'ddd';
const date = showFinalsSchedule && finalsDate ? finalsDate : new Date(2018, 0, 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,7 @@ function CourseInfoButton({
isMobileScreen || (scheduleManagementWidth && scheduleManagementWidth < theme.breakpoints.values.xs);

return (
<div
// onMouseEnter={handleMouseEnter}
// onMouseLeave={handleMouseLeave}
style={{ display: 'flex' }}
>
<div onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave} style={{ display: 'flex' }}>
<Button
className={classes.button}
variant="contained"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,7 @@ const SectionTableBody = withStyles(styles)((props: SectionTableBodyProps) => {
const isDark = useThemeStore((store) => store.isDark);
const activeColumns = useColumnStore((store) => store.activeColumns);
const previewMode = usePreviewStore((store) => store.previewMode);
const [hoveredEvent, setHoveredEvents] = useHoveredStore((store) => [store.hoveredEvent, store.setHoveredEvents]);
const setHoveredEvents = useHoveredStore((store) => store.setHoveredEvents);

const [addedCourse, setAddedCourse] = useState(
AppStore.getAddedSectionCodes().has(`${section.sectionCode} ${term}`)
Expand Down Expand Up @@ -528,17 +528,17 @@ const SectionTableBody = withStyles(styles)((props: SectionTableBodyProps) => {
setCalendarEvents(AppStore.getCourseEventsInCalendar());
}, [setCalendarEvents]);

const alreadyHovered = useMemo(() => {
return hoveredEvent?.section.sectionCode === section.sectionCode;
}, [hoveredEvent, section.sectionCode]);

const handleHover = useCallback(() => {
if (!previewMode || alreadyHovered || addedCourse) {
const handleMouseEnter = useCallback(() => {
if (!previewMode || addedCourse) {
setHoveredEvents(undefined);
} else {
setHoveredEvents(section, courseDetails, term);
}
}, [previewMode, alreadyHovered, addedCourse, setHoveredEvents, section, courseDetails, term]);
}, [previewMode, addedCourse, setHoveredEvents, section, courseDetails, term]);

const handleMouseLeave = useCallback(() => {
setHoveredEvents(undefined);
}, [setHoveredEvents]);

// Attach event listeners to the store.
useEffect(() => {
Expand Down Expand Up @@ -605,27 +605,37 @@ const SectionTableBody = withStyles(styles)((props: SectionTableBodyProps) => {
return Boolean(conflictingEvent);
}, [calendarEvents, sectionDetails]);

/* allowHighlight is always false on CourseRenderPane and always true on AddedCoursePane */
const computedAddedCourseStyle = allowHighlight
? isDark
? { background: '#b0b04f' }
: { background: '#fcfc97' }
: {};
const computedScheduleConflictStyle = scheduleConflict
? isDark
? { background: '#121212', opacity: '0.6' }
: { background: '#a0a0a0', opacity: '1' }
: {};
const computedRowStyle = useMemo(() => {
/* allowHighlight is always false on CourseRenderPane and always true on AddedCoursePane */
const computedAddedCourseStyle = allowHighlight
? isDark
? { background: '#b0b04f' }
: { background: '#fcfc97' }
: {};
const computedScheduleConflictStyle = scheduleConflict
? isDark
? { background: '#121212', opacity: '0.6' }
: { background: '#a0a0a0', opacity: '1' }
: {};

if (addedCourse) {
return computedAddedCourseStyle;
}

if (scheduleConflict) {
return computedScheduleConflictStyle;
}

const computedRowStyle = addedCourse ? computedAddedCourseStyle : computedScheduleConflictStyle;
return {};
}, [allowHighlight, isDark, scheduleConflict, addedCourse]);

return (
<TableRow
classes={{ root: classes.row }}
className={classNames(classes.tr)}
style={computedRowStyle}
onMouseEnter={handleHover}
onMouseLeave={handleHover}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
>
{Object.entries(tableBodyCells)
.filter(([column]) => activeColumns.includes(column as SectionTableColumn))
Expand Down
12 changes: 3 additions & 9 deletions apps/antalmanac/src/stores/calendarizeHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ export function getLocation(location: string): Location {
}

export const calendarizeCourseEvents = (currentCourses: ScheduleCourse[] = []): CourseEvent[] => {
console.log('hit', Date.now());

const foo = currentCourses.flatMap((course) => {
return currentCourses.flatMap((course) => {
return course.section.meetings
.filter((meeting) => !meeting.timeIsTBA)
.flatMap((meeting) => {
Expand Down Expand Up @@ -82,10 +80,6 @@ export const calendarizeCourseEvents = (currentCourses: ScheduleCourse[] = []):
});
});
});

console.log(foo);

return foo;
};

export function calendarizeFinals(currentCourses: ScheduleCourse[] = []): CourseEvent[] {
Expand Down Expand Up @@ -124,8 +118,8 @@ export function calendarizeFinals(currentCourses: ScheduleCourse[] = []): Course
const locationsWithNoDays = bldg
? bldg.map(getLocation)
: !course.section.meetings[0].timeIsTBA
? course.section.meetings[0].bldg.map(getLocation)
: [];
? course.section.meetings[0].bldg.map(getLocation)
: [];

/**
* Fallback to January 2018 if no finals start date is available.
Expand Down

0 comments on commit 5b4736a

Please sign in to comment.