63 lines
1.6 KiB
TypeScript
63 lines
1.6 KiB
TypeScript
import { useEffect, useState } from "react";
|
|
import {
|
|
getThemeCss,
|
|
listThemes,
|
|
type ThemeSummary
|
|
} from "./application-backend";
|
|
|
|
export type { ThemeSummary } from "./application-backend";
|
|
|
|
export function useThemeResources(
|
|
themeId: string,
|
|
onThemesLoaded: (themes: ThemeSummary[]) => void
|
|
) {
|
|
const [themes, setThemes] = useState<ThemeSummary[]>([]);
|
|
const [themeCss, setThemeCss] = useState("");
|
|
const [catalogError, setCatalogError] = useState("");
|
|
const [cssError, setCssError] = useState("");
|
|
|
|
useEffect(() => {
|
|
const controller = new AbortController();
|
|
|
|
void listThemes(controller.signal)
|
|
.then(({ themes: availableThemes }) => {
|
|
setThemes(availableThemes);
|
|
setCatalogError("");
|
|
onThemesLoaded(availableThemes);
|
|
})
|
|
.catch((reason: unknown) => {
|
|
if (!controller.signal.aborted) {
|
|
setCatalogError(
|
|
reason instanceof Error ? reason.message : "无法加载主题清单"
|
|
);
|
|
}
|
|
});
|
|
|
|
return () => controller.abort();
|
|
}, [onThemesLoaded]);
|
|
|
|
useEffect(() => {
|
|
const controller = new AbortController();
|
|
setThemeCss("");
|
|
setCssError("");
|
|
|
|
void getThemeCss(themeId, controller.signal)
|
|
.then(setThemeCss)
|
|
.catch((reason: unknown) => {
|
|
if (!controller.signal.aborted) {
|
|
setCssError(
|
|
reason instanceof Error ? reason.message : "无法加载主题"
|
|
);
|
|
}
|
|
});
|
|
|
|
return () => controller.abort();
|
|
}, [themeId]);
|
|
|
|
return {
|
|
error: catalogError || cssError,
|
|
themeCss,
|
|
themes
|
|
};
|
|
}
|