Skip to content

Commit 5c2aa97

Browse files
Soxasorahuumn
andauthored
feat: comment fee control (#1768)
* feat: comment fee control * update typeDefs for unarchiving territories * review: move functions to top level; consider saloon items * ux: cleaner post/reply cost section * hotfix: handle salon replies * bios don't have subs + simplify root query * move reply cost to accordian --------- Co-authored-by: Keyan <[email protected]> Co-authored-by: k00b <[email protected]>
1 parent ac321be commit 5c2aa97

File tree

11 files changed

+60
-11
lines changed

11 files changed

+60
-11
lines changed

api/paidAction/itemCreate.js

+26-2
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,33 @@ export const paymentMethods = [
1313
PAID_ACTION_PAYMENT_METHODS.PESSIMISTIC
1414
]
1515

16+
export const DEFAULT_ITEM_COST = 1000n
17+
18+
export async function getBaseCost ({ models, bio, parentId, subName }) {
19+
if (bio) return DEFAULT_ITEM_COST
20+
21+
if (parentId) {
22+
// the subname is stored in the root item of the thread
23+
const parent = await models.item.findFirst({
24+
where: { id: Number(parentId) },
25+
include: {
26+
root: { include: { sub: true } },
27+
sub: true
28+
}
29+
})
30+
31+
const root = parent.root ?? parent
32+
33+
if (!root.sub) return DEFAULT_ITEM_COST
34+
return satsToMsats(root.sub.replyCost)
35+
}
36+
37+
const sub = await models.sub.findUnique({ where: { name: subName } })
38+
return satsToMsats(sub.baseCost)
39+
}
40+
1641
export async function getCost ({ subName, parentId, uploadIds, boost = 0, bio }, { models, me }) {
17-
const sub = (parentId || bio) ? null : await models.sub.findUnique({ where: { name: subName } })
18-
const baseCost = sub ? satsToMsats(sub.baseCost) : 1000n
42+
const baseCost = await getBaseCost({ models, bio, parentId, subName })
1943

2044
// cost = baseCost * 10^num_items_in_10m * 100 (anon) or 1 (user) + upload fees + boost
2145
const [{ cost }] = await models.$queryRaw`

api/typeDefs/sub.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export default gql`
1616
1717
extend type Mutation {
1818
upsertSub(oldName: String, name: String!, desc: String, baseCost: Int!,
19+
replyCost: Int!,
1920
postTypes: [String!]!,
2021
billingType: String!, billingAutoRenew: Boolean!,
2122
moderated: Boolean!, nsfw: Boolean!): SubPaidAction!
@@ -24,7 +25,7 @@ export default gql`
2425
toggleSubSubscription(name: String!): Boolean!
2526
transferTerritory(subName: String!, userName: String!): Sub
2627
unarchiveTerritory(name: String!, desc: String, baseCost: Int!,
27-
postTypes: [String!]!,
28+
replyCost: Int!, postTypes: [String!]!,
2829
billingType: String!, billingAutoRenew: Boolean!,
2930
moderated: Boolean!, nsfw: Boolean!): SubPaidAction!
3031
}
@@ -45,6 +46,7 @@ export default gql`
4546
billedLastAt: Date!
4647
billPaidUntil: Date
4748
baseCost: Int!
49+
replyCost: Int!
4850
status: String!
4951
moderated: Boolean!
5052
moderatedCount: Int!

components/reply.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ export default forwardRef(function Reply ({
161161
{reply &&
162162
<div className={styles.reply}>
163163
<FeeButtonProvider
164-
baseLineItems={postCommentBaseLineItems({ baseCost: 1, comment: true, me: !!me })}
164+
baseLineItems={postCommentBaseLineItems({ baseCost: sub?.replyCost ?? 1, comment: true, me: !!me })}
165165
useRemoteLineItems={postCommentUseRemoteLineItems({ parentId: item.id, me: !!me })}
166166
>
167167
<Form

components/territory-form.js

+8
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ export default function TerritoryForm ({ sub }) {
9191
name: sub?.name || '',
9292
desc: sub?.desc || '',
9393
baseCost: sub?.baseCost || 10,
94+
replyCost: sub?.replyCost || 1,
9495
postTypes: sub?.postTypes || POST_TYPES,
9596
billingType: sub?.billingType || 'MONTHLY',
9697
billingAutoRenew: sub?.billingAutoRenew || false,
@@ -234,6 +235,13 @@ export default function TerritoryForm ({ sub }) {
234235
header={<div style={{ fontWeight: 'bold', fontSize: '92%' }}>options</div>}
235236
body={
236237
<>
238+
<Input
239+
label='reply cost'
240+
name='replyCost'
241+
type='number'
242+
required
243+
append={<InputGroup.Text className='text-monospace'>sats</InputGroup.Text>}
244+
/>
237245
<BootstrapForm.Label>moderation</BootstrapForm.Label>
238246
<Checkbox
239247
inline

components/territory-header.js

+10-3
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,16 @@ export function TerritoryInfo ({ sub }) {
5757
<span> on </span>
5858
<span className='fw-bold'>{new Date(sub.createdAt).toDateString()}</span>
5959
</div>
60-
<div className='text-muted'>
61-
<span>post cost </span>
62-
<span className='fw-bold'>{numWithUnits(sub.baseCost)}</span>
60+
<div className='d-flex'>
61+
<div className='text-muted'>
62+
<span>post cost </span>
63+
<span className='fw-bold'>{numWithUnits(sub.baseCost)}</span>
64+
</div>
65+
<span className='px-1'> \ </span>
66+
<div className='text-muted'>
67+
<span>reply cost </span>
68+
<span className='fw-bold'>{numWithUnits(sub.replyCost)}</span>
69+
</div>
6370
</div>
6471
<TerritoryBillingLine sub={sub} />
6572
</CardFooter>

fragments/items.js

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export const ITEM_FIELDS = gql`
3535
meMuteSub
3636
meSubscription
3737
nsfw
38+
replyCost
3839
}
3940
otsHash
4041
position

fragments/paidAction.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -264,10 +264,10 @@ export const UPDATE_COMMENT = gql`
264264
export const UPSERT_SUB = gql`
265265
${PAID_ACTION}
266266
mutation upsertSub($oldName: String, $name: String!, $desc: String, $baseCost: Int!,
267-
$postTypes: [String!]!, $billingType: String!,
267+
$replyCost: Int!, $postTypes: [String!]!, $billingType: String!,
268268
$billingAutoRenew: Boolean!, $moderated: Boolean!, $nsfw: Boolean!) {
269269
upsertSub(oldName: $oldName, name: $name, desc: $desc, baseCost: $baseCost,
270-
postTypes: $postTypes, billingType: $billingType,
270+
replyCost: $replyCost, postTypes: $postTypes, billingType: $billingType,
271271
billingAutoRenew: $billingAutoRenew, moderated: $moderated, nsfw: $nsfw) {
272272
result {
273273
name
@@ -279,10 +279,10 @@ export const UPSERT_SUB = gql`
279279
export const UNARCHIVE_TERRITORY = gql`
280280
${PAID_ACTION}
281281
mutation unarchiveTerritory($name: String!, $desc: String, $baseCost: Int!,
282-
$postTypes: [String!]!, $billingType: String!,
282+
$replyCost: Int!, $postTypes: [String!]!, $billingType: String!,
283283
$billingAutoRenew: Boolean!, $moderated: Boolean!, $nsfw: Boolean!) {
284284
unarchiveTerritory(name: $name, desc: $desc, baseCost: $baseCost,
285-
postTypes: $postTypes, billingType: $billingType,
285+
replyCost: $replyCost, postTypes: $postTypes, billingType: $billingType,
286286
billingAutoRenew: $billingAutoRenew, moderated: $moderated, nsfw: $nsfw) {
287287
result {
288288
name

fragments/subs.js

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export const SUB_FIELDS = gql`
2525
billedLastAt
2626
billPaidUntil
2727
baseCost
28+
replyCost
2829
userId
2930
desc
3031
status

lib/validate.js

+3
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,9 @@ export function territorySchema (args) {
317317
baseCost: intValidator
318318
.min(1, 'must be at least 1')
319319
.max(100000, 'must be at most 100k'),
320+
replyCost: intValidator
321+
.min(1, 'must be at least 1')
322+
.max(100000, 'must be at most 100k'),
320323
postTypes: array().of(string().oneOf(POST_TYPES)).min(1, 'must support at least one post type'),
321324
billingType: string().required('required').oneOf(TERRITORY_BILLING_TYPES, 'required'),
322325
nsfw: boolean()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- AlterTable
2+
ALTER TABLE "Sub" ADD COLUMN "replyCost" INTEGER NOT NULL DEFAULT 1;

prisma/schema.prisma

+1
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,7 @@ model Sub {
737737
rankingType RankingType
738738
allowFreebies Boolean @default(true)
739739
baseCost Int @default(1)
740+
replyCost Int @default(1)
740741
rewardsPct Int @default(50)
741742
desc String?
742743
status Status @default(ACTIVE)

0 commit comments

Comments
 (0)