@forge/react
11.17.0-experimental-04cc2b911.18.0-next.0
out/hooks/useTheme.js~
out/hooks/useTheme.jsModified+42−12
Index: package/out/hooks/useTheme.js
===================================================================
--- package/out/hooks/useTheme.js
+++ package/out/hooks/useTheme.js
@@ -6,32 +6,62 @@
const bridge_1 = require("@forge/bridge");
const isEqual_1 = tslib_1.__importDefault(require("lodash/isEqual"));
const useTheme = () => {
const [theme, setTheme] = (0, react_1.useState)(null);
+ const themeRef = (0, react_1.useRef)(null);
const themeLoadedRef = (0, react_1.useRef)(false);
+ const loadingContextRef = (0, react_1.useRef)(false);
+ const applyTheme = (0, react_1.useCallback)((nextTheme) => {
+ if ((0, isEqual_1.default)(themeRef.current, nextTheme)) {
+ return;
+ }
+ themeRef.current = nextTheme;
+ setTheme((current) => ((0, isEqual_1.default)(current, nextTheme) ? current : nextTheme));
+ }, []);
(0, react_1.useEffect)(() => {
+ let cancelled = false;
void (async () => {
- if (!themeLoadedRef.current) {
+ if (themeLoadedRef.current || loadingContextRef.current) {
+ return;
+ }
+ loadingContextRef.current = true;
+ try {
const context = await bridge_1.view.getContext();
- if (context?.theme && !themeLoadedRef.current) {
- setTheme((currentTheme) => {
- return (0, isEqual_1.default)(currentTheme, context.theme) ? currentTheme : context.theme;
- });
- themeLoadedRef.current = true;
+ if (cancelled || !context?.theme || themeLoadedRef.current) {
+ return;
}
+ applyTheme(context.theme);
+ themeLoadedRef.current = true;
}
+ finally {
+ loadingContextRef.current = false;
+ }
})();
- }, []);
+ return () => {
+ cancelled = true;
+ };
+ }, [applyTheme]);
(0, react_1.useEffect)(() => {
+ let unsubscribeFn = null;
+ let cancelled = false;
const sub = bridge_1.events.on('FORGE_CORE_THEME_CHANGED', ({ theme: updatedTheme }) => {
themeLoadedRef.current = true;
- setTheme((currentTheme) => {
- return (0, isEqual_1.default)(currentTheme, updatedTheme) ? currentTheme : updatedTheme;
- });
+ applyTheme(updatedTheme);
});
+ void sub.then((subscription) => {
+ if (cancelled) {
+ subscription.unsubscribe();
+ }
+ else {
+ unsubscribeFn = () => subscription.unsubscribe();
+ }
+ });
return () => {
- void sub.then((subscription) => subscription.unsubscribe());
+ cancelled = true;
+ if (unsubscribeFn) {
+ unsubscribeFn();
+ }
};
- }, []);
+ }, [applyTheme]);
return theme;
};
exports.useTheme = useTheme;