Skip to content

Commit

Permalink
Add Connect Wallet page
Browse files Browse the repository at this point in the history
  • Loading branch information
jribbink committed Jul 29, 2024
1 parent 13ec137 commit 65417aa
Show file tree
Hide file tree
Showing 13 changed files with 196 additions and 32 deletions.
33 changes: 27 additions & 6 deletions components/Discovery.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import { Flex, useModalContext } from '@chakra-ui/react'
import { useState } from 'react'
import { useWallets } from '../hooks/useWallets'
import { Wallet } from '../data/wallets'

import WalletSelection from './views/WalletSelection'
import ExploreWallets from './views/ExploreWallets'
import GetWallet from './views/GetWallet'
import ScanInstall from './views/ScanInstall'
import ConnectWallet from './views/ConnectWallet'
import { Flex, useModalContext } from '@chakra-ui/react'
import { useState } from 'react'
import { useWallets } from '../hooks/useWallets'
import { Wallet } from '../data/wallets'
import * as fcl from '@onflow/fcl'

export enum VIEWS {
WALLET_SELECTION,
EXPLORE_WALLETS,
GET_WALLET,
SCAN_INSTALL,
CONNECT_WALLET,
SCAN_CONNECT,
}

Expand All @@ -31,6 +33,16 @@ export default function Discovery() {
viewContent = (
<WalletSelection
onSwitchToLearnMore={() => setCurrentView(VIEWS.EXPLORE_WALLETS)}
onClickWallet={wallet => {
setSelectedWallet(wallet)
if (wallet.services.length === 1) {
// TODO: make sure WC/RPC behaviour is handled once integrated into Discovery
// (future PR)
fcl.WalletUtils.redirect(wallet.services[0])
} else {
setCurrentView(VIEWS.CONNECT_WALLET)
}
}}
/>
)
break
Expand Down Expand Up @@ -64,12 +76,21 @@ export default function Discovery() {
<ScanInstall
onBack={() => setCurrentView(VIEWS.WALLET_SELECTION)}
onCloseModal={modal.onClose}
/* TODO: This should link to the CONNECT_WALLET view once added */
// TODO: Implement next page
onContinue={() => setCurrentView(VIEWS.WALLET_SELECTION)}
wallet={selectedWallet}
/>
)
break
case VIEWS.CONNECT_WALLET:
viewContent = (
<ConnectWallet
onBack={() => setCurrentView(VIEWS.WALLET_SELECTION)}
onCloseModal={modal.onClose}
wallet={selectedWallet}
/>
)
break
}

return (
Expand Down
7 changes: 3 additions & 4 deletions components/GetWalletCard.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { isExtension } from '../helpers/services'
import {
Button,
Card,
CardBody,
Flex,
Expand All @@ -14,10 +13,10 @@ import HybridButton from './HybridButton'

type Props = {
wallet: Wallet
onButtonClick: () => void
onGetWallet?: () => void
}

export default function GetWalletCard({ wallet, onButtonClick }: Props) {
export default function GetWalletCard({ wallet, onGetWallet }: Props) {
const extensionService = wallet.services.find(isExtension)
const isExtensionService = !!extensionService
const isExtensionServiceInstalled = extensionService?.provider?.is_installed
Expand Down Expand Up @@ -64,7 +63,7 @@ export default function GetWalletCard({ wallet, onButtonClick }: Props) {
{...(!wallet.installLink
? { href: wallet.website }
: {
onClick: onButtonClick,
onClick: onGetWallet,
})}
>
Get
Expand Down
2 changes: 1 addition & 1 deletion components/GetWalletList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export default function GetWalletList({ onGetWallet }: GetWalletListProps) {
<GetWalletCard
key={wallet.uid}
wallet={wallet}
onButtonClick={() => onGetWallet(wallet)}
onGetWallet={() => onGetWallet(wallet)}
/>
)
})}
Expand Down
10 changes: 3 additions & 7 deletions components/ServiceCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,20 @@ import {
HStack,
Image,
Stack,
Tag,
Text,
} from '@chakra-ui/react'
import { Wallet } from '../data/wallets'

interface ServiceCardProps {
wallet: Wallet
onClick: () => void
}

export default function ServiceCard({ wallet }: ServiceCardProps) {
export default function ServiceCard({ wallet, onClick }: ServiceCardProps) {
const extensionService = wallet.services.find(isExtension)
const isExtensionService = !!extensionService
const isExtensionServiceInstalled = extensionService?.provider?.is_installed

const onSelect = () => {
// TODO: implement connect wallet logic, future PR
}

return (
<Card
size="sm"
Expand All @@ -33,7 +29,7 @@ export default function ServiceCard({ wallet }: ServiceCardProps) {
transitionDuration: '0.2s',
transitionTimingFunction: 'ease-in-out',
}}
onClick={onSelect}
onClick={onClick}
variant="unstyled"
>
<CardBody width="100%">
Expand Down
11 changes: 10 additions & 1 deletion components/ServiceGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ interface ServiceGroupProps {
wallets: Wallet[]
titleProps?: React.ComponentProps<typeof Text>
cardProps?: React.ComponentProps<typeof ServiceCard>
onClickWallet: (wallet: Wallet) => void
}

export default function ServiceGroup({
title,
wallets,
titleProps,
cardProps,
onClickWallet,
}: ServiceGroupProps) {
return (
<Stack spacing={1}>
Expand All @@ -22,7 +24,14 @@ export default function ServiceGroup({
</Text>
<Stack spacing={2}>
{wallets.map(wallet => {
return <ServiceCard key={wallet.uid} wallet={wallet} {...cardProps} />
return (
<ServiceCard
key={wallet.uid}
wallet={wallet}
onClick={() => onClickWallet(wallet)}
{...cardProps}
/>
)
})}
</Stack>
</Stack>
Expand Down
19 changes: 16 additions & 3 deletions components/ServiceList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@ import { useWalletHistory } from '../hooks/useWalletHistory'

interface ServiceListProps {
wallets: Wallet[]
onClickWallet: (wallet: Wallet) => void
}

export default function ServiceList({ wallets }: ServiceListProps) {
export default function ServiceList({
wallets,
onClickWallet,
}: ServiceListProps) {
const { isLastUsed } = useWalletHistory()

// Get the last used service, installed services, and recommended services
Expand Down Expand Up @@ -46,15 +50,24 @@ export default function ServiceList({ wallets }: ServiceListProps) {
titleProps={{
color: 'blue.400',
}}
onClickWallet={onClickWallet}
/>
)}

{installedWallets.length > 0 && (
<ServiceGroup title="Installed" wallets={installedWallets} />
<ServiceGroup
title="Installed"
wallets={installedWallets}
onClickWallet={onClickWallet}
/>
)}

{recommendedWallets.length > 0 && (
<ServiceGroup title="Recommended" wallets={recommendedWallets} />
<ServiceGroup
title="Recommended"
wallets={recommendedWallets}
onClickWallet={onClickWallet}
/>
)}
</Stack>
)
Expand Down
9 changes: 8 additions & 1 deletion components/WalletTypeCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ type WalletTypeCardProps = {
icon: string
title: string
description: string
unstyled?: boolean
button: {
text: string
} & (
Expand All @@ -23,6 +24,7 @@ export default function WalletTypeCard({
icon,
title,
description,
unstyled,
button: { text: buttonText, ...buttonProps },
}: WalletTypeCardProps) {
return (
Expand All @@ -33,7 +35,12 @@ export default function WalletTypeCard({
width="100%"
justifyContent="center"
alignItems="center"
backgroundColor="gray.100"
{...(!unstyled
? {
borderWidth: '1px',
backgroundColor: 'gray.100',
}
: {})}
>
<HStack p={4} w="sm" spacing={8}>
<Image
Expand Down
64 changes: 64 additions & 0 deletions components/views/ConnectWallet.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { Divider, Stack } from '@chakra-ui/react'
import ViewLayout from '../ViewLayout'
import WalletTypeCard from '../WalletTypeCard'
import ChromeIcon from '../Icons/chrome.svg'
import { Wallet } from '../../data/wallets'
import { FCL_SERVICE_METHODS } from '../../helpers/constants'
import { toTitleCase } from '../../helpers/strings'
import { toLower } from 'rambda'
import * as fcl from '@onflow/fcl'
import { Fragment } from 'react'

const CANNONICAL_SERVICE_NAMES = {
'WC/RPC': 'Mobile App',
[FCL_SERVICE_METHODS.EXT]: 'Browser Extension',
[FCL_SERVICE_METHODS.HTTP]: 'Web Browser',
[FCL_SERVICE_METHODS.TAB]: 'Web Browser',
[FCL_SERVICE_METHODS.POP]: 'Web Browser',
[FCL_SERVICE_METHODS.IFRAME]: 'Web Browser',
}

interface GetWalletProps {
onBack: () => void
onCloseModal: () => void
wallet: Wallet
}

export default function ConnectWallet({
onBack,
onCloseModal,
wallet,
}: GetWalletProps) {
return (
<ViewLayout
header={{
title: `Connect to ${wallet.name}`,
onBack,
onClose: onCloseModal,
}}
>
<Stack flexGrow={1} alignItems="center" spacing={4} px={6} pb={6}>
{wallet.services.map((service, i) => {
const cannonicalName = CANNONICAL_SERVICE_NAMES[service.method]
return (
<Fragment key={i}>
<WalletTypeCard
icon={ChromeIcon}
title={`${wallet.name} ${toTitleCase(cannonicalName)}`}
description={`Confirm the connection in the ${toLower(
cannonicalName
)}`}
button={{
text: `Connect`,
onClick: () => fcl.WalletUtils.redirect(service),
}}
unstyled
></WalletTypeCard>
{i < wallet.services.length - 1 && <Divider w="80%" />}
</Fragment>
)
})}
</Stack>
</ViewLayout>
)
}
9 changes: 7 additions & 2 deletions components/views/WalletSelection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,17 @@ import { useWallets } from '../../hooks/useWallets'
import { isGreaterThanOrEqualToVersion } from '../../helpers/version'
import { useConfig } from '../../contexts/ConfigContext'
import { SUPPORTED_VERSIONS } from '../../helpers/constants'
import { Wallet } from '../../data/wallets'

type Props = {
onClickWallet: (wallet: Wallet) => void
onSwitchToLearnMore: () => void
}

export default function WalletSelection({ onSwitchToLearnMore }: Props) {
export default function WalletSelection({
onSwitchToLearnMore,
onClickWallet,
}: Props) {
const modal = useModalContext()
const { wallets } = useWallets()
const { appVersion } = useConfig()
Expand All @@ -34,7 +39,7 @@ export default function WalletSelection({ onSwitchToLearnMore }: Props) {
<Stack overflow="scroll" px={8} pb={6} flexGrow={1}>
{/* TODO: replace this in future PR with Filter Bar */}
{/*isFeaturesSupported && <Features />*/}
<ServiceList wallets={wallets} />
<ServiceList onClickWallet={onClickWallet} wallets={wallets} />
</Stack>

<Divider color="gray.300" />
Expand Down
41 changes: 41 additions & 0 deletions contexts/NavigationContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { createContext, useContext, useState } from 'react'

export const NavigationContext = createContext({
navigate: (route: string) => {
console.log('Navigate to', route)
},
goBack: () => {
console.log('Go back')
},
history: [],
currentRoute: '',
})

export function Navigator({ children }) {
const [history, setHistory] = useState([])
const [currentRoute, setCurrentRoute] = useState('')

const navigate = route => {
setHistory([...history, currentRoute])
setCurrentRoute(route)
}

const goBack = () => {
const previousRoute = history.pop()
setCurrentRoute(previousRoute)
}

return (
<NavigationContext.Provider
value={{ navigate, goBack, history, currentRoute }}
></NavigationContext.Provider>
)
}

export function Route({ component }) {
return component
}

export function useNavigation() {
return useContext(NavigationContext)
}
7 changes: 0 additions & 7 deletions helpers/strings.js

This file was deleted.

Loading

0 comments on commit 65417aa

Please sign in to comment.