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

More wallet hooks: useWalletStatus & useWalletSupport #1646

Merged
merged 1 commit into from
Nov 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 7 additions & 12 deletions components/wallet-card.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,13 @@ import DraggableIcon from '@/svgs/draggable.svg'
import RecvIcon from '@/svgs/arrow-left-down-line.svg'
import SendIcon from '@/svgs/arrow-right-up-line.svg'
import { useWalletImage } from '@/components/wallet-image'

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
}
}
import { useWalletStatus, statusToClass } from '@/components/wallet-status'
import { useWalletSupport } from '@/components/wallet-support'

export default function WalletCard ({ wallet, draggable, onDragStart, onDragEnter, onDragEnd, onTouchStart, sourceIndex, targetIndex, index }) {
const image = useWalletImage(wallet)
const status = useWalletStatus(wallet)
const support = useWalletSupport(wallet)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh boy that's like a breathe of fresh air.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very good


return (
<Card
Expand All @@ -32,9 +27,9 @@ export default function WalletCard ({ wallet, draggable, onDragStart, onDragEnte
>
<div className={styles.cardMeta}>
<div className={styles.indicators}>
{wallet.status.any !== Status.Disabled && <DraggableIcon className={styles.drag} width={16} height={16} />}
{wallet.support.recv && <RecvIcon className={`${styles.indicator} ${statusToClass(wallet.status.recv)}`} />}
{wallet.support.send && <SendIcon className={`${styles.indicator} ${statusToClass(wallet.status.send)}`} />}
{status.any !== Status.Disabled && <DraggableIcon className={styles.drag} width={16} height={16} />}
{support.recv && <RecvIcon className={`${styles.indicator} ${statusToClass(status.recv)}`} />}
{support.send && <SendIcon className={`${styles.indicator} ${statusToClass(status.send)}`} />}
</div>
</div>
<Card.Body
Expand Down
47 changes: 47 additions & 0 deletions components/wallet-status.js
Original file line number Diff line number Diff line change
@@ -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
}
}
8 changes: 8 additions & 0 deletions components/wallet-support.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { supportsReceive, supportsSend } from '@/wallets/common'

export function useWalletSupport (wallet) {
return {
send: supportsSend(wallet),
recv: supportsReceive(wallet)
}
}
28 changes: 0 additions & 28 deletions wallets/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,31 +175,3 @@ export async function saveWalletLocally (name, config, userId) {
const storageKey = getStorageKey(name, userId)
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
}
}
}
24 changes: 4 additions & 20 deletions wallets/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import { SET_WALLET_PRIORITY, WALLETS } from '@/fragments/wallet'
import { SSR } from '@/lib/constants'
import { useApolloClient, useMutation, useQuery } from '@apollo/client'
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 { useWalletLogger, useWalletLogs } from '@/components/wallet-logger'
import { useWalletLogger } from '@/components/wallet-logger'
import { decode as bolt11Decode } from 'bolt11'
import walletDefs from '@/wallets/client'
import { generateMutation } from './graphql'
Expand Down Expand Up @@ -67,7 +67,6 @@ export function WalletsProvider ({ children }) {
const [setWalletPriority] = useMutation(SET_WALLET_PRIORITY)
const [serverWallets, setServerWallets] = useState([])
const client = useApolloClient()
const { logs } = useWalletLogs()

const { data, refetch } = useQuery(WALLETS,
SSR ? {} : { nextFetchPolicy: 'cache-and-network' })
Expand Down Expand Up @@ -130,23 +129,8 @@ export function WalletsProvider ({ children }) {
}

// sort by priority, then add status field
return Object.values(merged)
.sort(walletPrioritySort)
.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])
return Object.values(merged).sort(walletPrioritySort)
}, [serverWallets, localWallets])

const settings = useMemo(() => {
return {
Expand Down
Loading