stacker.news/api/resolvers/user.js

199 lines
6.2 KiB
JavaScript
Raw Normal View History

2021-05-22 00:09:11 +00:00
import { AuthenticationError, UserInputError } from 'apollo-server-errors'
2021-12-17 00:01:02 +00:00
import { decodeCursor, LIMIT, nextCursorEncoded } from '../../lib/cursor'
2021-09-23 17:42:00 +00:00
import { createMentions, getItem, SELECT } from './item'
import serialize from './serial'
2021-12-17 00:01:02 +00:00
export function topClause (within) {
let interval = ' AND "ItemAct".created_at >= $1 - INTERVAL '
switch (within) {
case 'day':
interval += "'1 day'"
break
case 'week':
interval += "'7 days'"
break
case 'month':
interval += "'1 month'"
break
case 'year':
interval += "'1 year'"
break
default:
interval = ''
break
}
return interval
}
2021-03-25 19:29:24 +00:00
export default {
Query: {
me: async (parent, args, { models, me }) =>
2021-06-27 03:09:39 +00:00
me ? await models.user.findUnique({ where: { id: me.id } }) : null,
2021-04-22 22:14:32 +00:00
user: async (parent, { name }, { models }) => {
return await models.user.findUnique({ where: { name } })
},
2021-03-25 19:29:24 +00:00
users: async (parent, args, { models }) =>
2021-05-21 22:32:21 +00:00
await models.user.findMany(),
nameAvailable: async (parent, { name }, { models, me }) => {
if (!me) {
throw new AuthenticationError('you must be logged in')
}
2021-09-02 22:22:00 +00:00
return me.name?.toUpperCase() === name?.toUpperCase() || !(await models.user.findUnique({ where: { name } }))
2021-12-17 00:01:02 +00:00
},
topUsers: async (parent, { cursor, within }, { models, me }) => {
const decodedCursor = decodeCursor(cursor)
const users = await models.$queryRaw(`
SELECT users.name, users.created_at, sum("ItemAct".sats) as stacked
FROM "ItemAct"
JOIN "Item" on "ItemAct"."itemId" = "Item".id
JOIN users on "Item"."userId" = users.id
WHERE act <> 'BOOST' AND "ItemAct".created_at <= $1
${topClause(within)}
GROUP BY users.id, users.name
ORDER BY stacked DESC NULLS LAST, users.created_at DESC
OFFSET $2
LIMIT ${LIMIT}`, decodedCursor.time, decodedCursor.offset)
return {
cursor: users.length === LIMIT ? nextCursorEncoded(decodedCursor) : null,
users
}
2021-05-21 22:32:21 +00:00
}
2021-03-25 19:29:24 +00:00
},
2021-05-22 00:09:11 +00:00
Mutation: {
setName: async (parent, { name }, { me, models }) => {
if (!me) {
throw new AuthenticationError('you must be logged in')
}
try {
2021-06-27 03:09:39 +00:00
await models.user.update({ where: { id: me.id }, data: { name } })
2021-05-22 00:09:11 +00:00
} catch (error) {
if (error.code === 'P2002') {
throw new UserInputError('name taken')
}
throw error
}
2021-09-23 17:42:00 +00:00
},
2021-10-30 16:20:11 +00:00
setSettings: async (parent, { tipDefault }, { me, models }) => {
if (!me) {
throw new AuthenticationError('you must be logged in')
}
await models.user.update({ where: { id: me.id }, data: { tipDefault } })
return true
},
2021-12-09 20:40:40 +00:00
setWalkthrough: async (parent, { upvotePopover, tipPopover }, { me, models }) => {
if (!me) {
throw new AuthenticationError('you must be logged in')
}
await models.user.update({ where: { id: me.id }, data: { upvotePopover, tipPopover } })
return true
},
2021-09-24 21:28:21 +00:00
upsertBio: async (parent, { bio }, { me, models }) => {
if (!me) {
throw new AuthenticationError('you must be logged in')
}
const user = await models.user.findUnique({ where: { id: me.id } })
let item
if (user.bioId) {
item = await models.item.update({
where: { id: Number(user.bioId) },
data: {
text: bio
}
})
} else {
([item] = await serialize(models,
models.$queryRaw(`${SELECT} FROM create_bio($1, $2, $3) AS "Item"`,
`@${me.name}'s bio`, bio, Number(me.id))))
}
await createMentions(item, models)
return await models.user.findUnique({ where: { id: me.id } })
}
2021-05-22 00:09:11 +00:00
},
2021-03-25 19:29:24 +00:00
User: {
2021-04-22 22:14:32 +00:00
nitems: async (user, args, { models }) => {
return await models.item.count({ where: { userId: user.id, parentId: null } })
},
ncomments: async (user, args, { models }) => {
return await models.item.count({ where: { userId: user.id, parentId: { not: null } } })
},
2021-04-27 21:30:58 +00:00
stacked: async (user, args, { models }) => {
2021-12-17 00:01:02 +00:00
if (user.stacked) {
return user.stacked
}
2021-04-27 21:30:58 +00:00
const [{ sum }] = await models.$queryRaw`
2021-09-08 21:51:23 +00:00
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}`
2021-05-11 15:52:50 +00:00
return sum || 0
2021-04-27 21:30:58 +00:00
},
sats: async (user, args, { models, me }) => {
if (me?.id !== user.id) {
return 0
}
2021-05-11 15:52:50 +00:00
return Math.floor(user.msats / 1000)
2021-06-24 23:56:01 +00:00
},
2021-09-23 17:42:00 +00:00
bio: async (user, args, { models }) => {
return getItem(user, { id: user.bioId }, { models })
},
2021-10-15 23:07:51 +00:00
hasInvites: async (user, args, { models }) => {
const anInvite = await models.invite.findFirst({
where: { userId: user.id }
})
return !!anInvite
},
2021-06-24 23:56:01 +00:00
hasNewNotes: async (user, args, { models }) => {
// check if any votes have been cast for them since checkedNotesAt
const votes = await models.$queryRaw(`
2021-09-08 21:51:23 +00:00
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
2021-06-24 23:56:01 +00:00
LIMIT 1`, user.id, user.checkedNotesAt)
if (votes.length > 0) {
return true
}
// check if they have any replies since checkedNotesAt
const newReplies = await models.$queryRaw(`
SELECT "Item".id, "Item".created_at
From "Item"
JOIN "Item" p ON "Item"."parentId" = p.id
WHERE p."userId" = $1
2021-06-24 23:56:01 +00:00
AND ("Item".created_at > $2 OR $2 IS NULL) AND "Item"."userId" <> $1
LIMIT 1`, user.id, user.checkedNotesAt)
2021-08-18 23:00:54 +00:00
if (newReplies.length > 0) {
return true
}
// check if they have any mentions since checkedNotesAt
const newMentions = await models.$queryRaw(`
SELECT "Item".id, "Item".created_at
From "Mention"
JOIN "Item" ON "Mention"."itemId" = "Item".id
WHERE "Mention"."userId" = $1
AND ("Mention".created_at > $2 OR $2 IS NULL)
AND "Item"."userId" <> $1
LIMIT 1`, user.id, user.checkedNotesAt)
return newMentions.length > 0
2021-05-11 15:52:50 +00:00
}
2021-03-25 19:29:24 +00:00
}
}