continued notification work
This commit is contained in:
		
							parent
							
								
									c8df41bfa5
								
							
						
					
					
						commit
						0afe46c030
					
				@ -5,9 +5,9 @@ export default {
 | 
				
			|||||||
  Query: {
 | 
					  Query: {
 | 
				
			||||||
    notifications: async (parent, { cursor }, { me, models }) => {
 | 
					    notifications: async (parent, { cursor }, { me, models }) => {
 | 
				
			||||||
      const decodedCursor = decodeCursor(cursor)
 | 
					      const decodedCursor = decodeCursor(cursor)
 | 
				
			||||||
      // if (!me) {
 | 
					      if (!me) {
 | 
				
			||||||
      //   throw new AuthenticationError('you must be logged in')
 | 
					        throw new AuthenticationError('you must be logged in')
 | 
				
			||||||
      // }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      /*
 | 
					      /*
 | 
				
			||||||
        So that we can cursor over results, we union notifications together ...
 | 
					        So that we can cursor over results, we union notifications together ...
 | 
				
			||||||
@ -63,12 +63,15 @@ export default {
 | 
				
			|||||||
        GROUP BY ${ITEM_SUBQUERY_FIELDS}, subquery.island ORDER BY max(subquery.voted_at) desc)
 | 
					        GROUP BY ${ITEM_SUBQUERY_FIELDS}, subquery.island ORDER BY max(subquery.voted_at) desc)
 | 
				
			||||||
        ORDER BY sort_time DESC
 | 
					        ORDER BY sort_time DESC
 | 
				
			||||||
        OFFSET $3
 | 
					        OFFSET $3
 | 
				
			||||||
        LIMIT ${LIMIT}`, 622, decodedCursor.time, decodedCursor.offset)
 | 
					        LIMIT ${LIMIT}`, me.id, decodedCursor.time, decodedCursor.offset)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      notifications = notifications.map(n => {
 | 
					      notifications = notifications.map(n => {
 | 
				
			||||||
        n.item = { ...n }
 | 
					        n.item = { ...n }
 | 
				
			||||||
        return n
 | 
					        return n
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      await models.user.update({ where: { id: me.id }, data: { checkedNotesAt: new Date() } })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      return {
 | 
					      return {
 | 
				
			||||||
        cursor: notifications.length === LIMIT ? nextCursorEncoded(decodedCursor) : null,
 | 
					        cursor: notifications.length === LIMIT ? nextCursorEncoded(decodedCursor) : null,
 | 
				
			||||||
        notifications
 | 
					        notifications
 | 
				
			||||||
 | 
				
			|||||||
@ -38,7 +38,7 @@ function Parent ({ item, rootText }) {
 | 
				
			|||||||
  )
 | 
					  )
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function Comment ({ item, children, replyOpen, includeParent, rootText, noComments, noReply, clickToContext }) {
 | 
					export default function Comment ({ item, children, replyOpen, includeParent, rootText, noComments, noReply }) {
 | 
				
			||||||
  const [reply, setReply] = useState(replyOpen)
 | 
					  const [reply, setReply] = useState(replyOpen)
 | 
				
			||||||
  const [edit, setEdit] = useState()
 | 
					  const [edit, setEdit] = useState()
 | 
				
			||||||
  const [collapse, setCollapse] = useState(false)
 | 
					  const [collapse, setCollapse] = useState(false)
 | 
				
			||||||
@ -50,28 +50,16 @@ export default function Comment ({ item, children, replyOpen, includeParent, roo
 | 
				
			|||||||
  const [canEdit, setCanEdit] =
 | 
					  const [canEdit, setCanEdit] =
 | 
				
			||||||
    useState(mine && (Date.now() < editThreshold))
 | 
					    useState(mine && (Date.now() < editThreshold))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  console.log('wtf router', router, item.id, ref.current)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  useEffect(() => {
 | 
					  useEffect(() => {
 | 
				
			||||||
    if (Number(router.query.commentId) === Number(item.id)) {
 | 
					    if (Number(router.query.commentId) === Number(item.id)) {
 | 
				
			||||||
      console.log(ref.current.scrollTop)
 | 
					 | 
				
			||||||
      ref.current.scrollIntoView()
 | 
					      ref.current.scrollIntoView()
 | 
				
			||||||
      // ref.current.classList.add('flash-it')
 | 
					      ref.current.classList.add('flash-it')
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }, [item])
 | 
					  }, [item])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <div
 | 
					    <div
 | 
				
			||||||
      ref={ref} onClick={() => {
 | 
					      ref={ref} className={includeParent ? '' : `${styles.comment} ${collapse ? styles.collapsed : ''}`}
 | 
				
			||||||
        if (clickToContext) {
 | 
					 | 
				
			||||||
          console.log('pushing')
 | 
					 | 
				
			||||||
          // router.push(`/items/${item.parentId}?commentId=${item.id}`, `/items/${item.parentId}`, { scroll: false })
 | 
					 | 
				
			||||||
          router.push({
 | 
					 | 
				
			||||||
            pathname: '/items/[id]',
 | 
					 | 
				
			||||||
            query: { id: item.parentId, commentId: item.id }
 | 
					 | 
				
			||||||
          }, `/items/${item.parentId}`)
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }} className={includeParent ? `${clickToContext ? styles.clickToContext : ''}` : `${styles.comment} ${collapse ? styles.collapsed : ''}`}
 | 
					 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      <div className={`${itemStyles.item} ${styles.item}`}>
 | 
					      <div className={`${itemStyles.item} ${styles.item}`}>
 | 
				
			||||||
        <UpVote itemId={item.id} meSats={item.meSats} className={styles.upvote} />
 | 
					        <UpVote itemId={item.id} meSats={item.meSats} className={styles.upvote} />
 | 
				
			||||||
 | 
				
			|||||||
@ -81,15 +81,6 @@
 | 
				
			|||||||
    padding-left: .2rem;
 | 
					    padding-left: .2rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.clickToContext {
 | 
					 | 
				
			||||||
    border-radius: .4rem;
 | 
					 | 
				
			||||||
    padding: .2rem 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.clickToContext:hover {
 | 
					 | 
				
			||||||
    background-color: rgba(0, 0, 0, 0.03);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.comment:not(:last-child) {
 | 
					.comment:not(:last-child) {
 | 
				
			||||||
    border-bottom-left-radius: 0;
 | 
					    border-bottom-left-radius: 0;
 | 
				
			||||||
    border-bottom-right-radius: 0;
 | 
					    border-bottom-right-radius: 0;
 | 
				
			||||||
@ -100,8 +91,3 @@
 | 
				
			|||||||
    border-top-left-radius: 0;
 | 
					    border-top-left-radius: 0;
 | 
				
			||||||
    border-top-right-radius: 0;
 | 
					    border-top-right-radius: 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
.clickToContext {
 | 
					 | 
				
			||||||
    scroll-behavior: smooth;
 | 
					 | 
				
			||||||
    cursor: pointer;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -3,8 +3,11 @@ import Button from 'react-bootstrap/Button'
 | 
				
			|||||||
import { MORE_FLAT_COMMENTS } from '../fragments/comments'
 | 
					import { MORE_FLAT_COMMENTS } from '../fragments/comments'
 | 
				
			||||||
import { useState } from 'react'
 | 
					import { useState } from 'react'
 | 
				
			||||||
import Comment, { CommentSkeleton } from './comment'
 | 
					import Comment, { CommentSkeleton } from './comment'
 | 
				
			||||||
 | 
					import styles from './notifications.module.css'
 | 
				
			||||||
 | 
					import { useRouter } from 'next/router'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function CommentsFlat ({ variables, ...props }) {
 | 
					export default function CommentsFlat ({ variables, ...props }) {
 | 
				
			||||||
 | 
					  const router = useRouter()
 | 
				
			||||||
  const { loading, error, data, fetchMore } = useQuery(MORE_FLAT_COMMENTS, {
 | 
					  const { loading, error, data, fetchMore } = useQuery(MORE_FLAT_COMMENTS, {
 | 
				
			||||||
    variables
 | 
					    variables
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
@ -12,12 +15,22 @@ export default function CommentsFlat ({ variables, ...props }) {
 | 
				
			|||||||
  if (loading) {
 | 
					  if (loading) {
 | 
				
			||||||
    return <CommentsFlatSkeleton />
 | 
					    return <CommentsFlatSkeleton />
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					 | 
				
			||||||
  const { moreFlatComments: { comments, cursor } } = data
 | 
					  const { moreFlatComments: { comments, cursor } } = data
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <>
 | 
					    <>
 | 
				
			||||||
      {comments.map(item => (
 | 
					      {comments.map(item => (
 | 
				
			||||||
        <Comment key={item.id} item={item} {...props} />
 | 
					        <div
 | 
				
			||||||
 | 
					          key={item.id}
 | 
				
			||||||
 | 
					          className={styles.clickToContext}
 | 
				
			||||||
 | 
					          onClick={() => {
 | 
				
			||||||
 | 
					            router.push({
 | 
				
			||||||
 | 
					              pathname: '/items/[id]',
 | 
				
			||||||
 | 
					              query: { id: item.parentId, commentId: item.id }
 | 
				
			||||||
 | 
					            }, `/items/${item.parentId}`)
 | 
				
			||||||
 | 
					          }}
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					          <Comment item={item} {...props} />
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
      ))}
 | 
					      ))}
 | 
				
			||||||
      <MoreFooter cursor={cursor} fetchMore={fetchMore} />
 | 
					      <MoreFooter cursor={cursor} fetchMore={fetchMore} />
 | 
				
			||||||
    </>
 | 
					    </>
 | 
				
			||||||
 | 
				
			|||||||
@ -14,7 +14,7 @@ import { useEffect } from 'react'
 | 
				
			|||||||
import { randInRange } from '../lib/rand'
 | 
					import { randInRange } from '../lib/rand'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function WalletSummary ({ me }) {
 | 
					function WalletSummary ({ me }) {
 | 
				
			||||||
  return `[${me.stacked},${me.sats}]`
 | 
					  return `${me.stacked} \\ ${me.sats}`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function Header () {
 | 
					export default function Header () {
 | 
				
			||||||
@ -32,20 +32,18 @@ export default function Header () {
 | 
				
			|||||||
    if (session) {
 | 
					    if (session) {
 | 
				
			||||||
      return (
 | 
					      return (
 | 
				
			||||||
        <div className='d-flex align-items-center'>
 | 
					        <div className='d-flex align-items-center'>
 | 
				
			||||||
          {me && me.hasNewNotes &&
 | 
					 | 
				
			||||||
          <Head>
 | 
					          <Head>
 | 
				
			||||||
              <link rel='shortcut icon' href='/favicon-notify.png' />
 | 
					            <link rel='shortcut icon' href={me && me.hasNewNotes ? '/favicon-notify.png' : '/favicon.png'} />
 | 
				
			||||||
            </Head>}
 | 
					          </Head>
 | 
				
			||||||
          <div className='position-relative'>
 | 
					          <div className='position-relative'>
 | 
				
			||||||
            <NavDropdown className='pl-0' title={`@${session.user.name}`} alignRight>
 | 
					            <NavDropdown className='px-0' title={`@${session.user.name}`} alignRight>
 | 
				
			||||||
              <Link href={'/' + session.user.name} passHref>
 | 
					              <Link href={'/' + session.user.name} passHref>
 | 
				
			||||||
                <NavDropdown.Item>profile</NavDropdown.Item>
 | 
					                <NavDropdown.Item>profile</NavDropdown.Item>
 | 
				
			||||||
              </Link>
 | 
					              </Link>
 | 
				
			||||||
              <Link href='/notifications' passHref>
 | 
					              <Link href='/notifications' passHref>
 | 
				
			||||||
                <NavDropdown.Item onClick={() => {
 | 
					                <NavDropdown.Item onClick={() => {
 | 
				
			||||||
                  // when it's a fresh click evict old notification cache
 | 
					                  // when it's a fresh click evict old notification cache
 | 
				
			||||||
                  client.cache.evict({ id: 'ROOT_QUERY', fieldName: 'moreFlatComments:{}' })
 | 
					                  client.cache.evict({ id: 'ROOT_QUERY', fieldName: 'notifications' })
 | 
				
			||||||
                  client.cache.evict({ id: 'ROOT_QUERY', fieldName: 'recentlyStacked' })
 | 
					 | 
				
			||||||
                }}
 | 
					                }}
 | 
				
			||||||
                >
 | 
					                >
 | 
				
			||||||
                  notifications
 | 
					                  notifications
 | 
				
			||||||
 | 
				
			|||||||
@ -4,8 +4,11 @@ import { useState } from 'react'
 | 
				
			|||||||
import Comment, { CommentSkeleton } from './comment'
 | 
					import Comment, { CommentSkeleton } from './comment'
 | 
				
			||||||
import Item from './item'
 | 
					import Item from './item'
 | 
				
			||||||
import { NOTIFICATIONS } from '../fragments/notifications'
 | 
					import { NOTIFICATIONS } from '../fragments/notifications'
 | 
				
			||||||
 | 
					import styles from './notifications.module.css'
 | 
				
			||||||
 | 
					import { useRouter } from 'next/router'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function Notifications ({ variables, ...props }) {
 | 
					export default function Notifications ({ variables, ...props }) {
 | 
				
			||||||
 | 
					  const router = useRouter()
 | 
				
			||||||
  const { loading, error, data, fetchMore } = useQuery(NOTIFICATIONS, {
 | 
					  const { loading, error, data, fetchMore } = useQuery(NOTIFICATIONS, {
 | 
				
			||||||
    variables
 | 
					    variables
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
@ -14,12 +17,26 @@ export default function Notifications ({ variables, ...props }) {
 | 
				
			|||||||
    return <CommentsFlatSkeleton />
 | 
					    return <CommentsFlatSkeleton />
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  const { notifications: { notifications, cursor } } = data
 | 
					  const { notifications: { notifications, cursor } } = data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <>
 | 
					    <>
 | 
				
			||||||
      {/* XXX we shouldn't use the index but we don't have a unique id in this union yet */}
 | 
					      {/* XXX we shouldn't use the index but we don't have a unique id in this union yet */}
 | 
				
			||||||
      {notifications.map((n, i) => (
 | 
					      {notifications.map((n, i) => (
 | 
				
			||||||
        <div key={i}>
 | 
					        <div
 | 
				
			||||||
          {n.__typename === 'Votification' && <small className='font-weight-bold text-success'>your {n.item.title ? 'post' : 'reply'} stacked {n.earnedSats} sats</small>}
 | 
					          key={i}
 | 
				
			||||||
 | 
					          className={styles.clickToContext}
 | 
				
			||||||
 | 
					          onClick={() => {
 | 
				
			||||||
 | 
					            if (n.__typename === 'Reply' || !n.item.title) {
 | 
				
			||||||
 | 
					              router.push({
 | 
				
			||||||
 | 
					                pathname: '/items/[id]',
 | 
				
			||||||
 | 
					                query: { id: n.item.parentId, commentId: n.item.id }
 | 
				
			||||||
 | 
					              }, `/items/${n.item.parentId}`)
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					              router.push(`items/${n.item.id}`)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }}
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					          {n.__typename === 'Votification' && <small className='font-weight-bold text-success ml-2'>your {n.item.title ? 'post' : 'reply'} stacked {n.earnedSats} sats</small>}
 | 
				
			||||||
          <div className={n.__typename === 'Votification' ? 'ml-sm-4 ml-2' : ''}>
 | 
					          <div className={n.__typename === 'Votification' ? 'ml-sm-4 ml-2' : ''}>
 | 
				
			||||||
            {n.item.title
 | 
					            {n.item.title
 | 
				
			||||||
              ? <Item item={n.item} />
 | 
					              ? <Item item={n.item} />
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										9
									
								
								components/notifications.module.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								components/notifications.module.css
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					.clickToContext {
 | 
				
			||||||
 | 
					    border-radius: .4rem;
 | 
				
			||||||
 | 
					    padding: .2rem 0;
 | 
				
			||||||
 | 
					    cursor: pointer;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.clickToContext:hover {
 | 
				
			||||||
 | 
					    background-color: rgba(0, 0, 0, 0.03);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -39,7 +39,7 @@ export default function UserComments ({ user }) {
 | 
				
			|||||||
    <Layout noSeo>
 | 
					    <Layout noSeo>
 | 
				
			||||||
      <Seo user={user} />
 | 
					      <Seo user={user} />
 | 
				
			||||||
      <UserHeader user={user} />
 | 
					      <UserHeader user={user} />
 | 
				
			||||||
      <CommentsFlat variables={{ userId: user.id }} includeParent noReply clickToContext />
 | 
					      <CommentsFlat variables={{ userId: user.id }} includeParent noReply />
 | 
				
			||||||
    </Layout>
 | 
					    </Layout>
 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -191,7 +191,7 @@ footer {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.flash-it {
 | 
					.flash-it {
 | 
				
			||||||
  animation: flash 2s linear 2;
 | 
					  animation: flash 2s linear 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@keyframes spin {
 | 
					@keyframes spin {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user