tips WIP
This commit is contained in:
parent
28d684da73
commit
93428e3183
@ -209,7 +209,7 @@ export default {
|
||||
|
||||
return await updateItem(parent, { id, data: { text } }, { me, models })
|
||||
},
|
||||
vote: async (parent, { id, sats = 1 }, { me, models }) => {
|
||||
act: async (parent, { id, act, sats }, { me, models }) => {
|
||||
// need to make sure we are logged in
|
||||
if (!me) {
|
||||
throw new AuthenticationError('you must be logged in')
|
||||
@ -219,7 +219,7 @@ export default {
|
||||
throw new UserInputError('sats must be positive', { argumentName: 'sats' })
|
||||
}
|
||||
|
||||
await serialize(models, models.$queryRaw`SELECT vote(${Number(id)}, ${me.name}, ${Number(sats)})`)
|
||||
await serialize(models, models.$queryRaw`SELECT item_act(${Number(id)}, ${me.id}, ${act}, ${Number(sats)})`)
|
||||
return sats
|
||||
}
|
||||
},
|
||||
@ -235,26 +235,26 @@ export default {
|
||||
return count || 0
|
||||
},
|
||||
sats: async (item, args, { models }) => {
|
||||
const { sum: { sats } } = await models.vote.aggregate({
|
||||
const { sum: { sats } } = await models.itemAct.aggregate({
|
||||
sum: {
|
||||
sats: true
|
||||
},
|
||||
where: {
|
||||
itemId: item.id,
|
||||
boost: false
|
||||
act: 'VOTE'
|
||||
}
|
||||
})
|
||||
|
||||
return sats || 0
|
||||
},
|
||||
boost: async (item, args, { models }) => {
|
||||
const { sum: { sats } } = await models.vote.aggregate({
|
||||
const { sum: { sats } } = await models.itemAct.aggregate({
|
||||
sum: {
|
||||
sats: true
|
||||
},
|
||||
where: {
|
||||
itemId: item.id,
|
||||
boost: true
|
||||
act: 'BOOST'
|
||||
}
|
||||
})
|
||||
|
||||
@ -263,13 +263,14 @@ export default {
|
||||
meSats: async (item, args, { me, models }) => {
|
||||
if (!me) return 0
|
||||
|
||||
const { sum: { sats } } = await models.vote.aggregate({
|
||||
const { sum: { sats } } = await models.itemAct.aggregate({
|
||||
sum: {
|
||||
sats: true
|
||||
},
|
||||
where: {
|
||||
itemId: item.id,
|
||||
userId: me.id
|
||||
userId: me.id,
|
||||
act: 'VOTE'
|
||||
}
|
||||
})
|
||||
|
||||
@ -353,7 +354,7 @@ const createItem = async (parent, { title, url, text, parentId }, { me, models }
|
||||
|
||||
const [item] = await serialize(models, models.$queryRaw(
|
||||
`${SELECT} FROM create_item($1, $2, $3, $4, $5) AS "Item"`,
|
||||
title, url, text, Number(parentId), me.name))
|
||||
title, url, text, Number(parentId), me.id))
|
||||
|
||||
await createMentions(item, models)
|
||||
|
||||
@ -391,19 +392,19 @@ const SELECT =
|
||||
`SELECT "Item".id, "Item".created_at as "createdAt", "Item".updated_at as "updatedAt", "Item".title,
|
||||
"Item".text, "Item".url, "Item"."userId", "Item"."parentId", ltree2text("Item"."path") AS "path"`
|
||||
|
||||
const LEFT_JOIN_SATS_SELECT = 'SELECT i.id, SUM(CASE WHEN "Vote".boost THEN 0 ELSE "Vote".sats END) as sats, SUM(CASE WHEN "Vote".boost THEN "Vote".sats ELSE 0 END) as boost'
|
||||
const LEFT_JOIN_SATS_SELECT = 'SELECT i.id, SUM(CASE WHEN "ItemAct".act = \'VOTE\' THEN "ItemAct".sats ELSE 0 END) as sats, SUM(CASE WHEN "ItemAct".act = \'BOOST\' THEN "ItemAct".sats ELSE 0 END) as boost'
|
||||
|
||||
function timedLeftJoinSats (num) {
|
||||
return `LEFT JOIN (${LEFT_JOIN_SATS_SELECT}
|
||||
FROM "Item" i
|
||||
JOIN "Vote" ON i.id = "Vote"."itemId" AND "Vote".created_at <= $${num}
|
||||
JOIN "ItemAct" ON i.id = "ItemAct"."itemId" AND "ItemAct".created_at <= $${num}
|
||||
GROUP BY i.id) x ON "Item".id = x.id`
|
||||
}
|
||||
|
||||
const LEFT_JOIN_SATS =
|
||||
`LEFT JOIN (${LEFT_JOIN_SATS_SELECT}
|
||||
FROM "Item" i
|
||||
JOIN "Vote" ON i.id = "Vote"."itemId"
|
||||
JOIN "ItemAct" ON i.id = "ItemAct"."itemId"
|
||||
GROUP BY i.id) x ON "Item".id = x.id`
|
||||
|
||||
function timedOrderBySats (num) {
|
||||
|
@ -53,14 +53,14 @@ export default {
|
||||
(SELECT ${ITEM_SUBQUERY_FIELDS}, max(subquery.voted_at) as "sortTime",
|
||||
sum(subquery.sats) as "earnedSats", false as mention
|
||||
FROM
|
||||
(SELECT ${ITEM_FIELDS}, "Vote".created_at as voted_at, "Vote".sats,
|
||||
ROW_NUMBER() OVER(ORDER BY "Vote".created_at) -
|
||||
ROW_NUMBER() OVER(PARTITION BY "Item".id ORDER BY "Vote".created_at) as island
|
||||
FROM "Vote"
|
||||
JOIN "Item" on "Vote"."itemId" = "Item".id
|
||||
WHERE "Vote"."userId" <> $1
|
||||
AND "Vote".created_at <= $2
|
||||
AND "Vote".boost = false
|
||||
(SELECT ${ITEM_FIELDS}, "ItemAct".created_at as voted_at, "ItemAct".sats,
|
||||
ROW_NUMBER() OVER(ORDER BY "ItemAct".created_at) -
|
||||
ROW_NUMBER() OVER(PARTITION BY "Item".id ORDER BY "ItemAct".created_at) as island
|
||||
FROM "ItemAct"
|
||||
JOIN "Item" on "ItemAct"."itemId" = "Item".id
|
||||
WHERE "ItemAct"."userId" <> $1
|
||||
AND "ItemAct".created_at <= $2
|
||||
AND "ItemAct".act <> 'BOOST'
|
||||
AND "Item"."userId" = $1) subquery
|
||||
GROUP BY ${ITEM_SUBQUERY_FIELDS}, subquery.island ORDER BY max(subquery.voted_at) desc)
|
||||
UNION ALL
|
||||
|
@ -44,10 +44,10 @@ export default {
|
||||
},
|
||||
stacked: async (user, args, { models }) => {
|
||||
const [{ sum }] = await models.$queryRaw`
|
||||
SELECT sum("Vote".sats)
|
||||
FROM "Vote"
|
||||
JOIN "Item" on "Vote"."itemId" = "Item".id
|
||||
WHERE "Vote"."userId" <> ${user.id} AND boost = false
|
||||
SELECT sum("ItemAct".sats)
|
||||
FROM "ItemAct"
|
||||
JOIN "Item" on "ItemAct"."itemId" = "Item".id
|
||||
WHERE "ItemAct"."userId" <> ${user.id} AND "ItemAct".act <> 'BOOST'
|
||||
AND "Item"."userId" = ${user.id}`
|
||||
return sum || 0
|
||||
},
|
||||
@ -57,12 +57,12 @@ export default {
|
||||
hasNewNotes: async (user, args, { models }) => {
|
||||
// check if any votes have been cast for them since checkedNotesAt
|
||||
const votes = await models.$queryRaw(`
|
||||
SELECT "Vote".id, "Vote".created_at
|
||||
FROM "Vote"
|
||||
JOIN "Item" on "Vote"."itemId" = "Item".id
|
||||
WHERE "Vote"."userId" <> $1
|
||||
AND ("Vote".created_at > $2 OR $2 IS NULL)
|
||||
AND "Vote".boost = false
|
||||
SELECT "ItemAct".id, "ItemAct".created_at
|
||||
FROM "ItemAct"
|
||||
JOIN "Item" on "ItemAct"."itemId" = "Item".id
|
||||
WHERE "ItemAct"."userId" <> $1
|
||||
AND ("ItemAct".created_at > $2 OR $2 IS NULL)
|
||||
AND "ItemAct".act <> 'BOOST'
|
||||
AND "Item"."userId" = $1
|
||||
LIMIT 1`, user.id, user.checkedNotesAt)
|
||||
if (votes.length > 0) {
|
||||
|
@ -16,7 +16,7 @@ export default gql`
|
||||
updateDiscussion(id: ID!, title: String!, text: String): Item!
|
||||
createComment(text: String!, parentId: ID!): Item!
|
||||
updateComment(id: ID!, text: String!): Item!
|
||||
vote(id: ID!, sats: Int): Int!
|
||||
act(id: ID!, act: String!, sats: Int): Int!
|
||||
}
|
||||
|
||||
type Items {
|
||||
|
@ -9,18 +9,18 @@ import ActionTooltip from './action-tooltip'
|
||||
export default function UpVote ({ itemId, meSats, className }) {
|
||||
const [session] = useSession()
|
||||
const { setError } = useFundError()
|
||||
const [vote] = useMutation(
|
||||
const [act] = useMutation(
|
||||
gql`
|
||||
mutation vote($id: ID!, $sats: Int!) {
|
||||
vote(id: $id, sats: $sats)
|
||||
mutation act($id: ID!, $sats: Int!) {
|
||||
act(id: $id, act: 'VOTE', sats: $sats)
|
||||
}`, {
|
||||
update (cache, { data: { vote } }) {
|
||||
update (cache, { data: { act } }) {
|
||||
// read in the cached object so we don't use meSats prop
|
||||
// which can be stale
|
||||
const item = cache.readFragment({
|
||||
id: `Item:${itemId}`,
|
||||
fragment: gql`
|
||||
fragment votedItem on Item {
|
||||
fragment actedItem on Item {
|
||||
meSats
|
||||
}
|
||||
`
|
||||
@ -29,13 +29,13 @@ export default function UpVote ({ itemId, meSats, className }) {
|
||||
id: `Item:${itemId}`,
|
||||
fields: {
|
||||
meSats (existingMeSats = 0) {
|
||||
return existingMeSats + vote
|
||||
return existingMeSats + act
|
||||
},
|
||||
sats (existingSats = 0) {
|
||||
return item.meSats === 0 ? existingSats + vote : existingSats
|
||||
return item.meSats === 0 ? existingSats + act : existingSats
|
||||
},
|
||||
boost (existingBoost = 0) {
|
||||
return item.meSats >= 1 ? existingBoost + vote : existingBoost
|
||||
return item.meSats >= 1 ? existingBoost + act : existingBoost
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -62,7 +62,7 @@ export default function UpVote ({ itemId, meSats, className }) {
|
||||
strike()
|
||||
if (!itemId) return
|
||||
try {
|
||||
await vote({ variables: { id: itemId, sats: 1 } })
|
||||
await act({ variables: { id: itemId, sats: 1 } })
|
||||
} catch (error) {
|
||||
if (error.toString().includes('insufficient funds')) {
|
||||
setError(true)
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
*/
|
||||
-- CreateEnum
|
||||
CREATE TYPE "ItemAct" AS ENUM ('VOTE', 'BOOST', 'TIP');
|
||||
CREATE TYPE "ItemActType" AS ENUM ('VOTE', 'BOOST', 'TIP');
|
||||
|
||||
-- DropForeignKey
|
||||
ALTER TABLE "Vote" DROP CONSTRAINT "Vote_itemId_fkey";
|
||||
|
@ -11,24 +11,24 @@ generator client {
|
||||
}
|
||||
|
||||
model User {
|
||||
id Int @id @default(autoincrement())
|
||||
createdAt DateTime @default(now()) @map(name: "created_at")
|
||||
updatedAt DateTime @default(now()) @updatedAt @map(name: "updated_at")
|
||||
name String? @unique @db.Citext
|
||||
email String? @unique
|
||||
emailVerified DateTime? @map(name: "email_verified")
|
||||
id Int @id @default(autoincrement())
|
||||
createdAt DateTime @default(now()) @map(name: "created_at")
|
||||
updatedAt DateTime @default(now()) @updatedAt @map(name: "updated_at")
|
||||
name String? @unique @db.Citext
|
||||
email String? @unique
|
||||
emailVerified DateTime? @map(name: "email_verified")
|
||||
image String?
|
||||
items Item[]
|
||||
mentions Mention[]
|
||||
messages Message[]
|
||||
itemActions ItemAction[]
|
||||
itemActions ItemAct[]
|
||||
invoices Invoice[]
|
||||
withdrawls Withdrawl[]
|
||||
msats Int @default(0)
|
||||
freeComments Int @default(5)
|
||||
freePosts Int @default(2)
|
||||
msats Int @default(0)
|
||||
freeComments Int @default(5)
|
||||
freePosts Int @default(2)
|
||||
checkedNotesAt DateTime?
|
||||
pubkey String? @unique
|
||||
pubkey String? @unique
|
||||
|
||||
@@map(name: "users")
|
||||
}
|
||||
@ -60,7 +60,7 @@ model Item {
|
||||
parent Item? @relation("ParentChildren", fields: [parentId], references: [id])
|
||||
parentId Int?
|
||||
children Item[] @relation("ParentChildren")
|
||||
actions ItemAction[]
|
||||
actions ItemAct[]
|
||||
mentions Mention[]
|
||||
path Unsupported("LTREE")?
|
||||
|
||||
@ -68,26 +68,26 @@ model Item {
|
||||
@@index([parentId])
|
||||
}
|
||||
|
||||
enum ItemActionType {
|
||||
enum ItemActType {
|
||||
VOTE
|
||||
BOOST
|
||||
TIP
|
||||
}
|
||||
|
||||
model ItemAction {
|
||||
id Int @id @default(autoincrement())
|
||||
createdAt DateTime @default(now()) @map(name: "created_at")
|
||||
updatedAt DateTime @updatedAt @map(name: "updated_at")
|
||||
sats Int @default(1)
|
||||
action ItemActionType @default(VOTE)
|
||||
item Item @relation(fields: [itemId], references: [id])
|
||||
model ItemAct {
|
||||
id Int @id @default(autoincrement())
|
||||
createdAt DateTime @default(now()) @map(name: "created_at")
|
||||
updatedAt DateTime @updatedAt @map(name: "updated_at")
|
||||
sats Int
|
||||
act ItemActType
|
||||
item Item @relation(fields: [itemId], references: [id])
|
||||
itemId Int
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
userId Int
|
||||
|
||||
@@index([itemId])
|
||||
@@index([userId])
|
||||
@@index([action])
|
||||
@@index([act])
|
||||
}
|
||||
|
||||
model Mention {
|
||||
|
Loading…
x
Reference in New Issue
Block a user