multiple comments with the same parent are exp in cost

This commit is contained in:
keyan 2022-04-17 08:13:52 -05:00
parent e168925f6c
commit 89fb68f746
7 changed files with 63 additions and 21 deletions

View File

@ -762,7 +762,7 @@ export default {
meComments: async (item, args, { me, models }) => {
if (!me) return 0
return await models.items.count({ where: { userId: me.id, parentId: item.id } })
return await models.item.count({ where: { userId: me.id, parentId: item.id } })
},
mine: async (item, args, { me, models }) => {
return me?.id === item.userId
@ -847,20 +847,6 @@ const createItem = async (parent, { title, url, text, boost, parentId }, { me, m
throw new UserInputError(`boost must be at least ${BOOST_MIN}`, { argumentName: 'boost' })
}
// check if they've already commented on this parent ... don't allow it if so
if (parentId) {
const existingComment = await models.item.findFirst({
where: {
parentId: Number(parentId),
userId: me.id
}
})
if (existingComment) {
throw new UserInputError("you've already commented on this item")
}
}
const [item] = await serialize(models,
models.$queryRaw(`${SELECT} FROM create_item($1, $2, $3, $4, $5, $6) AS "Item"`,
title, url, text, Number(boost || 0), Number(parentId), Number(me.id)))

View File

@ -174,7 +174,7 @@ export default function Comment ({
<div className={`${styles.children}`}>
{!noReply &&
<Reply
parentId={item.id} replyOpen={replyOpen}
parentId={item.id} meComments={item.meComments} replyOpen={replyOpen}
/>}
{children}
<div className={`${styles.comments} ml-sm-1 ml-md-3`}>

View File

@ -29,7 +29,7 @@ function BioItem ({ item, handleClick }) {
>edit bio
</Button>
</div>}
<Reply parentId={item.id} />
<Reply parentId={item.id} meComments={item.meComments} />
</>
)
}
@ -86,7 +86,7 @@ function TopLevelItem ({ item, noReply, ...props }) {
<ItemComponent item={item} {...props}>
{item.text && <ItemText item={item} />}
{item.url && <ItemEmbed item={item} />}
{!noReply && <Reply parentId={item.id} replyOpen />}
{!noReply && <Reply parentId={item.id} meComments={item.meComments} replyOpen />}
</ItemComponent>
)
}

View File

@ -12,7 +12,7 @@ export const CommentSchema = Yup.object({
text: Yup.string().required('required').trim()
})
export default function Reply ({ parentId, onSuccess, replyOpen }) {
export default function Reply ({ parentId, meComments, onSuccess, replyOpen }) {
const [reply, setReply] = useState(replyOpen)
const me = useMe()
@ -45,6 +45,9 @@ export default function Reply ({ parentId, onSuccess, replyOpen }) {
},
ncomments (existingNComments = 0) {
return existingNComments + 1
},
meComments (existingMeComments = 0) {
return existingMeComments + 1
}
}
})
@ -52,6 +55,8 @@ export default function Reply ({ parentId, onSuccess, replyOpen }) {
}
)
const cost = me?.freeComments ? 0 : Math.pow(10, meComments)
return (
<div>
{replyOpen
@ -87,8 +92,8 @@ export default function Reply ({ parentId, onSuccess, replyOpen }) {
required
hint={me?.freeComments ? <span className='text-success'>{me.freeComments} free comments left</span> : null}
/>
<ActionTooltip>
<SubmitButton variant='secondary' className='mt-1'>reply</SubmitButton>
<ActionTooltip overlayText={`${cost} sats`}>
<SubmitButton variant='secondary' className='mt-1'>reply{cost > 1 && <small> {cost} sats</small>}</SubmitButton>
</ActionTooltip>
</Form>
</div>

View File

@ -14,6 +14,7 @@ export const COMMENT_FIELDS = gql`
upvotes
boost
meSats
meComments
mine
ncomments
root {

View File

@ -83,6 +83,7 @@ export const ITEM_FULL = gql`
item(id: $id) {
...ItemFields
prior
meComments
position
text
comments {
@ -97,6 +98,7 @@ export const ITEM_WITH_COMMENTS = gql`
fragment ItemWithComments on Item {
...ItemFields
text
meComments
comments {
...CommentsRecursive
}

View File

@ -0,0 +1,48 @@
CREATE OR REPLACE FUNCTION create_item(title TEXT, url TEXT, text TEXT, boost INTEGER, parent_id INTEGER, user_id INTEGER)
RETURNS "Item"
LANGUAGE plpgsql
AS $$
DECLARE
user_msats INTEGER;
cost INTEGER;
free_posts INTEGER;
free_comments INTEGER;
freebie BOOLEAN;
item "Item";
BEGIN
PERFORM ASSERT_SERIALIZED();
SELECT msats, "freePosts", "freeComments"
INTO user_msats, free_posts, free_comments
FROM users WHERE id = user_id;
freebie := (parent_id IS NULL AND free_posts > 0) OR (parent_id IS NOT NULL AND free_comments > 0);
SELECT 1000 * POWER(10, COUNT(*)) INTO cost FROM "Item" WHERE "parentId" = parent_id AND "userId" = user_id;
IF NOT freebie AND cost > user_msats THEN
RAISE EXCEPTION 'SN_INSUFFICIENT_FUNDS';
END IF;
INSERT INTO "Item" (title, url, text, "userId", "parentId", created_at, updated_at)
VALUES (title, url, text, user_id, parent_id, now_utc(), now_utc()) RETURNING * INTO item;
IF freebie THEN
IF parent_id IS NULL THEN
UPDATE users SET "freePosts" = "freePosts" - 1 WHERE id = user_id;
ELSE
UPDATE users SET "freeComments" = "freeComments" - 1 WHERE id = user_id;
END IF;
ELSE
UPDATE users SET msats = msats - cost WHERE id = user_id;
INSERT INTO "ItemAct" (sats, "itemId", "userId", act, created_at, updated_at)
VALUES (cost / 1000, item.id, user_id, 'VOTE', now_utc(), now_utc());
END IF;
IF boost > 0 THEN
PERFORM item_act(item.id, user_id, 'BOOST', boost);
END IF;
RETURN item;
END;
$$;