Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add providers for context of web3 + tailwind theming #24

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 44 additions & 40 deletions app/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,53 +2,57 @@ import { MediaConfiguration } from "@zoralabs/nft-components";
import { Networks, NFTFetchConfiguration } from "@zoralabs/nft-hooks";
import { FC } from "react";
import web3 from "@/app/web3";
import Web3ReactManager from "@/components/Web3ReactManager";
import { ThemeProvider } from "@/hooks/useDarkMode";

export default function GlobalProvider({ children }: { children: FC }): JSX.Element {
return (
<NFTFetchConfiguration networkId={Networks.RINKEBY}>
<Web3ReactManager>
<web3.Provider>
<MediaConfiguration
networkId="4"
style={{
theme: {
borderStyle: "1px solid #4D4D4D", // dark-border
defaultBorderRadius: 0,
lineSpacing: 28,
// headerFont: "color: #691900;",
// titleFont: "color: #FF7246;", //dark-primary
bodyFont: "color: #FFFFFF;", // dark-primary
linkColor: "#FF7246", // ourange-300
buttonColor: {
primaryBackground: "#FFF",
primaryText: "#000",
background: "#000",
<NFTFetchConfiguration networkId={Networks.RINKEBY}>
<MediaConfiguration
networkId="4"
style={{
theme: {
borderStyle: "1px solid #4D4D4D", // dark-border
defaultBorderRadius: 0,
lineSpacing: 28,
// headerFont: "color: #691900;",
// titleFont: "color: #FF7246;", //dark-primary
bodyFont: "color: #FFFFFF;", // dark-primary
linkColor: "#FF7246", // ourange-300
buttonColor: {
primaryBackground: "#FFF",
primaryText: "#000",
background: "#000",
},
previewCard: {
background: "#060606", // dark-background
height: "330px",
width: "330px",
},
// titleFont: {
// color: "#fff",
// },
// mediaContentFont: {
// color: "#fff",
// },
},
previewCard: {
background: "#060606", // dark-background
height: "330px",
width: "330px",
},
// titleFont: {
// color: "#fff",
// },
// mediaContentFont: {
// color: "#fff",
// styles: {
// cardAuctionPricing: {
// display: "hidden",
// },
// cardItemInfo: {
// display: "hidden",
// },
// },
},
// styles: {
// cardAuctionPricing: {
// display: "hidden",
// },
// cardItemInfo: {
// display: "hidden",
// },
// },
}}
>
{children}
</MediaConfiguration>
}}
>
<ThemeProvider>{children}</ThemeProvider>
</MediaConfiguration>
</NFTFetchConfiguration>
</web3.Provider>
</NFTFetchConfiguration>
</Web3ReactManager>
);
}

Expand Down
5 changes: 5 additions & 0 deletions components/Layout/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
/* eslint-disable jsx-a11y/click-events-have-key-events */
/* eslint-disable jsx-a11y/no-static-element-interactions */
/* eslint-disable jsx-a11y/anchor-is-valid */ // next/link passes href

import { Popover, Transition } from "@headlessui/react"; // TailwindUI
import Link from "next/link"; // Dynamic routing
import { Fragment } from "react"; // State management, Fragment for TailwindUI
import web3 from "@/app/web3"; // Global State
import Wallet from "./Wallet";
import { useThemeUpdate } from "@/hooks/useDarkMode";

const learn = [
{
Expand Down Expand Up @@ -59,6 +62,7 @@ function classNames(...classes) {

const Navbar = (): JSX.Element => {
const { address } = web3.useContainer(); // Global state
const toggleTheme = useThemeUpdate();

return (
<div id="navContainer">
Expand Down Expand Up @@ -95,6 +99,7 @@ const Navbar = (): JSX.Element => {
>
{/* About */} CAUTION - RINKEBY TESTNET ONLY!
</a>
<div onClick={() => toggleTheme}>toggle</div>
{/* <div className="-my-2 -mr-2 md:hidden">
<Popover.Button className="inline-flex justify-center items-center p-2 bg-white text-dark-secondary hover:text-dark-secondary hover:bg-dark-background focus:outline-none focus:ring-2 focus:ring-inset focus:ring-yellow-500">
<span className="sr-only">Open menu</span>
Expand Down
18 changes: 11 additions & 7 deletions components/Layout/PageLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@
// import Footer from "./Footer.js";
import { ReactNode } from "react";
import Navbar from "./Navbar";
import { useTheme } from "@/hooks/useDarkMode";

const PageLayout = (props): JSX.Element => (
<div className="mx-auto w-full h-screen min-h-screen">
<Navbar />
{props.children}
{/* <Footer /> */}
</div>
);
const PageLayout = (props): JSX.Element => {
const darkTheme = useTheme();
return (
<div className={`mx-auto w-full h-screen min-h-screen ${darkTheme && "dark"}`}>
<Navbar />
{props.children}
{/* <Footer /> */}
</div>
);
};

export default PageLayout;
4 changes: 4 additions & 0 deletions components/Layout/Wallet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import Link from "next/link"; // Dynamic routing
import { useEffect, useState, Fragment } from "react"; // State management, Fragment for TailwindUI
import { Popover, Transition } from "@headlessui/react"; // TailwindUI
import { useActiveWeb3React } from "@/hooks/web3";
import web3 from "@/app/web3"; // Global state
import { checkForProfile } from "@/modules/mongodb/utils/functions";
import Button from "@/components/Button";
Expand All @@ -11,6 +12,9 @@ function classNames(...classes) {
}

const Wallet = (): JSX.Element => {
const { account, chainId, library, connector, deactivate } = useActiveWeb3React();
console.log(`account: `, account);
console.log(`chainId: `, chainId);
const { address, network, authenticate, disconnectWeb3 } = web3.useContainer();

const [signerProfile, setSignerProfile] = useState(); // Check for user on Ourz' user profile api.
Expand Down
49 changes: 49 additions & 0 deletions components/Web3ReactManager.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { useWeb3React } from "@web3-react/core";
import { useEffect } from "react";
import { NetworkContextName } from "@/modules/web3react/misc";
import { network } from "@/modules/web3react/connectors";
import { useEagerConnect, useInactiveListener } from "@/hooks/web3";

export default function Web3ReactManager({ children }: { children: JSX.Element }) {
const { active } = useWeb3React();
const { active: networkActive, error: networkError, activate: activateNetwork } = useWeb3React();
// const {
// active: networkActive,
// error: networkError,
// activate: activateNetwork,
// } = useWeb3React(NetworkContextName);

// try to eagerly connect to an injected provider, if it exists and has granted access already
const triedEager = useEagerConnect();

// after eagerly trying injected, if the network connect ever isn't active or in an error state, activate itd
useEffect(() => {
if (triedEager && !networkActive && !networkError && !active) {
activateNetwork(network).then(
() => {},
() => {}
);
}
}, [triedEager, networkActive, networkError, activateNetwork, active]);

// when there's no account connected, react to logins (broadly speaking) on the injected provider, if it exists
useInactiveListener(!triedEager);

// if the account context isn't active, and there's an error on the network context, it's an irrecoverable error
if (triedEager && !active && networkError) {
return (
<>
{/* <MessageWrapper>
<Message>
<Trans> */}
Oops! An unknown error occurred. Please refresh the page, or visit from another browser or
device.
{/* </Trans>
</Message>
</MessageWrapper> */}
</>
);
}

return children;
}
27 changes: 27 additions & 0 deletions hooks/useDarkMode.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React, { useContext, useState } from "react";

const ThemeContext = React.createContext();
const ThemeUpdateContext = React.createContext();

export function useTheme() {
return useContext(ThemeContext);
}

export function useThemeUpdate() {
return useContext(ThemeUpdateContext);
}

export function ThemeProvider({ children }) {
const [darkTheme, setDarkTheme] = useState(true);
function toggleTheme() {
setDarkTheme((prevDarkTheme) => !prevDarkTheme);
}

return (
<ThemeContext.Provider value={darkTheme}>
<ThemeUpdateContext.Provider value={() => toggleTheme()}>
{children}
</ThemeUpdateContext.Provider>
</ThemeContext.Provider>
);
}
90 changes: 90 additions & 0 deletions hooks/web3.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/* eslint-disable no-console */
import { Web3Provider } from "@ethersproject/providers";
import { useWeb3React } from "@web3-react/core";
import { useEffect, useState } from "react";
import { NetworkContextName } from "@/modules/web3react/misc";
import { injected } from "@/modules/web3react/connectors";

export function useActiveWeb3React() {
const context = useWeb3React<Web3Provider>();
// const contextNetwork = useWeb3React<Web3Provider>(NetworkContextName);
const contextNetwork = useWeb3React<Web3Provider>();
return context.active ? context : contextNetwork;
}

export function useEagerConnect() {
const { activate, active } = useWeb3React();
const [tried, setTried] = useState(false);

// then, if that fails, try connecting to an injected connector
useEffect(() => {
if (!active) {
injected.isAuthorized().then(
(isAuthorized) => {
if (isAuthorized) {
activate(injected, undefined, true).catch(() => {
setTried(true);
});
} else if (window.ethereum) {
activate(injected, undefined, true).catch(() => {
setTried(true);
});
} else {
setTried(true);
}
},
() => {}
);
}
}, [activate, active]);

// wait until we get confirmation of a connection to flip the flag
useEffect(() => {
if (active) {
setTried(true);
}
}, [active]);

return tried;
}

/**
* Use for network and injected - logs user in
* and out after checking what network theyre on
*/
export function useInactiveListener(suppress = false) {
const { active, error, activate } = useWeb3React();

useEffect(() => {
const { ethereum } = window;

if (ethereum && ethereum.on && !active && !error && !suppress) {
const handleChainChanged = () => {
// eat errors
activate(injected, undefined, true).catch((error) => {
console.error("Failed to activate after chain changed", error);
});
};

const handleAccountsChanged = (accounts: string[]) => {
if (accounts.length > 0) {
// eat errors
activate(injected, undefined, true).catch((error) => {
console.error("Failed to activate after accounts changed", error);
});
}
};

ethereum.on("chainChanged", handleChainChanged);
ethereum.on("accountsChanged", handleAccountsChanged);

return () => {
if (ethereum.removeListener) {
ethereum.removeListener("chainChanged", handleChainChanged);
ethereum.removeListener("accountsChanged", handleAccountsChanged);
}
};
}
return undefined;
}, [active, error, suppress, activate]);
}
Loading