@@ -256,31 +256,8 @@ const CalendarSlice = createSlice({
|
||||
} as Calendar;
|
||||
state.error = null;
|
||||
})
|
||||
.addCase(patchCalendarAsync.fulfilled, (state, action) => {
|
||||
.addCase(patchCalendarAsync.fulfilled, (state) => {
|
||||
state.pending = false;
|
||||
if (action.payload.patch.color) {
|
||||
state.list[action.payload.calId] = {
|
||||
...state.list[action.payload.calId],
|
||||
color: action.payload.patch.color,
|
||||
};
|
||||
Object.keys(state.list[action.payload.calId].events).forEach(
|
||||
(evId) =>
|
||||
(state.list[action.payload.calId].events[evId].color =
|
||||
action.payload.patch.color)
|
||||
);
|
||||
}
|
||||
if (action.payload.patch.desc) {
|
||||
state.list[action.payload.calId] = {
|
||||
...state.list[action.payload.calId],
|
||||
description: action.payload.patch.desc,
|
||||
};
|
||||
}
|
||||
if (action.payload.patch.name) {
|
||||
state.list[action.payload.calId] = {
|
||||
...state.list[action.payload.calId],
|
||||
name: action.payload.patch.name,
|
||||
};
|
||||
}
|
||||
state.error = null;
|
||||
})
|
||||
.addCase(addSharedCalendarAsync.fulfilled, (state, action) => {
|
||||
@@ -297,9 +274,8 @@ const CalendarSlice = createSlice({
|
||||
} as Calendar;
|
||||
state.error = null;
|
||||
})
|
||||
.addCase(removeCalendarAsync.fulfilled, (state, action) => {
|
||||
.addCase(removeCalendarAsync.fulfilled, (state) => {
|
||||
state.pending = false;
|
||||
delete state.list[action.payload.calId];
|
||||
state.error = null;
|
||||
})
|
||||
.addCase(patchACLCalendarAsync.fulfilled, (state, action) => {
|
||||
|
||||
@@ -105,7 +105,10 @@ export const getCalendarsListAsync = createAsyncThunk<
|
||||
if (fetchedCal) {
|
||||
importedCalendars[id] = {
|
||||
...fetchedCal,
|
||||
color: existingCal.color,
|
||||
color: {
|
||||
...existingCal.color,
|
||||
light: fetchedCal.color?.light,
|
||||
},
|
||||
events: existingCal.events || {},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ export function WebSocketGate() {
|
||||
Map<string, { calendar: Calendar; type?: "temp" }>
|
||||
>(new Map());
|
||||
const calendarsToHideRef = useRef<Set<string>>(new Set());
|
||||
const shouldRefreshCalendarListRef = useRef<boolean>(false);
|
||||
const debouncedUpdateFnRef = useRef<
|
||||
((dispatch: AppDispatch) => void) | undefined
|
||||
>();
|
||||
@@ -67,6 +68,7 @@ export function WebSocketGate() {
|
||||
const accumulators = {
|
||||
calendarsToRefresh: calendarsToRefreshRef.current,
|
||||
calendarsToHide: calendarsToHideRef.current,
|
||||
shouldRefreshCalendarListRef,
|
||||
debouncedUpdateFn: debouncedUpdateFnRef.current,
|
||||
currentDebouncePeriod: currentDebouncePeriodRef.current,
|
||||
};
|
||||
|
||||
@@ -3,8 +3,9 @@ import { WS_INBOUND_EVENTS } from "../protocols";
|
||||
export function parseMessage(message: unknown) {
|
||||
const calendarsToRefresh = new Set<string>();
|
||||
const calendarsToHide = new Set<string>();
|
||||
let shouldRefreshCalendarList = false;
|
||||
if (typeof message !== "object" || message === null) {
|
||||
return { calendarsToRefresh, calendarsToHide };
|
||||
return { calendarsToRefresh, calendarsToHide, shouldRefreshCalendarList };
|
||||
}
|
||||
|
||||
for (const [key, value] of Object.entries(message)) {
|
||||
@@ -21,11 +22,14 @@ export function parseMessage(message: unknown) {
|
||||
break;
|
||||
case WS_INBOUND_EVENTS.CALENDAR_CLIENT_REGISTERED:
|
||||
break;
|
||||
case WS_INBOUND_EVENTS.CALENDAR_LIST:
|
||||
shouldRefreshCalendarList = true;
|
||||
break;
|
||||
default: {
|
||||
calendarsToRefresh.add(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { calendarsToRefresh, calendarsToHide };
|
||||
return { calendarsToRefresh, calendarsToHide, shouldRefreshCalendarList };
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Calendar } from "@/features/Calendars/CalendarTypes";
|
||||
export interface UpdateCalendarsAccumulators {
|
||||
calendarsToRefresh: Map<string, { calendar: Calendar; type?: "temp" }>;
|
||||
calendarsToHide: Set<string>;
|
||||
shouldRefreshCalendarListRef: React.MutableRefObject<boolean>;
|
||||
debouncedUpdateFn?: (dispatch: AppDispatch) => void;
|
||||
currentDebouncePeriod?: number;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import type { AppDispatch } from "@/app/store";
|
||||
import { store } from "@/app/store";
|
||||
import { Calendar } from "@/features/Calendars/CalendarTypes";
|
||||
import { refreshCalendarWithSyncToken } from "@/features/Calendars/services";
|
||||
import {
|
||||
getCalendarsListAsync,
|
||||
refreshCalendarWithSyncToken,
|
||||
} from "@/features/Calendars/services";
|
||||
import { findCalendarById, getDisplayedCalendarRange } from "@/utils";
|
||||
import { setSelectedCalendars } from "@/utils/storage/setSelectedCalendars";
|
||||
import { debounce } from "lodash";
|
||||
@@ -17,7 +20,9 @@ function createDebouncedUpdate(
|
||||
string,
|
||||
{ calendar: Calendar; type?: "temp" }
|
||||
>,
|
||||
getCalendarsToHide: () => Set<string>
|
||||
getCalendarsToHide: () => Set<string>,
|
||||
getShouldRefreshCalendarList: () => boolean,
|
||||
resetShouldRefreshCalendarList: () => void
|
||||
) {
|
||||
return debounce(
|
||||
(dispatch: AppDispatch) => {
|
||||
@@ -26,14 +31,20 @@ function createDebouncedUpdate(
|
||||
// Snapshot state
|
||||
const calendarsToProcess = new Map(getCalendarsToRefresh());
|
||||
const calendarsToHideSnapshot = new Set(getCalendarsToHide());
|
||||
const shouldRefresh = getShouldRefreshCalendarList();
|
||||
|
||||
// Clear accumulators
|
||||
getCalendarsToRefresh().clear();
|
||||
getCalendarsToHide().clear();
|
||||
resetShouldRefreshCalendarList();
|
||||
|
||||
try {
|
||||
processCalendarsToRefresh(dispatch, currentRange, calendarsToProcess);
|
||||
processCalendarsToHide(calendarsToHideSnapshot);
|
||||
|
||||
if (shouldRefresh) {
|
||||
dispatch(getCalendarsListAsync());
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn("Error processing accumulated calendar updates:", error);
|
||||
}
|
||||
@@ -49,7 +60,8 @@ export function updateCalendars(
|
||||
accumulators: UpdateCalendarsAccumulators
|
||||
) {
|
||||
const state = store.getState();
|
||||
const { calendarsToRefresh, calendarsToHide } = parseMessage(message);
|
||||
const { calendarsToRefresh, calendarsToHide, shouldRefreshCalendarList } =
|
||||
parseMessage(message);
|
||||
|
||||
// Accumulate
|
||||
accumulateCalendarsToRefresh(
|
||||
@@ -59,6 +71,9 @@ export function updateCalendars(
|
||||
);
|
||||
accumulateCalendarsToHide(calendarsToHide, accumulators.calendarsToHide);
|
||||
|
||||
accumulators.shouldRefreshCalendarListRef.current ||=
|
||||
shouldRefreshCalendarList;
|
||||
|
||||
const debouncePeriod = window.WS_DEBOUNCE_PERIOD_MS ?? DEFAULT_DEBOUNCE_MS;
|
||||
|
||||
if (debouncePeriod > 0) {
|
||||
@@ -69,7 +84,11 @@ export function updateCalendars(
|
||||
accumulators.debouncedUpdateFn = createDebouncedUpdate(
|
||||
debouncePeriod,
|
||||
() => accumulators.calendarsToRefresh,
|
||||
() => accumulators.calendarsToHide
|
||||
() => accumulators.calendarsToHide,
|
||||
() => accumulators.shouldRefreshCalendarListRef.current,
|
||||
() => {
|
||||
accumulators.shouldRefreshCalendarListRef.current = false;
|
||||
}
|
||||
);
|
||||
accumulators.currentDebouncePeriod = debouncePeriod;
|
||||
}
|
||||
@@ -84,10 +103,14 @@ export function updateCalendars(
|
||||
|
||||
accumulators.calendarsToRefresh.clear();
|
||||
accumulators.calendarsToHide.clear();
|
||||
accumulators.shouldRefreshCalendarListRef.current = false;
|
||||
|
||||
try {
|
||||
processCalendarsToRefresh(dispatch, currentRange, calendarsToProcess);
|
||||
processCalendarsToHide(calendarsToHideSnapshot);
|
||||
if (shouldRefreshCalendarList) {
|
||||
dispatch(getCalendarsListAsync());
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn("Error processing calendar updates:", error);
|
||||
}
|
||||
|
||||
@@ -6,4 +6,5 @@ export const WS_INBOUND_EVENTS = {
|
||||
CLIENT_REGISTERED: "registered",
|
||||
CLIENT_UNREGISTERED: "unregistered",
|
||||
CALENDAR_CLIENT_REGISTERED: "calendarListRegistered",
|
||||
CALENDAR_LIST: "calendarList",
|
||||
} as const;
|
||||
|
||||
Reference in New Issue
Block a user