backsplash-app
Version:
An AI powered wallpaper app.
77 lines (67 loc) • 2.92 kB
text/typescript
import { useState, useEffect, useCallback } from "react";
const EXPANDED_CATEGORIES_STORE_KEY = "backsplash-expanded-categories"; // Matches StoreService.EXPANDED_CATEGORIES_KEY
export function useExpandedCategories() {
const [expandedCategories, setExpandedCategoriesInternal] = useState<string[]>([]);
useEffect(() => {
// Fetch initial value
window.electron.ipcRenderer
.invoke("store:get:expandedCategories")
.then((categories) => {
if (Array.isArray(categories)) {
setExpandedCategoriesInternal(categories);
}
})
.catch((err) => console.error("Error fetching expandedCategories:", err));
// Listener for updates from main process
const updateChannel = `store:updated:${EXPANDED_CATEGORIES_STORE_KEY}`;
const handleUpdate = (_event: any, newCategories: string[]) => {
if (Array.isArray(newCategories)) {
setExpandedCategoriesInternal(newCategories);
}
};
window.electron.ipcRenderer.on(updateChannel, handleUpdate);
return () => {
window.electron.ipcRenderer.removeListener(updateChannel, handleUpdate);
};
}, []); // Empty dependency array: run once on mount, cleanup on unmount
const setExpandedCategories = useCallback(
async (categories: string[] | ((prevCategories: string[]) => string[])) => {
try {
let newCategories: string[];
if (typeof categories === "function") {
setExpandedCategoriesInternal((prevInternalCategories) => {
newCategories = categories(prevInternalCategories);
window.electron.ipcRenderer
.invoke("store:set:expandedCategories", newCategories)
.catch((err) => console.error("Error setting expandedCategories via IPC:", err));
return newCategories;
});
} else {
newCategories = categories;
setExpandedCategoriesInternal(newCategories);
await window.electron.ipcRenderer.invoke("store:set:expandedCategories", newCategories);
}
// The broadcast listener store:updated:${EXPANDED_CATEGORIES_STORE_KEY} will ensure consistency if needed,
// but optimistic local update is good for UI responsiveness.
} catch (err) {
console.error("Error setting expandedCategories:", err);
// Potentially revert optimistic update or show error to user
}
},
[setExpandedCategoriesInternal],
); // setExpandedCategoriesInternal is stable
// Helper to toggle a single category
const toggleCategory = useCallback(
(categoryId: string) => {
setExpandedCategories((prev) =>
prev.includes(categoryId) ? prev.filter((id) => id !== categoryId) : [...prev, categoryId],
);
},
[setExpandedCategories],
);
return {
expandedCategories,
setExpandedCategories, // Expose the main setter
toggleCategory, // Expose the toggle helper
};
}