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

Adds a version check before showing filtered features #165

Merged
merged 14 commits into from
Jan 8, 2024
Merged
17 changes: 15 additions & 2 deletions components/Discovery.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import useSWR from 'swr'
import { sortByAddress } from '../helpers/services'
import { LOCAL_STORAGE_KEYS, PATHS } from '../helpers/constants'
import { LOCAL_STORAGE_KEYS, PATHS, SUPPORTED_VERSIONS } from '../helpers/constants'
import ServiceCard from './ServiceCard'
import Header from './Headers/Header'
import { useLocalStorage } from '../hooks/useLocalStorage'
import { getUserAgent } from '../helpers/userAgent'
import { Container, Stack } from '@chakra-ui/react'
import { Container, Text, Stack } from '@chakra-ui/react'
import { Service, Strategy } from '../types'
import Features from './Features'
import { isGreaterThanOrEqualToVersion } from '../helpers/version'

const fetcher = (url, opts) => {
return fetch(url, {
Expand All @@ -25,6 +27,7 @@ type Props = {
walletInclude: string[]
clientServices: Service[]
supportedStrategies: Strategy[]
clientConfig: { [key: string]: any }
port: number
}

Expand All @@ -35,6 +38,7 @@ export const Discovery = ({
walletInclude,
clientServices,
supportedStrategies,
clientConfig,
port,
}: Props) => {
const requestUrl = `/api${PATHS[network.toUpperCase()]}?discoveryType=UI`
Expand All @@ -43,6 +47,9 @@ export const Discovery = ({
type: ['authn'],
fclVersion: appVersion,
include: walletInclude,
features: {
suggested: clientConfig?.discoveryFeaturesSuggested || []
},
extensions,
userAgent: getUserAgent(),
clientServices, // TODO: maybe combine this with extensions except version support then needs to be fixed in later step
Expand All @@ -54,12 +61,18 @@ export const Discovery = ({
const [lastUsed, _] = useLocalStorage(LOCAL_STORAGE_KEYS.LAST_INSTALLED, null)
const services = sortByAddress(data, lastUsed)

const isFeaturesSupported = isGreaterThanOrEqualToVersion(
appVersion,
SUPPORTED_VERSIONS.SUGGESTED_FEATURES
)

if (!data) return <div />
if (error) return <div>Error Loading Data</div>

return (
<Container paddingTop={5} paddingBottom={5}>
<Header />
{isFeaturesSupported && <Features />}
<Stack spacing="12px">
{services.length === 0 && <div>No Wallets Found</div>}
{services.map((service, index) => {
Expand Down
32 changes: 32 additions & 0 deletions components/Features.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Box, HStack, Tag, Text, IconButton } from '@chakra-ui/react'
import { CheckIcon } from '@chakra-ui/icons'
import { useFCL } from '../hooks/useFCL'
import FEATURES_LIST from '../data/features.json'

export default function Features() {
const { clientConfig } = useFCL()
const featuresListKeys = FEATURES_LIST.map(f => f.name)
const suggestedFeatures = clientConfig?.discoveryFeaturesSuggested?.filter(f => featuresListKeys.includes(f)) || []

return (
<Box mb={5}>
<HStack mb={3}>
<Text fontSize='sm' as='b'>Wallet Requirements</Text>
<IconButton
isRound={true}
variant='solid'
colorScheme='teal'
aria-label='Done'
fontSize='sm'
size={'xs'}
icon={<CheckIcon />}
/>
</HStack>
<HStack>
{suggestedFeatures.map((suggestion, index) => (
<Tag key={index} size='sm'>{suggestion}</Tag>
))}
</HStack>
</Box>
)
}
40 changes: 4 additions & 36 deletions components/Headers/__tests__/__snapshots__/AppHeader.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,10 @@ exports[`Component: AppHeader should handle missing info and show unknown if no
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
gap: 0.5rem;
margin-bottom: 25px;
}

.emotion-0>*:not(style)~*:not(style) {
margin-top: 0.5rem;
-webkit-margin-end: 0px;
margin-inline-end: 0px;
margin-bottom: 0px;
-webkit-margin-start: 0px;
margin-inline-start: 0px;
}

.emotion-2 {
display: -webkit-box;
display: -webkit-flex;
Expand All @@ -33,15 +25,7 @@ exports[`Component: AppHeader should handle missing info and show unknown if no
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
}

.emotion-2>*:not(style)~*:not(style) {
margin-top: 0px;
-webkit-margin-end: 0px;
margin-inline-end: 0px;
margin-bottom: 0px;
-webkit-margin-start: 0.5rem;
margin-inline-start: 0.5rem;
gap: 0.5rem;
}

.emotion-3 {
Expand Down Expand Up @@ -77,18 +61,10 @@ exports[`Component: AppHeader should render the the component with icon 1`] = `
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
gap: 0.5rem;
margin-bottom: 25px;
}

.emotion-0>*:not(style)~*:not(style) {
margin-top: 0.5rem;
-webkit-margin-end: 0px;
margin-inline-end: 0px;
margin-bottom: 0px;
-webkit-margin-start: 0px;
margin-inline-start: 0px;
}

.emotion-2 {
display: -webkit-box;
display: -webkit-flex;
Expand All @@ -101,15 +77,7 @@ exports[`Component: AppHeader should render the the component with icon 1`] = `
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
}

.emotion-2>*:not(style)~*:not(style) {
margin-top: 0px;
-webkit-margin-end: 0px;
margin-inline-end: 0px;
margin-bottom: 0px;
-webkit-margin-start: 0.5rem;
margin-inline-start: 0.5rem;
gap: 0.5rem;
}

.emotion-3 {
Expand Down
40 changes: 4 additions & 36 deletions components/Headers/__tests__/__snapshots__/Header.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -70,18 +70,10 @@ exports[`Component: Header should render the configurable component if version i
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
gap: 0.5rem;
margin-bottom: 25px;
}

.emotion-0>*:not(style)~*:not(style) {
margin-top: 0.5rem;
-webkit-margin-end: 0px;
margin-inline-end: 0px;
margin-bottom: 0px;
-webkit-margin-start: 0px;
margin-inline-start: 0px;
}

.emotion-2 {
display: -webkit-box;
display: -webkit-flex;
Expand All @@ -94,15 +86,7 @@ exports[`Component: Header should render the configurable component if version i
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
}

.emotion-2>*:not(style)~*:not(style) {
margin-top: 0px;
-webkit-margin-end: 0px;
margin-inline-end: 0px;
margin-bottom: 0px;
-webkit-margin-start: 0.5rem;
margin-inline-start: 0.5rem;
gap: 0.5rem;
}

.emotion-3 {
Expand Down Expand Up @@ -149,18 +133,10 @@ exports[`Component: Header should show the DeveloperMessage if config is missing
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
gap: 0.5rem;
margin-bottom: 25px;
}

.emotion-0>*:not(style)~*:not(style) {
margin-top: 0.5rem;
-webkit-margin-end: 0px;
margin-inline-end: 0px;
margin-bottom: 0px;
-webkit-margin-start: 0px;
margin-inline-start: 0px;
}

.emotion-2 {
display: -webkit-box;
display: -webkit-flex;
Expand All @@ -173,15 +149,7 @@ exports[`Component: Header should show the DeveloperMessage if config is missing
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
}

.emotion-2>*:not(style)~*:not(style) {
margin-top: 0px;
-webkit-margin-end: 0px;
margin-inline-end: 0px;
margin-bottom: 0px;
-webkit-margin-start: 0.5rem;
margin-inline-start: 0.5rem;
gap: 0.5rem;
}

.emotion-3 {
Expand Down
62 changes: 51 additions & 11 deletions components/ServiceCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,19 @@ import {
Flex,
HStack,
Icon,
IconButton,
Image,
Spacer,
Stack,
Tag,
Text,
} from '@chakra-ui/react'
import { FiInfo } from 'react-icons/fi'
import { Service } from '../types'
import { getProviderMetadataByAddress } from '../helpers/metadata'
import { CheckIcon } from '@chakra-ui/icons'
import { useMemo } from 'react'
import FEATURES_LIST from '../data/features.json'

type Props = {
isEnabled: boolean
Expand All @@ -34,7 +40,7 @@ export default function ServiceCard({
service,
lastUsed = false,
}: Props) {
const { appVersion } = useFCL()
const { appVersion, clientConfig } = useFCL()
const [_, setLastUsed] = useLocalStorage(
LOCAL_STORAGE_KEYS.LAST_INSTALLED,
null
Expand All @@ -44,6 +50,14 @@ export default function ServiceCard({
const installLink = service?.provider?.install_link
const isExtensionService = isExtension(service)
const isExtensionServiceInstalled = Boolean(service?.provider?.is_installed)
const supportedFeatures = getProviderMetadataByAddress(service?.provider?.address)?.features?.supported || []
const isFeaturesSupported = isGreaterThanOrEqualToVersion(
appVersion,
SUPPORTED_VERSIONS.SUGGESTED_FEATURES
)
const featuresListKeys = FEATURES_LIST.map(f => f.name)
const suggestedFeatures = clientConfig?.discoveryFeaturesSuggested?.filter(f => featuresListKeys.includes(f)) || []


const onSelect = () => {
if (!service) return
Expand All @@ -69,6 +83,11 @@ export default function ServiceCard({
}
}

const hasSuggestedFeatures = useMemo(() => {
return suggestedFeatures.every(feature => supportedFeatures.includes(feature))
}, [suggestedFeatures, supportedFeatures])


const openMoreInfo = e => {
e.stopPropagation()
if (!hasWebsite) return
Expand All @@ -88,17 +107,38 @@ export default function ServiceCard({
>
<CardBody width="100%">
<Flex alignItems="center" justifyContent="space-between">
<HStack>
<Image src={icon} alt={name} borderRadius="full" boxSize="3rem" />
<Text fontSize="lg" as="b">
{truncateString(name, 13)}
</Text>
{isExtensionService && !isExtensionServiceInstalled && (
<Tag size="sm">Install Extension</Tag>
<Stack>
<Flex alignItems="center" justifyContent="space-between">
<HStack>
<Image src={icon} alt={name} borderRadius="full" boxSize="2.7rem" />
<Text fontSize="lg" as="b">
{truncateString(name, 10)}
</Text>
{isExtensionService && !isExtensionServiceInstalled && (
<Tag size="sm" colorScheme='cyan'>Install Extension</Tag>
)}
{lastUsed && <Tag size="sm" colorScheme='cyan'>Last Used</Tag>}
{isFeaturesSupported && hasSuggestedFeatures && (
<IconButton
isRound={true}
variant='solid'
colorScheme='teal'
aria-label='Done'
fontSize='sm'
size={'xs'}
icon={<CheckIcon />}
/>
)}
</HStack>
</Flex>
{isFeaturesSupported && (
<HStack mt={2}>
{supportedFeatures.map((feature, index) => {
return <Tag key={index} size="sm" colorScheme='gray'>{feature}</Tag>
})}
</HStack>
)}
{lastUsed && <Tag size="sm">Last Used</Tag>}
</HStack>
<Spacer />
</Stack>
{hasWebsite && (
<Box
color="lightgrey"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,12 @@ exports[`Component: DeveloperMessage should render the DeveloperMessage componen

<div
class="chakra-alert emotion-0"
data-status="warning"
role="alert"
>
<span
class="chakra-alert__icon emotion-1"
data-status="warning"
>
<svg
class="chakra-icon emotion-2"
Expand All @@ -72,11 +74,13 @@ exports[`Component: DeveloperMessage should render the DeveloperMessage componen
</span>
<div
class="chakra-alert__title emotion-3"
data-status="warning"
>
Missing Config
</div>
<div
class="chakra-alert__desc emotion-4"
data-status="warning"
>
See how to set your app title and icon

Expand Down
6 changes: 6 additions & 0 deletions data/features.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[
{
"name": "account-linking",
"description": "Users can link their wallet managed account to their various app accounts, giving them control of their assets."
}
]
Loading