Files
actual/packages/desktop-client/src/hooks/useThemeCatalog.ts
Matiss Janis Aboltins ee0e7ed3e0 Refactor theme catalog fetching to use custom hook (#6681)
* Refactor theme catalog fetching to use custom hook

- Move catalog fetching logic from ThemeInstaller to useThemeCatalog hook
- Fetch catalog asynchronously from GitHub instead of direct import
- Update tests to mock useThemeCatalog hook for faster test execution
- Remove catalog validation and translation dependencies from hook

* Remove redundant visibility checks for 'Demo Theme' button in ThemeInstaller tests and add assertion to verify presence of images.

* Refactor ThemeInstaller component to improve error handling and loading state display

- Change conditional rendering for catalog error to use ternary operator for clarity
- Simplify loading state display logic within the theme catalog view
- Ensure consistent styling and structure for theme items in the catalog

* Initialize loading state in useThemeCatalog hook to true

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-01-17 10:06:16 +00:00

54 lines
1.3 KiB
TypeScript

import { useEffect, useState } from 'react';
import { type CatalogTheme } from '@desktop-client/style/customThemes';
const CATALOG_URL =
'https://raw.githubusercontent.com/actualbudget/actual/master/packages/desktop-client/src/data/customThemeCatalog.json';
/**
* Custom hook to fetch and manage the theme catalog from GitHub.
*/
export function useThemeCatalog() {
const [data, setData] = useState<CatalogTheme[] | null>(null);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
const fetchCatalog = async () => {
setIsLoading(true);
setError(null);
try {
const response = await fetch(CATALOG_URL);
if (!response.ok) {
throw new Error(`Failed to fetch catalog: ${response.statusText}`);
}
const data = await response.json();
// Validate that data is an array
if (!Array.isArray(data)) {
throw new Error('Invalid catalog format: expected an array');
}
setData(data);
} catch (err) {
setError(
err instanceof Error ? err.message : 'Failed to load theme catalog',
);
} finally {
setIsLoading(false);
}
};
fetchCatalog();
}, []);
return {
data,
isLoading,
error,
};
}