Skip to content

Commit 95bcfbf

Browse files
committed
feat(context): implement new context and hooks for state management
- Refactored context management by introducing a new context provider and hooks for better state handling. - Removed old context implementation and replaced it with a more efficient structure using refs and subscriptions. - Added selectors for accessing authentication and resource states.
1 parent 9b31dd7 commit 95bcfbf

File tree

10 files changed

+206
-103
lines changed

10 files changed

+206
-103
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "electron-gp",
33
"private": true,
4-
"version": "0.2.23",
4+
"version": "0.3.24",
55
"type": "module",
66
"main": "dist-main/app.js",
77
"author": "traeop",
Lines changed: 2 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,6 @@
1-
import { useState, useMemo } from "react";
21
import type { TPropsProvider } from "./types";
3-
import { Context, ContextActions } from "../context";
2+
import { Provider as SyncProvider } from "../context/Context";
43

54
export const Provider = ({ children }: TPropsProvider) => {
6-
const [isUser, setUser] = useState<boolean | undefined>(undefined);
7-
const [isAuthenticated, setAuthenticated] = useState<boolean | undefined>(
8-
undefined
9-
);
10-
const [isResources, setResources] = useState<boolean | undefined>(undefined);
11-
12-
const value = useMemo(
13-
() => ({
14-
isUser,
15-
isAuthenticated,
16-
isResources,
17-
}),
18-
[isUser, isAuthenticated, isResources]
19-
);
20-
21-
const actions = useMemo(
22-
() => ({
23-
setUser,
24-
setResources,
25-
setAuthenticated,
26-
}),
27-
[setUser, setAuthenticated, setResources]
28-
);
29-
30-
return (
31-
<Context.Provider value={value}>
32-
<ContextActions.Provider value={actions}>
33-
{children}
34-
</ContextActions.Provider>
35-
</Context.Provider>
36-
);
5+
return <SyncProvider>{children}</SyncProvider>;
376
};
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import { createContext, useCallback, useRef } from "react";
2+
3+
import type { TContext, TProviderProps, TSubscriberCallback } from "./types";
4+
5+
export const Context = createContext<TContext | null>(null);
6+
7+
export function Provider({ children }: TProviderProps) {
8+
const isAuthenticated = useRef<boolean | undefined>(undefined);
9+
const isResources = useRef<boolean | undefined>(undefined);
10+
const isUser = useRef<boolean | undefined>(undefined);
11+
const subscribers = useRef<Set<TSubscriberCallback>>(new Set());
12+
13+
const notify = useCallback(() => {
14+
subscribers.current.forEach((callback) => callback());
15+
}, []);
16+
17+
const getIsAuthenticated = useCallback((): boolean | undefined => {
18+
return isAuthenticated.current;
19+
}, []);
20+
21+
const getIsResources = useCallback((): boolean | undefined => {
22+
return isResources.current;
23+
}, []);
24+
25+
const getIsUser = useCallback((): boolean | undefined => {
26+
return isUser.current;
27+
}, []);
28+
29+
const setAuthenticated = useCallback(
30+
(value: boolean | undefined): void => {
31+
if (isAuthenticated.current === value) {
32+
return;
33+
}
34+
35+
isAuthenticated.current = value;
36+
notify();
37+
},
38+
[notify],
39+
);
40+
41+
const setResources = useCallback(
42+
(value: boolean | undefined): void => {
43+
if (isResources.current === value) {
44+
return;
45+
}
46+
47+
isResources.current = value;
48+
notify();
49+
},
50+
[notify],
51+
);
52+
53+
const setUser = useCallback(
54+
(value: boolean | undefined): void => {
55+
if (isUser.current === value) {
56+
return;
57+
}
58+
59+
isUser.current = value;
60+
notify();
61+
},
62+
[notify],
63+
);
64+
65+
const subscribe = useCallback((callback: TSubscriberCallback) => {
66+
subscribers.current.add(callback);
67+
68+
return (): void => {
69+
subscribers.current.delete(callback);
70+
};
71+
}, []);
72+
73+
return (
74+
<Context.Provider
75+
value={{
76+
getIsAuthenticated,
77+
getIsResources,
78+
getIsUser,
79+
setAuthenticated,
80+
setResources,
81+
setUser,
82+
subscribe,
83+
}}
84+
>
85+
{children}
86+
</Context.Provider>
87+
);
88+
}

src/renderer/conceptions/Sync/context/context.ts

Lines changed: 0 additions & 7 deletions
This file was deleted.
Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,11 @@
1-
export * from "./Context";
1+
export { Context } from "./Context";
2+
export { useSyncContext } from "./useContext";
3+
export {
4+
useSyncIsAuthenticatedSelector,
5+
useSyncIsResourcesSelector,
6+
useSyncIsUserSelector,
7+
useSetSyncIsAuthenticatedDispatch,
8+
useSetSyncIsResourcesDispatch,
9+
useSetSyncIsUserDispatch,
10+
} from "./useSelectors";
11+
export type { TContext, TProviderProps } from "./types";
Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
1-
export type TContext = TSync;
1+
import type { PropsWithChildren } from "react";
22

3-
export type TContextActions = {
4-
setAuthenticated: React.Dispatch<React.SetStateAction<boolean | undefined>>;
5-
setUser: React.Dispatch<React.SetStateAction<boolean | undefined>>;
6-
setResources: React.Dispatch<React.SetStateAction<boolean | undefined>>;
3+
export type TProviderProps = PropsWithChildren;
4+
5+
export type TSubscriberCallback = () => void;
6+
7+
export type TContext = {
8+
getIsAuthenticated: () => boolean | undefined;
9+
getIsResources: () => boolean | undefined;
10+
getIsUser: () => boolean | undefined;
11+
setAuthenticated: (value: boolean | undefined) => void;
12+
setResources: (value: boolean | undefined) => void;
13+
setUser: (value: boolean | undefined) => void;
14+
subscribe: (callback: TSubscriberCallback) => () => void;
715
};
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { useContext } from "react";
2+
3+
import { Context } from "./Context";
4+
import type { TContext } from "./types";
5+
6+
export const useSyncContext = (): TContext => {
7+
const context = useContext(Context);
8+
9+
if (context === null) {
10+
throw new Error("Sync context is not available");
11+
}
12+
13+
return context;
14+
};
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { useSyncExternalStore } from "react";
2+
3+
import { useSyncContext } from "./useContext";
4+
5+
export const useSyncIsAuthenticatedSelector = (): boolean | undefined => {
6+
const { getIsAuthenticated, subscribe } = useSyncContext();
7+
8+
return useSyncExternalStore(
9+
subscribe,
10+
getIsAuthenticated,
11+
getIsAuthenticated,
12+
);
13+
};
14+
15+
export const useSyncIsResourcesSelector = (): boolean | undefined => {
16+
const { getIsResources, subscribe } = useSyncContext();
17+
18+
return useSyncExternalStore(subscribe, getIsResources, getIsResources);
19+
};
20+
21+
export const useSyncIsUserSelector = (): boolean | undefined => {
22+
const { getIsUser, subscribe } = useSyncContext();
23+
24+
return useSyncExternalStore(subscribe, getIsUser, getIsUser);
25+
};
26+
27+
export const useSetSyncIsAuthenticatedDispatch = () => {
28+
return useSyncContext().setAuthenticated;
29+
};
30+
31+
export const useSetSyncIsResourcesDispatch = () => {
32+
return useSyncContext().setResources;
33+
};
34+
35+
export const useSetSyncIsUserDispatch = () => {
36+
return useSyncContext().setUser;
37+
};
Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,28 @@
1-
import { useContext } from "react";
2-
import { Context, ContextActions } from "../context";
1+
import {
2+
useSyncIsAuthenticatedSelector,
3+
useSyncIsResourcesSelector,
4+
useSyncIsUserSelector,
5+
} from "../context/useSelectors";
6+
import { useSyncContext } from "../context/useContext";
37

48
export const useControlContext = () => {
5-
const context = useContext(Context);
9+
const isAuthenticated = useSyncIsAuthenticatedSelector();
10+
const isResources = useSyncIsResourcesSelector();
11+
const isUser = useSyncIsUserSelector();
612

7-
if (!context) {
8-
throw new Error("useControlContext must be used inside Provider");
9-
}
10-
return context;
13+
return {
14+
isAuthenticated,
15+
isResources,
16+
isUser,
17+
};
1118
};
1219

1320
export const useControlContextActions = () => {
14-
const context = useContext(ContextActions);
21+
const { setAuthenticated, setResources, setUser } = useSyncContext();
1522

16-
if (!context) {
17-
throw new Error("useControlContextActions must be used inside Provider");
18-
}
19-
return context;
23+
return {
24+
setAuthenticated,
25+
setResources,
26+
setUser,
27+
};
2028
};

src/renderer/conceptions/Sync/hooks/useIpc.ts

Lines changed: 20 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,34 @@
1-
import { useEffect } from "react";
1+
import { useCallback, useEffect } from "react";
22
import { useControlContextActions } from "./useControlContext";
33

44
export const useIpc = () => {
55
const { setUser, setAuthenticated, setResources } =
66
useControlContextActions();
77

8+
const subscribeSync = useCallback(() => {
9+
return window.electron.receive.subscribeSync(
10+
({ isAuthenticated, isResources, isUser }) => {
11+
if (isAuthenticated !== undefined) {
12+
setAuthenticated(isAuthenticated);
13+
}
14+
15+
if (isUser !== undefined) {
16+
setUser(isUser);
17+
}
18+
19+
if (isResources !== undefined) {
20+
setResources(isResources);
21+
}
22+
},
23+
);
24+
}, []);
25+
826
useEffect(() => {
927
window.electron.send.sync();
1028
}, []);
1129

1230
useEffect(() => {
13-
const unSub = window.electron.receive.subscribeSync(
14-
({ isAuthenticated, isResources, isUser }) => {
15-
setAuthenticated((prevValue) => {
16-
if (prevValue === undefined) {
17-
return isAuthenticated;
18-
}
19-
20-
if (prevValue !== undefined && isAuthenticated === undefined) {
21-
return prevValue;
22-
}
23-
24-
if (isAuthenticated !== undefined && prevValue !== undefined) {
25-
return isAuthenticated;
26-
}
27-
});
28-
setUser((prevValue) => {
29-
if (prevValue === undefined) {
30-
return isUser;
31-
}
32-
33-
if (prevValue !== undefined && isUser === undefined) {
34-
return prevValue;
35-
}
36-
37-
if (isUser !== undefined && prevValue !== undefined) {
38-
return isUser;
39-
}
40-
});
41-
setResources((prevValue) => {
42-
if (prevValue === undefined) {
43-
return isResources;
44-
}
45-
46-
if (prevValue !== undefined && isResources === undefined) {
47-
return prevValue;
48-
}
49-
50-
if (isResources !== undefined && prevValue !== undefined) {
51-
return isResources;
52-
}
53-
});
54-
}
55-
);
31+
const unSub = subscribeSync();
5632

5733
return unSub;
5834
}, []);

0 commit comments

Comments
 (0)