diff --git a/components/Balance.tsx b/components/Balance.tsx index 41dc1c4..6c102ac 100644 --- a/components/Balance.tsx +++ b/components/Balance.tsx @@ -41,11 +41,17 @@ const Balance: FC = ({ className }) => { const xnoBalanceDisplay = rawToNanoDisplay(account?.balance ?? '0') return ( -
+
setPreference('showCurrencyDash', nextShowCurrency(showCurrencyDash)) } + className="hover:cursor-pointer active:translate-y-0.5" >

Ӿ diff --git a/components/BottomMenu.tsx b/components/BottomMenu.tsx index 2a5b3d4..73de384 100644 --- a/components/BottomMenu.tsx +++ b/components/BottomMenu.tsx @@ -57,8 +57,8 @@ const BottomMenu: FC = ({ className }) => { > {pathname !== '/dashboard' && ( - - + + )} @@ -73,16 +73,16 @@ const BottomMenu: FC = ({ className }) => { {'share' in navigator ? ( ) : ( )} @@ -103,28 +103,28 @@ const BottomMenu: FC = ({ className }) => {
- +
- +

diff --git a/components/Layout.tsx b/components/Layout.tsx index d56739b..e912789 100644 --- a/components/Layout.tsx +++ b/components/Layout.tsx @@ -20,24 +20,22 @@ const Layout: FC = ({ children }) => { useListenToColorMedia() return ( -
+
-
-

- zep -

- +
+

zep

+
{pathname !== '/' ? ( <> -
+
{children} diff --git a/components/RecentTransactions.tsx b/components/RecentTransactions.tsx index 6917ef7..ed6e1f2 100644 --- a/components/RecentTransactions.tsx +++ b/components/RecentTransactions.tsx @@ -8,31 +8,41 @@ import useAccountReceivable from '../lib/hooks/useAccountReceivable' import useReceiveNano from '../lib/hooks/useReceiveNano' import rawToNanoDisplay from '../lib/xno/rawToNanoDisplay' -export interface Props { - className?: string -} +export interface Props {} -const RecentTransactions: FC = ({ className }) => { +const RecentTransactions: FC = () => { const { receive } = useReceiveNano() const { receivableBlocks, onBlockReceived } = useAccountReceivable() - const { data: accountHistory } = useAccountHistory() + const { + accountHistory, + loadMore, + hasMore, + loading: loadingHistory, + hasHistory, + } = useAccountHistory() const hasReceivable = receivableBlocks !== undefined && receivableBlocks.length > 0 const [receivablesExpanded, setReceivablesExpanded] = useState(false) + const mappedHistory = (accountHistory ?? []).flatMap(historyPage => + historyPage.history !== '' ? historyPage.history : [] + ) + + const initialLoading = loadingHistory && accountHistory === undefined + return ( <> {hasReceivable && (
-

+

incoming

- + {receivableBlocks.length} = ({ className }) => {
    {receivableBlocks.map(receivable => (
)}
-

+

recent transactions

- {accountHistory !== undefined && accountHistory.history !== '' ? ( -
    - {accountHistory.history.map(txn => ( + {initialLoading ? ( +
      +
    • +
    • +
    • +
    • +
    + ) : hasHistory ? ( +
      + {mappedHistory.map(txn => (
    1. @@ -138,9 +155,17 @@ const RecentTransactions: FC = ({ className }) => {
    2. ))} + {hasMore && ( + + )}
    ) : ( -
    +

    no transactions yet...

    get your first nano @@ -150,14 +175,6 @@ const RecentTransactions: FC = ({ className }) => {

    )}
- {false && ( - - )} ) } diff --git a/lib/hooks/useAccountHistory.ts b/lib/hooks/useAccountHistory.ts index 8e9fd9c..9c0788b 100644 --- a/lib/hooks/useAccountHistory.ts +++ b/lib/hooks/useAccountHistory.ts @@ -1,15 +1,50 @@ -import useSWR from 'swr' +import { useCallback, useEffect } from 'react' +import useSWRInfinite from 'swr/infinite' import { useCurrentAccount } from '../context/accountContext' import type { AccountHistoryResponse } from '../types' import fetchAccountHistory from '../xno/fetchAccountHistory' -const useAccountHistory = () => { +const useAccountHistory = (pageSize = 20) => { const account = useCurrentAccount() - return useSWR( - account !== undefined ? `history:${account.address}` : null, - (key: string) => fetchAccountHistory(key.split(':')[1]) + + const getKey = (index: number, prevPage: AccountHistoryResponse | null) => { + if (account === undefined) return null + + if (prevPage !== null && prevPage.previous === undefined) return null + + if (index === 0) return `history` + + return `history?cursor=${prevPage!.previous}` + } + + const { + data: accountHistory, + size, + setSize, + isValidating, + } = useSWRInfinite(getKey, (key: string) => + fetchAccountHistory( + account!.address, + pageSize, + key.split('=')[1] === key ? undefined : key.split('=')[1] + ) ) + + const hasMore = accountHistory?.[size - 1]?.previous !== undefined + const loadMore = () => setSize(prev => prev + 1) + const hasHistory = + accountHistory !== undefined && + accountHistory.length > 0 && + accountHistory[0].history !== '' + + return { + accountHistory, + loadMore, + hasMore, + loading: isValidating, + hasHistory, + } } export default useAccountHistory diff --git a/lib/hooks/useAccountReceivable.ts b/lib/hooks/useAccountReceivable.ts index f927bd1..2888cdd 100644 --- a/lib/hooks/useAccountReceivable.ts +++ b/lib/hooks/useAccountReceivable.ts @@ -1,12 +1,8 @@ -import { useCallback, useEffect, useMemo, useState } from 'react' +import { useCallback } from 'react' import useSWR from 'swr' import { useCurrentAccount } from '../context/accountContext' -import type { - AccountReceivableResponse, - BlocksInfoResponse, - ConfirmationMessage, -} from '../types' +import type { ConfirmationMessage } from '../types' import fetchAccountReceivable from '../xno/fetchAccountReceivable' import fetchBlocksInfo from '../xno/fetchBlocksInfo' import useListenToReceivable from './useListenToReceivable' @@ -40,7 +36,8 @@ const useAccountReceivable = () => { }) ) } - }) + }), + { revalidateOnFocus: false } ) const onBlockReceived = useCallback( diff --git a/lib/hooks/useReadQrFromVideo.ts b/lib/hooks/useReadQrFromVideo.ts index 4d5ada6..6a96041 100644 --- a/lib/hooks/useReadQrFromVideo.ts +++ b/lib/hooks/useReadQrFromVideo.ts @@ -11,7 +11,9 @@ const useReadQrFromVideo = (onQrCodeRead: (content: string) => void) => { const start = async () => { stream = await navigator.mediaDevices.getUserMedia({ - video: { facingMode: 'environment' }, + video: { + facingMode: 'environment', + }, }) video.srcObject = stream video.setAttribute('playsinline', 'true') // required to tell iOS safari we don't want fullscreen @@ -35,7 +37,8 @@ const useReadQrFromVideo = (onQrCodeRead: (content: string) => void) => { video.height ) - if (qr !== null) { + if (qr !== null && qr.data !== '') { + console.log(qr) onQrCodeRead(qr.data) return } @@ -48,7 +51,6 @@ const useReadQrFromVideo = (onQrCodeRead: (content: string) => void) => { start() return () => { - console.log(stream, video, stream?.getTracks()) if (stream !== undefined) { stream.getTracks().forEach(track => track.stop()) stream.addEventListener('addtrack', track => track.track.stop()) diff --git a/lib/xno/fetchAccountHistory.ts b/lib/xno/fetchAccountHistory.ts index 186de08..a0641b8 100644 --- a/lib/xno/fetchAccountHistory.ts +++ b/lib/xno/fetchAccountHistory.ts @@ -2,7 +2,7 @@ import fetcher from '../fetcher' import { AccountHistoryResponse } from '../types' import { defaultUrls } from './constants' -const fetchAccountHistory = (address: string, count = 20, head = undefined) => +const fetchAccountHistory = (address: string, count = 20, head?: string) => fetcher(defaultUrls.rpc, { method: 'POST', body: { diff --git a/pages/send/index.tsx b/pages/send/index.tsx index bb2cab9..b5c2639 100644 --- a/pages/send/index.tsx +++ b/pages/send/index.tsx @@ -53,11 +53,7 @@ const Send: NextPage = () => { if (sliderPercentage === 1) { const sendNano = async () => { try { - await send( - address as string, - (amount as string) ?? - convert(xnoToSend, { from: Unit.Nano, to: Unit.raw }) - ) + await send(address as string, amount as string) push('/dashboard') } catch { backToBase() @@ -67,8 +63,16 @@ const Send: NextPage = () => { } }, [sliderPercentage, push, address, amount, xnoToSend, send, backToBase]) + const hasQueryAmount = amount !== undefined && amount !== '' && amount !== '0' + const disableSlider = !hasQueryAmount + + useEffect(() => { + if (hasQueryAmount && xnoToSend === '') + setXnoToSend(convert(amount, { from: Unit.raw, to: Unit.Nano })) + }, [amount, xnoToSend, hasQueryAmount]) + return ( -
+

send

@@ -77,7 +81,7 @@ const Send: NextPage = () => { onSubmit={ev => ev.preventDefault()} className="flex flex-col gap-3 items-center h-full" > -
+
{ }} />
- - - + + to +
+ {address?.substring(0, 10)} {address?.substring(10, 21)} @@ -103,61 +108,71 @@ const Send: NextPage = () => { {address?.substring(21, 42)}
{address?.substring(42, 56)} - + {address?.substring(56)}
{ - if (sliding) setCurrentX(ev.clientX) + if (sliding && !disableSlider) setCurrentX(ev.clientX) }} onMouseUp={() => { - if (sliderPercentage !== 1) backToBase() + if (sliderPercentage !== 1 && !disableSlider) backToBase() }} onMouseLeave={() => { - if (sliderPercentage !== 1) backToBase() + if (sliderPercentage !== 1 && !disableSlider) backToBase() }} >
{ - setSliding(true) - setStartX(ev.touches.item(0).clientX) + if (!disableSlider) { + setSliding(true) + setStartX(ev.touches.item(0).clientX) + } }} onTouchMove={ev => { - if (sliding) setCurrentX(ev.touches.item(0).clientX) + if (sliding && !disableSlider) + setCurrentX(ev.touches.item(0).clientX) + }} + onTouchEnd={() => { + if (!disableSlider) backToBase() }} - onTouchEnd={() => backToBase()} onMouseDown={ev => { - setSliding(true) - setStartX(ev.clientX) + if (!disableSlider) { + setSliding(true) + setStartX(ev.clientX) + } }} > - + /> */} + + Ӿ +
slide to send diff --git a/pages/send/qr.tsx b/pages/send/qr.tsx index 076af45..c8c2ea6 100644 --- a/pages/send/qr.tsx +++ b/pages/send/qr.tsx @@ -22,13 +22,13 @@ const ReadQrCode: NextPage = () => { const { videoLive, videoRef } = useReadQrFromVideo(onQrCodeRead) return ( -
+

send