disable freebies setting (#1320)

* disable freebies setting

* await in disableFreebie resolver + better info modal
This commit is contained in:
Keyan 2024-08-21 09:37:25 -05:00 committed by GitHub
parent 555601c7de
commit bc94ec7d28
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 46 additions and 5 deletions

View File

@ -21,8 +21,10 @@ export async function getCost ({ subName, parentId, uploadIds, boost = 0, bio },
FROM image_fees_info(${me?.id || USER_ID.anon}::INTEGER, ${uploadIds}::INTEGER[]))
+ ${satsToMsats(boost)}::INTEGER as cost`
// sub allows freebies (or is a bio or a comment), cost is less than baseCost, not anon, and cost must be greater than user's balance
const freebie = (parentId || bio || sub?.allowFreebies) && cost <= baseCost && !!me && cost > me?.msats
// sub allows freebies (or is a bio or a comment), cost is less than baseCost, not anon,
// cost must be greater than user's balance, and user has not disabled freebies
const freebie = (parentId || bio || sub?.allowFreebies) && cost <= baseCost && !!me &&
cost > me?.msats && !me?.disableFreebies
return freebie ? BigInt(0) : BigInt(cost)
}

View File

@ -622,6 +622,19 @@ export default {
},
Mutation: {
disableFreebies: async (parent, args, { me, models }) => {
if (!me) {
throw new GraphQLError('you must be logged in', { extensions: { code: 'UNAUTHENTICATED' } })
}
// disable freebies if it hasn't been set yet
await models.user.update({
where: { id: me.id, disableFreebies: null },
data: { disableFreebies: true }
})
return true
},
setName: async (parent, data, { me, models }) => {
if (!me) {
throw new GraphQLError('you must be logged in', { extensions: { code: 'UNAUTHENTICATED' } })

View File

@ -43,6 +43,7 @@ export default gql`
toggleMute(id: ID): User
generateApiKey(id: ID!): String
deleteApiKey(id: ID!): User
disableFreebies: Boolean
}
type User {
@ -72,6 +73,7 @@ export default gql`
noReferralLinks: Boolean!
fiatCurrency: String!
satsFilter: Int!
disableFreebies: Boolean
hideBookmarks: Boolean!
hideCowboyHat: Boolean!
hideGithub: Boolean!
@ -141,6 +143,7 @@ export default gql`
noReferralLinks: Boolean!
fiatCurrency: String!
satsFilter: Int!
disableFreebies: Boolean
greeterMode: Boolean!
hideBookmarks: Boolean!
hideCowboyHat: Boolean!

View File

@ -79,7 +79,7 @@ export function FeeButtonProvider ({ baseLineItems = {}, useRemoteLineItems = ()
const lines = { ...baseLineItems, ...lineItems, ...remoteLineItems }
const total = Object.values(lines).reduce((acc, { modifier }) => modifier(acc), 0)
// freebies: there's only a base cost and we don't have enough sats
const free = total === lines.baseCost?.modifier(0) && lines.baseCost?.allowFreebies && me?.privates?.sats < total
const free = total === lines.baseCost?.modifier(0) && lines.baseCost?.allowFreebies && me?.privates?.sats < total && !me?.privates?.disableFreebies
return {
lines,
merge: mergeLineItems,
@ -88,7 +88,7 @@ export function FeeButtonProvider ({ baseLineItems = {}, useRemoteLineItems = ()
setDisabled,
free
}
}, [me?.privates?.sats, baseLineItems, lineItems, remoteLineItems, mergeLineItems, disabled, setDisabled])
}, [me?.privates?.sats, me?.privates?.disableFreebies, baseLineItems, lineItems, remoteLineItems, mergeLineItems, disabled, setDisabled])
return (
<FeeButtonContext.Provider value={value}>

View File

@ -53,6 +53,7 @@ export const ME = gql`
lnAddr
autoWithdrawMaxFeePercent
autoWithdrawThreshold
disableFreebies
}
optional {
isContributor
@ -105,6 +106,7 @@ export const SETTINGS_FIELDS = gql`
nostrRelays
wildWestMode
satsFilter
disableFreebies
nsfwMode
authMethods {
lightning

View File

@ -602,6 +602,7 @@ export const settingsSchema = object().shape({
diagnostics: boolean(),
noReferralLinks: boolean(),
hideIsContributor: boolean(),
disableFreebies: boolean().nullable(),
satsFilter: intValidator.required('required').min(0, 'must be at least 0').max(1000, 'must be at most 1000'),
zapUndos: intValidator.nullable().min(0, 'must be greater or equal to 0')
// exclude from cyclic analysis. see https://github.com/jquense/yup/issues/720

View File

@ -116,6 +116,7 @@ export default function Settings ({ ssrData }) {
tipRandomMin: settings?.tipRandomMin || 1,
tipRandomMax: settings?.tipRandomMax || 10,
turboTipping: settings?.turboTipping,
disableFreebies: settings?.disableFreebies,
zapUndos: settings?.zapUndos || (settings?.tipDefault ? 100 * settings.tipDefault : 2100),
zapUndosEnabled: settings?.zapUndos !== null,
fiatCurrency: settings?.fiatCurrency || 'USD',
@ -252,6 +253,20 @@ export default function Settings ({ ssrData }) {
required
append={<InputGroup.Text className='text-monospace'>sats</InputGroup.Text>}
/>
<Checkbox
label={
<div className='d-flex align-items-center'>disable freebies
<Info>
<p>Some posts and comments can be created without paying. However, that content has limited visibility.</p>
<p>If you disable freebies, you will always pay for your posts and comments and get standard visibility.</p>
<p>If you attach a sending wallet, we disable freebies for you unless you have checked/unchecked this value already.</p>
</Info>
</div>
}
name='disableFreebies'
/>
<div className='form-label'>notify me when ...</div>
<Checkbox
label='I stack sats from posts and comments'

View File

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "users" ADD COLUMN "disableFreebies" BOOLEAN;

View File

@ -64,6 +64,7 @@ model User {
zapUndos Int?
imgproxyOnly Boolean @default(false)
hideWalletBalance Boolean @default(false)
disableFreebies Boolean?
referrerId Int?
nostrPubkey String?
greeterMode Boolean @default(false)

View File

@ -6,7 +6,7 @@ import { SSR } from '@/lib/constants'
import { bolt11Tags } from '@/lib/bolt11'
import walletDefs from 'wallets/client'
import { gql, useApolloClient, useQuery } from '@apollo/client'
import { gql, useApolloClient, useMutation, useQuery } from '@apollo/client'
import { REMOVE_WALLET, WALLET_BY_TYPE } from '@/fragments/wallet'
import { autowithdrawInitial } from '@/components/autowithdraw-shared'
import { useShowModal } from '@/components/modal'
@ -25,6 +25,7 @@ export function useWallet (name) {
const me = useMe()
const showModal = useShowModal()
const toaster = useToast()
const [disableFreebies] = useMutation(gql`mutation { disableFreebies }`)
const wallet = name ? getWalletByName(name) : getEnabledWallet(me)
const { logger, deleteLogs } = useWalletLogger(wallet)
@ -36,6 +37,7 @@ export function useWallet (name) {
const enablePayments = useCallback(() => {
enableWallet(name, me)
logger.ok('payments enabled')
disableFreebies().catch(console.error)
}, [name, me, logger])
const disablePayments = useCallback(() => {