backsplash-app
Version:
An AI powered wallpaper app.
162 lines (145 loc) • 4.15 kB
text/typescript
import { atom } from "recoil";
import { syncEffect } from "recoil-sync";
import { number, string, array, object, union, literal, nullable, optional } from "@recoiljs/refine";
import { WallpaperHistoryEntry, WallpaperMetadata } from "@/types/wallpaper";
import { WallpaperMode } from "@/types/wallpaperModes";
import { STORE_MESSAGES } from "@/ipc/channels/messages";
// Import the update atoms
export * from "../state/atoms/updateAtoms";
// Types
export interface WallpaperData {
objectKey: string;
upscaledImageUrl: string | null;
originalImageUrl: string;
style: string;
generatedAt: string;
metadata?: WallpaperMetadata;
}
export interface SchedulerState {
isActive: boolean;
intervalMinutes: number | null;
nextChangeCountdown: string;
}
// Type checkers
const locationChecker = object({
city: string(),
state: string(),
country: string(),
temperature: number(),
local_time: string(),
});
const wallpaperMetadataChecker = object({
style: string(),
created_at: string(),
prompt: nullable(string()),
original_prompt: nullable(string()),
custom_style: nullable(string()),
location: nullable(locationChecker),
upscaled: nullable(union(literal(true), literal(false))),
upscale_date: nullable(string()),
});
const wallpaperDataChecker = object({
objectKey: string(),
upscaledImageUrl: nullable(string()),
originalImageUrl: string(),
style: string(),
generatedAt: string(),
metadata: nullable(wallpaperMetadataChecker),
});
const schedulerStateChecker = object({
isActive: union(literal(true), literal(false)),
intervalMinutes: nullable(number()),
nextChangeCountdown: string(),
});
const stringArrayChecker = array(string());
const wallpaperHistoryEntryChecker = object({
key: string(),
upscaledImageUrl: string(),
originalImageUrl: string(),
imageUrl: optional(string()),
setAt: string(),
metadata: optional(nullable(wallpaperMetadataChecker)),
isUpscaled: optional(union(literal(true), literal(false))),
});
// Atoms
export const lastWallpaperState = atom<WallpaperData | null>({
key: "lastWallpaperState",
default: null,
effects: [
syncEffect({
storeKey: "electron-store",
itemKey: STORE_MESSAGES.OPERATIONS.LAST_WALLPAPER,
refine: nullable(wallpaperDataChecker),
}),
],
});
export const wallpaperHistoryState = atom<readonly WallpaperHistoryEntry[]>({
key: "wallpaperHistoryState",
default: [],
effects: [
syncEffect({
storeKey: "electron-store",
itemKey: STORE_MESSAGES.OPERATIONS.WALLPAPER_HISTORY,
refine: array(wallpaperHistoryEntryChecker),
}),
],
});
export const schedulerState = atom<SchedulerState>({
key: "schedulerState",
default: {
isActive: false,
intervalMinutes: null,
nextChangeCountdown: "",
},
effects: [
syncEffect({
storeKey: "electron-store",
itemKey: STORE_MESSAGES.OPERATIONS.SCHEDULER_ACTIVE,
refine: schedulerStateChecker,
}),
],
});
export const expandedCategoriesState = atom<string[]>({
key: "expandedCategoriesState",
default: [],
effects: [
syncEffect({
storeKey: "electron-store",
itemKey: STORE_MESSAGES.OPERATIONS.EXPANDED_CATEGORIES,
refine: stringArrayChecker,
}),
],
});
export const activeStylesState = atom<string[]>({
key: "activeStylesState",
default: [],
effects: [
syncEffect({
storeKey: "electron-store",
itemKey: STORE_MESSAGES.OPERATIONS.ACTIVE_STYLES,
refine: stringArrayChecker,
}),
],
});
export const customStyleState = atom<string>({
key: "customStyleState",
default: "",
effects: [
syncEffect({
storeKey: "electron-store",
itemKey: STORE_MESSAGES.OPERATIONS.CUSTOM_STYLE,
refine: string(),
}),
],
});
export const currentWallpaperModeState = atom<WallpaperMode>({
key: "currentWallpaperModeState",
default: "RandomStyleSelection",
effects: [
syncEffect({
storeKey: "electron-store",
itemKey: STORE_MESSAGES.OPERATIONS.CURRENT_MODE,
refine: union(literal("RandomStyleSelection"), literal("CustomStyle"), literal("Location"), literal("Mood")),
}),
],
});