handmade-revolt/src/redux/reducers/sync.ts

95 lines
2.3 KiB
TypeScript

import type { Language } from "../../context/Locale";
import type { ThemeOptions } from "../../context/Theme";
import type { Notifications } from "./notifications";
import type { AppearanceOptions } from "./settings";
export type SyncKeys = "theme" | "appearance" | "locale" | "notifications";
export interface SyncData {
locale?: Language;
theme?: ThemeOptions;
appearance?: AppearanceOptions;
notifications?: Notifications;
}
export const DEFAULT_ENABLED_SYNC: SyncKeys[] = [
"theme",
"appearance",
"locale",
"notifications",
];
export interface SyncOptions {
disabled?: SyncKeys[];
revision?: {
[key: string]: number;
};
}
export type SyncUpdateAction = {
type: "SYNC_UPDATE";
update: { [key in SyncKeys]?: [number, SyncData[key]] };
};
export type SyncAction =
| { type: undefined }
| {
type: "SYNC_ENABLE_KEY";
key: SyncKeys;
}
| {
type: "SYNC_DISABLE_KEY";
key: SyncKeys;
}
| {
type: "SYNC_SET_REVISION";
key: SyncKeys;
timestamp: number;
}
| SyncUpdateAction;
export function sync(
state = {} as SyncOptions,
action: SyncAction,
): SyncOptions {
switch (action.type) {
case "SYNC_DISABLE_KEY":
return {
...state,
disabled: [
...(state.disabled ?? []).filter((v) => v !== action.key),
action.key,
],
};
case "SYNC_ENABLE_KEY":
return {
...state,
disabled: state.disabled?.filter((v) => v !== action.key),
};
case "SYNC_SET_REVISION":
return {
...state,
revision: {
...state.revision,
[action.key]: action.timestamp,
},
};
case "SYNC_UPDATE": {
const revision = { ...state.revision };
for (const key of Object.keys(action.update)) {
const value = action.update[key as SyncKeys];
if (value) {
revision[key] = value[0];
}
}
return {
...state,
revision,
};
}
default:
return state;
}
}