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!,
|
noteInvites: Boolean!, noteJobIndicator: Boolean!, noteCowboyHat: Boolean!, hideInvoiceDesc: Boolean!,
|
||||||
hideFromTopUsers: Boolean!, hideCowboyHat: Boolean!, clickToLoadImg: Boolean!,
|
hideFromTopUsers: Boolean!, hideCowboyHat: Boolean!, clickToLoadImg: Boolean!,
|
||||||
wildWestMode: Boolean!, greeterMode: Boolean!, nostrPubkey: String, nostrRelays: [String!], hideBookmarks: Boolean!,
|
wildWestMode: Boolean!, greeterMode: Boolean!, nostrPubkey: String, nostrRelays: [String!], hideBookmarks: Boolean!,
|
||||||
noteForwardedSats: Boolean!): User
|
noteForwardedSats: Boolean!, hideWalletBalance: Boolean!): User
|
||||||
setPhoto(photoId: ID!): Int!
|
setPhoto(photoId: ID!): Int!
|
||||||
upsertBio(bio: String!): User!
|
upsertBio(bio: String!): User!
|
||||||
setWalkthrough(tipPopover: Boolean, upvotePopover: Boolean): Boolean
|
setWalkthrough(tipPopover: Boolean, upvotePopover: Boolean): Boolean
|
||||||
|
@ -85,6 +85,7 @@ export default gql`
|
||||||
hideCowboyHat: Boolean!
|
hideCowboyHat: Boolean!
|
||||||
hideBookmarks: Boolean!
|
hideBookmarks: Boolean!
|
||||||
hideWelcomeBanner: Boolean!
|
hideWelcomeBanner: Boolean!
|
||||||
|
hideWalletBalance: Boolean!
|
||||||
clickToLoadImg: Boolean!
|
clickToLoadImg: Boolean!
|
||||||
wildWestMode: Boolean!
|
wildWestMode: Boolean!
|
||||||
greeterMode: Boolean!
|
greeterMode: Boolean!
|
||||||
|
|
|
@ -10,7 +10,7 @@ import Price from './price'
|
||||||
import { useMe } from './me'
|
import { useMe } from './me'
|
||||||
import Head from 'next/head'
|
import Head from 'next/head'
|
||||||
import { signOut } from 'next-auth/react'
|
import { signOut } from 'next-auth/react'
|
||||||
import { useCallback, useEffect } from 'react'
|
import { useCallback, useEffect, useState } from 'react'
|
||||||
import { randInRange } from '../lib/rand'
|
import { randInRange } from '../lib/rand'
|
||||||
import { abbrNum } from '../lib/format'
|
import { abbrNum } from '../lib/format'
|
||||||
import NoteIcon from '../svgs/notification-4-fill.svg'
|
import NoteIcon from '../svgs/notification-4-fill.svg'
|
||||||
|
@ -24,9 +24,21 @@ import { useLightning } from './lightning'
|
||||||
import { HAS_NOTIFICATIONS } from '../fragments/notifications'
|
import { HAS_NOTIFICATIONS } from '../fragments/notifications'
|
||||||
import AnonIcon from '../svgs/spy-fill.svg'
|
import AnonIcon from '../svgs/spy-fill.svg'
|
||||||
import Hat from './hat'
|
import Hat from './hat'
|
||||||
|
import HiddenWalletSummary from './hidden-wallet-summary'
|
||||||
|
|
||||||
function WalletSummary ({ me }) {
|
function WalletSummary ({ me, hideBalance }) {
|
||||||
if (!me) return null
|
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)}`
|
return `${abbrNum(me.sats)}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +144,9 @@ function StackerCorner ({ dropNavKey }) {
|
||||||
<NavProfileMenu me={me} dropNavKey={dropNavKey} />
|
<NavProfileMenu me={me} dropNavKey={dropNavKey} />
|
||||||
<Nav.Item>
|
<Nav.Item>
|
||||||
<Link href='/wallet' passHref legacyBehavior>
|
<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>
|
</Link>
|
||||||
</Nav.Item>
|
</Nav.Item>
|
||||||
</div>
|
</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
|
greeterMode
|
||||||
lastCheckedJobs
|
lastCheckedJobs
|
||||||
hideWelcomeBanner
|
hideWelcomeBanner
|
||||||
|
hideWalletBalance
|
||||||
}
|
}
|
||||||
}`
|
}`
|
||||||
|
|
||||||
|
@ -57,6 +58,7 @@ export const SETTINGS_FIELDS = gql`
|
||||||
hideCowboyHat
|
hideCowboyHat
|
||||||
hideBookmarks
|
hideBookmarks
|
||||||
clickToLoadImg
|
clickToLoadImg
|
||||||
|
hideWalletBalance
|
||||||
nostrPubkey
|
nostrPubkey
|
||||||
nostrRelays
|
nostrRelays
|
||||||
wildWestMode
|
wildWestMode
|
||||||
|
@ -86,14 +88,14 @@ mutation setSettings($tipDefault: Int!, $turboTipping: Boolean!, $fiatCurrency:
|
||||||
$noteInvites: Boolean!, $noteJobIndicator: Boolean!, $noteCowboyHat: Boolean!, $hideInvoiceDesc: Boolean!,
|
$noteInvites: Boolean!, $noteJobIndicator: Boolean!, $noteCowboyHat: Boolean!, $hideInvoiceDesc: Boolean!,
|
||||||
$hideFromTopUsers: Boolean!, $hideCowboyHat: Boolean!, $clickToLoadImg: Boolean!,
|
$hideFromTopUsers: Boolean!, $hideCowboyHat: Boolean!, $clickToLoadImg: Boolean!,
|
||||||
$wildWestMode: Boolean!, $greeterMode: Boolean!, $nostrPubkey: String, $nostrRelays: [String!], $hideBookmarks: Boolean!,
|
$wildWestMode: Boolean!, $greeterMode: Boolean!, $nostrPubkey: String, $nostrRelays: [String!], $hideBookmarks: Boolean!,
|
||||||
$noteForwardedSats: Boolean!) {
|
$noteForwardedSats: Boolean!, $hideWalletBalance: Boolean!) {
|
||||||
setSettings(tipDefault: $tipDefault, turboTipping: $turboTipping, fiatCurrency: $fiatCurrency,
|
setSettings(tipDefault: $tipDefault, turboTipping: $turboTipping, fiatCurrency: $fiatCurrency,
|
||||||
noteItemSats: $noteItemSats, noteEarning: $noteEarning, noteAllDescendants: $noteAllDescendants,
|
noteItemSats: $noteItemSats, noteEarning: $noteEarning, noteAllDescendants: $noteAllDescendants,
|
||||||
noteMentions: $noteMentions, noteDeposits: $noteDeposits, noteInvites: $noteInvites,
|
noteMentions: $noteMentions, noteDeposits: $noteDeposits, noteInvites: $noteInvites,
|
||||||
noteJobIndicator: $noteJobIndicator, noteCowboyHat: $noteCowboyHat, hideInvoiceDesc: $hideInvoiceDesc,
|
noteJobIndicator: $noteJobIndicator, noteCowboyHat: $noteCowboyHat, hideInvoiceDesc: $hideInvoiceDesc,
|
||||||
hideFromTopUsers: $hideFromTopUsers, hideCowboyHat: $hideCowboyHat, clickToLoadImg: $clickToLoadImg,
|
hideFromTopUsers: $hideFromTopUsers, hideCowboyHat: $hideCowboyHat, clickToLoadImg: $clickToLoadImg,
|
||||||
wildWestMode: $wildWestMode, greeterMode: $greeterMode, nostrPubkey: $nostrPubkey, nostrRelays: $nostrRelays, hideBookmarks: $hideBookmarks,
|
wildWestMode: $wildWestMode, greeterMode: $greeterMode, nostrPubkey: $nostrPubkey, nostrRelays: $nostrRelays, hideBookmarks: $hideBookmarks,
|
||||||
noteForwardedSats: $noteForwardedSats) {
|
noteForwardedSats: $noteForwardedSats, hideWalletBalance: $hideWalletBalance) {
|
||||||
...SettingsFields
|
...SettingsFields
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -223,7 +223,8 @@ export const settingsSchema = object({
|
||||||
string().matches(WS_REGEXP, 'invalid web socket address')
|
string().matches(WS_REGEXP, 'invalid web socket address')
|
||||||
).max(NOSTR_MAX_RELAY_NUM,
|
).max(NOSTR_MAX_RELAY_NUM,
|
||||||
({ max, value }) => `${Math.abs(max - value.length)} too many`),
|
({ 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'
|
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,
|
greeterMode: settings?.greeterMode,
|
||||||
nostrPubkey: settings?.nostrPubkey ? bech32encode(settings.nostrPubkey) : '',
|
nostrPubkey: settings?.nostrPubkey ? bech32encode(settings.nostrPubkey) : '',
|
||||||
nostrRelays: settings?.nostrRelays?.length ? settings?.nostrRelays : [''],
|
nostrRelays: settings?.nostrRelays?.length ? settings?.nostrRelays : [''],
|
||||||
hideBookmarks: settings?.hideBookmarks
|
hideBookmarks: settings?.hideBookmarks,
|
||||||
|
hideWalletBalance: settings?.hideWalletBalance
|
||||||
}}
|
}}
|
||||||
schema={settingsSchema}
|
schema={settingsSchema}
|
||||||
onSubmit={async ({ tipDefault, nostrPubkey, nostrRelays, ...values }) => {
|
onSubmit={async ({ tipDefault, nostrPubkey, nostrRelays, ...values }) => {
|
||||||
|
@ -230,6 +231,11 @@ export default function Settings ({ ssrData }) {
|
||||||
name='hideCowboyHat'
|
name='hideCowboyHat'
|
||||||
groupClassName='mb-0'
|
groupClassName='mb-0'
|
||||||
/>
|
/>
|
||||||
|
<Checkbox
|
||||||
|
label={<>hide my wallet balance</>}
|
||||||
|
name='hideWalletBalance'
|
||||||
|
groupClassName='mb-0'
|
||||||
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label={<>click to load external images</>}
|
label={<>click to load external images</>}
|
||||||
name='clickToLoadImg'
|
name='clickToLoadImg'
|
||||||
|
|
|
@ -18,6 +18,7 @@ import Nav from 'react-bootstrap/Nav'
|
||||||
import { SSR } from '../lib/constants'
|
import { SSR } from '../lib/constants'
|
||||||
import { numWithUnits } from '../lib/format'
|
import { numWithUnits } from '../lib/format'
|
||||||
import styles from '../components/user-header.module.css'
|
import styles from '../components/user-header.module.css'
|
||||||
|
import HiddenWalletSummary from '../components/hidden-wallet-summary'
|
||||||
|
|
||||||
export const getServerSideProps = getGetServerSideProps({ authRequired: true })
|
export const getServerSideProps = getGetServerSideProps({ authRequired: true })
|
||||||
|
|
||||||
|
@ -51,7 +52,13 @@ function YouHaveSats () {
|
||||||
const me = useMe()
|
const me = useMe()
|
||||||
return (
|
return (
|
||||||
<h2 className={`${me ? 'visible' : 'invisible'} text-success`}>
|
<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>
|
</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)
|
hideFromTopUsers Boolean @default(false)
|
||||||
turboTipping Boolean @default(false)
|
turboTipping Boolean @default(false)
|
||||||
clickToLoadImg Boolean @default(false)
|
clickToLoadImg Boolean @default(false)
|
||||||
|
hideWalletBalance Boolean @default(false)
|
||||||
referrerId Int?
|
referrerId Int?
|
||||||
nostrPubkey String?
|
nostrPubkey String?
|
||||||
nostrAuthPubkey String? @unique(map: "users.nostrAuthPubkey_unique")
|
nostrAuthPubkey String? @unique(map: "users.nostrAuthPubkey_unique")
|
||||||
|
|
Loading…
Reference in New Issue