poll for notifications less, don't retry gql
This commit is contained in:
parent
9431469453
commit
8de00c741d
|
@ -149,6 +149,118 @@ export default {
|
|||
users
|
||||
}
|
||||
},
|
||||
hasNewNotes: async (parent, args, { me, models }) => {
|
||||
if (!me) {
|
||||
return false
|
||||
}
|
||||
const user = await models.user.findUnique({ where: { id: me.id } })
|
||||
const lastChecked = user.checkedNotesAt || new Date(0)
|
||||
|
||||
// check if any votes have been cast for them since checkedNotesAt
|
||||
if (user.noteItemSats) {
|
||||
const votes = await models.$queryRaw(`
|
||||
SELECT "ItemAct".id, "ItemAct".created_at
|
||||
FROM "Item"
|
||||
JOIN "ItemAct" on "ItemAct"."itemId" = "Item".id
|
||||
WHERE "ItemAct"."userId" <> $1
|
||||
AND "ItemAct".created_at > $2
|
||||
AND "Item"."userId" = $1
|
||||
AND "ItemAct".act IN ('VOTE', 'TIP')
|
||||
LIMIT 1`, me.id, lastChecked)
|
||||
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 ${user.noteAllDescendants ? '"Item".path <@ p.path' : '"Item"."parentId" = p.id'}
|
||||
WHERE p."userId" = $1
|
||||
AND "Item".created_at > $2 AND "Item"."userId" <> $1
|
||||
${await filterClause(me, models)}
|
||||
LIMIT 1`, me.id, lastChecked)
|
||||
if (newReplies.length > 0) {
|
||||
return true
|
||||
}
|
||||
|
||||
// check if they have any mentions since checkedNotesAt
|
||||
if (user.noteMentions) {
|
||||
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
|
||||
AND "Item"."userId" <> $1
|
||||
LIMIT 1`, me.id, lastChecked)
|
||||
if (newMentions.length > 0) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
const job = await models.item.findFirst({
|
||||
where: {
|
||||
maxBid: {
|
||||
not: null
|
||||
},
|
||||
userId: me.id,
|
||||
statusUpdatedAt: {
|
||||
gt: lastChecked
|
||||
}
|
||||
}
|
||||
})
|
||||
if (job) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (user.noteEarning) {
|
||||
const earn = await models.earn.findFirst({
|
||||
where: {
|
||||
userId: me.id,
|
||||
createdAt: {
|
||||
gt: lastChecked
|
||||
},
|
||||
msats: {
|
||||
gte: 1000
|
||||
}
|
||||
}
|
||||
})
|
||||
if (earn) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
if (user.noteDeposits) {
|
||||
const invoice = await models.invoice.findFirst({
|
||||
where: {
|
||||
userId: me.id,
|
||||
confirmedAt: {
|
||||
gt: lastChecked
|
||||
}
|
||||
}
|
||||
})
|
||||
if (invoice) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// check if new invites have been redeemed
|
||||
if (user.noteInvites) {
|
||||
const newInvitees = await models.$queryRaw(`
|
||||
SELECT "Invite".id
|
||||
FROM users JOIN "Invite" on users."inviteId" = "Invite".id
|
||||
WHERE "Invite"."userId" = $1
|
||||
AND users.created_at > $2
|
||||
LIMIT 1`, me.id, lastChecked)
|
||||
if (newInvitees.length > 0) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
},
|
||||
searchUsers: async (parent, { q, limit, similarity }, { models }) => {
|
||||
return await models.$queryRaw`
|
||||
SELECT * FROM users where id > 615 AND SIMILARITY(name, ${q}) > ${Number(similarity) || 0.1} ORDER BY SIMILARITY(name, ${q}) DESC LIMIT ${Number(limit) || 5}`
|
||||
|
@ -362,114 +474,6 @@ export default {
|
|||
}).invites({ take: 1 })
|
||||
|
||||
return invites.length > 0
|
||||
},
|
||||
hasNewNotes: async (user, args, { me, models }) => {
|
||||
const lastChecked = user.checkedNotesAt || new Date(0)
|
||||
|
||||
// check if any votes have been cast for them since checkedNotesAt
|
||||
if (user.noteItemSats) {
|
||||
const votes = await models.$queryRaw(`
|
||||
SELECT "ItemAct".id, "ItemAct".created_at
|
||||
FROM "Item"
|
||||
JOIN "ItemAct" on "ItemAct"."itemId" = "Item".id
|
||||
WHERE "ItemAct"."userId" <> $1
|
||||
AND "ItemAct".created_at > $2
|
||||
AND "Item"."userId" = $1
|
||||
AND "ItemAct".act IN ('VOTE', 'TIP')
|
||||
LIMIT 1`, me.id, lastChecked)
|
||||
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 ${user.noteAllDescendants ? '"Item".path <@ p.path' : '"Item"."parentId" = p.id'}
|
||||
WHERE p."userId" = $1
|
||||
AND "Item".created_at > $2 AND "Item"."userId" <> $1
|
||||
${await filterClause(me, models)}
|
||||
LIMIT 1`, me.id, lastChecked)
|
||||
if (newReplies.length > 0) {
|
||||
return true
|
||||
}
|
||||
|
||||
// check if they have any mentions since checkedNotesAt
|
||||
if (user.noteMentions) {
|
||||
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
|
||||
AND "Item"."userId" <> $1
|
||||
LIMIT 1`, me.id, lastChecked)
|
||||
if (newMentions.length > 0) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
const job = await models.item.findFirst({
|
||||
where: {
|
||||
maxBid: {
|
||||
not: null
|
||||
},
|
||||
userId: me.id,
|
||||
statusUpdatedAt: {
|
||||
gt: lastChecked
|
||||
}
|
||||
}
|
||||
})
|
||||
if (job) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (user.noteEarning) {
|
||||
const earn = await models.earn.findFirst({
|
||||
where: {
|
||||
userId: me.id,
|
||||
createdAt: {
|
||||
gt: lastChecked
|
||||
},
|
||||
msats: {
|
||||
gte: 1000
|
||||
}
|
||||
}
|
||||
})
|
||||
if (earn) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
if (user.noteDeposits) {
|
||||
const invoice = await models.invoice.findFirst({
|
||||
where: {
|
||||
userId: me.id,
|
||||
confirmedAt: {
|
||||
gt: lastChecked
|
||||
}
|
||||
}
|
||||
})
|
||||
if (invoice) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// check if new invites have been redeemed
|
||||
if (user.noteInvites) {
|
||||
const newInvitees = await models.$queryRaw(`
|
||||
SELECT "Invite".id
|
||||
FROM users JOIN "Invite" on users."inviteId" = "Invite".id
|
||||
WHERE "Invite"."userId" = $1
|
||||
AND users.created_at > $2
|
||||
LIMIT 1`, me.id, lastChecked)
|
||||
if (newInvitees.length > 0) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import models from './models'
|
|||
import { print } from 'graphql'
|
||||
import lnd from './lnd'
|
||||
import search from './search'
|
||||
import { ME_SSR } from '../fragments/users'
|
||||
import { ME } from '../fragments/users'
|
||||
import { getPrice } from '../components/price'
|
||||
|
||||
export default async function getSSRApolloClient (req, me = null) {
|
||||
|
@ -40,7 +40,7 @@ export function getGetServerSideProps (query, variables = null, notFoundFunc, re
|
|||
const client = await getSSRApolloClient(req)
|
||||
|
||||
const { data: { me } } = await client.query({
|
||||
query: ME_SSR
|
||||
query: ME
|
||||
})
|
||||
|
||||
const price = await getPrice(me?.fiatCurrency)
|
||||
|
|
|
@ -9,6 +9,7 @@ export default gql`
|
|||
nameAvailable(name: String!): Boolean!
|
||||
topUsers(cursor: String, when: String, sort: String): Users
|
||||
searchUsers(q: String!, limit: Int, similarity: Float): [User!]!
|
||||
hasNewNotes: Boolean!
|
||||
}
|
||||
|
||||
type Users {
|
||||
|
@ -46,7 +47,6 @@ export default gql`
|
|||
spent(when: String): Int!
|
||||
freePosts: Int!
|
||||
freeComments: Int!
|
||||
hasNewNotes: Boolean!
|
||||
hasInvites: Boolean!
|
||||
tipDefault: Int!
|
||||
fiatCurrency: String!
|
||||
|
|
|
@ -35,7 +35,11 @@ export default function Header ({ sub }) {
|
|||
subLatestPost(name: $name)
|
||||
}
|
||||
`, { variables: { name: 'jobs' }, pollInterval: 600000, fetchPolicy: 'network-only' })
|
||||
|
||||
const { data: hasNewNotes } = useQuery(gql`
|
||||
{
|
||||
hasNewNotes
|
||||
}
|
||||
`, { pollInterval: 30000, fetchPolicy: 'cache-and-network' })
|
||||
const [lastCheckedJobs, setLastCheckedJobs] = useState(new Date().getTime())
|
||||
useEffect(() => {
|
||||
if (me) {
|
||||
|
@ -53,12 +57,12 @@ export default function Header ({ sub }) {
|
|||
return (
|
||||
<div className='d-flex align-items-center'>
|
||||
<Head>
|
||||
<link rel='shortcut icon' href={me?.hasNewNotes ? '/favicon-notify.png' : '/favicon.png'} />
|
||||
<link rel='shortcut icon' href={hasNewNotes?.hasNewNotes ? '/favicon-notify.png' : '/favicon.png'} />
|
||||
</Head>
|
||||
<Link href='/notifications' passHref>
|
||||
<Nav.Link eventKey='notifications' className='pl-0 position-relative'>
|
||||
<NoteIcon />
|
||||
{me?.hasNewNotes &&
|
||||
{hasNewNotes?.hasNewNotes &&
|
||||
<span className={styles.notification}>
|
||||
<span className='invisible'>{' '}</span>
|
||||
</span>}
|
||||
|
|
|
@ -3,36 +3,6 @@ import { COMMENT_FIELDS } from './comments'
|
|||
import { ITEM_FIELDS, ITEM_WITH_COMMENTS } from './items'
|
||||
|
||||
export const ME = gql`
|
||||
{
|
||||
me {
|
||||
id
|
||||
name
|
||||
sats
|
||||
stacked
|
||||
freePosts
|
||||
freeComments
|
||||
hasNewNotes
|
||||
tipDefault
|
||||
fiatCurrency
|
||||
bioId
|
||||
hasInvites
|
||||
upvotePopover
|
||||
tipPopover
|
||||
noteItemSats
|
||||
noteEarning
|
||||
noteAllDescendants
|
||||
noteMentions
|
||||
noteDeposits
|
||||
noteInvites
|
||||
noteJobIndicator
|
||||
hideInvoiceDesc
|
||||
wildWestMode
|
||||
greeterMode
|
||||
lastCheckedJobs
|
||||
}
|
||||
}`
|
||||
|
||||
export const ME_SSR = gql`
|
||||
{
|
||||
me {
|
||||
id
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { ApolloClient, InMemoryCache, from, HttpLink } from '@apollo/client'
|
||||
import { ApolloClient, InMemoryCache, HttpLink } from '@apollo/client'
|
||||
import { decodeCursor, LIMIT } from './cursor'
|
||||
import { RetryLink } from '@apollo/client/link/retry'
|
||||
// import { RetryLink } from '@apollo/client/link/retry'
|
||||
|
||||
const additiveLink = from([
|
||||
new RetryLink(),
|
||||
new HttpLink({ uri: '/api/graphql' })
|
||||
])
|
||||
// const additiveLink = from([
|
||||
// new RetryLink(),
|
||||
// new HttpLink({ uri: '/api/graphql' })
|
||||
// ])
|
||||
|
||||
function isFirstPage (cursor, existingThings) {
|
||||
if (cursor) {
|
||||
|
@ -20,7 +20,7 @@ function isFirstPage (cursor, existingThings) {
|
|||
|
||||
export default function getApolloClient () {
|
||||
global.apolloClient ||= new ApolloClient({
|
||||
link: additiveLink,
|
||||
link: new HttpLink({ uri: '/api/graphql' }),
|
||||
cache: new InMemoryCache({
|
||||
typePolicies: {
|
||||
Query: {
|
||||
|
|
Loading…
Reference in New Issue