Skip to content

feat: comment fee control #1768

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Feb 7, 2025
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 26 additions & 2 deletions api/paidAction/itemCreate.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,32 @@ export const paymentMethods = [
]

export async function getCost ({ subName, parentId, uploadIds, boost = 0, bio }, { models, me }) {
const sub = (parentId || bio) ? null : await models.sub.findUnique({ where: { name: subName } })
const baseCost = sub ? satsToMsats(sub.baseCost) : 1000n
const BIO_COST = 1000n
async function findRootItem (models, parentId) {
const item = await models.item.findFirst({
where: { id: Number(parentId) },
select: { rootId: true }
})

return models.item.findFirst({
where: { id: Number(item.rootId || parentId) },
include: { sub: true }
})
}
async function getBaseCost ({ models, bio, parentId, subName }) {
if (bio) return BIO_COST

if (parentId) {
const rootItem = await findRootItem(models, parentId)
return rootItem.bio ? BIO_COST : satsToMsats(rootItem.sub?.replyCost)
}

const sub = await models.sub.findUnique({ where: { name: subName } })
return satsToMsats(sub.baseCost)
}
const baseCost = await getBaseCost({ models, bio, parentId, subName })
// const sub = (parentId || bio) ? null : await models.sub.findUnique({ where: { name: subName } })
// const baseCost = sub ? satsToMsats(sub.baseCost) : 1000n

// cost = baseCost * 10^num_items_in_10m * 100 (anon) or 1 (user) + upload fees + boost
const [{ cost }] = await models.$queryRaw`
Expand Down
4 changes: 3 additions & 1 deletion api/typeDefs/sub.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export default gql`

extend type Mutation {
upsertSub(oldName: String, name: String!, desc: String, baseCost: Int!,
replyCost: Int!,
postTypes: [String!]!,
billingType: String!, billingAutoRenew: Boolean!,
moderated: Boolean!, nsfw: Boolean!): SubPaidAction!
Expand All @@ -24,7 +25,7 @@ export default gql`
toggleSubSubscription(name: String!): Boolean!
transferTerritory(subName: String!, userName: String!): Sub
unarchiveTerritory(name: String!, desc: String, baseCost: Int!,
postTypes: [String!]!,
replyCost: Int!, postTypes: [String!]!,
billingType: String!, billingAutoRenew: Boolean!,
moderated: Boolean!, nsfw: Boolean!): SubPaidAction!
}
Expand All @@ -45,6 +46,7 @@ export default gql`
billedLastAt: Date!
billPaidUntil: Date
baseCost: Int!
replyCost: Int!
status: String!
moderated: Boolean!
moderatedCount: Int!
Expand Down
3 changes: 2 additions & 1 deletion components/reply.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export default forwardRef(function Reply ({
const replyInput = useRef(null)
const showModal = useShowModal()
const root = useRoot()
const bio = root?.bio
const sub = item?.sub || root?.sub

useEffect(() => {
Expand Down Expand Up @@ -173,7 +174,7 @@ export default forwardRef(function Reply ({
{reply &&
<div className={styles.reply}>
<FeeButtonProvider
baseLineItems={postCommentBaseLineItems({ baseCost: 1, comment: true, me: !!me })}
baseLineItems={postCommentBaseLineItems({ baseCost: bio ? 1 : sub.replyCost, comment: true, me: !!me })}
useRemoteLineItems={postCommentUseRemoteLineItems({ parentId: item.id, me: !!me })}
>
<Form
Expand Down
8 changes: 8 additions & 0 deletions components/territory-form.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ export default function TerritoryForm ({ sub }) {
name: sub?.name || '',
desc: sub?.desc || '',
baseCost: sub?.baseCost || 10,
replyCost: sub?.replyCost || 1,
postTypes: sub?.postTypes || POST_TYPES,
billingType: sub?.billingType || 'MONTHLY',
billingAutoRenew: sub?.billingAutoRenew || false,
Expand Down Expand Up @@ -136,6 +137,13 @@ export default function TerritoryForm ({ sub }) {
required
append={<InputGroup.Text className='text-monospace'>sats</InputGroup.Text>}
/>
<Input
label='reply cost'
name='replyCost'
type='number'
required
append={<InputGroup.Text className='text-monospace'>sats</InputGroup.Text>}
/>
<CheckboxGroup label='post types' name='postTypes'>
<Row>
<Col xs={4} sm='auto'>
Expand Down
4 changes: 4 additions & 0 deletions components/territory-header.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ export function TerritoryInfo ({ sub }) {
<span>post cost </span>
<span className='fw-bold'>{numWithUnits(sub.baseCost)}</span>
</div>
<div className='text-muted'>
<span>reply cost </span>
<span className='fw-bold'>{numWithUnits(sub.replyCost)}</span>
</div>
<TerritoryBillingLine sub={sub} />
</CardFooter>
</>
Expand Down
1 change: 1 addition & 0 deletions fragments/items.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export const ITEM_FIELDS = gql`
meMuteSub
meSubscription
nsfw
replyCost
}
otsHash
position
Expand Down
8 changes: 4 additions & 4 deletions fragments/paidAction.js
Original file line number Diff line number Diff line change
Expand Up @@ -250,10 +250,10 @@ export const UPDATE_COMMENT = gql`
export const UPSERT_SUB = gql`
${PAID_ACTION}
mutation upsertSub($oldName: String, $name: String!, $desc: String, $baseCost: Int!,
$postTypes: [String!]!, $billingType: String!,
$replyCost: Int!, $postTypes: [String!]!, $billingType: String!,
$billingAutoRenew: Boolean!, $moderated: Boolean!, $nsfw: Boolean!) {
upsertSub(oldName: $oldName, name: $name, desc: $desc, baseCost: $baseCost,
postTypes: $postTypes, billingType: $billingType,
replyCost: $replyCost, postTypes: $postTypes, billingType: $billingType,
billingAutoRenew: $billingAutoRenew, moderated: $moderated, nsfw: $nsfw) {
result {
name
Expand All @@ -265,10 +265,10 @@ export const UPSERT_SUB = gql`
export const UNARCHIVE_TERRITORY = gql`
${PAID_ACTION}
mutation unarchiveTerritory($name: String!, $desc: String, $baseCost: Int!,
$postTypes: [String!]!, $billingType: String!,
$replyCost: Int!, $postTypes: [String!]!, $billingType: String!,
$billingAutoRenew: Boolean!, $moderated: Boolean!, $nsfw: Boolean!) {
unarchiveTerritory(name: $name, desc: $desc, baseCost: $baseCost,
postTypes: $postTypes, billingType: $billingType,
replyCost: $replyCost, postTypes: $postTypes, billingType: $billingType,
billingAutoRenew: $billingAutoRenew, moderated: $moderated, nsfw: $nsfw) {
result {
name
Expand Down
1 change: 1 addition & 0 deletions fragments/subs.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export const SUB_FIELDS = gql`
billedLastAt
billPaidUntil
baseCost
replyCost
userId
desc
status
Expand Down
3 changes: 3 additions & 0 deletions lib/validate.js
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,9 @@ export function territorySchema (args) {
baseCost: intValidator
.min(1, 'must be at least 1')
.max(100000, 'must be at most 100k'),
replyCost: intValidator
.min(1, 'must be at least 1')
.max(100000, 'must be at most 100k'),
postTypes: array().of(string().oneOf(POST_TYPES)).min(1, 'must support at least one post type'),
billingType: string().required('required').oneOf(TERRITORY_BILLING_TYPES, 'required'),
nsfw: boolean()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "Sub" ADD COLUMN "replyCost" INTEGER NOT NULL DEFAULT 1;
1 change: 1 addition & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,7 @@ model Sub {
rankingType RankingType
allowFreebies Boolean @default(true)
baseCost Int @default(1)
replyCost Int @default(1)
rewardsPct Int @default(50)
desc String?
status Status @default(ACTIVE)
Expand Down
Loading