Skip to content

Instantly share code, notes, and snippets.

@kingdayx
Last active November 11, 2020 09:44
Show Gist options
  • Save kingdayx/7b154f1e26c0393e75d7f40a02379a30 to your computer and use it in GitHub Desktop.
Save kingdayx/7b154f1e26c0393e75d7f40a02379a30 to your computer and use it in GitHub Desktop.
import React, {
createContext,
useContext,
useReducer,
useMemo,
useCallback,
useEffect,
} from "react";
import { useWeb3React } from "@web3-react/core";
import { safeAccess } from "../utils";
const BLOCK_NUMBER = "BLOCK_NUMBER";
const USD_PRICE = "USD_PRICE";
const WALLET_MODAL_OPEN = "WALLET_MODAL_OPEN";
const UPDATE_BLOCK_NUMBER = "UPDATE_BLOCK_NUMBER";
const TOGGLE_WALLET_MODAL = "TOGGLE_WALLET_MODAL";
const ApplicationContext = createContext("");
function useApplicationContext() {
return useContext(ApplicationContext);
}
function reducer(state, { type, payload }) {
switch (type) {
case UPDATE_BLOCK_NUMBER: {
const { networkId, blockNumber } = payload;
return {
...state,
[BLOCK_NUMBER]: {
...(safeAccess(state, [BLOCK_NUMBER]) || {}),
[networkId]: blockNumber,
},
};
}
case TOGGLE_WALLET_MODAL: {
return { ...state, [WALLET_MODAL_OPEN]: !state[WALLET_MODAL_OPEN] };
}
default: {
throw Error(
`Unexpected action type in ApplicationContext reducer: '${type}'.`
);
}
}
}
export default function Provider({ children }) {
const [state, dispatch] = useReducer(reducer, {
[BLOCK_NUMBER]: {},
[USD_PRICE]: {},
[WALLET_MODAL_OPEN]: false,
});
const updateBlockNumber = useCallback((networkId, blockNumber) => {
dispatch({
type: UPDATE_BLOCK_NUMBER,
payload: { networkId, blockNumber },
});
}, []);
const toggleWalletModal = useCallback(() => {
dispatch({ type: TOGGLE_WALLET_MODAL });
}, []);
return (
<ApplicationContext.Provider
value={useMemo(() => [state, { updateBlockNumber, toggleWalletModal }], [
state,
updateBlockNumber,
toggleWalletModal,
])}
>
{children}
</ApplicationContext.Provider>
);
}
export function Updater() {
const { library, chainId } = useWeb3React();
const [, { updateBlockNumber }] = useApplicationContext();
// update block number
useEffect(() => {
if (library) {
let stale = false;
function update() {
library
.getBlockNumber()
.then((blockNumber) => {
if (!stale) {
updateBlockNumber(chainId, blockNumber);
}
})
.catch(() => {
if (!stale) {
updateBlockNumber(chainId, null);
}
});
}
update();
library.on("block", update);
return () => {
stale = true;
library.removeListener("block", update);
};
}
}, [chainId, library, updateBlockNumber]);
return null;
}
export function useBlockNumber() {
const { chainId } = useWeb3React();
const [state] = useApplicationContext();
return safeAccess(state, [BLOCK_NUMBER, chainId]);
}
export function useWalletModalOpen() {
const [state] = useApplicationContext();
return state[WALLET_MODAL_OPEN];
}
export function useWalletModalToggle() {
const [, { toggleWalletModal }] = useApplicationContext();
return toggleWalletModal;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment