diff --git a/components/chain-list/all-chains-item.tsx b/components/chain-list/all-chains-item.tsx index d2e8c93..890b882 100644 --- a/components/chain-list/all-chains-item.tsx +++ b/components/chain-list/all-chains-item.tsx @@ -1,10 +1,15 @@ import { ChainItemType } from "../../types"; -import { Dispatch, FunctionComponent, SetStateAction } from "react"; +import { + Dispatch, + FunctionComponent, + SetStateAction, + useEffect, + useState, +} from "react"; import { ChainImage } from "./chain-image"; import { Flex1 } from "../../styles/flex-1"; import { - ChainImageContainer, ChainInfoContainer, ChainItemContainer, ChainName, @@ -13,43 +18,54 @@ import { import color from "../../styles/color"; import styled from "styled-components"; import { Checkbox } from "../checkbox"; +import AllChainsIcon from "../../public/images/svg/all-chains-icon.svg"; interface Props { - allChecked: boolean; - setAllChecked: Dispatch>; - chainItem: ChainItemType; + chainList: ChainItemType[]; + checkedItems: Set; + setCheckedItems: Dispatch>>; } export const AllChainsItem: FunctionComponent = (props) => { - const { allChecked, setAllChecked, chainItem } = props; + const { chainList, checkedItems, setCheckedItems } = props; + + const [checked, setChecked] = useState(false); const checkHandler = () => { - setAllChecked(!allChecked); + if (checked) { + setCheckedItems(new Set()); + } else if (chainList.length !== checkedItems.size) { + setCheckedItems(new Set(chainList)); + } }; + useEffect(() => { + if (chainList.length === checkedItems.size && checkedItems.size !== 0) { + setChecked(true); + } else { + setChecked(false); + } + }, [checkedItems]); + return ( - - - + - {`.${chainItem.prefix}`} - {chainItem.address} + {`.all chains(${chainList.length})`} + + {chainList.map((chain) => chain.chainName).join(", ")} + - + ); diff --git a/components/chain-list/chain-image.tsx b/components/chain-list/chain-image.tsx index fab6dfe..ada2f8f 100644 --- a/components/chain-list/chain-image.tsx +++ b/components/chain-list/chain-image.tsx @@ -21,6 +21,10 @@ export const ChainImage = ({ src, ...props }: ImageProps) => { }; const ImageWrapper = styled.div` + position: relative; + width: 3rem; + height: 3rem; + img { border-radius: 50%; } diff --git a/components/chain-list/chain-item.tsx b/components/chain-list/chain-item.tsx index c572151..317f319 100644 --- a/components/chain-list/chain-item.tsx +++ b/components/chain-list/chain-item.tsx @@ -1,4 +1,4 @@ -import { ChainItemType, WidthHeightProps } from "../../types"; +import { ChainItemType } from "../../types"; import { FunctionComponent, useEffect, useState } from "react"; import color from "../../styles/color"; @@ -39,13 +39,11 @@ export const ChainItem: FunctionComponent = (props) => { checked={checked} onClick={checkHandler} > - - - + {`.${chainItem.prefix}`} {chainItem.address} @@ -90,13 +88,6 @@ export const ChainItemContainer = styled.div<{ } `; -export const ChainImageContainer = styled.div` - width: ${(props) => props.width}; - height: ${(props) => props.height}; - - position: relative; -`; - export const ChainInfoContainer = styled.div` display: flex; flex-direction: column; diff --git a/components/chain-list/chain-list.tsx b/components/chain-list/chain-list.tsx index 9796425..805b241 100644 --- a/components/chain-list/chain-list.tsx +++ b/components/chain-list/chain-list.tsx @@ -5,8 +5,6 @@ import styled from "styled-components"; import { ChainItem } from "./chain-item"; interface Props { - allChecked: boolean; - setAllChecked: Dispatch>; chainList: ChainItemType[]; disabledChainList: ChainItemType[]; checkedItems: Set; @@ -14,14 +12,7 @@ interface Props { } export const ChainList: FunctionComponent = (props) => { - const { - allChecked, - setAllChecked, - chainList, - disabledChainList, - checkedItems, - setCheckedItems, - } = props; + const { chainList, disabledChainList, checkedItems, setCheckedItems } = props; const checkedItemHandler = (chainItem: ChainItemType, isChecked: boolean) => { const tempSet = new Set(checkedItems); @@ -35,22 +26,6 @@ export const ChainList: FunctionComponent = (props) => { setCheckedItems(tempSet); }; - useEffect(() => { - if (allChecked) { - setCheckedItems(new Set(chainList)); - } else if (chainList.length === checkedItems.size) { - setCheckedItems(new Set()); - } - }, [allChecked]); - - useEffect(() => { - if (chainList.length === checkedItems.size && checkedItems.size !== 0) { - setAllChecked(true); - } else { - setAllChecked(false); - } - }, [checkedItems]); - return ( {chainList.map((chainItem) => ( diff --git a/components/skeleton/skeleton-chain-list.tsx b/components/skeleton/skeleton-chain-list.tsx index ffc0170..4a22be2 100644 --- a/components/skeleton/skeleton-chain-list.tsx +++ b/components/skeleton/skeleton-chain-list.tsx @@ -21,7 +21,6 @@ import { } from "../twitter-profile"; import { ChainContainer, - ChainImageContainer, ChainInfoContainer, ChainItemContainer, } from "../chain-list"; @@ -60,9 +59,9 @@ export const SkeletonChainList: FunctionComponent = () => ( .map((_, index) => (
- + - + @@ -93,6 +92,13 @@ const SkeletonTitle = styled.div` background-color: ${color.grey["800"]}; `; +const SkeletonImageContainer = styled.div` + width: 3rem; + height: 3rem; + + position: relative; +`; + const SkeletonButtonContainer = styled.div` margin-top: 1.5rem; `; diff --git a/pages/verification/index.tsx b/pages/verification/index.tsx index 7a164d0..b1ee6fe 100644 --- a/pages/verification/index.tsx +++ b/pages/verification/index.tsx @@ -32,7 +32,6 @@ import { } from "../../wallets"; import { ChainIdHelper } from "@keplr-wallet/cosmos"; -import AllChainsIcon from "../../public/images/svg/all-chains-icon.svg"; import { AllChainsItem } from "../../components/chain-list/all-chains-item"; import { SearchInput } from "../../components/search-input"; import { @@ -55,7 +54,7 @@ import { TWITTER_LOGIN_ERROR, } from "../../constants/error-message"; import { makeClaimMessage, makeSetRecordMessage } from "../../messages"; -import Axios, { AxiosError } from "axios"; +import Axios from "axios"; import { BackButton } from "../../components/back-button"; export default function VerificationPage() { @@ -73,9 +72,6 @@ export default function VerificationPage() { const [registeredChainList, setRegisteredChainList] = useState< RegisteredAddresses[] >([]); - - const [allChains, setAllChains] = useState(); - const [allChecked, setAllChecked] = useState(false); const [checkedItems, setCheckedItems] = useState(new Set()); const [searchValue, setSearchValue] = useState(""); @@ -84,69 +80,16 @@ export default function VerificationPage() { const [isAgree, setIsAgree] = useState(false); useEffect(() => { - const init = async () => { - if (window.location.search) { - try { - const { state, code } = checkTwitterAuthQueryParameter( - window.location.search, - ); - - // Initialize Wallet - const keplrWallet = await initWallet(); - - // Fetch Twitter Profile - const twitterInfo = await fetchTwitterInfo(state, code); - - // contract check registered - const registeredQueryResponse = await queryRegisteredTwitterId( - twitterInfo.id, - ); - - setTwitterAuthInfo({ - ...twitterInfo, - isRegistered: "data" in registeredQueryResponse, - }); - - if ("data" in registeredQueryResponse) { - const ownerOfQueryResponse = await queryOwnerOfTwitterName( - registeredQueryResponse.data.name, - ); - - const addressesQueryResponse = await queryAddressesFromTwitterName( - registeredQueryResponse.data.name, - ); - - if (keplrWallet) { - const key = await keplrWallet.getKey(MainChainId); - setIsOwner(ownerOfQueryResponse.data.owner === key.bech32Address); - } - - setRegisteredChainList(addressesQueryResponse.data.addresses); - } - } catch (error) { - if (error instanceof Error && error.message === TWITTER_LOGIN_ERROR) { - await router.push("/"); - } - - console.error(error); - } finally { - setIsLoading(false); - } - } - }; - init(); }, []); useEffect(() => { - setAllChains({ - chainId: "all chains", - chainName: "all chains", - prefix: `all chains(${chainList.length})`, - address: chainList.map((chain) => chain.chainName).join(", "), - chainImageUrl: AllChainsIcon, - }); - }, [chainList]); + if (wallet) { + window.addEventListener("keplr_keystorechange", async () => { + await init(); + }); + } + }, [wallet]); useEffect(() => { const disabledChainList = chainList.filter((chain) => { @@ -166,18 +109,67 @@ export default function VerificationPage() { (chain) => !disabledChainList.includes(chain), ); - setAllChains({ - chainId: "all chains", - chainName: "all chains", - prefix: `all chains(${filteredChainList.length})`, - address: filteredChainList.map((chain) => chain.chainName).join(", "), - chainImageUrl: AllChainsIcon, - }); - setChainList(filteredChainList); setDisabledChainList(disabledChainList); + + setCheckedItems(new Set(filteredChainList)); }, [registeredChainList]); + useEffect(() => { + setCheckedItems(new Set(chainList)); + }, [chainList]); + + const init = async () => { + if (window.location.search) { + try { + const { state, code } = checkTwitterAuthQueryParameter( + window.location.search, + ); + + // Initialize Wallet + const keplrWallet = await initWallet(); + + // Fetch Twitter Profile + const twitterInfo = await fetchTwitterInfo(state, code); + + // contract check registered + const registeredQueryResponse = await queryRegisteredTwitterId( + twitterInfo.id, + ); + + setTwitterAuthInfo({ + ...twitterInfo, + isRegistered: "data" in registeredQueryResponse, + }); + + if ("data" in registeredQueryResponse) { + const ownerOfQueryResponse = await queryOwnerOfTwitterName( + registeredQueryResponse.data.name, + ); + + const addressesQueryResponse = await queryAddressesFromTwitterName( + registeredQueryResponse.data.name, + ); + + if (keplrWallet) { + const key = await keplrWallet.getKey(MainChainId); + setIsOwner(ownerOfQueryResponse.data.owner === key.bech32Address); + } + + setRegisteredChainList(addressesQueryResponse.data.addresses); + } + } catch (error) { + if (error instanceof Error && error.message === TWITTER_LOGIN_ERROR) { + await router.push("/"); + } + + console.error(error); + } finally { + setIsLoading(false); + } + } + }; + const initWallet = async () => { const keplr = await getKeplrFromWindow(); @@ -351,10 +343,15 @@ export default function VerificationPage() { } }; - const isRegisterButtonDisable = - checkedItems.size < 1 || - (!isOwner && registeredChainList.length > 0) || - !isAgree; + const isRegisterButtonDisable = (() => { + const hasCheckedItem = checkedItems.size > 0; + + if (isOwner) { + return !hasCheckedItem; + } else { + return !(isAgree && hasCheckedItem); + } + })(); return ( @@ -376,17 +373,15 @@ export default function VerificationPage() { /> - {allChains && !searchValue ? ( + {!searchValue ? ( ) : null} chain.chainId.includes(searchValue) || @@ -403,23 +398,27 @@ export default function VerificationPage() { setCheckedItems={setCheckedItems} /> - { - setIsAgree(!isAgree); - }} - > - I - check that Osmo is required for this transaction - - - - { + setIsAgree(!isAgree); + }} > - Register - - + I + check that Osmo is required for this transaction + + )} + + {chainList.length > 0 && ( + + + Register + + + )} )}