refactor(popup): match styles/reduce paint flicker (#136)
* refactor: match popup styles/reduce paint flicker
* fix: useSchedules hook
* feat: popup ✨
* fix: repaint issue on popup body
* fix: initial active schedule
* fix: center justification
* fix: reactivity error
This commit is contained in:
@@ -2,52 +2,61 @@ import { UserScheduleStore } from '@shared/storage/UserScheduleStore';
|
||||
import { UserSchedule } from '@shared/types/UserSchedule';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
let schedulesCache = [];
|
||||
let activeIndexCache = 0;
|
||||
let initialLoad = true;
|
||||
|
||||
/**
|
||||
* Fetches the user schedules from storage and sets the cached state.
|
||||
*/
|
||||
async function fetchData() {
|
||||
const [storedSchedules, storedActiveIndex] = await Promise.all([
|
||||
UserScheduleStore.get('schedules'),
|
||||
UserScheduleStore.get('activeIndex'),
|
||||
]);
|
||||
schedulesCache = storedSchedules.map(s => new UserSchedule(s));
|
||||
activeIndexCache = storedActiveIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom hook that manages user schedules.
|
||||
* @returns A tuple containing the active schedule and an array of all schedules.
|
||||
*/
|
||||
export default function useSchedules(): [active: UserSchedule | null, schedules: UserSchedule[]] {
|
||||
const [schedules, setSchedules] = useState<UserSchedule[]>([]);
|
||||
const [activeSchedule, setActiveSchedule] = useState<UserSchedule | null>(null);
|
||||
const [schedules, setSchedules] = useState<UserSchedule[]>(schedulesCache);
|
||||
const [activeIndex, setActiveIndex] = useState<number>(activeIndexCache);
|
||||
const [activeSchedule, setActiveSchedule] = useState<UserSchedule | null>(schedules[activeIndex]);
|
||||
|
||||
if (initialLoad) {
|
||||
initialLoad = false;
|
||||
|
||||
// trigger suspense
|
||||
// eslint-disable-next-line @typescript-eslint/no-throw-literal
|
||||
throw new Promise(res => {
|
||||
fetchData().then(res);
|
||||
});
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
const [storedSchedules, storedActiveIndex] = await Promise.all([
|
||||
UserScheduleStore.get('schedules'),
|
||||
UserScheduleStore.get('activeIndex'),
|
||||
]);
|
||||
setSchedules(storedSchedules.map(s => new UserSchedule(s)));
|
||||
setActiveSchedule(new UserSchedule(storedSchedules[storedActiveIndex]));
|
||||
const l1 = UserScheduleStore.listen('schedules', ({ newValue }) => {
|
||||
setSchedules(newValue.map(s => new UserSchedule(s)));
|
||||
});
|
||||
|
||||
const l2 = UserScheduleStore.listen('activeIndex', ({ newValue }) => {
|
||||
setActiveIndex(newValue);
|
||||
});
|
||||
|
||||
return () => {
|
||||
UserScheduleStore.removeListener(l1);
|
||||
UserScheduleStore.removeListener(l2);
|
||||
};
|
||||
|
||||
fetchData();
|
||||
|
||||
const setupListeners = () => {
|
||||
const l1 = UserScheduleStore.listen('schedules', ({ newValue }) => {
|
||||
setSchedules(newValue.map(s => new UserSchedule(s)));
|
||||
setActiveSchedule(currentActive => {
|
||||
const newActiveIndex = newValue.findIndex(s => s.name === currentActive?.name);
|
||||
return new UserSchedule(newValue[newActiveIndex]);
|
||||
});
|
||||
});
|
||||
|
||||
const l2 = UserScheduleStore.listen('activeIndex', ({ newValue }) => {
|
||||
setSchedules(currentSchedules => {
|
||||
setActiveSchedule(new UserSchedule(currentSchedules[newValue]));
|
||||
return currentSchedules;
|
||||
});
|
||||
});
|
||||
|
||||
return () => {
|
||||
UserScheduleStore.removeListener(l1);
|
||||
UserScheduleStore.removeListener(l2);
|
||||
};
|
||||
};
|
||||
|
||||
const init = UserScheduleStore.initialize();
|
||||
init.then(() => setupListeners()).catch(console.error);
|
||||
}, []);
|
||||
|
||||
// recompute active schedule on a schedule/index change
|
||||
useEffect(() => {
|
||||
setActiveSchedule(schedules[activeIndex]);
|
||||
});
|
||||
|
||||
return [activeSchedule, schedules];
|
||||
}
|
||||
|
||||
@@ -57,6 +66,7 @@ export default function useSchedules(): [active: UserSchedule | null, schedules:
|
||||
* @returns A promise that resolves when the active schedule has been switched.
|
||||
*/
|
||||
export async function switchSchedule(name: string): Promise<void> {
|
||||
console.log('Switching schedule...');
|
||||
const schedules = await UserScheduleStore.get('schedules');
|
||||
const activeIndex = schedules.findIndex(s => s.name === name);
|
||||
await UserScheduleStore.set('activeIndex', activeIndex);
|
||||
|
||||
Reference in New Issue
Block a user