From 89fb68f746f425ba24324bf2d3f4a7cb4cff5df5 Mon Sep 17 00:00:00 2001 From: keyan Date: Sun, 17 Apr 2022 08:13:52 -0500 Subject: [PATCH] multiple comments with the same parent are exp in cost --- api/resolvers/item.js | 16 +------ components/comment.js | 2 +- components/item-full.js | 4 +- components/reply.js | 11 +++-- fragments/comments.js | 1 + fragments/items.js | 2 + .../20220415193617_exp_comments/migration.sql | 48 +++++++++++++++++++ 7 files changed, 63 insertions(+), 21 deletions(-) create mode 100644 prisma/migrations/20220415193617_exp_comments/migration.sql diff --git a/api/resolvers/item.js b/api/resolvers/item.js index e2d247e9..f85457e3 100644 --- a/api/resolvers/item.js +++ b/api/resolvers/item.js @@ -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))) diff --git a/components/comment.js b/components/comment.js index fc3c8f78..7619c4ae 100644 --- a/components/comment.js +++ b/components/comment.js @@ -174,7 +174,7 @@ export default function Comment ({
{!noReply && } {children}
diff --git a/components/item-full.js b/components/item-full.js index 3ecfd75c..5916dce9 100644 --- a/components/item-full.js +++ b/components/item-full.js @@ -29,7 +29,7 @@ function BioItem ({ item, handleClick }) { >edit bio
} - + ) } @@ -86,7 +86,7 @@ function TopLevelItem ({ item, noReply, ...props }) { {item.text && } {item.url && } - {!noReply && } + {!noReply && } ) } diff --git a/components/reply.js b/components/reply.js index b0fa6e20..eff66d56 100644 --- a/components/reply.js +++ b/components/reply.js @@ -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 (
{replyOpen @@ -87,8 +92,8 @@ export default function Reply ({ parentId, onSuccess, replyOpen }) { required hint={me?.freeComments ? {me.freeComments} free comments left : null} /> - - reply + + reply{cost > 1 && {cost} sats}
diff --git a/fragments/comments.js b/fragments/comments.js index 7798e2bf..9b162e5a 100644 --- a/fragments/comments.js +++ b/fragments/comments.js @@ -14,6 +14,7 @@ export const COMMENT_FIELDS = gql` upvotes boost meSats + meComments mine ncomments root { diff --git a/fragments/items.js b/fragments/items.js index 1ff4f5d6..f7d09828 100644 --- a/fragments/items.js +++ b/fragments/items.js @@ -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 } diff --git a/prisma/migrations/20220415193617_exp_comments/migration.sql b/prisma/migrations/20220415193617_exp_comments/migration.sql new file mode 100644 index 00000000..35531939 --- /dev/null +++ b/prisma/migrations/20220415193617_exp_comments/migration.sql @@ -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; +$$; \ No newline at end of file