refactor: split Lume Provider into LumeStatusProvider, NetworksProvider, and AuthProvider
This commit is contained in:
parent
40f6699064
commit
dc3fe6adb6
|
@ -0,0 +1,38 @@
|
|||
import { createContext, useState, useContext, ReactNode } from "react";
|
||||
|
||||
// AuthContextType
|
||||
export interface AuthContextType {
|
||||
isLoggedIn: boolean;
|
||||
setIsLoggedIn: (value: boolean) => void;
|
||||
}
|
||||
|
||||
// AuthContext
|
||||
const AuthContext = createContext<AuthContextType | undefined>(undefined);
|
||||
|
||||
// AuthProvider
|
||||
interface AuthProviderProps {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
|
||||
const [isLoggedIn, setIsLoggedIn] = useState(false);
|
||||
|
||||
return (
|
||||
<AuthContext.Provider value={{ isLoggedIn, setIsLoggedIn }}>
|
||||
{children}
|
||||
</AuthContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
// useAuth hook
|
||||
export function useAuth() {
|
||||
const context = useContext(AuthContext);
|
||||
|
||||
if (!context) {
|
||||
throw new Error("useAuth must be used within an AuthProvider");
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
export default AuthProvider;
|
|
@ -0,0 +1,45 @@
|
|||
import { createContext, useState, useContext, ReactNode } from "react";
|
||||
|
||||
// LumeStatusContextType
|
||||
interface LumeStatusContextType {
|
||||
inited: boolean;
|
||||
setInited: (value: boolean) => void;
|
||||
ready: boolean;
|
||||
setReady: (value: boolean) => void;
|
||||
}
|
||||
|
||||
// LumeStatusContext
|
||||
export const LumeStatusContext = createContext<
|
||||
LumeStatusContextType | undefined
|
||||
>(undefined);
|
||||
|
||||
// LumeStatusProvider
|
||||
interface LumeStatusProviderProps {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export const LumeStatusProvider: React.FC<LumeStatusProviderProps> = ({
|
||||
children,
|
||||
}) => {
|
||||
const [inited, setInited] = useState(false);
|
||||
const [ready, setReady] = useState(false);
|
||||
|
||||
return (
|
||||
<LumeStatusContext.Provider value={{ inited, setInited, ready, setReady }}>
|
||||
{children}
|
||||
</LumeStatusContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
// useLumeStatus hook
|
||||
export function useLumeStatus() {
|
||||
const context = useContext(LumeStatusContext);
|
||||
|
||||
if (!context) {
|
||||
throw new Error("useLumeStatus must be used within a LumeStatusProvider");
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
export default LumeStatusProvider;
|
|
@ -8,7 +8,6 @@ import {
|
|||
} from "react";
|
||||
import { createClient as createNetworkRegistryClient } from "@lumeweb/kernel-network-registry-client";
|
||||
import { createNetworkClient } from "@lumeweb/libkernel/module";
|
||||
import { init, loginComplete } from "@lumeweb/libkernel/kernel";
|
||||
|
||||
type SyncState = "done" | "syncing" | "error";
|
||||
|
||||
|
@ -26,45 +25,35 @@ interface NetworkStatus {
|
|||
error?: string;
|
||||
}
|
||||
|
||||
type LumeObject = {
|
||||
export interface NetworksContextType {
|
||||
networks: Network[];
|
||||
};
|
||||
|
||||
export type LumeContextType = {
|
||||
isLoggedIn: boolean;
|
||||
setIsLoggedIn: (value: boolean) => void;
|
||||
lume: LumeObject;
|
||||
inited: boolean;
|
||||
setInited: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
ready: boolean;
|
||||
setReady: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
};
|
||||
setNetworks: React.Dispatch<React.SetStateAction<Network[]>>;
|
||||
}
|
||||
|
||||
const networkRegistry = createNetworkRegistryClient();
|
||||
|
||||
const LumeContext = createContext<LumeContextType | undefined>(undefined);
|
||||
// Networks Context
|
||||
const NetworksContext = createContext<NetworksContextType | undefined>(
|
||||
undefined,
|
||||
);
|
||||
|
||||
const LumeProvider = ({ children }) => {
|
||||
const [isLoggedIn, setIsLoggedIn] = useState(false);
|
||||
const [ready, setReady] = useState<boolean>(false);
|
||||
const [inited, setInited] = useState<boolean>(false);
|
||||
const [lume, setLume] = useState<LumeObject>({ networks: [] });
|
||||
const NetworksProvider = ({ children }) => {
|
||||
const [networks, setNetworks] = useState<Network[]>([]);
|
||||
const statusUnsubs = useRef(new Map());
|
||||
const isMounted = useRef(true); // Use a ref to track mounting
|
||||
|
||||
const handleStatusUpdate = useCallback((id, newNetwork) => {
|
||||
setLume((prevLume) => {
|
||||
const updatedNetworks = prevLume.networks.map((network) =>
|
||||
setNetworks((prevNetworks) => {
|
||||
return prevNetworks.map((network) =>
|
||||
network.id === id ? { ...network, ...newNetwork } : network,
|
||||
);
|
||||
return { ...prevLume, networks: updatedNetworks };
|
||||
});
|
||||
}, []);
|
||||
|
||||
const fetchAndUpdateNetworks = useCallback(async () => {
|
||||
const unsub = () => {
|
||||
statusUnsubs.current.forEach((unsub) => unsub());
|
||||
statusUnsubs.current = new Map<any, any>();
|
||||
statusUnsubs.current.clear();
|
||||
};
|
||||
|
||||
try {
|
||||
|
@ -110,10 +99,7 @@ const LumeProvider = ({ children }) => {
|
|||
statusUnsubs.current = newStatusUnsubs;
|
||||
|
||||
if (isMounted.current) {
|
||||
setLume((prevLume) => ({
|
||||
...prevLume,
|
||||
networks: Array.from(newNetworksMap.values()),
|
||||
}));
|
||||
setNetworks(Array.from(newNetworksMap.values()));
|
||||
} else {
|
||||
unsub();
|
||||
}
|
||||
|
@ -139,29 +125,18 @@ const LumeProvider = ({ children }) => {
|
|||
}, [fetchAndUpdateNetworks]);
|
||||
|
||||
return (
|
||||
<LumeContext.Provider
|
||||
value={{
|
||||
lume,
|
||||
ready,
|
||||
setReady,
|
||||
isLoggedIn,
|
||||
setIsLoggedIn,
|
||||
inited,
|
||||
setInited,
|
||||
}}>
|
||||
<NetworksContext.Provider value={{ networks, setNetworks }}>
|
||||
{children}
|
||||
</LumeContext.Provider>
|
||||
</NetworksContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export default LumeProvider;
|
||||
|
||||
export function useLume() {
|
||||
const ctx = useContext(LumeContext);
|
||||
|
||||
if (!ctx) {
|
||||
throw new Error("useLume must be used within a LumeProvider");
|
||||
export function useNetworks() {
|
||||
const context = useContext(NetworksContext);
|
||||
if (!context) {
|
||||
throw new Error("useNetworks must be used within a NetworksProvider");
|
||||
}
|
||||
|
||||
return ctx;
|
||||
return context;
|
||||
}
|
||||
|
||||
export default NetworksProvider;
|
|
@ -1,11 +1,11 @@
|
|||
import * as Dialog from "@radix-ui/react-dialog";
|
||||
import { Network, useLume } from "../LumeProvider";
|
||||
import Logo from "../../../assets/lume-logo.png";
|
||||
import { cva } from "class-variance-authority";
|
||||
import { cn } from "../../utils";
|
||||
import { useState, useEffect } from "react";
|
||||
import React from "react";
|
||||
import camelCase from "camelcase";
|
||||
import { useNetworks, type Network } from "../../NetworksProvider";
|
||||
|
||||
const SYNCSTATE_TO_TEXT: Record<Network["syncState"], string> = {
|
||||
done: "Synced",
|
||||
|
@ -18,9 +18,7 @@ LumeDashboardTrigger.displayName = "LumeDashboardTrigger";
|
|||
|
||||
const LumeDashboard = (props: any) => {
|
||||
const { children }: { children: React.PropsWithChildren } = props;
|
||||
const {
|
||||
lume: { networks },
|
||||
} = useLume();
|
||||
const { networks } = useNetworks();
|
||||
|
||||
const [uniqueNetworkTypes, setUniqueNetworkTypes] = useState<string[]>([]);
|
||||
|
||||
|
|
|
@ -3,15 +3,15 @@ import {
|
|||
// loginComplete,
|
||||
// logoutComplete,
|
||||
} from "@lumeweb/libkernel/kernel";
|
||||
import { useLume } from "../LumeProvider";
|
||||
import React, { useContext } from "react";
|
||||
import { useAuth } from "../../AuthProvider.js";
|
||||
|
||||
export const LumeIdentityContext = React.createContext<
|
||||
{ open: boolean; setOpen: (open: boolean) => void } | undefined
|
||||
>(undefined);
|
||||
|
||||
export function useLumeIndentity() {
|
||||
const { isLoggedIn, setIsLoggedIn } = useLume();
|
||||
export function useLumeIdentity() {
|
||||
const { isLoggedIn, setIsLoggedIn } = useAuth();
|
||||
const ctx = useContext(LumeIdentityContext);
|
||||
|
||||
if (!ctx) {
|
||||
|
|
|
@ -10,7 +10,7 @@ import {
|
|||
ExclamationTriangleIcon,
|
||||
} from "@radix-ui/react-icons";
|
||||
import { AnimatePresence, m } from "framer-motion";
|
||||
import { useLumeIndentity } from "./LumeIdentityContext";
|
||||
import { useLumeIdentity } from "./LumeIdentityContext";
|
||||
import { useMemo, useState } from "react";
|
||||
|
||||
import * as bip39 from "@scure/bip39";
|
||||
|
@ -54,7 +54,7 @@ const SubmitButtonComponent = () => {
|
|||
};
|
||||
|
||||
const SeedPhraseInputComponent = () => {
|
||||
const { signIn } = useLumeIndentity();
|
||||
const { signIn } = useLumeIdentity();
|
||||
return (
|
||||
<m.form
|
||||
className="flex-col flex gap-y-4"
|
||||
|
@ -118,7 +118,7 @@ const SeedPhraseGenerationComponent = ({ phraseLength = 12 }) => {
|
|||
"idle" | "clicked"
|
||||
>("idle");
|
||||
const [step, setStep] = useState<number>(0);
|
||||
const { signIn } = useLumeIndentity();
|
||||
const { signIn } = useLumeIdentity();
|
||||
|
||||
const phrases = useMemo(() => {
|
||||
return bip39
|
||||
|
@ -158,10 +158,12 @@ const SeedPhraseGenerationComponent = ({ phraseLength = 12 }) => {
|
|||
<div
|
||||
key={`SeedPhrase_${index}`}
|
||||
className={`${TW_PREFIX} relative justify-center items-center gap-2 flex h-10 rounded border border-current ring-current text-neutral-700 w-[calc(33%-8px)]`}>
|
||||
<span className={`${TW_PREFIX} text-white text-md font-normal leading-normal w-full h-fit px-2 bg-transparent text-center`}>
|
||||
<span
|
||||
className={`${TW_PREFIX} text-white text-md font-normal leading-normal w-full h-fit px-2 bg-transparent text-center`}>
|
||||
{phrase}
|
||||
</span>
|
||||
<span className={`${TW_PREFIX} left-[6px] top-0 absolute text-current text-xs font-normal leading-normal`}>
|
||||
<span
|
||||
className={`${TW_PREFIX} left-[6px] top-0 absolute text-current text-xs font-normal leading-normal`}>
|
||||
{index + 1}
|
||||
</span>
|
||||
</div>
|
||||
|
|
18
src/index.ts
18
src/index.ts
|
@ -1,8 +1,18 @@
|
|||
export {
|
||||
default as LumeProvider,
|
||||
useLume,
|
||||
type LumeContextType,
|
||||
} from "./components/lume/LumeProvider";
|
||||
default as AuthProvider,
|
||||
useAuth,
|
||||
type AuthContextType,
|
||||
} from "./components/AuthProvider";
|
||||
export {
|
||||
default as NetworksProvider,
|
||||
useNetworks,
|
||||
type NetworksContextType,
|
||||
} from "./components/NetworksProvider";
|
||||
export {
|
||||
default as LumeStatusProvider,
|
||||
useLumeStatus,
|
||||
type LumeStatusContext,
|
||||
} from "src/components/LumeStatusProvider.js";
|
||||
export {
|
||||
default as LumeDashboard,
|
||||
LumeDashboardTrigger,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React from "react";
|
||||
import { StoryFn, Meta } from "@storybook/react";
|
||||
import LumeDashboard from "../src/components/lume/LumeDashboard/LumeDashboard.js";
|
||||
import LumeProvider from "../src/components/lume/LumeProvider.js";
|
||||
import NetworksProvider from "src/components/NetworksProvider.js";
|
||||
|
||||
export default {
|
||||
title: "LumeDashboard",
|
||||
|
@ -9,9 +9,9 @@ export default {
|
|||
} as Meta<typeof LumeDashboard>;
|
||||
|
||||
const Template: StoryFn<typeof LumeDashboard> = (args) => (
|
||||
<LumeProvider>
|
||||
<NetworksProvider>
|
||||
<LumeDashboard {...args} />
|
||||
</LumeProvider>
|
||||
</NetworksProvider>
|
||||
);
|
||||
|
||||
export const Primary = Template.bind({});
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React from "react";
|
||||
import { StoryFn, Meta } from "@storybook/react";
|
||||
import LumeIdentity from "../src/components/lume/LumeIdentity/LumeIdentity.js";
|
||||
import LumeProvider from "../src/components/lume/LumeProvider.js";
|
||||
import AuthProvider from "src/components/AuthProvider.js";
|
||||
|
||||
export default {
|
||||
title: "LumeIdentity",
|
||||
|
@ -9,9 +9,9 @@ export default {
|
|||
} as Meta<typeof LumeIdentity>;
|
||||
|
||||
const Template: StoryFn<typeof LumeIdentity> = (args) => (
|
||||
<LumeProvider>
|
||||
<AuthProvider>
|
||||
<LumeIdentity {...args} />
|
||||
</LumeProvider>
|
||||
</AuthProvider>
|
||||
);
|
||||
|
||||
export const Primary = Template.bind({});
|
||||
|
|
Loading…
Reference in New Issue