Hide wallet balance (#481)
* Hide wallet balance on long press * Use setting to hide wallet balance * Fix layout shift on hover * Fix SSR warning about useLayoutEffect See https://reactjs.org/link/uselayouteffect-ssr * Also hide balance in wallet --------- Co-authored-by: ekzyis <ek@stacker.news>
This commit is contained in:
parent
1a6dc879a2
commit
6df654b208
|
@ -25,7 +25,7 @@ export default gql`
|
|||
noteInvites: Boolean!, noteJobIndicator: Boolean!, noteCowboyHat: Boolean!, hideInvoiceDesc: Boolean!,
|
||||
hideFromTopUsers: Boolean!, hideCowboyHat: Boolean!, clickToLoadImg: Boolean!,
|
||||
wildWestMode: Boolean!, greeterMode: Boolean!, nostrPubkey: String, nostrRelays: [String!], hideBookmarks: Boolean!,
|
||||
noteForwardedSats: Boolean!): User
|
||||
noteForwardedSats: Boolean!, hideWalletBalance: Boolean!): User
|
||||
setPhoto(photoId: ID!): Int!
|
||||
upsertBio(bio: String!): User!
|
||||
setWalkthrough(tipPopover: Boolean, upvotePopover: Boolean): Boolean
|
||||
|
@ -85,6 +85,7 @@ export default gql`
|
|||
hideCowboyHat: Boolean!
|
||||
hideBookmarks: Boolean!
|
||||
hideWelcomeBanner: Boolean!
|
||||
hideWalletBalance: Boolean!
|
||||
clickToLoadImg: Boolean!
|
||||
wildWestMode: Boolean!
|
||||
greeterMode: Boolean!
|
||||
|
|
|
@ -10,7 +10,7 @@ import Price from './price'
|
|||
import { useMe } from './me'
|
||||
import Head from 'next/head'
|
||||
import { signOut } from 'next-auth/react'
|
||||
import { useCallback, useEffect } from 'react'
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import { randInRange } from '../lib/rand'
|
||||
import { abbrNum } from '../lib/format'
|
||||
import NoteIcon from '../svgs/notification-4-fill.svg'
|
||||
|
@ -24,9 +24,21 @@ import { useLightning } from './lightning'
|
|||
import { HAS_NOTIFICATIONS } from '../fragments/notifications'
|
||||
import AnonIcon from '../svgs/spy-fill.svg'
|
||||
import Hat from './hat'
|
||||
import HiddenWalletSummary from './hidden-wallet-summary'
|
||||
|
||||
function WalletSummary ({ me }) {
|
||||
if (!me) return null
|
||||
function WalletSummary ({ me, hideBalance }) {
|
||||
const [show, setShow] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
// fix warning about useLayoutEffect usage during SSR
|
||||
// see https://reactjs.org/link/uselayouteffect-ssr
|
||||
setShow(true)
|
||||
}, [])
|
||||
|
||||
if (!me || !show) return null
|
||||
if (me.hideWalletBalance) {
|
||||
return <HiddenWalletSummary abbreviate fixedWidth />
|
||||
}
|
||||
return `${abbrNum(me.sats)}`
|
||||
}
|
||||
|
||||
|
@ -132,7 +144,9 @@ function StackerCorner ({ dropNavKey }) {
|
|||
<NavProfileMenu me={me} dropNavKey={dropNavKey} />
|
||||
<Nav.Item>
|
||||
<Link href='/wallet' passHref legacyBehavior>
|
||||
<Nav.Link eventKey='wallet' className='text-success px-0 text-nowrap'><WalletSummary me={me} /></Nav.Link>
|
||||
<Nav.Link eventKey='wallet' className='text-success px-0 text-nowrap'>
|
||||
<WalletSummary me={me} />
|
||||
</Nav.Link>
|
||||
</Link>
|
||||
</Nav.Item>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import { useState, useRef, useLayoutEffect } from 'react'
|
||||
import { abbrNum, numWithUnits } from '../lib/format'
|
||||
import { useMe } from './me'
|
||||
|
||||
export default function HiddenWalletSummary ({ abbreviate, fixedWidth }) {
|
||||
const me = useMe()
|
||||
const [hover, setHover] = useState(false)
|
||||
|
||||
// prevent layout shifts when hovering by fixing width to initial rendered width
|
||||
const ref = useRef()
|
||||
const [width, setWidth] = useState(undefined)
|
||||
useLayoutEffect(() => {
|
||||
setWidth(ref.current?.offsetWidth)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<span ref={ref} style={{ width: fixedWidth ? width : undefined }} className='d-inline-block' align='right' onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}>
|
||||
{hover ? (abbreviate ? abbrNum(me.sats) : numWithUnits(me.sats, { abbreviate: false })) : '*****'}
|
||||
</span>
|
||||
)
|
||||
}
|
|
@ -35,6 +35,7 @@ export const ME = gql`
|
|||
greeterMode
|
||||
lastCheckedJobs
|
||||
hideWelcomeBanner
|
||||
hideWalletBalance
|
||||
}
|
||||
}`
|
||||
|
||||
|
@ -57,6 +58,7 @@ export const SETTINGS_FIELDS = gql`
|
|||
hideCowboyHat
|
||||
hideBookmarks
|
||||
clickToLoadImg
|
||||
hideWalletBalance
|
||||
nostrPubkey
|
||||
nostrRelays
|
||||
wildWestMode
|
||||
|
@ -86,14 +88,14 @@ mutation setSettings($tipDefault: Int!, $turboTipping: Boolean!, $fiatCurrency:
|
|||
$noteInvites: Boolean!, $noteJobIndicator: Boolean!, $noteCowboyHat: Boolean!, $hideInvoiceDesc: Boolean!,
|
||||
$hideFromTopUsers: Boolean!, $hideCowboyHat: Boolean!, $clickToLoadImg: Boolean!,
|
||||
$wildWestMode: Boolean!, $greeterMode: Boolean!, $nostrPubkey: String, $nostrRelays: [String!], $hideBookmarks: Boolean!,
|
||||
$noteForwardedSats: Boolean!) {
|
||||
$noteForwardedSats: Boolean!, $hideWalletBalance: Boolean!) {
|
||||
setSettings(tipDefault: $tipDefault, turboTipping: $turboTipping, fiatCurrency: $fiatCurrency,
|
||||
noteItemSats: $noteItemSats, noteEarning: $noteEarning, noteAllDescendants: $noteAllDescendants,
|
||||
noteMentions: $noteMentions, noteDeposits: $noteDeposits, noteInvites: $noteInvites,
|
||||
noteJobIndicator: $noteJobIndicator, noteCowboyHat: $noteCowboyHat, hideInvoiceDesc: $hideInvoiceDesc,
|
||||
hideFromTopUsers: $hideFromTopUsers, hideCowboyHat: $hideCowboyHat, clickToLoadImg: $clickToLoadImg,
|
||||
wildWestMode: $wildWestMode, greeterMode: $greeterMode, nostrPubkey: $nostrPubkey, nostrRelays: $nostrRelays, hideBookmarks: $hideBookmarks,
|
||||
noteForwardedSats: $noteForwardedSats) {
|
||||
noteForwardedSats: $noteForwardedSats, hideWalletBalance: $hideWalletBalance) {
|
||||
...SettingsFields
|
||||
}
|
||||
}
|
||||
|
|
|
@ -223,7 +223,8 @@ export const settingsSchema = object({
|
|||
string().matches(WS_REGEXP, 'invalid web socket address')
|
||||
).max(NOSTR_MAX_RELAY_NUM,
|
||||
({ max, value }) => `${Math.abs(max - value.length)} too many`),
|
||||
hideBookmarks: boolean()
|
||||
hideBookmarks: boolean(),
|
||||
hideWalletBalance: boolean()
|
||||
})
|
||||
|
||||
const warningMessage = 'If I logout, even accidentally, I will never be able to access my account again'
|
||||
|
|
|
@ -76,7 +76,8 @@ export default function Settings ({ ssrData }) {
|
|||
greeterMode: settings?.greeterMode,
|
||||
nostrPubkey: settings?.nostrPubkey ? bech32encode(settings.nostrPubkey) : '',
|
||||
nostrRelays: settings?.nostrRelays?.length ? settings?.nostrRelays : [''],
|
||||
hideBookmarks: settings?.hideBookmarks
|
||||
hideBookmarks: settings?.hideBookmarks,
|
||||
hideWalletBalance: settings?.hideWalletBalance
|
||||
}}
|
||||
schema={settingsSchema}
|
||||
onSubmit={async ({ tipDefault, nostrPubkey, nostrRelays, ...values }) => {
|
||||
|
@ -230,6 +231,11 @@ export default function Settings ({ ssrData }) {
|
|||
name='hideCowboyHat'
|
||||
groupClassName='mb-0'
|
||||
/>
|
||||
<Checkbox
|
||||
label={<>hide my wallet balance</>}
|
||||
name='hideWalletBalance'
|
||||
groupClassName='mb-0'
|
||||
/>
|
||||
<Checkbox
|
||||
label={<>click to load external images</>}
|
||||
name='clickToLoadImg'
|
||||
|
|
|
@ -18,6 +18,7 @@ import Nav from 'react-bootstrap/Nav'
|
|||
import { SSR } from '../lib/constants'
|
||||
import { numWithUnits } from '../lib/format'
|
||||
import styles from '../components/user-header.module.css'
|
||||
import HiddenWalletSummary from '../components/hidden-wallet-summary'
|
||||
|
||||
export const getServerSideProps = getGetServerSideProps({ authRequired: true })
|
||||
|
||||
|
@ -51,7 +52,13 @@ function YouHaveSats () {
|
|||
const me = useMe()
|
||||
return (
|
||||
<h2 className={`${me ? 'visible' : 'invisible'} text-success`}>
|
||||
you have <span className='text-monospace'>{me && numWithUnits(me.sats, { abbreviate: false })}</span>
|
||||
you have{' '}
|
||||
<span className='text-monospace'>{me && (
|
||||
me.hideWalletBalance
|
||||
? <HiddenWalletSummary />
|
||||
: numWithUnits(me.sats, { abbreviate: false })
|
||||
)}
|
||||
</span>
|
||||
</h2>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
-- AlterTable
|
||||
ALTER TABLE "users" ADD COLUMN "hideWalletBalance" BOOLEAN NOT NULL DEFAULT false;
|
|
@ -51,6 +51,7 @@ model User {
|
|||
hideFromTopUsers Boolean @default(false)
|
||||
turboTipping Boolean @default(false)
|
||||
clickToLoadImg Boolean @default(false)
|
||||
hideWalletBalance Boolean @default(false)
|
||||
referrerId Int?
|
||||
nostrPubkey String?
|
||||
nostrAuthPubkey String? @unique(map: "users.nostrAuthPubkey_unique")
|
||||
|
|
Loading…
Reference in New Issue