Jd/new network switch (#98)

* halfway

* better network switching

* remove leftIcons with transactionButton

* just also disallow leftIcon on transaction button

* better wording

* some further updates

* fix proposal button
This commit is contained in:
Jonas Daniels
2022-04-29 21:50:15 -07:00
committed by GitHub
parent 61606a4123
commit 56119b5cdf
33 changed files with 280 additions and 167 deletions
+1 -1
View File
@@ -249,7 +249,7 @@ export const SelectReveal: React.FC<SelectRevealProps> = ({
<FormLabel>Image</FormLabel>
<Box width={{ base: "auto", md: "350px" }}>
<FileInput
accept="image/*"
accept={{ "image/*": [] }}
value={imageUrl}
showUploadButton
setValue={(file) => setValue("image", file)}
+134 -20
View File
@@ -1,13 +1,39 @@
import { ConnectWallet, useWeb3 } from "@3rdweb-sdk/react";
import { Tooltip } from "@chakra-ui/react";
import { useNetworkMismatch } from "@thirdweb-dev/react";
import React from "react";
import { Button, ButtonProps } from "tw-components";
import {
Flex,
Icon,
Popover,
PopoverArrow,
PopoverBody,
PopoverContent,
PopoverTrigger,
useDisclosure,
} from "@chakra-ui/react";
import {
useDesiredChainId,
useNetwork,
useNetworkMismatch,
} from "@thirdweb-dev/react";
import React, { useCallback, useRef } from "react";
import { AiOutlineWarning } from "react-icons/ai";
import { VscDebugDisconnect } from "react-icons/vsc";
import { Button, ButtonProps, Card, Heading, Text } from "tw-components";
import {
SUPPORTED_CHAIN_ID,
SupportedChainIdToNetworkMap,
getNetworkFromChainId,
} from "utils/network";
export const MismatchButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ children, isDisabled, onClick, loadingText, type, ...props }, ref) => {
const { address } = useWeb3();
const initialFocusRef = useRef<HTMLButtonElement>(null);
const networksMismatch = useNetworkMismatch();
const { isOpen, onOpen, onClose } = useDisclosure();
if (!address) {
return (
<ConnectWallet borderRadius="full" colorScheme="primary" {...props} />
@@ -15,26 +41,114 @@ export const MismatchButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
}
return (
<Tooltip
isDisabled={!networksMismatch}
label="To do this please switch yout wallet network."
hasArrow
shouldWrapChildren
<Popover
initialFocusRef={initialFocusRef}
isLazy
isOpen={isOpen}
onOpen={networksMismatch ? onOpen : undefined}
onClose={onClose}
>
<Button
w="full"
{...props}
type={type}
loadingText={loadingText}
onClick={onClick}
ref={ref}
isDisabled={networksMismatch || isDisabled}
<PopoverTrigger>
<Button
{...props}
type={networksMismatch ? "button" : type}
loadingText={loadingText}
onClick={networksMismatch ? undefined : onClick}
ref={ref}
isDisabled={isDisabled}
>
{children}
</Button>
</PopoverTrigger>
<Card
as={PopoverContent}
bg="backgroundCardHighlight"
mx={6}
boxShadow="0px 0px 2px 0px var(--popper-arrow-shadow-color)"
>
{children}
</Button>
</Tooltip>
<PopoverArrow bg="backgroundCardHighlight" />
<PopoverBody>
<MismatchNotice
initialFocusRef={initialFocusRef}
onClose={onClose}
/>
</PopoverBody>
</Card>
</Popover>
);
},
);
MismatchButton.displayName = "MismatchButton";
const MismatchNotice: React.VFC<{
initialFocusRef: React.RefObject<HTMLButtonElement>;
onClose: () => void;
}> = ({ initialFocusRef, onClose }) => {
const { chainId, getNetworkMetadata } = useWeb3();
const activeChainId = useDesiredChainId();
const signerChainId = chainId as SUPPORTED_CHAIN_ID;
const [network, switchNetwork] = useNetwork();
const actuallyCanAttemptSwitch = !!switchNetwork;
const signerNetworkIsSupported =
signerChainId in SupportedChainIdToNetworkMap;
const walletNetwork = (
signerNetworkIsSupported
? getNetworkFromChainId(signerChainId)
: getNetworkMetadata(signerChainId as unknown as number).chainName
)
.split("")
.map((s, idx) => (idx === 0 ? s.toUpperCase() : s))
.join("");
const twNetwork = getNetworkFromChainId(activeChainId)
.split("")
.map((s, idx) => (idx === 0 ? s.toUpperCase() : s))
.join("");
const onSwitchWallet = useCallback(async () => {
if (actuallyCanAttemptSwitch && activeChainId) {
await switchNetwork(activeChainId);
}
onClose();
}, [activeChainId, actuallyCanAttemptSwitch, onClose, switchNetwork]);
return (
<Flex direction="column" gap={4}>
<Heading size="label.lg">
<Flex gap={2} align="center">
<Icon boxSize={6} as={AiOutlineWarning} />
<span>Network Mismatch</span>
</Flex>
</Heading>
<Text>
You are connected to the <strong>{walletNetwork}</strong> network but
you are trying to interact on the <strong>{twNetwork}</strong> network.
</Text>
<Button
ref={actuallyCanAttemptSwitch ? initialFocusRef : undefined}
leftIcon={<Icon as={VscDebugDisconnect} />}
size="sm"
onClick={onSwitchWallet}
isLoading={network.loading}
isDisabled={!actuallyCanAttemptSwitch}
colorScheme="orange"
>
Switch wallet to {twNetwork}
</Button>
{!actuallyCanAttemptSwitch && (
<Text size="body.sm" fontStyle="italic">
Your connected wallet does not support programatic switching.
<br />
Please manually switch the network in your wallet.
</Text>
)}
</Flex>
);
};
+2 -2
View File
@@ -5,7 +5,7 @@ import useDimensions from "react-cool-dimensions";
import { BiTransferAlt } from "react-icons/bi";
import { ButtonProps, Text } from "tw-components";
export interface TransactionButtonProps extends ButtonProps {
export interface TransactionButtonProps extends Omit<ButtonProps, "leftIcon"> {
transactionCount: number;
}
@@ -64,7 +64,7 @@ export const TransactionButton: React.FC<TransactionButtonProps> = ({
top={0}
bottom={0}
left={0}
px={4}
px={size === "sm" ? 3 : size === "lg" ? 6 : size === "xs" ? 2 : 4}
>
<Flex
as="span"
@@ -325,7 +325,7 @@ const BuiltinContractForm: React.VFC<BuiltinContractFormProps> = ({
>
<FormLabel>Image</FormLabel>
<FileInput
accept="image/*"
accept={{ "image/*": [] }}
value={useImageFileOrUrl(watch("image"))}
setValue={(file) =>
setValue("image", file, { shouldTouch: true })
@@ -181,7 +181,7 @@ const CustomContractForm: React.VFC<CustomContractFormProps> = ({
>
<FormLabel>Image</FormLabel>
<FileInput
accept="image/*"
accept={{ "image/*": [] }}
value={useImageFileOrUrl(watch("image"))}
setValue={(file) =>
setValue("image", file, { shouldTouch: true })
@@ -1,6 +1,5 @@
import { ContractId } from "../types";
import { isContractIdBuiltInContract } from "../utils";
import { NetworkMismatchNotice } from "components/notices/NetworkMismatch";
import { CustomSDKContext } from "contexts/custom-sdk-context";
import dynamic from "next/dynamic";
import { useState } from "react";
@@ -41,7 +40,6 @@ export const ContractDeployForm: React.VFC<ContractDeployFormProps> = ({
onChainSelect={setSelectedChain}
/>
)}
<NetworkMismatchNotice />
</CustomSDKContext>
);
};
@@ -3,10 +3,10 @@ import { useActiveChainId, useWeb3 } from "@3rdweb-sdk/react";
import { ListerOnly } from "@3rdweb-sdk/react/components/roles/lister-only";
import { Flex, Icon, Tooltip, useDisclosure } from "@chakra-ui/react";
import { ChainId } from "@thirdweb-dev/react";
import { MismatchButton } from "components/buttons/MismatchButton";
import { MintDrawer } from "components/shared/MintDrawer";
import React from "react";
import { FiPlus } from "react-icons/fi";
import { Button } from "tw-components";
import { SUPPORTED_CHAIN_ID } from "utils/network";
const UNSUPPORTED_CHAINS = [ChainId.Avalanche, ChainId.Fantom];
@@ -33,13 +33,14 @@ export const ListButton: React.FC<IListButtonProps> = ({
hasArrow
>
<Flex>
<MismatchButton
<Button
{...restButtonProps}
leftIcon={<Icon as={FiPlus} />}
isDisabled
colorScheme="primary"
>
New Listing
</MismatchButton>
</Button>
</Flex>
</Tooltip>
</ListerOnly>
@@ -50,13 +51,14 @@ export const ListButton: React.FC<IListButtonProps> = ({
<ListerOnly contract={contract}>
<>
<MintDrawer isOpen={isOpen} onClose={onClose} contract={contract} />
<MismatchButton
<Button
{...restButtonProps}
onClick={onOpen}
leftIcon={<Icon as={FiPlus} />}
colorScheme="primary"
>
New Listing
</MismatchButton>
</Button>
</>
</ListerOnly>
);
@@ -2,10 +2,10 @@ import { IContractActionButtonProps } from "./types";
import { MinterOnly } from "@3rdweb-sdk/react";
import { Icon, useDisclosure } from "@chakra-ui/react";
import { EditionDrop, NFTDrop } from "@thirdweb-dev/sdk";
import { MismatchButton } from "components/buttons/MismatchButton";
import { MintDrawer } from "components/shared/MintDrawer";
import React, { useMemo } from "react";
import { FiPlus } from "react-icons/fi";
import { Button } from "tw-components";
export interface IMintButtonProps extends IContractActionButtonProps {}
export const MintButton: React.FC<IMintButtonProps> = ({
@@ -24,13 +24,13 @@ export const MintButton: React.FC<IMintButtonProps> = ({
<MinterOnly contract={contract}>
<>
<MintDrawer isOpen={isOpen} onClose={onClose} contract={contract} />
<MismatchButton
<Button
{...restButtonProps}
onClick={onOpen}
leftIcon={<Icon as={FiPlus} />}
>
{mintButtonText}
</MismatchButton>
</Button>
</>
</MinterOnly>
);
@@ -4,10 +4,10 @@ import {
} from "@3rdweb-sdk/react/hooks/useVote";
import { Icon, Tooltip, useDisclosure } from "@chakra-ui/react";
import { ValidContractInstance } from "@thirdweb-dev/sdk";
import { MismatchButton } from "components/buttons/MismatchButton";
import { MintDrawer } from "components/shared/MintDrawer";
import { useTxNotifications } from "hooks/useTxNotifications";
import { FiPlus } from "react-icons/fi";
import { Button } from "tw-components";
interface IVoteButton {
contract?: ValidContractInstance;
@@ -19,13 +19,13 @@ export const ProposalButton: React.FC<IVoteButton> = ({ contract }) => {
return (
<>
<MintDrawer isOpen={isOpen} onClose={onClose} contract={contract} />
<MismatchButton
<Button
colorScheme="primary"
onClick={onOpen}
leftIcon={<Icon as={FiPlus} />}
>
Create Proposal
</MismatchButton>
</Button>
</>
);
};
@@ -56,13 +56,13 @@ export const DelegateButton: React.FC<IVoteButton> = ({ contract }) => {
return (
<Tooltip label="You need to delegate tokens to this contract before you can make proposals and vote.">
<MismatchButton
<Button
colorScheme="primary"
onClick={delegateTokens}
isLoading={isDelegating}
>
Delegate Tokens
</MismatchButton>
</Button>
</Tooltip>
);
};
@@ -27,7 +27,7 @@ export const ContractEmptyState: React.FC<IContractEmptyState> = ({
alt="Empty state illustration"
w="130px"
/>
<Heading size="label.2xl" textAlign="center">
<Heading size="label.xl" textAlign="center">
{title}
</Heading>
</Stack>
@@ -10,7 +10,6 @@ import {
DrawerFooter,
FormControl,
FormErrorMessage,
Icon,
Input,
Stack,
Textarea,
@@ -19,13 +18,12 @@ import {
import { useNFTMint } from "@thirdweb-dev/react";
import { Erc721 } from "@thirdweb-dev/sdk";
import { OpenSeaPropertyBadge } from "components/badges/opensea";
import { MismatchButton } from "components/buttons/MismatchButton";
import { TransactionButton } from "components/buttons/TransactionButton";
import { FileInput } from "components/shared/FileInput";
import { useImageFileOrUrl } from "hooks/useImageFileOrUrl";
import { useTxNotifications } from "hooks/useTxNotifications";
import React from "react";
import { useForm } from "react-hook-form";
import { FiPlus } from "react-icons/fi";
import { Button, FormHelperText, FormLabel, Heading } from "tw-components";
import { NFTMetadataInputLimited } from "types/modified-types";
@@ -166,7 +164,7 @@ export const CustomNFTMintForm: React.FC<CustomNFTMintForm> = ({
<FormLabel>Cover Image</FormLabel>
<FileInput
maxContainerWidth={"200px"}
accept="image/*"
accept={{ "image/*": [] }}
value={imageUrl}
showUploadButton
setValue={(file) => setValue("image", file)}
@@ -248,15 +246,15 @@ export const CustomNFTMintForm: React.FC<CustomNFTMintForm> = ({
>
Cancel
</Button>
<MismatchButton
<TransactionButton
transactionCount={1}
isLoading={isLoading}
leftIcon={<Icon as={FiPlus} />}
form={MINT_FORM_ID}
type="submit"
colorScheme="primary"
>
Mint NFT
</MismatchButton>
</TransactionButton>
</DrawerFooter>
</>
);
@@ -12,7 +12,6 @@ import {
DrawerFooter,
FormControl,
FormErrorMessage,
Icon,
Input,
Stack,
Textarea,
@@ -20,13 +19,12 @@ import {
} from "@chakra-ui/react";
import { Edition } from "@thirdweb-dev/sdk";
import { OpenSeaPropertyBadge } from "components/badges/opensea";
import { MismatchButton } from "components/buttons/MismatchButton";
import { TransactionButton } from "components/buttons/TransactionButton";
import { FileInput } from "components/shared/FileInput";
import { useImageFileOrUrl } from "hooks/useImageFileOrUrl";
import { useTxNotifications } from "hooks/useTxNotifications";
import React from "react";
import { useForm } from "react-hook-form";
import { FiPlus } from "react-icons/fi";
import { Button, FormHelperText, FormLabel, Heading } from "tw-components";
import { NFTMetadataInputLimited } from "types/modified-types";
@@ -164,7 +162,7 @@ export const EditionMintForm: React.FC<IEditionMintForm> = ({ contract }) => {
<FormLabel>Cover Image</FormLabel>
<FileInput
maxContainerWidth={"200px"}
accept="image/*"
accept={{ "image/*": [] }}
value={imageUrl}
showUploadButton
setValue={(file) => setValue("image", file)}
@@ -256,15 +254,15 @@ export const EditionMintForm: React.FC<IEditionMintForm> = ({ contract }) => {
>
Cancel
</Button>
<MismatchButton
<TransactionButton
transactionCount={1}
isLoading={mint.isLoading}
leftIcon={<Icon as={FiPlus} />}
form={MINT_FORM_ID}
type="submit"
colorScheme="primary"
>
Create NFTs
</MismatchButton>
</TransactionButton>
</DrawerFooter>
</>
);
@@ -12,7 +12,6 @@ import {
DrawerFooter,
FormControl,
FormErrorMessage,
Icon,
Input,
Stack,
Textarea,
@@ -20,13 +19,12 @@ import {
} from "@chakra-ui/react";
import { EditionDrop } from "@thirdweb-dev/sdk";
import { OpenSeaPropertyBadge } from "components/badges/opensea";
import { MismatchButton } from "components/buttons/MismatchButton";
import { TransactionButton } from "components/buttons/TransactionButton";
import { FileInput } from "components/shared/FileInput";
import { useImageFileOrUrl } from "hooks/useImageFileOrUrl";
import { useTxNotifications } from "hooks/useTxNotifications";
import React from "react";
import { useForm } from "react-hook-form";
import { FiPlus } from "react-icons/fi";
import { Button, FormHelperText, FormLabel, Heading } from "tw-components";
import { NFTMetadataInputLimited } from "types/modified-types";
@@ -169,7 +167,7 @@ export const EditionDropMintForm: React.FC<INFTDropMintForm> = ({
<FormLabel>Cover Image</FormLabel>
<FileInput
maxContainerWidth={"200px"}
accept="image/*"
accept={{ "image/*": [] }}
value={imageUrl}
showUploadButton
setValue={(file) => setValue("image", file)}
@@ -252,15 +250,15 @@ export const EditionDropMintForm: React.FC<INFTDropMintForm> = ({
>
Cancel
</Button>
<MismatchButton
<TransactionButton
transactionCount={1}
isLoading={mint.isLoading}
leftIcon={<Icon as={FiPlus} />}
form={MINT_FORM_ID}
type="submit"
colorScheme="primary"
>
Create Edition Drop
</MismatchButton>
</TransactionButton>
</DrawerFooter>
</>
);
@@ -12,7 +12,6 @@ import {
DrawerFooter,
FormControl,
FormErrorMessage,
Icon,
Input,
Stack,
Textarea,
@@ -20,13 +19,12 @@ import {
} from "@chakra-ui/react";
import { NFTCollection } from "@thirdweb-dev/sdk";
import { OpenSeaPropertyBadge } from "components/badges/opensea";
import { MismatchButton } from "components/buttons/MismatchButton";
import { TransactionButton } from "components/buttons/TransactionButton";
import { FileInput } from "components/shared/FileInput";
import { useImageFileOrUrl } from "hooks/useImageFileOrUrl";
import { useTxNotifications } from "hooks/useTxNotifications";
import React from "react";
import { useForm } from "react-hook-form";
import { FiPlus } from "react-icons/fi";
import { Button, FormHelperText, FormLabel, Heading } from "tw-components";
import { NFTMetadataInputLimited } from "types/modified-types";
@@ -167,7 +165,7 @@ export const NFTCollectionMintForm: React.FC<INFTCollectionMintForm> = ({
<FormLabel>Cover Image</FormLabel>
<FileInput
maxContainerWidth={"200px"}
accept="image/*"
accept={{ "image/*": [] }}
value={imageUrl}
showUploadButton
setValue={(file) => setValue("image", file)}
@@ -249,15 +247,15 @@ export const NFTCollectionMintForm: React.FC<INFTCollectionMintForm> = ({
>
Cancel
</Button>
<MismatchButton
<TransactionButton
transactionCount={1}
isLoading={mint.isLoading}
leftIcon={<Icon as={FiPlus} />}
form={MINT_FORM_ID}
type="submit"
colorScheme="primary"
>
Mint NFT
</MismatchButton>
</TransactionButton>
</DrawerFooter>
</>
);
@@ -12,7 +12,6 @@ import {
DrawerFooter,
FormControl,
FormErrorMessage,
Icon,
Input,
Stack,
Textarea,
@@ -20,13 +19,12 @@ import {
} from "@chakra-ui/react";
import { NFTDrop } from "@thirdweb-dev/sdk";
import { OpenSeaPropertyBadge } from "components/badges/opensea";
import { MismatchButton } from "components/buttons/MismatchButton";
import { TransactionButton } from "components/buttons/TransactionButton";
import { FileInput } from "components/shared/FileInput";
import { useImageFileOrUrl } from "hooks/useImageFileOrUrl";
import { useTxNotifications } from "hooks/useTxNotifications";
import React from "react";
import { useForm } from "react-hook-form";
import { FiPlus } from "react-icons/fi";
import { Button, FormHelperText, FormLabel, Heading } from "tw-components";
import { NFTMetadataInputLimited } from "types/modified-types";
@@ -167,7 +165,7 @@ export const NFTDropMintForm: React.FC<INFTDropMintForm> = ({ contract }) => {
<FormLabel>Cover Image</FormLabel>
<FileInput
maxContainerWidth={"200px"}
accept="image/*"
accept={{ "image/*": [] }}
value={imageUrl}
showUploadButton
setValue={(file) => setValue("image", file)}
@@ -250,15 +248,15 @@ export const NFTDropMintForm: React.FC<INFTDropMintForm> = ({ contract }) => {
>
Cancel
</Button>
<MismatchButton
<TransactionButton
transactionCount={1}
isLoading={mint.isLoading}
leftIcon={<Icon as={FiPlus} />}
form={MINT_FORM_ID}
type="submit"
colorScheme="primary"
>
Create Drop
</MismatchButton>
</TransactionButton>
</DrawerFooter>
</>
);
@@ -5,17 +5,15 @@ import {
DrawerFooter,
FormControl,
FormErrorMessage,
Icon,
Input,
Stack,
useModalContext,
} from "@chakra-ui/react";
import { Token } from "@thirdweb-dev/sdk";
import { MismatchButton } from "components/buttons/MismatchButton";
import type { Token } from "@thirdweb-dev/sdk";
import { TransactionButton } from "components/buttons/TransactionButton";
import { useTxNotifications } from "hooks/useTxNotifications";
import React from "react";
import { useForm } from "react-hook-form";
import { FiPlus } from "react-icons/fi";
import { Button, FormLabel } from "tw-components";
const MINT_FORM_ID = "token-mint-form";
@@ -75,15 +73,15 @@ export const TokenMintForm: React.FC<ITokenMintForm> = ({ contract }) => {
>
Cancel
</Button>
<MismatchButton
<TransactionButton
transactionCount={1}
isLoading={mint.isLoading}
leftIcon={<Icon as={FiPlus} />}
form={MINT_FORM_ID}
type="submit"
colorScheme="primary"
>
Mint Tokens
</MismatchButton>
</TransactionButton>
</DrawerFooter>
</>
);
@@ -8,17 +8,15 @@ import {
DrawerFooter,
FormControl,
FormErrorMessage,
Icon,
Stack,
Textarea,
useModalContext,
} from "@chakra-ui/react";
import { Vote } from "@thirdweb-dev/sdk";
import { MismatchButton } from "components/buttons/MismatchButton";
import { TransactionButton } from "components/buttons/TransactionButton";
import { useTxNotifications } from "hooks/useTxNotifications";
import React from "react";
import { useForm } from "react-hook-form";
import { FiPlus } from "react-icons/fi";
import { Button, FormLabel } from "tw-components";
const MINT_FORM_ID = "proposal-mint-form";
@@ -74,15 +72,15 @@ export const ProposalMintForm: React.FC<IProposalMintForm> = ({ contract }) => {
>
Cancel
</Button>
<MismatchButton
<TransactionButton
transactionCount={1}
isLoading={propose.isLoading}
leftIcon={<Icon as={FiPlus} />}
form={MINT_FORM_ID}
type="submit"
colorScheme="primary"
>
Submit Proposal
</MismatchButton>
</TransactionButton>
</DrawerFooter>
</>
);
@@ -6,7 +6,7 @@ import {
AirdropAddressInput,
AirdropUpload,
} from "components/batch-upload/AirdropUpload";
import { MismatchButton } from "components/buttons/MismatchButton";
import { TransactionButton } from "components/buttons/TransactionButton";
import { useTxNotifications } from "hooks/useTxNotifications";
import React, { useCallback } from "react";
import { useForm } from "react-hook-form";
@@ -110,7 +110,8 @@ export const AirdropSection: React.FC<IAirdropSection> = ({
</Flex>
</Flex>
</Stack>
<MismatchButton
<TransactionButton
transactionCount={1}
isLoading={airdrop.isLoading}
type="submit"
colorScheme="primary"
@@ -118,7 +119,7 @@ export const AirdropSection: React.FC<IAirdropSection> = ({
rightIcon={<Icon as={IoMdSend} />}
>
Airdrop
</MismatchButton>
</TransactionButton>
</Stack>
</form>
</Stack>
@@ -8,7 +8,7 @@ import {
Stack,
} from "@chakra-ui/react";
import { Edition, EditionDrop, ValidContractInstance } from "@thirdweb-dev/sdk";
import { MismatchButton } from "components/buttons/MismatchButton";
import { TransactionButton } from "components/buttons/TransactionButton";
import { useTxNotifications } from "hooks/useTxNotifications";
import React, { useCallback } from "react";
import { useForm } from "react-hook-form";
@@ -75,14 +75,15 @@ export const BurnSection: React.FC<IBurnSection> = ({ contract, tokenId }) => {
</FormControl>
)}
</Stack>
<MismatchButton
<TransactionButton
transactionCount={1}
isLoading={burn.isLoading}
type="submit"
colorScheme="primary"
rightIcon={<Icon as={FaBurn} />}
>
Burn
</MismatchButton>
</TransactionButton>
</Stack>
</form>
</Stack>
@@ -9,7 +9,7 @@ import {
} from "@chakra-ui/react";
import { AddressZero } from "@ethersproject/constants";
import { Edition, EditionDrop, ValidContractInstance } from "@thirdweb-dev/sdk";
import { MismatchButton } from "components/buttons/MismatchButton";
import { TransactionButton } from "components/buttons/TransactionButton";
import { useTxNotifications } from "hooks/useTxNotifications";
import React, { useCallback } from "react";
import { useForm } from "react-hook-form";
@@ -86,14 +86,15 @@ export const TransferSection: React.FC<ITransferSection> = ({
</FormControl>
)}
</Stack>
<MismatchButton
<TransactionButton
transactionCount={1}
isLoading={transfer.isLoading}
type="submit"
colorScheme="primary"
rightIcon={<Icon as={IoMdSend} />}
>
Send
</MismatchButton>
Transfer
</TransactionButton>
</Stack>
</form>
</Stack>
@@ -43,7 +43,6 @@ import { Row, usePagination, useTable } from "react-table";
import { Card, Heading, Text } from "tw-components";
interface IRawContractItemsTable<TContract extends ContractWithGetAll> {
// items: TTableType<TContract>[];
contract?: TContract;
emptyState?: IContractEmptyState;
lazyMint?: true;
+45 -38
View File
@@ -5,12 +5,13 @@ import {
useHasVotedOnProposal,
useTokensDelegated,
} from "@3rdweb-sdk/react/hooks/useVote";
import { Flex, Icon, Stack } from "@chakra-ui/react";
import { Flex, Icon } from "@chakra-ui/react";
import {
ProposalState,
Proposal as ProposalType,
VoteType,
} from "@thirdweb-dev/sdk";
import { TransactionButton } from "components/buttons/TransactionButton";
import { ethers } from "ethers";
import { useSingleQueryParam } from "hooks/useQueryParam";
import { useTxNotifications } from "hooks/useTxNotifications";
@@ -83,10 +84,13 @@ export const Proposal: React.FC<IProposal> = ({ proposal }) => {
const { data: delegated } = useTokensDelegated(voteAddress);
const { mutate: execute, isLoading: isExecuting } =
useExecuteProposalMutation(proposal.proposalId.toString(), voteAddress);
const { mutate: vote, isLoading: isVoting } = useCastVoteMutation(
proposal.proposalId.toString(),
voteAddress,
);
const {
mutate: vote,
isLoading: isVoting,
variables,
} = useCastVoteMutation(proposal.proposalId.toString(), voteAddress);
console.log("*** data", { variables });
const votes = useMemo(() => {
return {
@@ -183,42 +187,45 @@ export const Proposal: React.FC<IProposal> = ({ proposal }) => {
!hasVoted &&
!hasVotedLoading &&
delegated ? (
<Stack direction="row" spacing={2} mt="24px">
{isVoting ? (
<Button width="80px" size="sm" isLoading />
) : (
<>
<Button
width="80px"
size="sm"
leftIcon={<Icon as={FiCheck} />}
onClick={() => castVote(1)}
>
For
</Button>
<Button
width="80px"
size="sm"
leftIcon={<Icon as={FiX} />}
onClick={() => castVote(0)}
>
Against
</Button>
<Button
width="80px"
size="sm"
leftIcon={<Icon as={FiMinus} />}
onClick={() => castVote(2)}
>
Abstain
</Button>
</>
)}
</Stack>
<Flex mt="24px" gap={2}>
<TransactionButton
size="sm"
transactionCount={1}
rightIcon={<Icon as={FiCheck} />}
onClick={() => castVote(1)}
colorScheme="green"
isDisabled={isVoting && variables?.voteType !== 1}
isLoading={isVoting && variables?.voteType === 1}
>
Approve
</TransactionButton>
<TransactionButton
size="sm"
transactionCount={1}
rightIcon={<Icon as={FiX} />}
onClick={() => castVote(0)}
colorScheme="red"
isDisabled={isVoting && variables?.voteType !== 0}
isLoading={isVoting && variables?.voteType === 0}
>
Against
</TransactionButton>
<TransactionButton
colorScheme="blackAlpha"
size="sm"
transactionCount={1}
rightIcon={<Icon as={FiMinus} />}
onClick={() => castVote(2)}
isDisabled={isVoting && variables?.voteType !== 2}
isLoading={isVoting && variables?.voteType === 2}
>
Abstain
</TransactionButton>
</Flex>
) : (
canExecute && (
<Button
colorScheme="blue"
colorScheme="primary"
size="sm"
leftIcon={<Icon as={FiCheck} />}
onClick={executeProposal}
@@ -95,7 +95,7 @@ export const ContractMetadata = <TContract extends ValidContractClass>({
metadataMutation.isLoading ||
isDisabled
}
accept="image/*"
accept={{ "image/*": [] }}
value={useImageFileOrUrl(watch("image"))}
setValue={(file) =>
setValue("image", file, { shouldTouch: true })
+5 -4
View File
@@ -26,7 +26,7 @@ import {
Tr,
} from "@chakra-ui/react";
import { useToken } from "@thirdweb-dev/react";
import { MismatchButton } from "components/buttons/MismatchButton";
import { TransactionButton } from "components/buttons/TransactionButton";
import { useSingleQueryParam } from "hooks/useQueryParam";
import { useTxNotifications } from "hooks/useTxNotifications";
import React from "react";
@@ -157,7 +157,8 @@ export const TransferModal: React.FC<IMintModal> = ({ isOpen, onClose }) => {
</ModalBody>
<ModalFooter>
<MismatchButton
<TransactionButton
transactionCount={1}
isLoading={mutation.isLoading}
type="submit"
form={FORM_ID}
@@ -165,8 +166,8 @@ export const TransferModal: React.FC<IMintModal> = ({ isOpen, onClose }) => {
rightIcon={<FiSend />}
isDisabled={!watch("to") || !watch("amount")}
>
Send Transfer
</MismatchButton>
Transfer
</TransactionButton>
</ModalFooter>
</ModalContent>
</Modal>
@@ -1,11 +1,10 @@
import { ButtonGroup, Flex, Icon, useDisclosure } from "@chakra-ui/react";
import type { Erc721 } from "@thirdweb-dev/sdk";
import { MismatchButton } from "components/buttons/MismatchButton";
import { MintDrawer } from "components/shared/MintDrawer";
import dynamic from "next/dynamic";
import { useMemo } from "react";
import { FiPlus } from "react-icons/fi";
import { Heading } from "tw-components";
import { Button, Heading } from "tw-components";
const QueryAllTable = dynamic(() => import("./query-all-table"));
@@ -25,14 +24,14 @@ const NftOverviewPage: React.VFC<NftOverviewPageProps> = ({ contract }) => {
<Flex direction="row" justify="space-between" align="center">
<Heading size="title.sm">Contract Tokens</Heading>
<ButtonGroup>
<MismatchButton
<Button
isDisabled={!contractSupportsMinting}
leftIcon={<Icon as={FiPlus} />}
colorScheme="primary"
onClick={onOpen}
>
{contractSupportsMinting ? "Mint" : "Minting not supported"}
</MismatchButton>
</Button>
<MintDrawer isOpen={isOpen} onClose={onClose} contract={contract} />
</ButtonGroup>
</Flex>
-2
View File
@@ -13,7 +13,6 @@ import {
import { ColorModeToggle } from "components/color-mode/color-mode-toggle";
import { Logo } from "components/logo";
import { InsufficientFunds } from "components/notices/InsufficientFunds";
import { NetworkMismatchNotice } from "components/notices/NetworkMismatch";
import { useTrack } from "hooks/analytics/useTrack";
import { NextSeo } from "next-seo";
import { useRouter } from "next/router";
@@ -201,7 +200,6 @@ export const AppShell: React.FC = ({ children }) => {
</Container>
{pathname !== "/dashboard" && (
<>
<NetworkMismatchNotice />
<InsufficientFunds />
</>
)}
+7 -3
View File
@@ -11,13 +11,13 @@ import {
} from "@chakra-ui/react";
import { useImageFileOrUrl } from "hooks/useImageFileOrUrl";
import React, { useCallback } from "react";
import { DropEvent, FileRejection, useDropzone } from "react-dropzone";
import { Accept, DropEvent, FileRejection, useDropzone } from "react-dropzone";
import { AiFillEye, AiOutlineFileAdd } from "react-icons/ai";
import { FiImage, FiUpload } from "react-icons/fi";
import { Button, Text } from "tw-components";
interface IFileInputProps extends BoxProps {
accept?: HTMLInputElement["accept"];
accept?: Accept;
setValue: (file: File) => void;
isDisabled?: boolean;
value?: string | File;
@@ -56,7 +56,11 @@ export const FileInput: React.FC<IFileInputProps> = ({
const file: File | null = value instanceof File ? value : null;
const fileUrl = useImageFileOrUrl(value);
const helperText = accept === "image/*" ? "image" : "file";
const helperText =
accept &&
Object.keys(accept).filter((k) => k.split("/")[0] !== "image").length === 1
? "image"
: "file";
// Don't display non image file types
const noDisplay = file && !file.type.includes("image");
+1 -1
View File
@@ -40,7 +40,7 @@
"react": "17.0.2",
"react-cool-dimensions": "^2.0.7",
"react-dom": "17.0.2",
"react-dropzone": "^12.0.2",
"react-dropzone": "^13.0.0",
"react-hook-form": "^7.19.5",
"react-icons": "^4.2.0",
"react-query": "^4.0.0-beta.3",
@@ -4,7 +4,6 @@ import { Icon } from "@chakra-ui/react";
import { useEditionDrop } from "@thirdweb-dev/react";
import { AppLayout } from "components/app-layouts/app";
import { EditionDropBatchUpload } from "components/batch-upload/EditionDropBatchUpload";
import { MismatchButton } from "components/buttons/MismatchButton";
import { MintButton } from "components/contract-pages/action-buttons/MintButton";
import { ContractLayout } from "components/contract-pages/contract-layout";
import { ContractItemsTable } from "components/contract-pages/table";
@@ -13,6 +12,7 @@ import { useSingleQueryParam } from "hooks/useQueryParam";
import { ConsolePage } from "pages/_app";
import React from "react";
import { RiCheckboxMultipleBlankLine } from "react-icons/ri";
import { Button } from "tw-components";
const EditionDropPage: ConsolePage = () => {
const {
@@ -43,14 +43,14 @@ const EditionDropPage: ConsolePage = () => {
primaryAction={<MintButton colorScheme="primary" contract={contract} />}
secondaryAction={
<MinterOnly contract={contract}>
<MismatchButton
<Button
leftIcon={<Icon as={RiCheckboxMultipleBlankLine} />}
onClick={onBatchOpen}
colorScheme="primary"
variant="outline"
>
Batch Upload
</MismatchButton>
</Button>
</MinterOnly>
}
emptyState={{
@@ -38,7 +38,7 @@ import { useRouter } from "next/router";
import { ConsolePage } from "pages/_app";
import React, { useState } from "react";
import { RiCheckboxMultipleBlankLine } from "react-icons/ri";
import { Card } from "tw-components";
import { Button, Card } from "tw-components";
const NFTDropPage: ConsolePage = () => {
const {
@@ -86,14 +86,14 @@ const NFTDropPage: ConsolePage = () => {
primaryAction={<MintButton colorScheme="primary" contract={contract} />}
secondaryAction={
<MinterOnly contract={contract}>
<MismatchButton
<Button
leftIcon={<Icon as={RiCheckboxMultipleBlankLine} />}
onClick={onBatchOpen}
colorScheme="primary"
variant="outline"
>
Batch Upload
</MismatchButton>
</Button>
</MinterOnly>
}
tertiaryAction={
+6 -1
View File
@@ -154,7 +154,12 @@ const Dashboard: ConsolePage = () => {
return (
<Flex direction="column" gap={8}>
{!!combinedList.length && (
<Flex justify="space-between" align="top">
<Flex
justify="space-between"
align="top"
gap={4}
direction={{ base: "column", md: "row" }}
>
<Flex gap={2} direction="column">
<Heading size="title.md">Deployed contracts</Heading>
<Text fontStyle="italic" maxW="container.md">
-3
View File
@@ -5,7 +5,6 @@ import { TransactionButton } from "components/buttons/TransactionButton";
import { DeployableContractTable } from "components/contract-components/contract-table";
import { usePublishMutation } from "components/contract-components/hooks";
import { ContractId } from "components/contract-components/types";
import { NetworkMismatchNotice } from "components/notices/NetworkMismatch";
import { UrlMap } from "constants/mappings";
import { CustomSDKContext } from "contexts/custom-sdk-context";
import { useTrack } from "hooks/analytics/useTrack";
@@ -142,8 +141,6 @@ const ContractsPublishPageWrapped: React.VFC = () => {
</TransactionButton>
</Flex>
</Flex>
{/* TODO remove this somehow */}
<NetworkMismatchNotice />
</Track>
);
};
+4 -4
View File
@@ -7056,10 +7056,10 @@ [email protected]:
object-assign "^4.1.1"
scheduler "^0.20.2"
react-dropzone@^12.0.2:
version "12.1.0"
resolved "https://registry.yarnpkg.com/react-dropzone/-/react-dropzone-12.1.0.tgz#e097b37e9da6f9e324efc757b7434ebc6f3dc2cb"
integrity sha512-iBYHA1rbopIvtzokEX4QubO6qk5IF/x3BtKGu74rF2JkQDXnwC4uO/lHKpaw4PJIV6iIAYOlwLv2FpiGyqHNog==
react-dropzone@^13.0.0:
version "13.0.0"
resolved "https://registry.yarnpkg.com/react-dropzone/-/react-dropzone-13.0.0.tgz#b29c331a1a7e9d21ac4d5666e7b763917f5f4b85"
integrity sha512-BwzHZlmwC2wFKtGbuWw6A+D+uUaJgUGuheALoVFwTNztwV+7NLzdUrHHUkF9mRkI9u5pJDivH3wo+BgSyYVoTQ==
dependencies:
attr-accept "^2.2.2"
file-selector "^0.5.0"