diff --git a/api/typeDefs/user.js b/api/typeDefs/user.js
index 29d8a427..f8f813aa 100644
--- a/api/typeDefs/user.js
+++ b/api/typeDefs/user.js
@@ -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!
diff --git a/components/header.js b/components/header.js
index 3f1f4de0..fd7ed2b8 100644
--- a/components/header.js
+++ b/components/header.js
@@ -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
+ }
return `${abbrNum(me.sats)}`
}
@@ -132,7 +144,9 @@ function StackerCorner ({ dropNavKey }) {
-
+
+
+
diff --git a/components/hidden-wallet-summary.js b/components/hidden-wallet-summary.js
new file mode 100644
index 00000000..d769aee5
--- /dev/null
+++ b/components/hidden-wallet-summary.js
@@ -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 (
+ setHover(true)} onMouseLeave={() => setHover(false)}>
+ {hover ? (abbreviate ? abbrNum(me.sats) : numWithUnits(me.sats, { abbreviate: false })) : '*****'}
+
+ )
+}
diff --git a/fragments/users.js b/fragments/users.js
index bbd42868..2df5eaa6 100644
--- a/fragments/users.js
+++ b/fragments/users.js
@@ -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
}
}
diff --git a/lib/validate.js b/lib/validate.js
index 82b78ea7..0062f2f2 100644
--- a/lib/validate.js
+++ b/lib/validate.js
@@ -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'
diff --git a/pages/settings.js b/pages/settings.js
index c000c915..eb8d8de2 100644
--- a/pages/settings.js
+++ b/pages/settings.js
@@ -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'
/>
+ hide my wallet balance>}
+ name='hideWalletBalance'
+ groupClassName='mb-0'
+ />
click to load external images>}
name='clickToLoadImg'
diff --git a/pages/wallet.js b/pages/wallet.js
index 993e7faa..a5ed2723 100644
--- a/pages/wallet.js
+++ b/pages/wallet.js
@@ -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 (
- you have {me && numWithUnits(me.sats, { abbreviate: false })}
+ you have{' '}
+ {me && (
+ me.hideWalletBalance
+ ?
+ : numWithUnits(me.sats, { abbreviate: false })
+ )}
+
)
}
diff --git a/prisma/migrations/20230912122629_hide_wallet_balance/migration.sql b/prisma/migrations/20230912122629_hide_wallet_balance/migration.sql
new file mode 100644
index 00000000..5ba5db5d
--- /dev/null
+++ b/prisma/migrations/20230912122629_hide_wallet_balance/migration.sql
@@ -0,0 +1,2 @@
+-- AlterTable
+ALTER TABLE "users" ADD COLUMN "hideWalletBalance" BOOLEAN NOT NULL DEFAULT false;
diff --git a/prisma/schema.prisma b/prisma/schema.prisma
index 214b87e8..d03f5b9a 100644
--- a/prisma/schema.prisma
+++ b/prisma/schema.prisma
@@ -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")