attempts at voting before running into cache issues
This commit is contained in:
		
							parent
							
								
									900b70da77
								
							
						
					
					
						commit
						c626998952
					
				@ -6,7 +6,10 @@ import resolvers from './resolvers'
 | 
				
			|||||||
import typeDefs from './typeDefs'
 | 
					import typeDefs from './typeDefs'
 | 
				
			||||||
import models from './models'
 | 
					import models from './models'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const client = new ApolloClient({
 | 
					export default async function serverSideClient (req) {
 | 
				
			||||||
 | 
					  const session = await getSession({ req })
 | 
				
			||||||
 | 
					  console.log(session)
 | 
				
			||||||
 | 
					  return new ApolloClient({
 | 
				
			||||||
    ssrMode: true,
 | 
					    ssrMode: true,
 | 
				
			||||||
    // Instead of "createHttpLink" use SchemaLink here
 | 
					    // Instead of "createHttpLink" use SchemaLink here
 | 
				
			||||||
    link: new SchemaLink({
 | 
					    link: new SchemaLink({
 | 
				
			||||||
@ -14,15 +17,11 @@ const client = new ApolloClient({
 | 
				
			|||||||
        schemas: typeDefs,
 | 
					        schemas: typeDefs,
 | 
				
			||||||
        resolvers: resolvers
 | 
					        resolvers: resolvers
 | 
				
			||||||
      }),
 | 
					      }),
 | 
				
			||||||
    context: async ({ req }) => {
 | 
					      context: {
 | 
				
			||||||
      const session = await getSession({ req })
 | 
					 | 
				
			||||||
      return {
 | 
					 | 
				
			||||||
        models,
 | 
					        models,
 | 
				
			||||||
        me: session ? session.user : null
 | 
					        me: session ? session.user : null
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    }),
 | 
					    }),
 | 
				
			||||||
    cache: new InMemoryCache()
 | 
					    cache: new InMemoryCache()
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
export default client
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -1,64 +1,5 @@
 | 
				
			|||||||
import { UserInputError, AuthenticationError } from 'apollo-server-micro'
 | 
					import { UserInputError, AuthenticationError } from 'apollo-server-micro'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const createItem = async (parent, { title, text, url, parentId }, { me, models }) => {
 | 
					 | 
				
			||||||
  if (!me) {
 | 
					 | 
				
			||||||
    throw new AuthenticationError('You must be logged in')
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const data = {
 | 
					 | 
				
			||||||
    title,
 | 
					 | 
				
			||||||
    url,
 | 
					 | 
				
			||||||
    text,
 | 
					 | 
				
			||||||
    user: {
 | 
					 | 
				
			||||||
      connect: {
 | 
					 | 
				
			||||||
        name: me.name
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (parentId) {
 | 
					 | 
				
			||||||
    data.parent = {
 | 
					 | 
				
			||||||
      connect: {
 | 
					 | 
				
			||||||
        id: parseInt(parentId)
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const item = await models.item.create({ data })
 | 
					 | 
				
			||||||
  item.comments = []
 | 
					 | 
				
			||||||
  return item
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function nestComments (flat, parentId) {
 | 
					 | 
				
			||||||
  const result = []
 | 
					 | 
				
			||||||
  let added = 0
 | 
					 | 
				
			||||||
  for (let i = 0; i < flat.length;) {
 | 
					 | 
				
			||||||
    if (!flat[i].comments) flat[i].comments = []
 | 
					 | 
				
			||||||
    if (Number(flat[i].parentId) === Number(parentId)) {
 | 
					 | 
				
			||||||
      result.push(flat[i])
 | 
					 | 
				
			||||||
      added++
 | 
					 | 
				
			||||||
      i++
 | 
					 | 
				
			||||||
    } else if (result.length > 0) {
 | 
					 | 
				
			||||||
      const item = result[result.length - 1]
 | 
					 | 
				
			||||||
      const [nested, newAdded] = nestComments(flat.slice(i), item.id)
 | 
					 | 
				
			||||||
      if (newAdded === 0) {
 | 
					 | 
				
			||||||
        break
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      item.comments.push(...nested)
 | 
					 | 
				
			||||||
      i += newAdded
 | 
					 | 
				
			||||||
      added += newAdded
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      break
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return [result, added]
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// we have to do our own query because ltree is unsupported
 | 
					 | 
				
			||||||
const SELECT =
 | 
					 | 
				
			||||||
  `SELECT id, created_at as "createdAt", updated_at as "updatedAt", title,
 | 
					 | 
				
			||||||
    text, url, "userId", "parentId", ltree2text("path") AS "path"`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default {
 | 
					export default {
 | 
				
			||||||
  Query: {
 | 
					  Query: {
 | 
				
			||||||
    items: async (parent, args, { models }) => {
 | 
					    items: async (parent, args, { models }) => {
 | 
				
			||||||
@ -142,6 +83,29 @@ export default {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      return await createItem(parent, { text, parentId }, { me, models })
 | 
					      return await createItem(parent, { text, parentId }, { me, models })
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    vote: async (parent, { id, sats = 1 }, { me, models }) => {
 | 
				
			||||||
 | 
					      // need to make sure we are logged in
 | 
				
			||||||
 | 
					      if (!me) {
 | 
				
			||||||
 | 
					        throw new AuthenticationError('You must be logged in')
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      const data = {
 | 
				
			||||||
 | 
					        sats,
 | 
				
			||||||
 | 
					        item: {
 | 
				
			||||||
 | 
					          connect: {
 | 
				
			||||||
 | 
					            id: parseInt(id)
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        user: {
 | 
				
			||||||
 | 
					          connect: {
 | 
				
			||||||
 | 
					            name: me.name
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      await models.vote.create({ data })
 | 
				
			||||||
 | 
					      return sats
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -155,6 +119,96 @@ export default {
 | 
				
			|||||||
        WHERE path <@ text2ltree(${item.path}) AND id != ${item.id}`
 | 
					        WHERE path <@ text2ltree(${item.path}) AND id != ${item.id}`
 | 
				
			||||||
      return count
 | 
					      return count
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    sats: () => 0
 | 
					    sats: async (item, args, { models }) => {
 | 
				
			||||||
 | 
					      const { sum: { sats } } = await models.vote.aggregate({
 | 
				
			||||||
 | 
					        sum: {
 | 
				
			||||||
 | 
					          sats: true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        where: {
 | 
				
			||||||
 | 
					          itemId: item.id
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return sats
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    meSats: async (item, args, { me, models }) => {
 | 
				
			||||||
 | 
					      if (!me) return 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      const { sum: { sats } } = await models.vote.aggregate({
 | 
				
			||||||
 | 
					        sum: {
 | 
				
			||||||
 | 
					          sats: true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        where: {
 | 
				
			||||||
 | 
					          itemId: item.id,
 | 
				
			||||||
 | 
					          userId: me.id
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return sats
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const createItem = async (parent, { title, text, url, parentId }, { me, models }) => {
 | 
				
			||||||
 | 
					  if (!me) {
 | 
				
			||||||
 | 
					    throw new AuthenticationError('You must be logged in')
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const data = {
 | 
				
			||||||
 | 
					    title,
 | 
				
			||||||
 | 
					    url,
 | 
				
			||||||
 | 
					    text,
 | 
				
			||||||
 | 
					    item: {
 | 
				
			||||||
 | 
					      connect: {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    user: {
 | 
				
			||||||
 | 
					      connect: {
 | 
				
			||||||
 | 
					        name: me.name
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (parentId) {
 | 
				
			||||||
 | 
					    data.parent = {
 | 
				
			||||||
 | 
					      connect: {
 | 
				
			||||||
 | 
					        id: parseInt(parentId)
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const item = await models.item.create({ data })
 | 
				
			||||||
 | 
					  item.comments = []
 | 
				
			||||||
 | 
					  return item
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function nestComments (flat, parentId) {
 | 
				
			||||||
 | 
					  const result = []
 | 
				
			||||||
 | 
					  let added = 0
 | 
				
			||||||
 | 
					  for (let i = 0; i < flat.length;) {
 | 
				
			||||||
 | 
					    if (!flat[i].comments) flat[i].comments = []
 | 
				
			||||||
 | 
					    if (Number(flat[i].parentId) === Number(parentId)) {
 | 
				
			||||||
 | 
					      result.push(flat[i])
 | 
				
			||||||
 | 
					      added++
 | 
				
			||||||
 | 
					      i++
 | 
				
			||||||
 | 
					    } else if (result.length > 0) {
 | 
				
			||||||
 | 
					      const item = result[result.length - 1]
 | 
				
			||||||
 | 
					      const [nested, newAdded] = nestComments(flat.slice(i), item.id)
 | 
				
			||||||
 | 
					      if (newAdded === 0) {
 | 
				
			||||||
 | 
					        break
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      item.comments.push(...nested)
 | 
				
			||||||
 | 
					      i += newAdded
 | 
				
			||||||
 | 
					      added += newAdded
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      break
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return [result, added]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// we have to do our own query because ltree is unsupported
 | 
				
			||||||
 | 
					const SELECT =
 | 
				
			||||||
 | 
					  `SELECT id, created_at as "createdAt", updated_at as "updatedAt", title,
 | 
				
			||||||
 | 
					    text, url, "userId", "parentId", ltree2text("path") AS "path"`
 | 
				
			||||||
 | 
				
			|||||||
@ -15,7 +15,7 @@ export default gql`
 | 
				
			|||||||
    createLink(title: String!, url: String): Item!
 | 
					    createLink(title: String!, url: String): Item!
 | 
				
			||||||
    createDiscussion(title: String!, text: String): Item!
 | 
					    createDiscussion(title: String!, text: String): Item!
 | 
				
			||||||
    createComment(text: String!, parentId: ID!): Item!
 | 
					    createComment(text: String!, parentId: ID!): Item!
 | 
				
			||||||
    vote(sats: Int): Int!
 | 
					    vote(id: ID!, sats: Int): Int!
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  type Item {
 | 
					  type Item {
 | 
				
			||||||
@ -28,6 +28,7 @@ export default gql`
 | 
				
			|||||||
    user: User!
 | 
					    user: User!
 | 
				
			||||||
    depth: Int!
 | 
					    depth: Int!
 | 
				
			||||||
    sats: Int!
 | 
					    sats: Int!
 | 
				
			||||||
 | 
					    meSats: Int!
 | 
				
			||||||
    ncomments: Int!
 | 
					    ncomments: Int!
 | 
				
			||||||
    comments: [Item!]!
 | 
					    comments: [Item!]!
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
@ -50,7 +50,7 @@ export default function Comment ({ item, children, replyOpen, includeParent, cac
 | 
				
			|||||||
      <div />
 | 
					      <div />
 | 
				
			||||||
      <div>
 | 
					      <div>
 | 
				
			||||||
        <div className={`${itemStyles.item} ${styles.item}`}>
 | 
					        <div className={`${itemStyles.item} ${styles.item}`}>
 | 
				
			||||||
          <UpVote className={styles.upvote} />
 | 
					          <UpVote itemId={item.id} meSats={item.meSats} className={styles.upvote} />
 | 
				
			||||||
          <div className={itemStyles.hunk}>
 | 
					          <div className={itemStyles.hunk}>
 | 
				
			||||||
            <div className={itemStyles.other}>
 | 
					            <div className={itemStyles.other}>
 | 
				
			||||||
              <Link href={`/${item.user.name}`} passHref>
 | 
					              <Link href={`/${item.user.name}`} passHref>
 | 
				
			||||||
 | 
				
			|||||||
@ -20,7 +20,7 @@ export default function Header () {
 | 
				
			|||||||
        <>
 | 
					        <>
 | 
				
			||||||
          <Nav.Item>
 | 
					          <Nav.Item>
 | 
				
			||||||
            <Link href={'/' + session.user.name} passHref>
 | 
					            <Link href={'/' + session.user.name} passHref>
 | 
				
			||||||
              <Nav.Link className='text-reset'>@{session.user.name}</Nav.Link>
 | 
					              <Nav.Link>@{session.user.name}</Nav.Link>
 | 
				
			||||||
            </Link>
 | 
					            </Link>
 | 
				
			||||||
          </Nav.Item>
 | 
					          </Nav.Item>
 | 
				
			||||||
          <Nav.Item>
 | 
					          <Nav.Item>
 | 
				
			||||||
@ -51,6 +51,9 @@ export default function Header () {
 | 
				
			|||||||
                <Nav.Link>post</Nav.Link>
 | 
					                <Nav.Link>post</Nav.Link>
 | 
				
			||||||
              </Link>
 | 
					              </Link>
 | 
				
			||||||
            </Nav.Item>
 | 
					            </Nav.Item>
 | 
				
			||||||
 | 
					            <Nav.Item>
 | 
				
			||||||
 | 
					              <Nav.Link href='https://bitcoinerjobs.co' target='_blank'>jobs</Nav.Link>
 | 
				
			||||||
 | 
					            </Nav.Item>
 | 
				
			||||||
          </Nav>
 | 
					          </Nav>
 | 
				
			||||||
          <Nav className='ml-auto align-items-center' activeKey={router.asPath.split('?')[0]}>
 | 
					          <Nav className='ml-auto align-items-center' activeKey={router.asPath.split('?')[0]}>
 | 
				
			||||||
            <Corner />
 | 
					            <Corner />
 | 
				
			||||||
 | 
				
			|||||||
@ -13,7 +13,7 @@ export default function Item ({ item, rank, children }) {
 | 
				
			|||||||
          </div>)
 | 
					          </div>)
 | 
				
			||||||
        : <div />}
 | 
					        : <div />}
 | 
				
			||||||
      <div className={styles.item}>
 | 
					      <div className={styles.item}>
 | 
				
			||||||
        <UpVote />
 | 
					        <UpVote itemId={item.id} meSats={item.meSats} />
 | 
				
			||||||
        <div className={styles.hunk}>
 | 
					        <div className={styles.hunk}>
 | 
				
			||||||
          <div className={`${styles.main} flex-wrap flex-md-nowrap`}>
 | 
					          <div className={`${styles.main} flex-wrap flex-md-nowrap`}>
 | 
				
			||||||
            <Link href={`/items/${item.id}`} passHref>
 | 
					            <Link href={`/items/${item.id}`} passHref>
 | 
				
			||||||
 | 
				
			|||||||
@ -24,7 +24,7 @@ export default function Reply ({ parentId, onSuccess, cacheId }) {
 | 
				
			|||||||
        cache.modify({
 | 
					        cache.modify({
 | 
				
			||||||
          id: cacheId || `Item:${parentId}`,
 | 
					          id: cacheId || `Item:${parentId}`,
 | 
				
			||||||
          fields: {
 | 
					          fields: {
 | 
				
			||||||
            comments (existingCommentRefs = [], { readField }) {
 | 
					            comments (existingCommentRefs = []) {
 | 
				
			||||||
              const newCommentRef = cache.writeFragment({
 | 
					              const newCommentRef = cache.writeFragment({
 | 
				
			||||||
                data: createComment,
 | 
					                data: createComment,
 | 
				
			||||||
                fragment: COMMENTS,
 | 
					                fragment: COMMENTS,
 | 
				
			||||||
 | 
				
			|||||||
@ -1,16 +1,55 @@
 | 
				
			|||||||
import { LightningConsumer } from './lightning'
 | 
					import { LightningConsumer } from './lightning'
 | 
				
			||||||
import UpArrow from '../svgs/lightning-arrow.svg'
 | 
					import UpArrow from '../svgs/lightning-arrow.svg'
 | 
				
			||||||
import styles from './upvote.module.css'
 | 
					import styles from './upvote.module.css'
 | 
				
			||||||
 | 
					import { gql, useMutation } from '@apollo/client'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default function UpVote ({ itemId, meSats, className, item }) {
 | 
				
			||||||
 | 
					  const [vote] = useMutation(
 | 
				
			||||||
 | 
					    gql`
 | 
				
			||||||
 | 
					      mutation vote($id: ID!, $sats: Int!) {
 | 
				
			||||||
 | 
					        vote(id: $id, sats: $sats)
 | 
				
			||||||
 | 
					      }`, {
 | 
				
			||||||
 | 
					      update (cache, { data: { vote } }) {
 | 
				
			||||||
 | 
					        if (item) {
 | 
				
			||||||
 | 
					          item.sats += vote
 | 
				
			||||||
 | 
					          item.meSats += vote
 | 
				
			||||||
 | 
					          return
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        cache.modify({
 | 
				
			||||||
 | 
					          id: `Item:${itemId}`,
 | 
				
			||||||
 | 
					          fields: {
 | 
				
			||||||
 | 
					            sats (existingSats = 0) {
 | 
				
			||||||
 | 
					              return existingSats + vote
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            meSats (existingMeSats = 0) {
 | 
				
			||||||
 | 
					              return existingMeSats + vote
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function UpVote ({ className }) {
 | 
					 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <LightningConsumer>
 | 
					    <LightningConsumer>
 | 
				
			||||||
      {({ strike }) =>
 | 
					      {({ strike }) =>
 | 
				
			||||||
        <UpArrow
 | 
					        <UpArrow
 | 
				
			||||||
          width={24}
 | 
					          width={24}
 | 
				
			||||||
          height={24}
 | 
					          height={24}
 | 
				
			||||||
          className={`${styles.upvote} ${className || ''}`}
 | 
					          className={
 | 
				
			||||||
          onClick={strike}
 | 
					            `${styles.upvote}
 | 
				
			||||||
 | 
					            ${className || ''}
 | 
				
			||||||
 | 
					            ${meSats ? (meSats > 1 ? styles.stimi : styles.voted) : ''}`
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          onClick={async () => {
 | 
				
			||||||
 | 
					            if (!itemId) return
 | 
				
			||||||
 | 
					            const { error } = await vote({ variables: { id: itemId, sats: 1 } })
 | 
				
			||||||
 | 
					            if (error) {
 | 
				
			||||||
 | 
					              throw new Error({ message: error.toString() })
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            strike()
 | 
				
			||||||
 | 
					          }}
 | 
				
			||||||
        />}
 | 
					        />}
 | 
				
			||||||
    </LightningConsumer>
 | 
					    </LightningConsumer>
 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
 | 
				
			|||||||
@ -8,3 +8,13 @@
 | 
				
			|||||||
    fill: darkgray;
 | 
					    fill: darkgray;
 | 
				
			||||||
    cursor: pointer;
 | 
					    cursor: pointer;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.upvote.voted {
 | 
				
			||||||
 | 
					    fill: #F6911D;
 | 
				
			||||||
 | 
					    filter: drop-shadow(0 0 7px #F6911D);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.upvote.stimi {
 | 
				
			||||||
 | 
					    fill: #993DF5;
 | 
				
			||||||
 | 
					    filter: drop-shadow(0 0 7px #C28BF9);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -10,6 +10,7 @@ export const COMMENT_FIELDS = gql`
 | 
				
			|||||||
      name
 | 
					      name
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    sats
 | 
					    sats
 | 
				
			||||||
 | 
					    meSats
 | 
				
			||||||
    ncomments
 | 
					    ncomments
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
`
 | 
					`
 | 
				
			||||||
 | 
				
			|||||||
@ -11,6 +11,7 @@ export const ITEM_FIELDS = gql`
 | 
				
			|||||||
      name
 | 
					      name
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    sats
 | 
					    sats
 | 
				
			||||||
 | 
					    meSats
 | 
				
			||||||
    ncomments
 | 
					    ncomments
 | 
				
			||||||
  }`
 | 
					  }`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -5,8 +5,8 @@ import { gql } from '@apollo/client'
 | 
				
			|||||||
import ApolloClient from '../api/client'
 | 
					import ApolloClient from '../api/client'
 | 
				
			||||||
import UserHeader from '../components/user-header'
 | 
					import UserHeader from '../components/user-header'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export async function getServerSideProps ({ params }) {
 | 
					export async function getServerSideProps ({ req, params }) {
 | 
				
			||||||
  const { error, data: { user } } = await ApolloClient.query({
 | 
					  const { error, data: { user } } = await (await ApolloClient(req)).query({
 | 
				
			||||||
    query:
 | 
					    query:
 | 
				
			||||||
      gql`{
 | 
					      gql`{
 | 
				
			||||||
        user(name: "${params.username}") {
 | 
					        user(name: "${params.username}") {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,3 @@
 | 
				
			|||||||
import gql from 'graphql-tag'
 | 
					 | 
				
			||||||
import Item from '../../components/item'
 | 
					import Item from '../../components/item'
 | 
				
			||||||
import Layout from '../../components/layout'
 | 
					import Layout from '../../components/layout'
 | 
				
			||||||
import ApolloClient from '../../api/client'
 | 
					import ApolloClient from '../../api/client'
 | 
				
			||||||
@ -7,23 +6,18 @@ import Comment from '../../components/comment'
 | 
				
			|||||||
import Text from '../../components/text'
 | 
					import Text from '../../components/text'
 | 
				
			||||||
import Comments from '../../components/comments'
 | 
					import Comments from '../../components/comments'
 | 
				
			||||||
import { COMMENTS } from '../../fragments/comments'
 | 
					import { COMMENTS } from '../../fragments/comments'
 | 
				
			||||||
 | 
					import { ITEM_FIELDS } from '../../fragments/items'
 | 
				
			||||||
 | 
					import { gql } from '@apollo/client'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export async function getServerSideProps ({ params }) {
 | 
					export async function getServerSideProps ({ req, params }) {
 | 
				
			||||||
  const { error, data: { item } } = await ApolloClient.query({
 | 
					  const { error, data: { item } } = await (await ApolloClient(req)).query({
 | 
				
			||||||
    query:
 | 
					    query:
 | 
				
			||||||
      gql`{
 | 
					      gql`
 | 
				
			||||||
 | 
					      ${ITEM_FIELDS}
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
        item(id: ${params.id}) {
 | 
					        item(id: ${params.id}) {
 | 
				
			||||||
          id
 | 
					          ...ItemFields
 | 
				
			||||||
          createdAt
 | 
					 | 
				
			||||||
          title
 | 
					 | 
				
			||||||
          url
 | 
					 | 
				
			||||||
          text
 | 
					          text
 | 
				
			||||||
          parentId
 | 
					 | 
				
			||||||
          user {
 | 
					 | 
				
			||||||
            name
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          sats
 | 
					 | 
				
			||||||
          ncomments
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }`
 | 
					      }`
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
 | 
				
			|||||||
@ -66,7 +66,7 @@ export default function login ({ providers, csrfToken, error }) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            return (
 | 
					            return (
 | 
				
			||||||
              <Button
 | 
					              <Button
 | 
				
			||||||
                className={`d-block mt-2 ${styles.providerButton}`}
 | 
					                className={`mt-2 ${styles.providerButton}`}
 | 
				
			||||||
                key={provider.name}
 | 
					                key={provider.name}
 | 
				
			||||||
                variant={variant}
 | 
					                variant={variant}
 | 
				
			||||||
                onClick={() => signIn(provider.id)}
 | 
					                onClick={() => signIn(provider.id)}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										26
									
								
								prisma/migrations/20210426184717_vote/migration.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								prisma/migrations/20210426184717_vote/migration.sql
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					-- DropIndex
 | 
				
			||||||
 | 
					DROP INDEX "item_gist_path_index";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- CreateTable
 | 
				
			||||||
 | 
					CREATE TABLE "Vote" (
 | 
				
			||||||
 | 
					    "id" SERIAL NOT NULL,
 | 
				
			||||||
 | 
					    "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
 | 
				
			||||||
 | 
					    "updated_at" TIMESTAMP(3) NOT NULL,
 | 
				
			||||||
 | 
					    "sats" INTEGER NOT NULL,
 | 
				
			||||||
 | 
					    "itemId" INTEGER NOT NULL,
 | 
				
			||||||
 | 
					    "userId" INTEGER NOT NULL,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    PRIMARY KEY ("id")
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- CreateIndex
 | 
				
			||||||
 | 
					CREATE INDEX "Vote.itemId_index" ON "Vote"("itemId");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- CreateIndex
 | 
				
			||||||
 | 
					CREATE INDEX "Vote.userId_index" ON "Vote"("userId");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- AddForeignKey
 | 
				
			||||||
 | 
					ALTER TABLE "Vote" ADD FOREIGN KEY ("itemId") REFERENCES "Item"("id") ON DELETE CASCADE ON UPDATE CASCADE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- AddForeignKey
 | 
				
			||||||
 | 
					ALTER TABLE "Vote" ADD FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
 | 
				
			||||||
							
								
								
									
										3
									
								
								prisma/migrations/20210426193558_stimi/migration.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								prisma/migrations/20210426193558_stimi/migration.sql
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					-- AlterTable
 | 
				
			||||||
 | 
					ALTER TABLE "Vote" ADD COLUMN     "stimi" BOOLEAN NOT NULL DEFAULT false,
 | 
				
			||||||
 | 
					ALTER COLUMN "sats" SET DEFAULT 1;
 | 
				
			||||||
@ -55,7 +55,8 @@ model Vote {
 | 
				
			|||||||
  id        Int      @id @default(autoincrement())
 | 
					  id        Int      @id @default(autoincrement())
 | 
				
			||||||
  createdAt DateTime @default(now()) @map(name: "created_at")
 | 
					  createdAt DateTime @default(now()) @map(name: "created_at")
 | 
				
			||||||
  updatedAt DateTime @updatedAt @map(name: "updated_at")
 | 
					  updatedAt DateTime @updatedAt @map(name: "updated_at")
 | 
				
			||||||
  sats      Int
 | 
					  sats      Int      @default(1)
 | 
				
			||||||
 | 
					  stimi     Boolean  @default(false)
 | 
				
			||||||
  item      Item     @relation(fields: [itemId], references: [id])
 | 
					  item      Item     @relation(fields: [itemId], references: [id])
 | 
				
			||||||
  itemId    Int
 | 
					  itemId    Int
 | 
				
			||||||
  user      User     @relation(fields: [userId], references: [id])
 | 
					  user      User     @relation(fields: [userId], references: [id])
 | 
				
			||||||
 | 
				
			|||||||
@ -5,6 +5,7 @@ $theme-colors: (
 | 
				
			|||||||
  "info" : #007cbe,
 | 
					  "info" : #007cbe,
 | 
				
			||||||
  "success" : #5c8001,
 | 
					  "success" : #5c8001,
 | 
				
			||||||
  "twitter" : #1da1f2,
 | 
					  "twitter" : #1da1f2,
 | 
				
			||||||
 | 
					  "boost" : #7A0CE9,
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$body-bg: #fafafa;
 | 
					$body-bg: #fafafa;
 | 
				
			||||||
@ -50,6 +51,14 @@ $container-max-widths: (
 | 
				
			|||||||
  font-weight: bold;
 | 
					  font-weight: bold;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.alert-dismissible .close {
 | 
				
			||||||
 | 
					  font-weight: 300;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.nav-item {
 | 
				
			||||||
 | 
					  font-weight: 500;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.form-control:focus {
 | 
					.form-control:focus {
 | 
				
			||||||
  border-color: #fada5e;
 | 
					  border-color: #fada5e;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,8 @@
 | 
				
			|||||||
.login .providerButton {
 | 
					.login .providerButton {
 | 
				
			||||||
    width: 100%;
 | 
					    width: 100%;
 | 
				
			||||||
 | 
					    justify-content: center;
 | 
				
			||||||
 | 
					    align-items: center;
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.page {
 | 
					.page {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user