Skip to content

Commit

Permalink
Better loadings (#90)
Browse files Browse the repository at this point in the history
  • Loading branch information
sdlyy authored Dec 11, 2023
1 parent 7fb146b commit e8c3517
Show file tree
Hide file tree
Showing 19 changed files with 189 additions and 57 deletions.
13 changes: 13 additions & 0 deletions packages/frontend/src/hooks/useChangelogApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {
} from '@lz/libs'
import { useEffect, useState } from 'react'

import { hasBeenAborted } from './utils'

interface UseChangelogApiHookOptions {
shouldFetch: boolean
chainId: ChainId
Expand Down Expand Up @@ -40,6 +42,7 @@ export function useChangelogApi({
if (!shouldFetch) {
return
}
const abortController = new AbortController()
setIsLoading(true)
async function fetchData() {
try {
Expand All @@ -49,6 +52,9 @@ export function useChangelogApi({
ChainId.getName(chainId) +
'/' +
address.toString(),
{
signal: abortController.signal,
},
)

if (!result.ok) {
Expand All @@ -67,6 +73,9 @@ export function useChangelogApi({
})
setIsError(false)
} catch (e) {
if (hasBeenAborted(e)) {
return
}
console.error(e)
setIsError(true)
} finally {
Expand All @@ -75,6 +84,10 @@ export function useChangelogApi({
}

void fetchData()

return () => {
abortController.abort()
}
}, [shouldFetch, chainId, apiUrl, address])

return [data, isLoading, isError] as const
Expand Down
21 changes: 17 additions & 4 deletions packages/frontend/src/hooks/useDiscoveryApi.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { ChainId, DiscoveryApi } from '@lz/libs'
import { useEffect, useState } from 'react'

import { hasBeenAborted } from './utils'

interface DiscoveryData {
data: DiscoveryApi
chainId: ChainId
Expand All @@ -22,26 +24,34 @@ export function useDiscoveryApi({
const [data, setData] = useState<DiscoveryData | null>(null)

useEffect(() => {
const abortController = new AbortController()

setIsLoading(true)
setIsError(false)
async function fetchData() {
try {
const result = await fetch(
apiUrl + 'discovery/' + ChainId.getName(chainId),
{
signal: abortController.signal,
},
)

if (!result.ok) {
setIsLoading(false)
setIsError(true)
}

const data = await result.text()
const parsed = DiscoveryApi.parse(JSON.parse(data))
setData({ data: parsed, chainId })
setIsError(false)
setIsLoading(false)
} catch (e) {
console.error(e)
if (hasBeenAborted(e)) {
return
}
setIsError(true)
} finally {
setIsLoading(false)
}
}

Expand All @@ -51,7 +61,10 @@ export function useDiscoveryApi({
void fetchData()
}, intervalMs)

return () => clearInterval(fetchDataInterval)
return () => {
clearInterval(fetchDataInterval)
abortController.abort()
}
}, [chainId, intervalMs, apiUrl])

return [data, isLoading, isError] as const
Expand Down
14 changes: 13 additions & 1 deletion packages/frontend/src/hooks/useSafeApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import {
} from '@lz/libs'
import { useEffect, useState } from 'react'

import { hasBeenAborted } from './utils'

interface UseStatusApiHookOptions {
chainId: ChainId
multisigAddress: EthereumAddress
Expand All @@ -23,23 +25,33 @@ export function useSafeApi({

useEffect(() => {
const api = createSafeApiClient(chainId)
const abortController = new AbortController()

async function fetch() {
setIsLoading(true)
try {
const transactions = await api.getMultisigTransactions(
multisigAddress.toString(),
abortController.signal,
)

setTransactions(transactions)
setIsLoading(false)
} catch {
} catch (e) {
if (hasBeenAborted(e)) {
return
}
console.error(e)
setIsError(true)
}
setIsLoading(false)
}

void fetch()

return () => {
abortController.abort()
}
}, [chainId, multisigAddress])

return [isLoading, isError, transactions] as const
Expand Down
3 changes: 3 additions & 0 deletions packages/frontend/src/hooks/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function hasBeenAborted(e: unknown): e is DOMException {
return e instanceof DOMException && e.name === 'AbortError'
}
16 changes: 13 additions & 3 deletions packages/frontend/src/view/components/BlockchainAddress.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ import {
import { useAddressInfo } from '../../hooks/addressInfoContext'
import { useChainId } from '../../hooks/chainIdContext'
import { UnverifiedIcon } from '../icons/UnverifiedIcon'
import { WarningIcon } from '../icons/WarningIcon'
import { Copyable } from './Copyable'
import { Tooltip } from './Tooltip'

interface Props {
address: EthereumAddress
full?: boolean
warnOnEoa?: string
}

export function BlockchainAddress(props: Props) {
Expand All @@ -38,6 +40,12 @@ export function BlockchainAddress(props: Props) {
</Tooltip>
)}

{addressInfo && addressInfo.name === 'EOA' && props.warnOnEoa && (
<Tooltip text={props.warnOnEoa}>
<WarningIcon className="stroke-yellow-100" width="14" height="14" />
</Tooltip>
)}

{addressInfo && !props.full ? (
<>
<Tooltip text={props.address.toString()} className="md:hidden">
Expand All @@ -50,9 +58,11 @@ export function BlockchainAddress(props: Props) {
{props.address.toString()}
</a>{' '}
</Tooltip>{' '}
<span className="whitespace-nowrap text-xs text-zinc-500">
{addressInfo.name.length > 0 && `(${addressInfo.name})`}
</span>
{addressInfo.name.length > 0 && (
<span className="whitespace-nowrap text-xs text-zinc-500">
({addressInfo.name})
</span>
)}
</>
) : (
<Tooltip text={'Show on ' + explorerName}>
Expand Down
6 changes: 3 additions & 3 deletions packages/frontend/src/view/components/ExpandableContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ export function ExpandableContainer(props: Props) {
>
{props.children}
</div>
<button
<div
onClick={() => setIsExpanded(!isExpanded)}
className={cx(
'flex w-full flex-row items-center justify-center gap-2 rounded-lg border border-yellow-100 p-3 text-xs text-yellow-100 transition-colors duration-300 hover:bg-yellow-100/10',
'flex w-full cursor-pointer flex-row items-center justify-center gap-2 rounded-lg border border-yellow-100 p-3 text-xs text-yellow-100 transition-colors duration-300 hover:bg-yellow-100/10',
isExpanded && 'mt-4',
)}
>
Expand All @@ -35,7 +35,7 @@ export function ExpandableContainer(props: Props) {
onClick={() => setIsExpanded(!isExpanded)}
isExpanded={isExpanded}
/>
</button>
</div>
</div>
)
}
27 changes: 27 additions & 0 deletions packages/frontend/src/view/components/Info.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { InfoIcon } from '../icons/InfoIcon'

export function Info({
title,
subtitle,
}: {
title: string
subtitle?: string
}) {
return (
<section className="p-2">
<div className="flex items-center justify-center gap-3 p-5">
<div className="w-[45px]">
<InfoIcon fill="#3db6bc" />
</div>
<div className="flex flex-col gap-1">
<span className="text-sm leading-4 md:text-lg">{title}</span>
{subtitle && (
<span className="text-2xs leading-4 text-gray-100 md:text-sm">
{subtitle}
</span>
)}
</div>
</div>
</section>
)
}
7 changes: 5 additions & 2 deletions packages/frontend/src/view/components/NetworkData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,20 @@ import { getEndpointIdFromChainId } from '@lz/libs'

import { useChainId } from '../../hooks/chainIdContext'
import { MaxWidthLayout } from './Layout'
import { LoadingCover } from './status/LoadingCover'

interface Props {
latestBlock: number
isLoading?: boolean
}

export function NetworkData({ latestBlock }: Props): JSX.Element {
export function NetworkData({ latestBlock, isLoading }: Props): JSX.Element {
const chainId = useChainId()
return (
<section className="mb-4 bg-gray-900 p-4 md:mb-10 md:p-8">
<MaxWidthLayout>
<section className="flex items-stretch gap-2.5 md:gap-5">
<section className="relative flex items-stretch gap-2.5 md:gap-5">
{isLoading && <LoadingCover />}
<DataBlock label="Chain ID" value={chainId.toString()} />
<DataBlock
label="Endpoint ID"
Expand Down
18 changes: 9 additions & 9 deletions packages/frontend/src/view/components/PaginatedContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,26 +33,26 @@ export function PaginationControls({
currentPage: number
setPage: (page: number) => void
}) {
const baseButtonClass =
'flex h-[30px] w-[30px] items-center justify-center rounded'

const pageTiles = Array.from({ length: amountOfPages }, (_, i) => (
<button
key={i}
onClick={() => setPage(i + 1)}
className={cx(
'flex min-h-[30px] min-w-[30px] items-center justify-center rounded transition-colors hover:bg-gray-50',
currentPage === i + 1 && 'bg-gray-50',
baseButtonClass,
'transition-color duration-150',
currentPage === i + 1 ? 'bg-gray-200' : 'hover:bg-gray-400',
)}
>
{i + 1}
</button>
))

const baseButtonClass =
'flex h-[30px] w-[30px] items-center transition-all duration-300 justify-center rounded brightness-100 filter hover:brightness-[120%]'

const notAllowedClass =
'bg-yellow-300 cursor-not-allowed hover:brightness-[100%]'

const allowedClass = 'bg-yellow-100'
const notAllowedClass = 'bg-yellow-300 cursor-not-allowed'
const allowedClass =
'bg-yellow-100 transition-all brightness-100 filter hover:brightness-[120%] duration-300'

return (
<div className="flex items-center gap-2 md:gap-3">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import cx from 'classnames'

import { LoadingCover } from './status/LoadingCover'

interface Props {
title: React.ReactNode
description?: React.ReactNode
subtitle?: React.ReactNode
children?: React.ReactNode
className?: string
isLoading?: boolean
}

export function ProtocolComponentCard({
Expand All @@ -14,14 +17,17 @@ export function ProtocolComponentCard({
subtitle,
description,
className,
isLoading,
}: Props) {
return (
<section
className={cx(
'm-4 rounded-lg bg-gray-900 px-5 py-6 md:m-0 md:mb-10 md:p-8',
'relative m-4 rounded-lg bg-gray-900 px-5 py-6 md:m-0 md:mb-10 md:p-8',
className,
)}
>
{isLoading && <LoadingCover />}

<div className="flex flex-col justify-between md:mb-4 md:flex-row">
<h2 className="mb-4 w-full text-xl md:mb-0">{title}</h2>
{subtitle && (
Expand Down
14 changes: 11 additions & 3 deletions packages/frontend/src/view/components/Warning.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,28 @@ import { WarningIcon } from '../icons/WarningIcon'
export function Warning({
title,
subtitle,
slim = false,
}: {
title: string
subtitle?: string
slim?: boolean
}) {
const padding = slim ? 'p-0 mb-0' : 'p-5 m-12'
return (
<section className="mb-12 p-6">
<section className={padding}>
<div className="flex items-center justify-center gap-3 p-5">
<div className="w-[45px]">
<WarningIcon className="stroke-yellow-100" />
</div>
<div className="flex flex-col gap-1">
<span className="text-lg">{title}</span>
<span className="text-sm leading-5 md:text-lg md:leading-4">
{title}
</span>

{subtitle && (
<span className="text-sm text-gray-100">{subtitle}</span>
<span className="text-2xs text-gray-100 md:text-sm">
{subtitle}
</span>
)}
</div>
</div>
Expand Down
Loading

0 comments on commit e8c3517

Please sign in to comment.