Create useWalletStatus and useWalletSupport (#1646)

This commit is contained in:
ekzyis 2024-11-24 03:19:22 +01:00 committed by GitHub
parent f5569d7444
commit b0207a2906
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 66 additions and 60 deletions

View File

@ -8,18 +8,13 @@ import DraggableIcon from '@/svgs/draggable.svg'
import RecvIcon from '@/svgs/arrow-left-down-line.svg' import RecvIcon from '@/svgs/arrow-left-down-line.svg'
import SendIcon from '@/svgs/arrow-right-up-line.svg' import SendIcon from '@/svgs/arrow-right-up-line.svg'
import { useWalletImage } from '@/components/wallet-image' import { useWalletImage } from '@/components/wallet-image'
import { useWalletStatus, statusToClass } from '@/components/wallet-status'
const statusToClass = status => { import { useWalletSupport } from '@/components/wallet-support'
switch (status) {
case Status.Enabled: return styles.success
case Status.Disabled: return styles.disabled
case Status.Error: return styles.error
case Status.Warning: return styles.warning
}
}
export default function WalletCard ({ wallet, draggable, onDragStart, onDragEnter, onDragEnd, onTouchStart, sourceIndex, targetIndex, index }) { export default function WalletCard ({ wallet, draggable, onDragStart, onDragEnter, onDragEnd, onTouchStart, sourceIndex, targetIndex, index }) {
const image = useWalletImage(wallet) const image = useWalletImage(wallet)
const status = useWalletStatus(wallet)
const support = useWalletSupport(wallet)
return ( return (
<Card <Card
@ -32,9 +27,9 @@ export default function WalletCard ({ wallet, draggable, onDragStart, onDragEnte
> >
<div className={styles.cardMeta}> <div className={styles.cardMeta}>
<div className={styles.indicators}> <div className={styles.indicators}>
{wallet.status.any !== Status.Disabled && <DraggableIcon className={styles.drag} width={16} height={16} />} {status.any !== Status.Disabled && <DraggableIcon className={styles.drag} width={16} height={16} />}
{wallet.support.recv && <RecvIcon className={`${styles.indicator} ${statusToClass(wallet.status.recv)}`} />} {support.recv && <RecvIcon className={`${styles.indicator} ${statusToClass(status.recv)}`} />}
{wallet.support.send && <SendIcon className={`${styles.indicator} ${statusToClass(wallet.status.send)}`} />} {support.send && <SendIcon className={`${styles.indicator} ${statusToClass(status.send)}`} />}
</div> </div>
</div> </div>
<Card.Body <Card.Body

View File

@ -0,0 +1,47 @@
import { canReceive, canSend, isConfigured, Status } from '@/wallets/common'
import { useWalletLogs } from '@/components/wallet-logger'
import styles from '@/styles/wallet.module.css'
export function useWalletStatus (wallet) {
const { logs } = useWalletLogs(wallet)
return statusFromLogs(wallet, {
any: wallet.config?.enabled && isConfigured(wallet) ? Status.Enabled : Status.Disabled,
send: wallet.config?.enabled && canSend(wallet) ? Status.Enabled : Status.Disabled,
recv: wallet.config?.enabled && canReceive(wallet) ? Status.Enabled : Status.Disabled
}, logs)
}
const statusFromLogs = (wallet, status, logs) => {
if (status.any === Status.Disabled) return status
// override status depending on if there have been warnings or errors in the logs recently
// find first log from which we can derive status (logs are sorted by recent first)
const walletLogs = logs.filter(l => l.wallet === wallet.def.name)
const sendLevel = walletLogs.find(l => l.context?.status && l.context?.send)?.level
const recvLevel = walletLogs.find(l => l.context?.status && l.context?.recv)?.level
const levelToStatus = (level) => {
switch (level?.toLowerCase()) {
case 'ok':
case 'success': return Status.Enabled
case 'error': return Status.Error
case 'warn': return Status.Warning
}
}
return {
any: status.any,
send: levelToStatus(sendLevel) || status.send,
recv: levelToStatus(recvLevel) || status.recv
}
}
export const statusToClass = status => {
switch (status) {
case Status.Enabled: return styles.success
case Status.Disabled: return styles.disabled
case Status.Error: return styles.error
case Status.Warning: return styles.warning
}
}

View File

@ -0,0 +1,8 @@
import { supportsReceive, supportsSend } from '@/wallets/common'
export function useWalletSupport (wallet) {
return {
send: supportsSend(wallet),
recv: supportsReceive(wallet)
}
}

View File

@ -175,31 +175,3 @@ export async function saveWalletLocally (name, config, userId) {
const storageKey = getStorageKey(name, userId) const storageKey = getStorageKey(name, userId)
window.localStorage.setItem(storageKey, JSON.stringify(config)) window.localStorage.setItem(storageKey, JSON.stringify(config))
} }
export const statusFromLog = (wallet, logs) => {
if (wallet.status.any === Status.Disabled) return wallet
// override status depending on if there have been warnings or errors in the logs recently
// find first log from which we can derive status (logs are sorted by recent first)
const walletLogs = logs.filter(l => l.wallet === wallet.def.name)
const sendLevel = walletLogs.find(l => l.context?.status && l.context?.send)?.level
const recvLevel = walletLogs.find(l => l.context?.status && l.context?.recv)?.level
const levelToStatus = (level) => {
switch (level?.toLowerCase()) {
case 'ok':
case 'success': return Status.Enabled
case 'error': return Status.Error
case 'warn': return Status.Warning
}
}
return {
...wallet,
status: {
...wallet.status,
send: levelToStatus(sendLevel) || wallet.status.send,
recv: levelToStatus(recvLevel) || wallet.status.recv
}
}
}

View File

@ -3,9 +3,9 @@ import { SET_WALLET_PRIORITY, WALLETS } from '@/fragments/wallet'
import { SSR } from '@/lib/constants' import { SSR } from '@/lib/constants'
import { useApolloClient, useMutation, useQuery } from '@apollo/client' import { useApolloClient, useMutation, useQuery } from '@apollo/client'
import { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react' import { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react'
import { getStorageKey, getWalletByType, Status, walletPrioritySort, canSend, isConfigured, upsertWalletVariables, siftConfig, saveWalletLocally, canReceive, supportsReceive, supportsSend, statusFromLog } from './common' import { getStorageKey, getWalletByType, walletPrioritySort, canSend, isConfigured, upsertWalletVariables, siftConfig, saveWalletLocally } from './common'
import useVault from '@/components/vault/use-vault' import useVault from '@/components/vault/use-vault'
import { useWalletLogger, useWalletLogs } from '@/components/wallet-logger' import { useWalletLogger } from '@/components/wallet-logger'
import { decode as bolt11Decode } from 'bolt11' import { decode as bolt11Decode } from 'bolt11'
import walletDefs from '@/wallets/client' import walletDefs from '@/wallets/client'
import { generateMutation } from './graphql' import { generateMutation } from './graphql'
@ -67,7 +67,6 @@ export function WalletsProvider ({ children }) {
const [setWalletPriority] = useMutation(SET_WALLET_PRIORITY) const [setWalletPriority] = useMutation(SET_WALLET_PRIORITY)
const [serverWallets, setServerWallets] = useState([]) const [serverWallets, setServerWallets] = useState([])
const client = useApolloClient() const client = useApolloClient()
const { logs } = useWalletLogs()
const { data, refetch } = useQuery(WALLETS, const { data, refetch } = useQuery(WALLETS,
SSR ? {} : { nextFetchPolicy: 'cache-and-network' }) SSR ? {} : { nextFetchPolicy: 'cache-and-network' })
@ -130,23 +129,8 @@ export function WalletsProvider ({ children }) {
} }
// sort by priority, then add status field // sort by priority, then add status field
return Object.values(merged) return Object.values(merged).sort(walletPrioritySort)
.sort(walletPrioritySort) }, [serverWallets, localWallets])
.map(w => {
return {
...w,
support: {
recv: supportsReceive(w),
send: supportsSend(w)
},
status: {
any: w.config?.enabled && isConfigured(w) ? Status.Enabled : Status.Disabled,
send: w.config?.enabled && canSend(w) ? Status.Enabled : Status.Disabled,
recv: w.config?.enabled && canReceive(w) ? Status.Enabled : Status.Disabled
}
}
}).map(w => statusFromLog(w, logs))
}, [serverWallets, localWallets, logs])
const settings = useMemo(() => { const settings = useMemo(() => {
return { return {