improve bounty performance
This commit is contained in:
parent
e13e37744e
commit
5306b11157
|
@ -920,27 +920,6 @@ export default {
|
|||
|
||||
return (msats && msatsToSats(msats)) || 0
|
||||
},
|
||||
bountyPaid: async (item, args, { models }) => {
|
||||
if (!item.bounty) {
|
||||
return null
|
||||
}
|
||||
|
||||
// if there's a child where the OP paid the amount, but it isn't the OP's own comment
|
||||
const paid = await models.$queryRaw`
|
||||
-- Sum up the sats and if they are greater than or equal to item.bounty than return true, else return false
|
||||
SELECT "Item"."id"
|
||||
FROM "ItemAct"
|
||||
JOIN "Item" ON "ItemAct"."itemId" = "Item"."id"
|
||||
WHERE "ItemAct"."userId" = ${item.userId}
|
||||
AND "Item".path <@ text2ltree (${item.path})
|
||||
AND "Item"."userId" <> ${item.userId}
|
||||
AND act IN ('TIP', 'FEE')
|
||||
GROUP BY "Item"."id"
|
||||
HAVING coalesce(sum("ItemAct"."msats"), 0) >= ${item.bounty * 1000}
|
||||
`
|
||||
|
||||
return paid.length > 0
|
||||
},
|
||||
bountyPaidTo: async (item, args, { models }) => {
|
||||
if (!item.bounty) {
|
||||
return []
|
||||
|
@ -951,7 +930,7 @@ export default {
|
|||
FROM "ItemAct"
|
||||
JOIN "Item" ON "ItemAct"."itemId" = "Item"."id"
|
||||
WHERE "ItemAct"."userId" = ${item.userId}
|
||||
AND "Item".path <@ text2ltree (${item.path})
|
||||
AND "Item"."rootId" = ${item.id}
|
||||
AND "Item"."userId" <> ${item.userId}
|
||||
AND act IN ('TIP', 'FEE')
|
||||
GROUP BY "Item"."id"
|
||||
|
@ -990,13 +969,7 @@ export default {
|
|||
if (!item.parentId) {
|
||||
return null
|
||||
}
|
||||
return (await models.$queryRaw(`
|
||||
${SELECT}
|
||||
FROM "Item"
|
||||
WHERE id = (
|
||||
SELECT ltree2text(subltree(path, 0, 1))::integer
|
||||
FROM "Item"
|
||||
WHERE id = $1)`, Number(item.id)))[0]
|
||||
return await models.item.findUnique({ where: { id: item.rootId } })
|
||||
},
|
||||
parent: async (item, args, { models }) => {
|
||||
if (!item.parentId) {
|
||||
|
@ -1160,7 +1133,8 @@ function nestComments (flat, parentId) {
|
|||
// we have to do our own query because ltree is unsupported
|
||||
export const SELECT =
|
||||
`SELECT "Item".id, "Item".created_at as "createdAt", "Item".updated_at as "updatedAt", "Item".title,
|
||||
"Item".text, "Item".url, "Item"."bounty", "Item"."userId", "Item"."fwdUserId", "Item"."parentId", "Item"."pinId", "Item"."maxBid",
|
||||
"Item".text, "Item".url, "Item"."bounty", "Item"."userId", "Item"."fwdUserId", "Item"."parentId",
|
||||
"Item"."pinId", "Item"."maxBid", "Item"."rootId",
|
||||
"Item".company, "Item".location, "Item".remote, "Item"."deletedAt",
|
||||
"Item"."subName", "Item".status, "Item"."uploadId", "Item"."pollCost",
|
||||
"Item".msats, "Item".ncomments, "Item"."commentMsats", "Item"."lastCommentAt", "Item"."weightedVotes",
|
||||
|
|
|
@ -90,7 +90,6 @@ export default gql`
|
|||
mine: Boolean!
|
||||
boost: Int!
|
||||
bounty: Int
|
||||
bountyPaid: Boolean
|
||||
bountyPaidTo: [Int]!
|
||||
sats: Int!
|
||||
commentSats: Int!
|
||||
|
|
|
@ -101,7 +101,7 @@ function TopLevelItem ({ item, noReply, ...props }) {
|
|||
{item.poll && <Poll item={item} />}
|
||||
{item.bounty &&
|
||||
<div className='font-weight-bold mt-2 mb-3'>
|
||||
{item.bountyPaid
|
||||
{item.bountyPaidTo?.length
|
||||
? (
|
||||
<div className='px-3 py-1 d-inline-block bg-grey-medium rounded text-success'>
|
||||
<Check className='fill-success' /> {item.bounty} sats paid
|
||||
|
|
|
@ -78,8 +78,8 @@ export default function Item ({ item, rank, showFwdUser, toc, children }) {
|
|||
{item.pollCost && <span> <PollIcon className='fill-grey vertical-align-baseline' height={14} width={14} /></span>}
|
||||
{item.bounty > 0 &&
|
||||
<span>
|
||||
<ActionTooltip notForm overlayText={`${abbrNum(item.bounty)} ${item.bountyPaid ? 'sats paid' : 'sats bounty'}`}>
|
||||
<BountyIcon className={`${styles.bountyIcon} ${item.bountyPaid ? 'fill-success vertical-align-middle' : 'fill-grey vertical-align-middle'}`} height={16} width={16} />
|
||||
<ActionTooltip notForm overlayText={`${abbrNum(item.bounty)} ${item.bountyPaidTo?.length ? 'sats paid' : 'sats bounty'}`}>
|
||||
<BountyIcon className={`${styles.bountyIcon} ${item.bountyPaidTo?.length ? 'fill-success vertical-align-middle' : 'fill-grey vertical-align-middle'}`} height={16} width={16} />
|
||||
</ActionTooltip>
|
||||
</span>}
|
||||
</a>
|
||||
|
|
|
@ -50,9 +50,6 @@ export default function PayBounty ({ children, item }) {
|
|||
cache.modify({
|
||||
id: `Item:${item.root.id}`,
|
||||
fields: {
|
||||
bountyPaid () {
|
||||
return true
|
||||
},
|
||||
bountyPaidTo (existingPaidTo = []) {
|
||||
return [...existingPaidTo, Number(item.id)]
|
||||
}
|
||||
|
@ -84,7 +81,7 @@ export default function PayBounty ({ children, item }) {
|
|||
}
|
||||
}
|
||||
|
||||
if (!me || item.root.user.name !== me.name || item.mine || item.root.bountyPaid) {
|
||||
if (item.mine || item.root.user.name !== me.name) {
|
||||
return null
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ export const ITEM_FIELDS = gql`
|
|||
upvotes
|
||||
boost
|
||||
bounty
|
||||
bountyPaid
|
||||
bountyPaidTo
|
||||
path
|
||||
meSats
|
||||
meDontLike
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
-- AlterTable
|
||||
ALTER TABLE "Item" ADD COLUMN "rootId" INTEGER;
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Item.rootId_index" ON "Item"("rootId");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Item" ADD FOREIGN KEY ("rootId") REFERENCES "Item"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
@ -0,0 +1,28 @@
|
|||
-- Store root ids of all existing items
|
||||
UPDATE "Item"
|
||||
SET "rootId" = ltree2text(subltree(path, 0, 1))::integer
|
||||
WHERE "parentId" IS NOT NULL;
|
||||
|
||||
CREATE OR REPLACE FUNCTION update_item_path() RETURNS TRIGGER AS $$
|
||||
DECLARE
|
||||
npath ltree;
|
||||
root_id INTEGER;
|
||||
BEGIN
|
||||
IF NEW."parentId" IS NULL THEN
|
||||
SELECT NEW.id::text::ltree INTO npath;
|
||||
NEW."path" = npath;
|
||||
ELSEIF TG_OP = 'INSERT' OR OLD."parentId" IS NULL OR OLD."parentId" != NEW."parentId" THEN
|
||||
SELECT "path" || NEW.id::text, ltree2text(subltree("path", 0, 1))::integer
|
||||
FROM "Item"
|
||||
WHERE id = NEW."parentId"
|
||||
INTO npath, root_id;
|
||||
|
||||
IF npath IS NULL THEN
|
||||
RAISE EXCEPTION 'Invalid parent_id %', NEW."parentId";
|
||||
END IF;
|
||||
NEW."path" = npath;
|
||||
NEW."rootId" = root_id;
|
||||
END IF;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
|
@ -222,6 +222,9 @@ model Item {
|
|||
parent Item? @relation("ParentChildren", fields: [parentId], references: [id])
|
||||
parentId Int?
|
||||
children Item[] @relation("ParentChildren")
|
||||
root Item? @relation("RootDescendant", fields: [rootId], references: [id])
|
||||
rootId Int?
|
||||
descendants Item[] @relation("RootDescendant")
|
||||
actions ItemAct[]
|
||||
mentions Mention[]
|
||||
path Unsupported("LTREE")?
|
||||
|
@ -280,6 +283,7 @@ model Item {
|
|||
@@index([freebie])
|
||||
@@index([createdAt])
|
||||
@@index([userId])
|
||||
@@index([rootId])
|
||||
@@index([parentId])
|
||||
@@index([status])
|
||||
@@index([maxBid])
|
||||
|
|
Loading…
Reference in New Issue