mirror of
https://github.com/MetaFam/TheGame.git
synced 2026-04-24 03:00:09 -04:00
adding better user feedback with toasts
- also added a new LandingPageConnect button
This commit is contained in:
177
packages/web/components/Landing/LandingConnectButton.tsx
Normal file
177
packages/web/components/Landing/LandingConnectButton.tsx
Normal file
@@ -0,0 +1,177 @@
|
||||
/* eslint-disable no-nested-ternary */
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Icon,
|
||||
Spinner,
|
||||
Text,
|
||||
Tooltip,
|
||||
useBreakpointValue,
|
||||
useToast,
|
||||
VStack,
|
||||
} from '@metafam/ds';
|
||||
import { MetaLink } from 'components/Link';
|
||||
import { useWeb3 } from 'lib/hooks';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { GoSignIn, GoSignOut } from 'react-icons/go';
|
||||
import { shortenAddress } from 'utils/stringHelpers';
|
||||
|
||||
export const LandingConnectButton = ({ isIconStyle = false, ...props }) => {
|
||||
const {
|
||||
connect,
|
||||
disconnect,
|
||||
connected,
|
||||
connecting,
|
||||
address,
|
||||
chainId,
|
||||
provider,
|
||||
} = useWeb3();
|
||||
const [wrongNetwork, setWrongNetwork] = useState(false);
|
||||
const spinnerSize = useBreakpointValue({ base: 'sm', '2xl': 'md' });
|
||||
const toast = useToast();
|
||||
const toastRef = useRef<string | number | undefined>();
|
||||
|
||||
useEffect(() => {
|
||||
if (connected && address && provider) {
|
||||
const networkName = provider.network.name;
|
||||
const shortAddress = shortenAddress(address);
|
||||
console.log('Connected to', networkName, 'with address', shortAddress);
|
||||
|
||||
if (toastRef.current && chainId !== '0x89') {
|
||||
setWrongNetwork(true);
|
||||
toastRef.current = toast({
|
||||
title: `Wallet Connection`,
|
||||
description: (
|
||||
<VStack spacing={2} justifyItems="start">
|
||||
<Text>
|
||||
<Box as="strong" textTransform="capitalize">
|
||||
{networkName ?? ''} ({chainId})
|
||||
</Box>{' '}
|
||||
network is not supported. This area of the website requires{' '}
|
||||
<strong>Polygon (id: 0x89)</strong> network. Please switch
|
||||
networks.
|
||||
</Text>
|
||||
<Text>
|
||||
You can visit{' '}
|
||||
<MetaLink href="https://chainlist.org/chain/137" isExternal>
|
||||
chainlist.org
|
||||
</MetaLink>{' '}
|
||||
to add Polygon to your wallet.
|
||||
</Text>
|
||||
</VStack>
|
||||
),
|
||||
status: 'warning',
|
||||
isClosable: true,
|
||||
duration: 5000,
|
||||
});
|
||||
} else {
|
||||
setWrongNetwork(false);
|
||||
toastRef.current = toast({
|
||||
title: 'Wallet Connection',
|
||||
description: `Successfully connected to ${networkName} with ${shortAddress}. 🥳`,
|
||||
status: 'success',
|
||||
isClosable: true,
|
||||
duration: 5000,
|
||||
});
|
||||
}
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [connected, chainId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!connected) {
|
||||
setWrongNetwork(false);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [connected, provider]);
|
||||
|
||||
// useEffect(() => {
|
||||
// if (!connected) {
|
||||
// toast({
|
||||
// title: 'Wallet Connection',
|
||||
// description: 'You are disconnected from the app. See you soon, Anon',
|
||||
// status: 'success',
|
||||
// isClosable: true,
|
||||
// duration: 5000,
|
||||
// });
|
||||
// }
|
||||
// // eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
// }, [connected]);
|
||||
|
||||
return (
|
||||
<Tooltip
|
||||
label={
|
||||
connected && wrongNetwork
|
||||
? 'Change to Polygon network 👆'
|
||||
: `${connected ? 'Disconnect' : 'Connect'} wallet`
|
||||
}
|
||||
hasArrow
|
||||
placement="bottom"
|
||||
>
|
||||
{!isIconStyle ? (
|
||||
<Button
|
||||
onClick={connected ? disconnect : connect}
|
||||
variant="ghost"
|
||||
aria-label="Connect to Web3 wallet"
|
||||
color={
|
||||
wrongNetwork
|
||||
? 'brightIdOrange.600'
|
||||
: 'var(--chakra-colors-landing550)'
|
||||
}
|
||||
textShadow={
|
||||
wrongNetwork
|
||||
? 'brightIdOrange.400'
|
||||
: 'var(--chakra-colors-landing500)'
|
||||
}
|
||||
isDisabled={connecting}
|
||||
size={'xl'}
|
||||
>
|
||||
{connecting ? (
|
||||
<Spinner size="sm" />
|
||||
) : connected ? (
|
||||
'Connected'
|
||||
) : (
|
||||
'Connect'
|
||||
)}
|
||||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
onClick={connected ? disconnect : connect}
|
||||
variant="ghost"
|
||||
display="inline-flex"
|
||||
alignItems="center"
|
||||
fontWeight="normal"
|
||||
color={wrongNetwork ? 'brightIdOrange.600' : 'white'}
|
||||
// textShadow={`0 0 8px var(--chakra-colors-landing500)`}
|
||||
borderRadius="inherit inherit 0 0"
|
||||
opacity={0.3}
|
||||
px={{ base: 1, xl: 2 }}
|
||||
sx={{
|
||||
// svg: {
|
||||
// filter: 'drop-shadow(0 0 10px var(--chakra-colors-diamond))',
|
||||
// },
|
||||
'&:hover': {
|
||||
backgroundColor: 'transparent',
|
||||
color: 'var(--chakra-colors-landing300)',
|
||||
opacity: 1,
|
||||
svg: {
|
||||
filter: 'drop-shadow(0 0 10px var(--chakra-colors-landing300))',
|
||||
},
|
||||
},
|
||||
}}
|
||||
{...props}
|
||||
>
|
||||
{connecting ? (
|
||||
<Spinner size={spinnerSize} />
|
||||
) : (
|
||||
<Icon
|
||||
as={connected ? GoSignOut : GoSignIn}
|
||||
h={{ base: 6, '2xl': 8 }}
|
||||
w={{ base: 6, '2xl': 8 }}
|
||||
/>
|
||||
)}
|
||||
</Button>
|
||||
)}
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
@@ -8,11 +8,9 @@ import {
|
||||
Icon,
|
||||
IconButton,
|
||||
Link,
|
||||
Spinner,
|
||||
Stack,
|
||||
Text,
|
||||
Tooltip,
|
||||
useBreakpointValue,
|
||||
usePrefersReducedMotion,
|
||||
useToast,
|
||||
VStack,
|
||||
@@ -21,14 +19,13 @@ import OctoBg from 'assets/baby_octo.png';
|
||||
import MetaGameLogo from 'assets/logo.png';
|
||||
import { MetaLink } from 'components/Link';
|
||||
import { SetStateAction } from 'jotai';
|
||||
import { useWeb3 } from 'lib/hooks';
|
||||
import { get, set } from 'lib/store';
|
||||
import { Dispatch, ReactNode, useCallback, useEffect, useState } from 'react';
|
||||
import { FaToggleOff, FaToggleOn } from 'react-icons/fa';
|
||||
import { GoSignIn, GoSignOut } from 'react-icons/go';
|
||||
import { MdClose } from 'react-icons/md';
|
||||
|
||||
import { AnimatedWaves, upDownAnimation } from './animations';
|
||||
import { LandingConnectButton } from './LandingConnectButton';
|
||||
|
||||
export const LandingHeader: React.FC = () => {
|
||||
const [toggle, setToggle] = useState(false);
|
||||
@@ -46,8 +43,6 @@ export const LandingHeader: React.FC = () => {
|
||||
const [effectsToggle, setEffectsToggle] = useState(noMotion);
|
||||
const toggleIcon = effectsToggle ? FaToggleOff : FaToggleOn;
|
||||
const [noticeOpen, setNoticeOpen] = useState(false);
|
||||
const { connect, disconnect, connected, connecting } = useWeb3();
|
||||
const spinnerSize = useBreakpointValue({ base: 'sm', '2xl': 'md' });
|
||||
const toast = useToast();
|
||||
|
||||
const handleCloseNotice = useCallback(() => {
|
||||
@@ -73,37 +68,6 @@ export const LandingHeader: React.FC = () => {
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [effectsToggle, noMotion]);
|
||||
|
||||
// eslint-disable-next-line no-promise-executor-return
|
||||
// const sleep = (ms: number) => new Promise(r => setTimeout(r, ms));
|
||||
|
||||
// const handleDisconnect = () => {
|
||||
// disconnect();
|
||||
|
||||
// sleep(1000).then(() => {
|
||||
// console.log('disconnected?');
|
||||
|
||||
// if (!connected) {
|
||||
// toast({
|
||||
// title: 'Wallet disconnected',
|
||||
// description: 'Any local data has been removed. See you soon, Anon! 🐙',
|
||||
// status: 'success',
|
||||
// duration: 5000,
|
||||
// isClosable: true,
|
||||
// });
|
||||
// console.log('disconnected');
|
||||
// }
|
||||
|
||||
// }).catch(() => {
|
||||
// toast({
|
||||
// title: 'Wallet disconnect',
|
||||
// description: 'We couldn\'t disconnect your wallet. Please try again.',
|
||||
// status: 'error',
|
||||
// duration: 5000,
|
||||
// isClosable: true,
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
|
||||
/** Initially set the motion pref if it's not already set */
|
||||
useEffect(() => {
|
||||
if (typeof window !== 'undefined' && window.matchMedia !== undefined) {
|
||||
@@ -218,14 +182,10 @@ export const LandingHeader: React.FC = () => {
|
||||
display="inline-block"
|
||||
fontWeight="normal"
|
||||
color="white"
|
||||
// textShadow={`0 0 8px var(--chakra-colors-landing500)`}
|
||||
borderRadius="inherit inherit 0 0"
|
||||
opacity={0.3}
|
||||
px={{ base: 1, xl: 2 }}
|
||||
sx={{
|
||||
// svg: {
|
||||
// filter: 'drop-shadow(0 0 10px var(--chakra-colors-diamond))',
|
||||
// },
|
||||
'&:hover': {
|
||||
backgroundColor: 'transparent',
|
||||
color: 'var(--chakra-colors-landing300)',
|
||||
@@ -241,48 +201,7 @@ export const LandingHeader: React.FC = () => {
|
||||
</Button>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip
|
||||
label={`${connected ? 'Disconnect' : 'Connect'} wallet`}
|
||||
hasArrow
|
||||
placement="bottom"
|
||||
>
|
||||
<Button
|
||||
onClick={connected ? disconnect : connect}
|
||||
variant="ghost"
|
||||
display="inline-flex"
|
||||
alignItems="center"
|
||||
fontWeight="normal"
|
||||
color="white"
|
||||
// textShadow={`0 0 8px var(--chakra-colors-landing500)`}
|
||||
borderRadius="inherit inherit 0 0"
|
||||
opacity={0.3}
|
||||
px={{ base: 1, xl: 2 }}
|
||||
sx={{
|
||||
// svg: {
|
||||
// filter: 'drop-shadow(0 0 10px var(--chakra-colors-diamond))',
|
||||
// },
|
||||
'&:hover': {
|
||||
backgroundColor: 'transparent',
|
||||
color: 'var(--chakra-colors-landing300)',
|
||||
opacity: 1,
|
||||
svg: {
|
||||
filter:
|
||||
'drop-shadow(0 0 10px var(--chakra-colors-landing300))',
|
||||
},
|
||||
},
|
||||
}}
|
||||
>
|
||||
{connecting ? (
|
||||
<Spinner size={spinnerSize} />
|
||||
) : (
|
||||
<Icon
|
||||
as={connected ? GoSignOut : GoSignIn}
|
||||
h={{ base: 6, '2xl': 8 }}
|
||||
w={{ base: 6, '2xl': 8 }}
|
||||
/>
|
||||
)}
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<LandingConnectButton isIconStyle />
|
||||
<Button
|
||||
onClick={() => setToggle(!toggle)}
|
||||
sx={{
|
||||
|
||||
@@ -3,13 +3,14 @@ import {
|
||||
Box,
|
||||
Button,
|
||||
ButtonGroup,
|
||||
Spinner,
|
||||
Text,
|
||||
Tooltip,
|
||||
usePrefersReducedMotion,
|
||||
VStack,
|
||||
} from '@metafam/ds';
|
||||
import { animated, useSpring } from '@react-spring/web';
|
||||
import OctoBg from 'assets/baby_octo.png';
|
||||
import { LandingConnectButton } from 'components/Landing/LandingConnectButton';
|
||||
import { useGame } from 'contexts/GameContext';
|
||||
import { useWeb3 } from 'lib/hooks';
|
||||
import { get } from 'lib/store';
|
||||
@@ -20,6 +21,7 @@ import {
|
||||
useEffect,
|
||||
useState,
|
||||
} from 'react';
|
||||
import { shortenAddress } from 'utils/stringHelpers';
|
||||
|
||||
export const Chiev = ({
|
||||
won,
|
||||
@@ -33,8 +35,12 @@ export const Chiev = ({
|
||||
const root = typeof window !== 'undefined' ? document.body : null;
|
||||
const { mintChiev, txLoading } = useGame();
|
||||
const [claiming, setClaiming] = useState(false);
|
||||
const { address: account, connect, connecting } = useWeb3();
|
||||
const { address: account, chainId, connected } = useWeb3();
|
||||
const [wrongNetwork, setWrongNetwork] = useState(false);
|
||||
const claimed = get('ChievClaimed') === 'true' ?? false;
|
||||
const chievId = BigInt(
|
||||
'0x480000000000000000000000000000000000000000000000000000000002',
|
||||
);
|
||||
// const [claimed, setClaimed] = useState(false);
|
||||
// const toast = useToast();
|
||||
const springProps = useSpring({
|
||||
@@ -69,25 +75,26 @@ export const Chiev = ({
|
||||
const handleMinting = useCallback(async () => {
|
||||
try {
|
||||
setClaiming(true);
|
||||
const chievId = BigInt(
|
||||
'0x480000000000000000000000000000000000000000000000000000000002',
|
||||
);
|
||||
|
||||
const tx = await mintChiev(chievId);
|
||||
if (tx) {
|
||||
// setClaimed(true);
|
||||
console.log('receipt', tx);
|
||||
setClaiming(false);
|
||||
|
||||
// if (tx.hash) {
|
||||
// setClaimed(true);
|
||||
// }
|
||||
}
|
||||
setClaiming(false);
|
||||
} catch (error: any) {
|
||||
console.log('handleMintingError', error);
|
||||
}
|
||||
}, [mintChiev]);
|
||||
}, [chievId, mintChiev]);
|
||||
|
||||
useEffect(() => {
|
||||
if (connected && chainId !== '0x89') {
|
||||
console.log('wrong network');
|
||||
setWrongNetwork(true);
|
||||
// throw new Error('Wrong network');
|
||||
} else if (connected && chainId === '0x89') {
|
||||
setWrongNetwork(false);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [connected, chainId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof window !== 'undefined' && window.matchMedia !== undefined) {
|
||||
@@ -189,42 +196,41 @@ export const Chiev = ({
|
||||
<Text>Mint your free NFT here...</Text>
|
||||
<ButtonGroup spacing={5}>
|
||||
{!account ? (
|
||||
<Button
|
||||
onClick={connect}
|
||||
variant="ghost"
|
||||
aria-label="Connect to Web3 wallet"
|
||||
color={'var(--chakra-colors-landing550)'}
|
||||
textShadow="var(--chakra-colors-landing500)"
|
||||
isDisabled={connecting}
|
||||
size={'xl'}
|
||||
>
|
||||
{connecting ? <Spinner size="sm" /> : 'Connect'}
|
||||
</Button>
|
||||
<LandingConnectButton />
|
||||
) : (
|
||||
<Button
|
||||
onClick={handleMinting}
|
||||
isDisabled={txLoading || claiming || claimed}
|
||||
variant="white"
|
||||
color={account ? 'green' : 'var(--chakra-colors-landing550)'}
|
||||
textShadow="var(--chakra-colors-landing500)"
|
||||
size={'xl'}
|
||||
<Tooltip
|
||||
label={
|
||||
wrongNetwork
|
||||
? `Change to Polygon network`
|
||||
: `Wallet: ${shortenAddress(account)}`
|
||||
}
|
||||
hasArrow
|
||||
isOpen={wrongNetwork}
|
||||
bg={wrongNetwork ? 'brightIdOrange.600' : 'initial'}
|
||||
>
|
||||
{txLoading || claiming
|
||||
? 'Claiming...'
|
||||
: claimed
|
||||
? 'Claimed'
|
||||
: 'Claim'}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={handleMinting}
|
||||
isDisabled={txLoading || claiming || claimed || wrongNetwork}
|
||||
variant="white"
|
||||
color={
|
||||
account
|
||||
? wrongNetwork
|
||||
? 'brightIdOrange.600'
|
||||
: 'green'
|
||||
: 'var(--chakra-colors-landing550)'
|
||||
}
|
||||
textShadow="var(--chakra-colors-landing500)"
|
||||
size={'xl'}
|
||||
>
|
||||
{txLoading || claiming
|
||||
? 'Claiming...'
|
||||
: claimed
|
||||
? 'Claimed'
|
||||
: 'Claim'}
|
||||
</Button>
|
||||
</Tooltip>
|
||||
)}
|
||||
{/* <Button
|
||||
onClick={handleMinting}
|
||||
variant="ghost"
|
||||
color={'var(--chakra-colors-landing550)'}
|
||||
textShadow="var(--chakra-colors-landing500)"
|
||||
size={'xl'}
|
||||
>
|
||||
{txLoading ? 'Claiming...' : 'Claim'}
|
||||
</Button> */}
|
||||
|
||||
<Button
|
||||
onClick={() => setWon(false)}
|
||||
variant="ghost"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -86,8 +86,6 @@ export const OnboardingGame: React.FC = (): JSX.Element => {
|
||||
const fetchGameData = useCallback(async () => {
|
||||
try {
|
||||
setHasError(false);
|
||||
// setIsLoading(true);
|
||||
console.log('fetchGameData...');
|
||||
|
||||
// const response = await fetch(CONFIG.onboardingGameDataURL);
|
||||
// console.log('fetchGameData RES', response.status);
|
||||
@@ -143,12 +141,10 @@ export const OnboardingGame: React.FC = (): JSX.Element => {
|
||||
? data.elements[state]
|
||||
: data.elements[data.startingElement];
|
||||
|
||||
// console.log('gameDataState', data);
|
||||
const elementData: CurrentElementState = {
|
||||
...element,
|
||||
elementId: state ?? data.startingElement,
|
||||
};
|
||||
// console.log('elementData', elementData);
|
||||
|
||||
setCurrentElement(elementData);
|
||||
const visited = parseInt(visits, 10);
|
||||
@@ -196,8 +192,6 @@ export const OnboardingGame: React.FC = (): JSX.Element => {
|
||||
return connectionData;
|
||||
});
|
||||
|
||||
console.log('got connections', { connectionIds, elementConnections });
|
||||
|
||||
setCurrentConnections(elementConnections);
|
||||
return elementConnections;
|
||||
}
|
||||
@@ -214,25 +208,16 @@ export const OnboardingGame: React.FC = (): JSX.Element => {
|
||||
const getJumpers = (jumperIds: string[]) => {
|
||||
try {
|
||||
if (jumperIds.length > 0) {
|
||||
// console.log('getJumpers', { jumperIds });
|
||||
|
||||
const elementJumpers = jumperIds.map((id: string) => {
|
||||
console.log('elementJumpers', { id });
|
||||
|
||||
const jumperData = {
|
||||
...gameDataState?.jumpers[id],
|
||||
jumperId: id,
|
||||
// elementId: jumpers[id].elementId,
|
||||
};
|
||||
console.log('jumperData', jumperData);
|
||||
|
||||
return jumperData;
|
||||
});
|
||||
|
||||
// console.log('getJumpers returns', { elementJumpers });
|
||||
|
||||
setCurrentJumpers(elementJumpers);
|
||||
console.log('set jumpers', { elementJumpers });
|
||||
|
||||
return elementJumpers;
|
||||
}
|
||||
@@ -266,7 +251,6 @@ export const OnboardingGame: React.FC = (): JSX.Element => {
|
||||
/** Call to get connections when the currentElement changes */
|
||||
useEffect(() => {
|
||||
if (currentElement !== undefined && currentElement.outputs !== null) {
|
||||
// setCurrentConnections([])
|
||||
getConnections(currentElement.outputs);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
@@ -275,26 +259,18 @@ export const OnboardingGame: React.FC = (): JSX.Element => {
|
||||
/** Call to get jumpers when the currentConnections change */
|
||||
useEffect(() => {
|
||||
if (currentConnections !== undefined && currentConnections.length > 0) {
|
||||
// setCurrentJumpers([])
|
||||
|
||||
console.log('jumpers uef: Current connections', currentConnections);
|
||||
|
||||
const jumpers: any[] = currentConnections.filter(
|
||||
(
|
||||
connection: ConnectionStateItem,
|
||||
): IConnection['targetid'] | undefined => {
|
||||
if (connection.targetType === 'jumpers') {
|
||||
// console.log('We found a jumper', connection);
|
||||
return connection.targetid;
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
);
|
||||
if (jumpers !== undefined && jumpers.length > 0) {
|
||||
console.log('Mapping jumpers...', jumpers);
|
||||
|
||||
const jumperIds = jumpers.map((jumper: IConnection) => jumper.targetid);
|
||||
console.log('jumperIds', jumperIds);
|
||||
getJumpers(jumperIds);
|
||||
}
|
||||
}
|
||||
@@ -323,16 +299,13 @@ export const OnboardingGame: React.FC = (): JSX.Element => {
|
||||
* if the paragraph has a link, push it into the `choices` array.
|
||||
*/
|
||||
if (parsedContent.length > 0) {
|
||||
console.log('parsedContent', parsedContent);
|
||||
parsedContent.forEach((paragraph: JSX.Element) => {
|
||||
const { children } = paragraph.props;
|
||||
if (children) {
|
||||
const hasLink = children.type === 'a';
|
||||
if (!hasLink) {
|
||||
// console.log('no link', paragraph);
|
||||
dialogue.push(paragraph);
|
||||
} else {
|
||||
// console.log('has link', children);
|
||||
choices.push(children);
|
||||
}
|
||||
}
|
||||
@@ -340,7 +313,6 @@ export const OnboardingGame: React.FC = (): JSX.Element => {
|
||||
});
|
||||
setCurrentDialogue(dialogue);
|
||||
setCurrentChoices(choices);
|
||||
console.log('makeCurrentSectionDialogue', { dialogue, choices });
|
||||
return {
|
||||
currentDialogue: dialogue,
|
||||
currentChoices: choices,
|
||||
@@ -368,7 +340,6 @@ export const OnboardingGame: React.FC = (): JSX.Element => {
|
||||
*/
|
||||
useEffect(() => {
|
||||
if (typeof window !== 'undefined' && currentDialogue !== undefined) {
|
||||
// makeCurrentSectionDialogue(currentElement);
|
||||
setIsTyping(true);
|
||||
const elementsToType = document.querySelectorAll('.typing-text');
|
||||
const phrases: string[] = [];
|
||||
|
||||
@@ -33,6 +33,7 @@ export const CONFIG = {
|
||||
openseaApiKey: process.env.OPENSEA_API_KEY || '',
|
||||
onboardingGameDataURL:
|
||||
'https://ipfs.fleek.co/ipfs/bafybeig5n6md7kemfjgdbguiepzisrt2y6icxhsj65kyrirs3kqgpv56eu',
|
||||
openseaBaseURL: 'https://testnets.opensea.io',
|
||||
polygonscanBaseURL: 'https://mumbai.polygonscan.com',
|
||||
openseaBaseURL: 'https://opensea.io',
|
||||
polygonscanBaseURL: 'https://polygonscan.com',
|
||||
chievContractAddress: '0x85fCaAFc0dA050FCE685DcB8965F0C1Aa1Ba466b',
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* eslint-disable no-underscore-dangle */
|
||||
import { useToast } from '@metafam/ds';
|
||||
import { Text, useToast, VStack } from '@metafam/ds';
|
||||
import { httpLink } from '@metafam/utils';
|
||||
import type {
|
||||
GameProperties,
|
||||
@@ -7,8 +7,9 @@ import type {
|
||||
IGameContext,
|
||||
IGameState,
|
||||
} from 'components/Landing/OnboardingGame/gameTypes';
|
||||
// import { BigNumber, Contract, providers, utils } from 'ethers';
|
||||
import { Contract, utils } from 'ethers';
|
||||
import { MetaLink } from 'components/Link';
|
||||
import { CONFIG } from 'config';
|
||||
import { Contract } from 'ethers';
|
||||
import { useWeb3 } from 'lib/hooks';
|
||||
import React, {
|
||||
useCallback,
|
||||
@@ -19,8 +20,6 @@ import React, {
|
||||
} from 'react';
|
||||
|
||||
import gameJson from '../components/Landing/OnboardingGame/metagame-onboarding-game.json';
|
||||
// import { providerOptions } from 'utils/walletOptions';
|
||||
// import Web3Modal from 'web3modal';
|
||||
import ABI from '../contracts/BulkDisbursableNFTs.abi';
|
||||
import { get, remove, set } from '../lib/store';
|
||||
|
||||
@@ -54,8 +53,7 @@ export const GameContext = React.createContext<IGameContext>({
|
||||
|
||||
export const GameContextProvider: React.FC = ({ children }) => {
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
// const [txLoading, setTxLoading] = useState(false);
|
||||
const [txLoading] = useState(false);
|
||||
const [txLoading, setTxLoading] = useState(false);
|
||||
const [gameDataState, setGameDataState] = useState<GamePropertiesType>();
|
||||
const {
|
||||
address,
|
||||
@@ -96,7 +94,6 @@ export const GameContextProvider: React.FC = ({ children }) => {
|
||||
useEffect(() => {
|
||||
if (address) {
|
||||
setAccount(address);
|
||||
console.log('hexValue', utils.hexlify(80001));
|
||||
}
|
||||
}, [address]);
|
||||
|
||||
@@ -160,7 +157,6 @@ export const GameContextProvider: React.FC = ({ children }) => {
|
||||
}
|
||||
|
||||
const state = get('OnboardingGameState');
|
||||
console.log('Saved position', state);
|
||||
return state;
|
||||
};
|
||||
|
||||
@@ -171,10 +167,6 @@ export const GameContextProvider: React.FC = ({ children }) => {
|
||||
const handleChoice = useCallback(
|
||||
async (target: string): Promise<string | undefined> => {
|
||||
try {
|
||||
// console.log('handleChoice', target);
|
||||
|
||||
// await fakeLoading(500);
|
||||
|
||||
if (target) gameState(target);
|
||||
const success = gameState() === target;
|
||||
if (success) {
|
||||
@@ -218,84 +210,25 @@ export const GameContextProvider: React.FC = ({ children }) => {
|
||||
return false;
|
||||
}, []);
|
||||
|
||||
// const getProviderOrSigner = useCallback(
|
||||
// async (needSigner = false) => {
|
||||
// try {
|
||||
// // Connect to Metamask
|
||||
// // Since we store `web3Modal` as a reference, we need to access the `current` value to get access to the underlying object
|
||||
// const web3Modal = new Web3Modal({
|
||||
// network: 'mumbai',
|
||||
// cacheProvider: true,
|
||||
// providerOptions,
|
||||
// });
|
||||
|
||||
// const prov = await web3Modal.connect();
|
||||
// const web3Provider = new providers.Web3Provider(prov);
|
||||
// console.log(
|
||||
// 'get provider/signer',
|
||||
// { web3Provider, provider, prov },
|
||||
// provider?.network.chainId,
|
||||
// );
|
||||
// // If user is not connected to the Rinkeby network, let them know and throw an error
|
||||
// if (provider && provider.network.chainId !== 80001) {
|
||||
// throw new Error(
|
||||
// `Change network to Polygon Mumbai. Current: ${chainId}/${provider.network.chainId}`,
|
||||
// );
|
||||
// }
|
||||
|
||||
// if (needSigner) {
|
||||
// const signer = web3Provider.getSigner();
|
||||
// return signer;
|
||||
// }
|
||||
// return web3Provider;
|
||||
// } catch (error: any) {
|
||||
// console.log('getProviderOrSigner error', { error });
|
||||
// const msg = (error?.message as string) || 'unknown error';
|
||||
// setTxLoading(false);
|
||||
// toast({
|
||||
// title: 'Wrong network',
|
||||
// description: msg,
|
||||
// status: 'warning',
|
||||
// isClosable: true,
|
||||
// duration: 5000,
|
||||
// });
|
||||
// return undefined;
|
||||
// }
|
||||
// },
|
||||
// [chainId, provider, toast],
|
||||
// );
|
||||
|
||||
// async function getNonce(signer: providers.JsonRpcSigner) {
|
||||
// return (await signer).getTransactionCount();
|
||||
// }
|
||||
|
||||
// const getGasPrice = useCallback(async (): Promise<BigNumber | null> => {
|
||||
// try {
|
||||
// if (provider) {
|
||||
// const feeData = await provider.getFeeData();
|
||||
// console.log('getGasPrice', feeData);
|
||||
|
||||
// return feeData.gasPrice;
|
||||
// }
|
||||
// return null;
|
||||
// } catch (error) {
|
||||
// console.log('getGasPrice error', { error });
|
||||
// return null;
|
||||
// }
|
||||
// }, [provider]);
|
||||
|
||||
const mintChiev = useCallback(
|
||||
async (tokenId: bigint): Promise<any> => {
|
||||
try {
|
||||
if (address === undefined) await connect();
|
||||
if (provider == null) throw new Error('Provider not set.');
|
||||
const contractAddress = '0x85fCaAFc0dA050FCE685DcB8965F0C1Aa1Ba466b';
|
||||
|
||||
const contractAddress = CONFIG.chievContractAddress;
|
||||
const token = new Contract(contractAddress, ABI, provider.getSigner());
|
||||
const confirmationsWait = 2;
|
||||
const metadataURI = await token.uri(tokenId);
|
||||
if (!metadataURI || metadataURI === '') {
|
||||
throw new Error(`No metadata for token ${tokenId}.`);
|
||||
}
|
||||
console.log({ metadataURI, h: httpLink(metadataURI) });
|
||||
toast({
|
||||
title: 'Claim in progress',
|
||||
description: 'Please sign the transaction in your wallet.',
|
||||
status: 'info',
|
||||
isClosable: true,
|
||||
});
|
||||
const response = await fetch(httpLink(metadataURI)!);
|
||||
const metadata = await response.json();
|
||||
const tx = await token['mint(address[],uint256,bytes)'](
|
||||
@@ -303,86 +236,54 @@ export const GameContextProvider: React.FC = ({ children }) => {
|
||||
tokenId,
|
||||
[],
|
||||
);
|
||||
const receipt = await tx.wait();
|
||||
const nftURL = httpLink(metadata.external_url);
|
||||
console.log({ nftURL, receipt });
|
||||
|
||||
toast({
|
||||
title: 'Claim in progress',
|
||||
description: 'Please sign the transaction in your wallet.',
|
||||
title: 'Chiev claim',
|
||||
description: (
|
||||
<>
|
||||
<Text>Transaction hash: {tx.hash}</Text>
|
||||
<Text>Waiting for {confirmationsWait} confirmations…</Text>
|
||||
</>
|
||||
),
|
||||
status: 'info',
|
||||
isClosable: true,
|
||||
duration: 5000,
|
||||
});
|
||||
// const signer = provider?.getSigner() as providers.JsonRpcSigner;
|
||||
// const contract = new Contract(contractAddress, ABI, signer);
|
||||
// const confirmations = 2;
|
||||
// console.log('Contract', { contract, ABI, signer });
|
||||
// const nonce = await getNonce(signer);
|
||||
// const gasFee = await getGasPrice();
|
||||
// const claimOptions = {
|
||||
// receiver: account,
|
||||
// tokenId,
|
||||
// quantity,
|
||||
// pricePerToken: utils.parseEther('0')._hex,
|
||||
// currency,
|
||||
// proofs: [utils.formatBytes32String('')],
|
||||
// proofMax: BigNumber.from('1')._hex,
|
||||
// value: utils.parseEther('0')._hex,
|
||||
// };
|
||||
|
||||
// const tx = await contract.functions.claim(
|
||||
// claimOptions.receiver,
|
||||
// claimOptions.tokenId,
|
||||
// claimOptions.quantity,
|
||||
// claimOptions.currency,
|
||||
// claimOptions.value,
|
||||
// claimOptions.proofs,
|
||||
// claimOptions.proofMax,
|
||||
// {
|
||||
// value: claimOptions.value,
|
||||
// gasPrice: gasFee,
|
||||
// nonce,
|
||||
// },
|
||||
// );
|
||||
// if (tx.hash) {
|
||||
// setTxLoading(true);
|
||||
// const receiptUrl = `${CONFIG.polygonscanBaseURL}/tx/${tx.hash}`;
|
||||
// toast({
|
||||
// title: 'Chiev claim',
|
||||
// description: `Claim in progress: ${tx.hash}`,
|
||||
// status: 'info',
|
||||
// isClosable: true,
|
||||
// duration: 5000,
|
||||
// });
|
||||
// await tx.wait(confirmations);
|
||||
// set('ChievClaimed', 'true');
|
||||
const receipt = await tx.wait(confirmationsWait);
|
||||
const receiptUrl = `${CONFIG.polygonscanBaseURL}/tx/${tx.hash}`;
|
||||
const nftURL = httpLink(metadata.external_url);
|
||||
|
||||
// toast({
|
||||
// title: 'Chiev claimed 🎉',
|
||||
// description: (
|
||||
// <VStack spacing={2} textAlign="left">
|
||||
// <Text textAlign="left">
|
||||
// <MetaLink href={receiptUrl} isExternal>
|
||||
// View your receipt
|
||||
// </MetaLink>{' '}
|
||||
// 👀
|
||||
// </Text>
|
||||
// <Text textAlign="left">
|
||||
// Check it out on{' '}
|
||||
// <MetaLink href={viewNFTUrl} isExternal>
|
||||
// OpenSea
|
||||
// </MetaLink>{' '}
|
||||
// 🐙
|
||||
// </Text>
|
||||
// </VStack>
|
||||
// ),
|
||||
// status: 'success',
|
||||
// isClosable: true,
|
||||
// duration: 5000,
|
||||
// });
|
||||
// setTxLoading(false);
|
||||
// }
|
||||
return tx;
|
||||
// throw new Error('No account');
|
||||
set('ChievClaimed', 'true');
|
||||
|
||||
toast({
|
||||
title: 'Chiev claimed 🎉',
|
||||
description: (
|
||||
<VStack spacing={2} textAlign="left" justifyItems="start">
|
||||
<Text textAlign="left">
|
||||
<MetaLink href={receiptUrl} isExternal>
|
||||
View your receipt
|
||||
</MetaLink>{' '}
|
||||
👀
|
||||
</Text>
|
||||
{nftURL !== undefined && (
|
||||
<Text textAlign="left">
|
||||
Check it out on{' '}
|
||||
<MetaLink href={nftURL} isExternal>
|
||||
chiev.es
|
||||
</MetaLink>{' '}
|
||||
🐙
|
||||
</Text>
|
||||
)}
|
||||
</VStack>
|
||||
),
|
||||
status: 'success',
|
||||
isClosable: true,
|
||||
duration: 5000,
|
||||
});
|
||||
setTxLoading(false);
|
||||
|
||||
return receipt;
|
||||
} catch (error: any) {
|
||||
console.log('mintChiev error', { error });
|
||||
const msg = (error?.message as string) || 'unknown error';
|
||||
@@ -393,7 +294,6 @@ export const GameContextProvider: React.FC = ({ children }) => {
|
||||
isClosable: true,
|
||||
duration: 5000,
|
||||
});
|
||||
// setTxLoading(false);
|
||||
return msg;
|
||||
}
|
||||
},
|
||||
|
||||
@@ -55,3 +55,13 @@ export const safelyParseTextForTyping = (content: string) => {
|
||||
const parsed = parse(clean, options);
|
||||
return parsed;
|
||||
};
|
||||
|
||||
export const shortenAddress = (address: string, sliceSize?: number): string => {
|
||||
const sliceNumber = sliceSize ?? 4;
|
||||
const start: string = address.toLowerCase().slice(0, sliceNumber);
|
||||
const end: string = address
|
||||
.toLowerCase()
|
||||
.slice(Math.max(0, address.length - sliceNumber));
|
||||
const shortAddress = `${start}...${end}`;
|
||||
return shortAddress;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user