better organize user graphql types

This commit is contained in:
keyan 2023-11-09 19:05:35 -06:00
parent d86d8b3bac
commit 494b8b3dcd
13 changed files with 372 additions and 291 deletions

View File

@ -23,6 +23,15 @@ const loadContributors = async (set) => {
}
async function authMethods (user, args, { models, me }) {
if (!me || me.id !== user.id) {
return {
lightning: false,
twitter: false,
github: false,
nostr: false
}
}
const accounts = await models.account.findMany({
where: {
userId: me.id
@ -465,7 +474,7 @@ export default {
throw error
}
},
setSettings: async (parent, { nostrRelays, ...data }, { me, models }) => {
setSettings: async (parent, { settings: { nostrRelays, ...data } }, { me, models }) => {
if (!me) {
throw new GraphQLError('you must be logged in', { extensions: { code: 'UNAUTHENTICATED' } })
}
@ -617,7 +626,59 @@ export default {
},
User: {
authMethods,
privates: async (user, args, { me, models }) => {
if (!me || me.id !== user.id) {
return null
}
return user
},
optional: user => user,
meSubscriptionPosts: async (user, args, { me, models }) => {
if (!me) return false
if (typeof user.meSubscriptionPosts !== 'undefined') return user.meSubscriptionPosts
const subscription = await models.userSubscription.findUnique({
where: {
followerId_followeeId: {
followerId: Number(me.id),
followeeId: Number(user.id)
}
}
})
return !!subscription?.postsSubscribedAt
},
meSubscriptionComments: async (user, args, { me, models }) => {
if (!me) return false
if (typeof user.meSubscriptionComments !== 'undefined') return user.meSubscriptionComments
const subscription = await models.userSubscription.findUnique({
where: {
followerId_followeeId: {
followerId: Number(me.id),
followeeId: Number(user.id)
}
}
})
return !!subscription?.commentsSubscribedAt
},
meMute: async (user, args, { me, models }) => {
if (!me) return false
if (typeof user.meMute !== 'undefined') return user.meMute
const mute = await models.mute.findUnique({
where: {
muterId_mutedId: {
muterId: Number(me.id),
mutedId: Number(user.id)
}
}
})
return !!mute
},
since: async (user, args, { models }) => {
// get the user's first item
const item = await models.item.findFirst({
@ -630,12 +691,6 @@ export default {
})
return item?.id
},
maxStreak: async (user, args, { models }) => {
const [{ max }] = await models.$queryRaw`
SELECT MAX(COALESCE("endedAt", (now() AT TIME ZONE 'America/Chicago')::date) - "startedAt")
FROM "Streak" WHERE "userId" = ${user.id}`
return max
},
nitems: async (user, { when, from, to }, { models }) => {
if (typeof user.nitems !== 'undefined') {
return user.nitems
@ -652,21 +707,6 @@ export default {
}
})
},
meMute: async (user, args, { me, models }) => {
if (!me) return false
if (typeof user.meMute !== 'undefined') return user.meMute
const mute = await models.mute.findUnique({
where: {
muterId_mutedId: {
muterId: Number(me.id),
mutedId: Number(user.id)
}
}
})
return !!mute
},
nposts: async (user, { when, from, to }, { models }) => {
if (typeof user.nposts !== 'undefined') {
return user.nposts
@ -701,23 +741,72 @@ export default {
}
})
},
nbookmarks: async (user, { when, from, to }, { models }) => {
if (typeof user.nBookmarks !== 'undefined') {
return user.nBookmarks
bio: async (user, args, { models, me }) => {
return getItem(user, { id: user.bioId }, { models, me })
}
},
UserPrivates: {
sats: async (user, args, { models, me }) => {
if (!me || me.id !== user.id) {
return 0
}
return msatsToSats(user.msats)
},
authMethods,
hasInvites: async (user, args, { models }) => {
const invites = await models.user.findUnique({
where: { id: user.id }
}).invites({ take: 1 })
return invites.length > 0
},
nostrRelays: async (user, args, { models, me }) => {
if (user.id !== me.id) {
return []
}
const [gte, lte] = whenRange(when, from, to)
return await models.bookmark.count({
where: {
userId: user.id,
createdAt: {
gte,
lte
}
}
const relays = await models.userNostrRelay.findMany({
where: { userId: user.id }
})
return relays?.map(r => r.nostrRelayAddr)
}
},
UserOptional: {
streak: async (user, args, { models }) => {
if (user.hideCowboyHat) {
return null
}
return user.streak
},
stacked: async (user, { when, from, to }, { models }) => {
maxStreak: async (user, args, { models }) => {
if (user.hideCowboyHat) {
return null
}
const [{ max }] = await models.$queryRaw`
SELECT MAX(COALESCE("endedAt", (now() AT TIME ZONE 'America/Chicago')::date) - "startedAt")
FROM "Streak" WHERE "userId" = ${user.id}`
return max
},
isContributor: async (user, args, { me }) => {
// lazy init contributors only once
if (contributors.size === 0) {
await loadContributors(contributors)
}
if (me?.id === user.id) {
return contributors.has(user.name)
}
return !user.hideIsContributor && contributors.has(user.name)
},
stacked: async (user, { when, from, to }, { models, me }) => {
if ((!me || me.id !== user.id) && user.hideFromTopUsers) {
return null
}
if (typeof user.stacked !== 'undefined') {
return user.stacked
}
@ -750,7 +839,11 @@ export default {
return 0
},
spent: async (user, { when, from, to }, { models }) => {
spent: async (user, { when, from, to }, { models, me }) => {
if ((!me || me.id !== user.id) && user.hideFromTopUsers) {
return null
}
if (typeof user.spent !== 'undefined') {
return user.spent
}
@ -771,7 +864,11 @@ export default {
return (msats && msatsToSats(msats)) || 0
},
referrals: async (user, { when, from, to }, { models }) => {
referrals: async (user, { when, from, to }, { models, me }) => {
if ((!me || me.id !== user.id) && user.hideFromTopUsers) {
return null
}
if (typeof user.referrals !== 'undefined') {
return user.referrals
}
@ -786,69 +883,6 @@ export default {
}
}
})
},
sats: async (user, args, { models, me }) => {
if (me?.id !== user.id) {
return 0
}
return msatsToSats(user.msats)
},
bio: async (user, args, { models, me }) => {
return getItem(user, { id: user.bioId }, { models, me })
},
hasInvites: async (user, args, { models }) => {
const invites = await models.user.findUnique({
where: { id: user.id }
}).invites({ take: 1 })
return invites.length > 0
},
nostrRelays: async (user, args, { models }) => {
const relays = await models.userNostrRelay.findMany({
where: { userId: user.id }
})
return relays?.map(r => r.nostrRelayAddr)
},
meSubscriptionPosts: async (user, args, { me, models }) => {
if (!me) return false
if (typeof user.meSubscriptionPosts !== 'undefined') return user.meSubscriptionPosts
const subscription = await models.userSubscription.findUnique({
where: {
followerId_followeeId: {
followerId: Number(me.id),
followeeId: Number(user.id)
}
}
})
return !!subscription?.postsSubscribedAt
},
meSubscriptionComments: async (user, args, { me, models }) => {
if (!me) return false
if (typeof user.meSubscriptionComments !== 'undefined') return user.meSubscriptionComments
const subscription = await models.userSubscription.findUnique({
where: {
followerId_followeeId: {
followerId: Number(me.id),
followeeId: Number(user.id)
}
}
})
return !!subscription?.commentsSubscribedAt
},
isContributor: async (user, args, { me }) => {
// lazy init contributors only once
if (contributors.size === 0) {
await loadContributors(contributors)
}
if (me?.id === user.id) {
return contributors.has(user.name)
}
return !user.hideIsContributor && contributors.has(user.name)
}
}
}

View File

@ -87,7 +87,7 @@ export function getGetServerSideProps (
}
const { data: { price } } = await client.query({
query: PRICE, variables: { fiatCurrency: me?.fiatCurrency }
query: PRICE, variables: { fiatCurrency: me?.privates?.fiatCurrency }
})
const { data: { blockHeight } } = await client.query({

View File

@ -20,12 +20,7 @@ export default gql`
extend type Mutation {
setName(name: String!): String
setSettings(tipDefault: Int!, turboTipping: Boolean!, fiatCurrency: String!, withdrawMaxFeeDefault: Int!, noteItemSats: Boolean!,
noteEarning: Boolean!, noteAllDescendants: Boolean!, noteMentions: Boolean!, noteDeposits: Boolean!,
noteInvites: Boolean!, noteJobIndicator: Boolean!, noteCowboyHat: Boolean!, hideInvoiceDesc: Boolean!, autoDropBolt11s: Boolean!,
hideFromTopUsers: Boolean!, hideCowboyHat: Boolean!, imgproxyOnly: Boolean!,
wildWestMode: Boolean!, greeterMode: Boolean!, nostrPubkey: String, nostrCrossposting: Boolean, nostrRelays: [String!], hideBookmarks: Boolean!,
noteForwardedSats: Boolean!, hideWalletBalance: Boolean!, hideIsContributor: Boolean!, diagnostics: Boolean!): User
setSettings(settings: SettingsInput!): User
setPhoto(photoId: ID!): Int!
upsertBio(bio: String!): User!
setWalkthrough(tipPopover: Boolean, upvotePopover: Boolean): Boolean
@ -37,6 +32,56 @@ export default gql`
toggleMute(id: ID): User
}
type User {
id: ID!
createdAt: Date!
name: String
nitems(when: String, from: String, to: String): Int!
nposts(when: String, from: String, to: String): Int!
ncomments(when: String, from: String, to: String): Int!
bio: Item
bioId: Int
photoId: Int
since: Int
optional: UserOptional!
privates: UserPrivates
meMute: Boolean!
meSubscriptionPosts: Boolean!
meSubscriptionComments: Boolean!
}
input SettingsInput {
autoDropBolt11s: Boolean!
diagnostics: Boolean!
fiatCurrency: String!
greeterMode: Boolean!
hideBookmarks: Boolean!
hideCowboyHat: Boolean!
hideFromTopUsers: Boolean!
hideInvoiceDesc: Boolean!
hideIsContributor: Boolean!
hideWalletBalance: Boolean!
imgproxyOnly: Boolean!
nostrCrossposting: Boolean!
nostrPubkey: String
nostrRelays: [String!]
noteAllDescendants: Boolean!
noteCowboyHat: Boolean!
noteDeposits: Boolean!
noteEarning: Boolean!
noteForwardedSats: Boolean!
noteInvites: Boolean!
noteItemSats: Boolean!
noteJobIndicator: Boolean!
noteMentions: Boolean!
tipDefault: Int!
turboTipping: Boolean!
wildWestMode: Boolean!
withdrawMaxFeeDefault: Int!
}
type AuthMethods {
lightning: Boolean!
nostr: Boolean!
@ -45,74 +90,63 @@ export default gql`
email: String
}
type Image {
id: ID!
createdAt: Date!
updatedAt: Date!
type: String!
size: Int!
width: Int
height: Int
itemId: Int
userId: Int!
}
type UserPrivates {
"""
extremely sensitive
"""
sats: Int!
authMethods: AuthMethods!
type User {
id: ID!
createdAt: Date!
name: String
nitems(when: String, from: String, to: String): Int!
nposts(when: String, from: String, to: String): Int!
ncomments(when: String, from: String, to: String): Int!
nbookmarks(when: String, from: String, to: String): Int!
stacked(when: String, from: String, to: String): Int!
spent(when: String, from: String, to: String): Int!
referrals(when: String, from: String, to: String): Int!
freePosts: Int!
freeComments: Int!
"""
only relevant to user
"""
lastCheckedJobs: String
hideWelcomeBanner: Boolean!
tipPopover: Boolean!
upvotePopover: Boolean!
hasInvites: Boolean!
tipDefault: Int!
turboTipping: Boolean!
"""
mirrors SettingsInput
"""
autoDropBolt11s: Boolean!
diagnostics: Boolean!
fiatCurrency: String!
withdrawMaxFeeDefault: Int!
greeterMode: Boolean!
hideBookmarks: Boolean!
hideCowboyHat: Boolean!
hideFromTopUsers: Boolean!
hideInvoiceDesc: Boolean!
hideIsContributor: Boolean!
hideWalletBalance: Boolean!
imgproxyOnly: Boolean!
nostrCrossposting: Boolean!
nostrPubkey: String
nostrRelays: [String!]
bio: Item
bioId: Int
photoId: Int
noteAllDescendants: Boolean!
noteCowboyHat: Boolean!
noteDeposits: Boolean!
noteEarning: Boolean!
noteForwardedSats: Boolean!
noteInvites: Boolean!
noteItemSats: Boolean!
noteJobIndicator: Boolean!
noteMentions: Boolean!
tipDefault: Int!
turboTipping: Boolean!
wildWestMode: Boolean!
withdrawMaxFeeDefault: Int!
}
type UserOptional {
"""
conditionally private
"""
stacked(when: String, from: String, to: String): Int
spent(when: String, from: String, to: String): Int
referrals(when: String, from: String, to: String): Int
streak: Int
maxStreak: Int
sats: Int!
since: Int
upvotePopover: Boolean!
tipPopover: Boolean!
nostrCrossposting: Boolean!
noteItemSats: Boolean!
noteEarning: Boolean!
noteAllDescendants: Boolean!
noteMentions: Boolean!
noteDeposits: Boolean!
noteInvites: Boolean!
noteJobIndicator: Boolean!
noteCowboyHat: Boolean!
noteForwardedSats: Boolean!
hideInvoiceDesc: Boolean!
autoDropBolt11s: Boolean!
hideFromTopUsers: Boolean!
hideCowboyHat: Boolean!
hideBookmarks: Boolean!
hideWelcomeBanner: Boolean!
hideWalletBalance: Boolean!
diagnostics: Boolean!
imgproxyOnly: Boolean!
wildWestMode: Boolean!
greeterMode: Boolean!
lastCheckedJobs: String
authMethods: AuthMethods!
isContributor: Boolean!
hideIsContributor: Boolean!
meSubscriptionPosts: Boolean!
meSubscriptionComments: Boolean!
meMute: Boolean
isContributor: Boolean
}
`

View File

@ -21,11 +21,11 @@ export default function Hat ({ user, badge, className = 'ms-1', height = 16, wid
)
}
if (user.streak === null || user.hideCowboyHat) {
const streak = user.optional.streak
if (streak === null) {
return null
}
const streak = user.streak
return (
<HatTooltip overlayText={streak
? `${numWithUnits(streak, { abbreviate: false, unitSingular: 'day', unitPlural: 'days' })}`

View File

@ -9,9 +9,12 @@ export const MeContext = React.createContext({
export function MeProvider ({ me, children }) {
const { data } = useQuery(ME, SSR ? {} : { pollInterval: 1000, nextFetchPolicy: 'cache-and-network' })
const futureMe = data?.me || me
const contextValue = {
me: data?.me || me
me: futureMe
? { ...futureMe, ...futureMe.privates, ...futureMe.optional }
: null
}
return (

View File

@ -69,7 +69,7 @@ export default function Seo ({ sub, item, user }) {
}
}
if (user) {
desc = `@${user.name} has [${user.stacked} stacked, ${numWithUnits(user.nitems, { unitSingular: 'item', unitPlural: 'items' })}]`
desc = `@${user.name} has [${user.optional.stacked ? `${user.optional.stacked} stacked,` : ''}${numWithUnits(user.nitems, { unitSingular: 'item', unitPlural: 'items' })}]`
}
return (

View File

@ -187,9 +187,11 @@ function HeaderHeader ({ user }) {
const isMe = me?.name === user.name
const Satistics = () => (
<div className={`mb-2 ms-0 ms-sm-1 ${styles.username} text-success`}>
{numWithUnits(user.stacked, { abbreviate: false, format: true })} stacked
</div>)
user.optional.stacked !== null &&
<div className={`mb-2 ms-0 ms-sm-1 ${styles.username} text-success`}>
{numWithUnits(user.optional.stacked, { abbreviate: false, format: true })} stacked
</div>
)
const lnurlp = encodeLNUrl(new URL(`https://stacker.news/.well-known/lnurlp/${user.name}`))
return (
@ -227,8 +229,8 @@ function HeaderHeader ({ user }) {
? <Link href={`/items/${user.since}`} className='ms-1'>#{user.since}</Link>
: <span>never</span>}
</small>
<small className='text-muted d-flex-inline'>longest cowboy streak: {user.maxStreak !== null ? user.maxStreak : 'none'}</small>
{user.isContributor && <small className='text-muted d-flex align-items-center'><CodeIcon className='me-1' height={16} width={16} /> verified stacker.news contributor</small>}
{user.optional.maxStreak !== null && <small className='text-muted d-flex-inline'>longest cowboy streak: {user.optional.maxStreak}</small>}
{user.optional.isContributor && <small className='text-muted d-flex align-items-center'><CodeIcon className='me-1' height={16} width={16} /> verified stacker.news contributor</small>}
</div>
</div>
</div>

View File

@ -10,8 +10,8 @@ import { useData } from './use-data'
import Hat from './hat'
// all of this nonsense is to show the stat we are sorting by first
const Stacked = ({ user }) => (<span>{abbrNum(user.stacked)} stacked</span>)
const Spent = ({ user }) => (<span>{abbrNum(user.spent)} spent</span>)
const Stacked = ({ user }) => (user.optional.stacked !== null && <span>{abbrNum(user.optional.stacked)} stacked</span>)
const Spent = ({ user }) => (user.optional.spent !== null && <span>{abbrNum(user.optional.spent)} spent</span>)
const Posts = ({ user }) => (
<Link href={`/${user.name}/posts`} className='text-reset'>
{numWithUnits(user.nposts, { unitSingular: 'post', unitPlural: 'posts' })}
@ -20,7 +20,7 @@ const Comments = ({ user }) => (
<Link href={`/${user.name}/comments`} className='text-reset'>
{numWithUnits(user.ncomments, { unitSingular: 'comment', unitPlural: 'comments' })}
</Link>)
const Referrals = ({ user }) => (<span>{numWithUnits(user.referrals, { unitSingular: 'referral', unitPlural: 'referrals' })}</span>)
const Referrals = ({ user }) => (user.optional.referrals !== null && <span>{numWithUnits(user.optional.referrals, { unitSingular: 'referral', unitPlural: 'referrals' })}</span>)
const Seperator = () => (<span> \ </span>)
const STAT_POS = {

View File

@ -8,10 +8,11 @@ export const COMMENT_FIELDS = gql`
deletedAt
text
user {
name
streak
hideCowboyHat
id
name
optional {
streak
}
meMute
}
sats
@ -45,8 +46,9 @@ export const COMMENTS_ITEM_EXT_FIELDS = gql`
subName
user {
name
streak
hideCowboyHat
optional {
streak
}
id
}
}

View File

@ -5,17 +5,18 @@ export const INVITE_FIELDS = gql`
id
createdAt
invitees {
name
id
name
}
gift
limit
revoked
user {
name
streak
hideCowboyHat
id
name
optional {
streak
}
}
poor
}

View File

@ -10,10 +10,11 @@ export const ITEM_FIELDS = gql`
title
url
user {
name
streak
hideCowboyHat
id
name
optional {
streak
}
meMute
}
otsHash
@ -60,10 +61,11 @@ export const ITEM_FULL_FIELDS = gql`
bountyPaidTo
subName
user {
name
streak
hideCowboyHat
id
name
optional {
streak
}
}
}
forwards {

View File

@ -7,19 +7,53 @@ export const ME = gql`
me {
id
name
streak
sats
stacked
freePosts
freeComments
bioId
privates {
autoDropBolt11s
diagnostics
fiatCurrency
greeterMode
hideCowboyHat
hideFromTopUsers
hideInvoiceDesc
hideIsContributor
hideWalletBalance
hideWelcomeBanner
imgproxyOnly
lastCheckedJobs
nostrCrossposting
noteAllDescendants
noteCowboyHat
noteDeposits
noteEarning
noteForwardedSats
noteInvites
noteItemSats
noteJobIndicator
noteMentions
sats
tipDefault
tipPopover
turboTipping
upvotePopover
wildWestMode
withdrawMaxFeeDefault
}
optional {
isContributor
stacked
streak
}
}
}`
export const SETTINGS_FIELDS = gql`
fragment SettingsFields on User {
privates {
tipDefault
turboTipping
fiatCurrency
withdrawMaxFeeDefault
bioId
upvotePopover
tipPopover
nostrCrossposting
noteItemSats
noteEarning
noteAllDescendants
@ -33,53 +67,23 @@ export const ME = gql`
autoDropBolt11s
hideFromTopUsers
hideCowboyHat
hideBookmarks
hideIsContributor
imgproxyOnly
hideWalletBalance
diagnostics
nostrPubkey
nostrCrossposting
nostrRelays
wildWestMode
greeterMode
lastCheckedJobs
hideWelcomeBanner
hideWalletBalance
isContributor
hideIsContributor
}
}`
export const SETTINGS_FIELDS = gql`
fragment SettingsFields on User {
tipDefault
turboTipping
fiatCurrency
withdrawMaxFeeDefault
noteItemSats
noteEarning
noteAllDescendants
noteMentions
noteDeposits
noteInvites
noteJobIndicator
noteCowboyHat
noteForwardedSats
hideInvoiceDesc
autoDropBolt11s
hideFromTopUsers
hideCowboyHat
hideBookmarks
hideIsContributor
imgproxyOnly
hideWalletBalance
diagnostics
nostrPubkey
nostrCrossposting
nostrRelays
wildWestMode
greeterMode
authMethods {
lightning
nostr
github
twitter
email
authMethods {
lightning
nostr
github
twitter
email
}
}
}`
@ -94,22 +98,11 @@ ${SETTINGS_FIELDS}
export const SET_SETTINGS =
gql`
${SETTINGS_FIELDS}
mutation setSettings($tipDefault: Int!, $turboTipping: Boolean!, $fiatCurrency: String!, $withdrawMaxFeeDefault: Int!, $noteItemSats: Boolean!,
$noteEarning: Boolean!, $noteAllDescendants: Boolean!, $noteMentions: Boolean!, $noteDeposits: Boolean!,
$noteInvites: Boolean!, $noteJobIndicator: Boolean!, $noteCowboyHat: Boolean!, $hideInvoiceDesc: Boolean!, $autoDropBolt11s: Boolean!,
$hideFromTopUsers: Boolean!, $hideCowboyHat: Boolean!, $imgproxyOnly: Boolean!,
$wildWestMode: Boolean!, $greeterMode: Boolean!, $nostrPubkey: String, $nostrCrossposting: Boolean!, $nostrRelays: [String!], $hideBookmarks: Boolean!,
$noteForwardedSats: Boolean!, $hideWalletBalance: Boolean!, $hideIsContributor: Boolean!, $diagnostics: Boolean!) {
setSettings(tipDefault: $tipDefault, turboTipping: $turboTipping, fiatCurrency: $fiatCurrency, withdrawMaxFeeDefault: $withdrawMaxFeeDefault,
noteItemSats: $noteItemSats, noteEarning: $noteEarning, noteAllDescendants: $noteAllDescendants,
noteMentions: $noteMentions, noteDeposits: $noteDeposits, noteInvites: $noteInvites,
noteJobIndicator: $noteJobIndicator, noteCowboyHat: $noteCowboyHat, hideInvoiceDesc: $hideInvoiceDesc, autoDropBolt11s: $autoDropBolt11s,
hideFromTopUsers: $hideFromTopUsers, hideCowboyHat: $hideCowboyHat, imgproxyOnly: $imgproxyOnly,
wildWestMode: $wildWestMode, greeterMode: $greeterMode, nostrPubkey: $nostrPubkey, nostrCrossposting: $nostrCrossposting, nostrRelays: $nostrRelays, hideBookmarks: $hideBookmarks,
noteForwardedSats: $noteForwardedSats, hideWalletBalance: $hideWalletBalance, hideIsContributor: $hideIsContributor, diagnostics: $diagnostics) {
...SettingsFields
}
mutation setSettings($settings: SettingsInput!) {
setSettings(settings: $settings) {
...SettingsFields
}
}
`
export const NAME_QUERY =
@ -139,14 +132,16 @@ gql`
searchUsers(q: $q, limit: $limit, similarity: $similarity) {
id
name
streak
hideCowboyHat
photoId
stacked
spent
ncomments
nposts
referrals
optional {
streak
stacked
spent
referrals
}
}
}`
@ -154,17 +149,19 @@ export const USER_FIELDS = gql`
fragment UserFields on User {
id
name
streak
maxStreak
hideCowboyHat
nitems
stacked
since
photoId
isContributor
nitems
meSubscriptionPosts
meSubscriptionComments
meMute
optional {
stacked
streak
maxStreak
isContributor
}
}`
export const TOP_USERS = gql`
@ -173,14 +170,16 @@ export const TOP_USERS = gql`
users {
id
name
streak
hideCowboyHat
photoId
stacked(when: $when, from: $from, to: $to)
spent(when: $when, from: $from, to: $to)
ncomments(when: $when, from: $from, to: $to)
nposts(when: $when, from: $from, to: $to)
referrals(when: $when, from: $from, to: $to)
optional {
streak
stacked(when: $when, from: $from, to: $to)
spent(when: $when, from: $from, to: $to)
referrals(when: $when, from: $from, to: $to)
}
}
cursor
}
@ -193,14 +192,16 @@ export const TOP_COWBOYS = gql`
users {
id
name
streak
hideCowboyHat
photoId
stacked(when: "forever")
spent(when: "forever")
ncomments(when: "forever")
nposts(when: "forever")
referrals(when: "forever")
optional {
streak
stacked(when: "forever")
spent(when: "forever")
referrals(when: "forever")
}
}
cursor
}

View File

@ -52,7 +52,7 @@ export default function Settings ({ ssrData }) {
const logger = useLogger()
const { data } = useQuery(SETTINGS)
const { settings } = data || ssrData
const { settings: { privates: settings } } = data || ssrData
if (!data && !ssrData) return <PageLoading />
return (
@ -105,11 +105,13 @@ export default function Settings ({ ssrData }) {
try {
await setSettings({
variables: {
tipDefault: Number(tipDefault),
withdrawMaxFeeDefault: Number(withdrawMaxFeeDefault),
nostrPubkey,
nostrRelays: nostrRelaysFiltered,
...values
settings: {
tipDefault: Number(tipDefault),
withdrawMaxFeeDefault: Number(withdrawMaxFeeDefault),
nostrPubkey,
nostrRelays: nostrRelaysFiltered,
...values
}
}
})
toaster.success('saved settings')