poll for notifications less, don't retry gql
This commit is contained in:
		
							parent
							
								
									32651bea92
								
							
						
					
					
						commit
						f1a4e9c682
					
				@ -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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user