diff --git a/api/resolvers/item.js b/api/resolvers/item.js
index f726b465..340dae54 100644
--- a/api/resolvers/item.js
+++ b/api/resolvers/item.js
@@ -34,19 +34,28 @@ export async function getItem (parent, { id }, { models }) {
export default {
Query: {
- moreItems: async (parent, { sort, cursor, userId, within }, { me, models }) => {
+ moreItems: async (parent, { sort, cursor, name, within }, { me, models }) => {
const decodedCursor = decodeCursor(cursor)
- let items
- let interval = 'INTERVAL '
+ let items; let user; let interval = 'INTERVAL '
+
switch (sort) {
case 'user':
+ if (!name) {
+ throw new UserInputError('must supply name', { argumentName: 'name' })
+ }
+
+ user = await models.user.findUnique({ where: { name } })
+ if (!user) {
+ throw new UserInputError('no user has that name', { argumentName: 'name' })
+ }
+
items = await models.$queryRaw(`
${SELECT}
FROM "Item"
WHERE "userId" = $1 AND "parentId" IS NULL AND created_at <= $2
ORDER BY created_at DESC
OFFSET $3
- LIMIT ${LIMIT}`, Number(userId), decodedCursor.time, decodedCursor.offset)
+ LIMIT ${LIMIT}`, user.id, decodedCursor.time, decodedCursor.offset)
break
case 'hot':
// HACK we can speed hack the first hot page, by limiting our query to only
@@ -67,7 +76,7 @@ export default {
LIMIT ${LIMIT}`, decodedCursor.time, decodedCursor.offset, new Date(new Date() - 7))
}
- if (decodedCursor.offset !== 0 || items.length < LIMIT) {
+ if (decodedCursor.offset !== 0 || items?.length < LIMIT) {
items = await models.$queryRaw(`
${SELECT}
FROM "Item"
@@ -79,7 +88,7 @@ export default {
}
break
case 'top':
- switch (within) {
+ switch (within?.pop()) {
case 'day':
interval += "'1 day'"
break
@@ -119,11 +128,16 @@ export default {
items
}
},
- moreFlatComments: async (parent, { cursor, userId }, { me, models }) => {
+ moreFlatComments: async (parent, { cursor, name }, { me, models }) => {
const decodedCursor = decodeCursor(cursor)
- if (!userId) {
- throw new UserInputError('must supply userId', { argumentName: 'userId' })
+ if (!name) {
+ throw new UserInputError('must supply name', { argumentName: 'name' })
+ }
+
+ const user = await models.user.findUnique({ where: { name } })
+ if (!user) {
+ throw new UserInputError('no user has that name', { argumentName: 'name' })
}
const comments = await models.$queryRaw(`
@@ -133,7 +147,7 @@ export default {
AND created_at <= $2
ORDER BY created_at DESC
OFFSET $3
- LIMIT ${LIMIT}`, Number(userId), decodedCursor.time, decodedCursor.offset)
+ LIMIT ${LIMIT}`, user.id, decodedCursor.time, decodedCursor.offset)
return {
cursor: comments.length === LIMIT ? nextCursorEncoded(decodedCursor) : null,
@@ -141,13 +155,6 @@ export default {
}
},
item: getItem,
- userComments: async (parent, { userId }, { models }) => {
- return await models.$queryRaw(`
- ${SELECT}
- FROM "Item"
- WHERE "userId" = $1 AND "parentId" IS NOT NULL
- ORDER BY created_at DESC`, Number(userId))
- },
pageTitle: async (parent, { url }, { models }) => {
try {
const response = await fetch(ensureProtocol(url), { redirect: 'follow' })
@@ -524,11 +531,12 @@ const LEFT_JOIN_SATS =
JOIN "ItemAct" ON i.id = "ItemAct"."itemId"
GROUP BY i.id) x ON "Item".id = x.id`
+/* NOTE: because many items will have the same rank, we need to tie break with a unique field so pagination works */
function timedOrderBySats (num) {
return `ORDER BY ((x.sats-1)/POWER(EXTRACT(EPOCH FROM ($${num} - "Item".created_at))/3600+2, 1.5) +
- (x.boost)/POWER(EXTRACT(EPOCH FROM ($${num} - "Item".created_at))/3600+2, 5)) DESC NULLS LAST`
+ (x.boost)/POWER(EXTRACT(EPOCH FROM ($${num} - "Item".created_at))/3600+2, 5)) DESC NULLS LAST, "Item".id DESC`
}
const ORDER_BY_SATS =
`ORDER BY ((x.sats-1)/POWER(EXTRACT(EPOCH FROM ((NOW() AT TIME ZONE 'UTC') - "Item".created_at))/3600+2, 1.5) +
- (x.boost)/POWER(EXTRACT(EPOCH FROM ((NOW() AT TIME ZONE 'UTC') - "Item".created_at))/3600+2, 5)) DESC NULLS LAST`
+ (x.boost)/POWER(EXTRACT(EPOCH FROM ((NOW() AT TIME ZONE 'UTC') - "Item".created_at))/3600+2, 5)) DESC NULLS LAST, "Item".id DESC`
diff --git a/api/ssrApollo.js b/api/ssrApollo.js
index 625f660a..82d7d4a7 100644
--- a/api/ssrApollo.js
+++ b/api/ssrApollo.js
@@ -5,6 +5,7 @@ import { getSession } from 'next-auth/client'
import resolvers from './resolvers'
import typeDefs from './typeDefs'
import models from './models'
+import { print } from 'graphql'
export default async function getSSRApolloClient (req) {
const session = req && await getSession({ req })
@@ -23,3 +24,29 @@ export default async function getSSRApolloClient (req) {
cache: new InMemoryCache()
})
}
+
+export function getGetServerSideProps (query, variables = null) {
+ return async function ({ req, params }) {
+ const client = await getSSRApolloClient(req)
+ const { error, data } = await client.query({
+ query,
+ variables: { ...params, ...variables }
+ })
+
+ if (error || !data) {
+ return {
+ notFound: true
+ }
+ }
+
+ return {
+ props: {
+ apollo: {
+ query: print(query),
+ variables: { ...params, ...variables }
+ },
+ data
+ }
+ }
+ }
+}
diff --git a/api/typeDefs/item.js b/api/typeDefs/item.js
index 54b80f18..5200591a 100644
--- a/api/typeDefs/item.js
+++ b/api/typeDefs/item.js
@@ -2,10 +2,9 @@ import { gql } from 'apollo-server-micro'
export default gql`
extend type Query {
- moreItems(sort: String!, cursor: String, userId: ID, within: String): Items
- moreFlatComments(cursor: String, userId: ID): Comments
+ moreItems(sort: String!, cursor: String, name: String, within: [String]): Items
+ moreFlatComments(cursor: String, name: String!): Comments
item(id: ID!): Item
- userComments(userId: ID!): [Item!]
pageTitle(url: String!): String
}
diff --git a/components/comments-flat.js b/components/comments-flat.js
index bad23b49..ed766a53 100644
--- a/components/comments-flat.js
+++ b/components/comments-flat.js
@@ -8,8 +8,7 @@ import MoreFooter from './more-footer'
export default function CommentsFlat ({ variables, comments, cursor, ...props }) {
const router = useRouter()
const { data, fetchMore } = useQuery(MORE_FLAT_COMMENTS, {
- variables,
- fetchPolicy: router.query.cache ? 'cache-first' : undefined
+ variables
})
if (!data && !comments) {
diff --git a/components/comments.js b/components/comments.js
index 5c2b7c96..dfcd1929 100644
--- a/components/comments.js
+++ b/components/comments.js
@@ -1,5 +1,4 @@
import { useQuery } from '@apollo/client'
-import { useRouter } from 'next/router'
import { useEffect } from 'react'
import Comment, { CommentSkeleton } from './comment'
@@ -22,10 +21,7 @@ export function CommentsSkeleton () {
}
export function CommentsQuery ({ query, ...props }) {
- const router = useRouter()
- const { error, data } = useQuery(query, {
- fetchPolicy: router.query.cache ? 'cache-first' : undefined
- })
+ const { error, data } = useQuery(query)
if (error) return
Failed to load!
if (!data) {
diff --git a/components/header.js b/components/header.js
index 66c61bc3..477bcd4a 100644
--- a/components/header.js
+++ b/components/header.js
@@ -16,16 +16,6 @@ function WalletSummary ({ me }) {
return `${me?.sats} \\ ${me?.stacked}`
}
-function RefreshableLink ({ href, children, ...props }) {
- const router = useRouter()
- const same = router.asPath === href
- return (
-
- {children}
-
- )
-}
-
export default function Header () {
const router = useRouter()
const path = router.asPath.split('?')[0]
@@ -61,7 +51,7 @@ export default function Header () {
}
-
+
notifications
{me?.hasNewNotes &&
@@ -69,7 +59,7 @@ export default function Header () {
{' '}
}
-
+
wallet
@@ -84,12 +74,12 @@ export default function Header () {
-
+
recent
-
-
+
+
top
-
+
{me
? (
@@ -139,18 +129,18 @@ export default function Header () {
className={styles.navbarNav}
activeKey={path}
>
-
+
STACKER NEWS
-
-
+
+
SN
-
+
+
{sort}
-
+
}
key={`/${sort}`}
id='recent-top-button'
diff --git a/components/items.js b/components/items.js
index 09f15ebd..f048c899 100644
--- a/components/items.js
+++ b/components/items.js
@@ -2,15 +2,10 @@ import { useQuery } from '@apollo/client'
import Item, { ItemSkeleton } from './item'
import styles from './items.module.css'
import { MORE_ITEMS } from '../fragments/items'
-import { useRouter } from 'next/router'
import MoreFooter from './more-footer'
export default function Items ({ variables, rank, items, cursor }) {
- const router = useRouter()
- const { data, fetchMore } = useQuery(MORE_ITEMS, {
- variables,
- fetchPolicy: router.query.cache ? 'cache-first' : undefined
- })
+ const { data, fetchMore } = useQuery(MORE_ITEMS, { variables })
if (!data && !items) {
return
diff --git a/components/notifications.js b/components/notifications.js
index 70d86982..cdbc1d2a 100644
--- a/components/notifications.js
+++ b/components/notifications.js
@@ -44,11 +44,7 @@ function Notification ({ n }) {
}
export default function Notifications ({ notifications, cursor, lastChecked, variables }) {
- const router = useRouter()
- const { data, fetchMore } = useQuery(NOTIFICATIONS, {
- variables,
- fetchPolicy: router.query.cache ? 'cache-first' : undefined
- })
+ const { data, fetchMore } = useQuery(NOTIFICATIONS, { variables })
if (data) {
({ notifications: { notifications, cursor } } = data)
diff --git a/components/user-header.js b/components/user-header.js
index 05362081..fded93ef 100644
--- a/components/user-header.js
+++ b/components/user-header.js
@@ -71,7 +71,7 @@ export default function UserHeader ({ user }) {
}
router.replace({
pathname: router.pathname,
- query: { ...router.query, username: name }
+ query: { ...router.query, name }
})
client.writeFragment({
diff --git a/fragments/comments.js b/fragments/comments.js
index 2235c586..f263c317 100644
--- a/fragments/comments.js
+++ b/fragments/comments.js
@@ -27,8 +27,8 @@ export const COMMENT_FIELDS = gql`
export const MORE_FLAT_COMMENTS = gql`
${COMMENT_FIELDS}
- query MoreFlatComments($cursor: String, $userId: ID) {
- moreFlatComments(cursor: $cursor, userId: $userId) {
+ query MoreFlatComments($cursor: String, $name: String!) {
+ moreFlatComments(cursor: $cursor, name: $name) {
cursor
comments {
...CommentFields
diff --git a/fragments/items.js b/fragments/items.js
index 03008a49..b32edf41 100644
--- a/fragments/items.js
+++ b/fragments/items.js
@@ -28,20 +28,30 @@ export const ITEM_FIELDS = gql`
export const MORE_ITEMS = gql`
${ITEM_FIELDS}
- query MoreItems($sort: String!, $cursor: String, $userId: ID, $within: String) {
- moreItems(sort: $sort, cursor: $cursor, userId: $userId, within: $within) {
+ query MoreItems($sort: String!, $cursor: String, $name: String, $within: [String]) {
+ moreItems(sort: $sort, cursor: $cursor, name: $name, within: $within) {
cursor
items {
...ItemFields
}
}
- } `
+ }`
-export const ITEM_FULL = id => gql`
+export const ITEM = gql`
+ ${ITEM_FIELDS}
+
+ query Item($id: ID!) {
+ item(id: $id) {
+ ...ItemFields
+ text
+ }
+ }`
+
+export const ITEM_FULL = gql`
${ITEM_FIELDS}
${COMMENTS}
- {
- item(id: ${id}) {
+ query Item($id: ID!) {
+ item(id: $id) {
...ItemFields
text
comments {
diff --git a/fragments/users.js b/fragments/users.js
index 447865c5..ad2cc860 100644
--- a/fragments/users.js
+++ b/fragments/users.js
@@ -1,4 +1,5 @@
import { gql } from '@apollo/client'
+import { COMMENT_FIELDS } from './comments'
import { ITEM_FIELDS, ITEM_WITH_COMMENTS } from './items'
export const USER_FIELDS = gql`
@@ -17,14 +18,52 @@ export const USER_FIELDS = gql`
}
}`
-export const USER_FULL = name => gql`
+export const USER_FULL = gql`
${USER_FIELDS}
${ITEM_WITH_COMMENTS}
- {
- user(name: "${name}") {
+ query User($name: String!) {
+ user(name: $name) {
...UserFields
bio {
...ItemWithComments
}
}
}`
+
+export const USER_WITH_COMMENTS = gql`
+ ${USER_FIELDS}
+ ${ITEM_WITH_COMMENTS}
+ ${COMMENT_FIELDS}
+ query UserWithComments($name: String!) {
+ user(name: $name) {
+ ...UserFields
+ bio {
+ ...ItemWithComments
+ }
+ }
+ moreFlatComments(name: $name) {
+ cursor
+ comments {
+ ...CommentFields
+ }
+ }
+ }`
+
+export const USER_WITH_POSTS = gql`
+ ${USER_FIELDS}
+ ${ITEM_WITH_COMMENTS}
+ ${ITEM_FIELDS}
+ query UserWithPosts($name: String!, $sort: String!) {
+ user(name: $name) {
+ ...UserFields
+ bio {
+ ...ItemWithComments
+ }
+ }
+ moreItems(sort: $sort, name: $name) {
+ cursor
+ items {
+ ...ItemFields
+ }
+ }
+ }`
diff --git a/fragments/wallet.js b/fragments/wallet.js
new file mode 100644
index 00000000..c0766463
--- /dev/null
+++ b/fragments/wallet.js
@@ -0,0 +1,25 @@
+import { gql } from '@apollo/client'
+
+export const INVOICE = gql`
+ query Invoice($id: ID!) {
+ invoice(id: $id) {
+ id
+ bolt11
+ msatsReceived
+ cancelled
+ confirmedAt
+ expiresAt
+ }
+ }`
+
+export const WITHDRAWL = gql`
+ query Withdrawl($id: ID!) {
+ withdrawl(id: $id) {
+ id
+ bolt11
+ satsPaid
+ satsFeePaying
+ satsFeePaid
+ status
+ }
+ }`
diff --git a/lib/apollo.js b/lib/apollo.js
index 5474c04c..96e1e75f 100644
--- a/lib/apollo.js
+++ b/lib/apollo.js
@@ -7,14 +7,14 @@ const additiveLink = from([
new HttpLink({ uri: '/api/graphql' })
])
-function isFirstPage (cursor, existing) {
+function isFirstPage (cursor, existingThings) {
if (cursor) {
const decursor = decodeCursor(cursor)
return decursor.offset === LIMIT
} else {
// we don't have anything cached, or our existing items are less than
// or equal to a full page
- return !existing || !existing.items || existing.items.length < LIMIT
+ return existingThings?.length < LIMIT
}
}
@@ -26,9 +26,9 @@ export default function getApolloClient () {
Query: {
fields: {
moreItems: {
- keyArgs: ['sort', 'userId', 'within'],
+ keyArgs: ['sort', 'name', 'within'],
merge (existing, incoming) {
- if (isFirstPage(incoming.cursor, existing)) {
+ if (isFirstPage(incoming.cursor, existing?.items)) {
return incoming
}
@@ -39,9 +39,9 @@ export default function getApolloClient () {
}
},
moreFlatComments: {
- keyArgs: ['userId'],
+ keyArgs: ['name'],
merge (existing, incoming) {
- if (isFirstPage(incoming.cursor, existing)) {
+ if (isFirstPage(incoming.cursor, existing?.comments)) {
return incoming
}
@@ -54,7 +54,7 @@ export default function getApolloClient () {
notifications: {
keyArgs: false,
merge (existing, incoming) {
- if (isFirstPage(incoming.cursor, existing)) {
+ if (isFirstPage(incoming.cursor, existing?.notifications)) {
return incoming
}
@@ -72,11 +72,11 @@ export default function getApolloClient () {
defaultOptions: {
// cache-and-network allows us to refresh pages on navigation
watchQuery: {
- fetchPolicy: 'cache-and-network',
+ fetchPolicy: 'cache-only',
nextFetchPolicy: 'cache-first'
},
query: {
- fetchPolicy: 'cache-and-network',
+ fetchPolicy: 'cache-only',
nextFetchPolicy: 'cache-first'
}
}
diff --git a/pages/[name]/comments.js b/pages/[name]/comments.js
new file mode 100644
index 00000000..5f438157
--- /dev/null
+++ b/pages/[name]/comments.js
@@ -0,0 +1,30 @@
+import Layout from '../../components/layout'
+import { useQuery } from '@apollo/client'
+import UserHeader from '../../components/user-header'
+import CommentsFlat from '../../components/comments-flat'
+import Seo from '../../components/seo'
+import { USER_WITH_COMMENTS } from '../../fragments/users'
+import { getGetServerSideProps } from '../../api/ssrApollo'
+
+export const getServerSideProps = getGetServerSideProps(USER_WITH_COMMENTS)
+
+export default function UserComments (
+ { data: { user, moreFlatComments: { comments, cursor } } }) {
+ const { data } = useQuery(
+ USER_WITH_COMMENTS, { variables: { name: user.name } })
+
+ if (data) {
+ ({ user, moreFlatComments: { comments, cursor } } = data)
+ }
+
+ return (
+
+
+
+
+
+ )
+}
diff --git a/pages/[username]/index.js b/pages/[name]/index.js
similarity index 83%
rename from pages/[username]/index.js
rename to pages/[name]/index.js
index b510cf02..433424e1 100644
--- a/pages/[username]/index.js
+++ b/pages/[name]/index.js
@@ -12,28 +12,10 @@ import ActionTooltip from '../../components/action-tooltip'
import TextareaAutosize from 'react-textarea-autosize'
import { useMe } from '../../components/me'
import { USER_FULL } from '../../fragments/users'
-import { useRouter } from 'next/router'
import { ITEM_FIELDS } from '../../fragments/items'
-import getSSRApolloClient from '../../api/ssrApollo'
+import { getGetServerSideProps } from '../../api/ssrApollo'
-export async function getServerSideProps ({ req, params: { username } }) {
- const client = await getSSRApolloClient(req)
- const { error, data } = await client.query({
- query: USER_FULL(username)
- })
-
- if (error || !data?.user) {
- return {
- notFound: true
- }
- }
-
- return {
- props: {
- user: data.user
- }
- }
-}
+export const getServerSideProps = getGetServerSideProps(USER_FULL)
const BioSchema = Yup.object({
bio: Yup.string().required('required').trim()
@@ -93,15 +75,12 @@ export function BioForm ({ handleSuccess, bio }) {
)
}
-export default function User ({ user }) {
+export default function User ({ data: { user } }) {
const [create, setCreate] = useState(false)
const [edit, setEdit] = useState(false)
const me = useMe()
- const router = useRouter()
- const { data } = useQuery(USER_FULL(user.name), {
- fetchPolicy: router.query.cache ? 'cache-first' : undefined
- })
+ const { data } = useQuery(USER_FULL, { variables: { name: user.name } })
if (data) {
({ user } = data)
diff --git a/pages/[name]/posts.js b/pages/[name]/posts.js
new file mode 100644
index 00000000..016ec60b
--- /dev/null
+++ b/pages/[name]/posts.js
@@ -0,0 +1,29 @@
+import Layout from '../../components/layout'
+import { useQuery } from '@apollo/client'
+import UserHeader from '../../components/user-header'
+import Seo from '../../components/seo'
+import Items from '../../components/items'
+import { USER_WITH_POSTS } from '../../fragments/users'
+import { getGetServerSideProps } from '../../api/ssrApollo'
+
+export const getServerSideProps = getGetServerSideProps(USER_WITH_POSTS, { sort: 'user' })
+
+export default function UserPosts ({ data: { user, moreItems: { items, cursor } } }) {
+ const { data } = useQuery(USER_WITH_POSTS,
+ { variables: { name: user.name, sort: 'user' } })
+
+ if (data) {
+ ({ user, moreItems: { items, cursor } } = data)
+ }
+
+ return (
+
+
+
+
+
+ )
+}
diff --git a/pages/[username]/comments.js b/pages/[username]/comments.js
deleted file mode 100644
index 6c344b85..00000000
--- a/pages/[username]/comments.js
+++ /dev/null
@@ -1,64 +0,0 @@
-import Layout from '../../components/layout'
-import { useQuery } from '@apollo/client'
-import UserHeader from '../../components/user-header'
-import CommentsFlat from '../../components/comments-flat'
-import Seo from '../../components/seo'
-import { USER_FULL } from '../../fragments/users'
-import { useRouter } from 'next/router'
-import { MORE_FLAT_COMMENTS } from '../../fragments/comments'
-import { getServerSideProps as headerProps } from './index'
-import getSSRApolloClient from '../../api/ssrApollo'
-
-export async function getServerSideProps ({ req, params: { username } }) {
- const { notFound, props } = await headerProps({ req, params: { username } })
-
- if (notFound) {
- return {
- notFound
- }
- }
-
- const { user } = props
- const client = await getSSRApolloClient(req)
- const { data } = await client.query({
- query: MORE_FLAT_COMMENTS,
- variables: { userId: user.id }
- })
-
- let comments, cursor
- if (data) {
- ({ moreFlatComments: { comments, cursor } } = data)
- }
-
- return {
- props: {
- ...props,
- comments,
- cursor
- }
- }
-}
-
-export default function UserComments ({ user, comments, cursor }) {
- const router = useRouter()
-
- const { data } = useQuery(
- USER_FULL(user.name), {
- fetchPolicy: router.query.cache ? 'cache-first' : undefined
- })
-
- if (data) {
- ({ user } = data)
- }
-
- return (
-
-
-
-
-
- )
-}
diff --git a/pages/[username]/posts.js b/pages/[username]/posts.js
deleted file mode 100644
index 84fb2988..00000000
--- a/pages/[username]/posts.js
+++ /dev/null
@@ -1,64 +0,0 @@
-import Layout from '../../components/layout'
-import { useQuery } from '@apollo/client'
-import UserHeader from '../../components/user-header'
-import Seo from '../../components/seo'
-import Items from '../../components/items'
-import { useRouter } from 'next/router'
-import { USER_FULL } from '../../fragments/users'
-import { getServerSideProps as headerProps } from './index'
-import getSSRApolloClient from '../../api/ssrApollo'
-import { MORE_ITEMS } from '../../fragments/items'
-
-export async function getServerSideProps ({ req, params: { username } }) {
- const { notFound, props } = await headerProps({ req, params: { username } })
-
- if (notFound) {
- return {
- notFound
- }
- }
-
- const { user } = props
- const client = await getSSRApolloClient(req)
- const { data } = await client.query({
- query: MORE_ITEMS,
- variables: { sort: 'user', userId: user.id }
- })
-
- let items, cursor
- if (data) {
- ({ moreItems: { items, cursor } } = data)
- }
-
- return {
- props: {
- ...props,
- items,
- cursor
- }
- }
-}
-
-export default function UserPosts ({ user, items, cursor }) {
- const router = useRouter()
-
- const { data } = useQuery(
- USER_FULL(user.name), {
- fetchPolicy: router.query.cache ? 'cache-first' : undefined
- })
-
- if (data) {
- ({ user } = data)
- }
-
- return (
-
-
-
-
-
- )
-}
diff --git a/pages/_app.js b/pages/_app.js
index 0267e949..f02f6795 100644
--- a/pages/_app.js
+++ b/pages/_app.js
@@ -1,33 +1,34 @@
import '../styles/globals.scss'
-import { ApolloProvider } from '@apollo/client'
+import { ApolloProvider, gql } from '@apollo/client'
import { Provider } from 'next-auth/client'
import { FundErrorModal, FundErrorProvider } from '../components/fund-error'
import { MeProvider } from '../components/me'
import PlausibleProvider from 'next-plausible'
import { LightningProvider } from '../components/lightning'
-import { useRouter } from 'next/router'
-import { useEffect } from 'react'
import { ItemActModal, ItemActProvider } from '../components/item-act'
import getApolloClient from '../lib/apollo'
function MyApp ({ Component, pageProps: { session, ...props } }) {
- const router = useRouter()
-
- useEffect(() => {
- router.beforePopState(({ url, as, options }) => {
- // we need to tell the next page to use a cache-first fetch policy ...
- // so that scroll position can be maintained
- const fullurl = new URL(url, 'https://stacker.news')
- fullurl.searchParams.set('cache', true)
- router.push(`${fullurl.pathname}${fullurl.search}`, as, options)
- return false
- })
- }, [])
+ const client = getApolloClient()
+ /*
+ If we are on the client, we populate the apollo cache with the
+ ssr data
+ */
+ if (typeof window !== 'undefined') {
+ const { apollo, data } = props
+ if (apollo) {
+ client.writeQuery({
+ query: gql`${apollo.query}`,
+ data: data,
+ variables: apollo.variables
+ })
+ }
+ }
return (
-
+
diff --git a/pages/index.js b/pages/index.js
index 88848b4a..58b248b9 100644
--- a/pages/index.js
+++ b/pages/index.js
@@ -1,36 +1,17 @@
import Layout from '../components/layout'
import Items from '../components/items'
-import { useRouter } from 'next/router'
-import getSSRApolloClient from '../api/ssrApollo'
+import { getGetServerSideProps } from '../api/ssrApollo'
import { MORE_ITEMS } from '../fragments/items'
-export async function getServerSideProps ({ req }) {
- const client = await getSSRApolloClient(req)
- const { data } = await client.query({
- query: MORE_ITEMS,
- variables: { sort: 'hot' }
- })
+const variables = { sort: 'hot' }
+export const getServerSideProps = getGetServerSideProps(MORE_ITEMS, variables)
- let items, cursor
- if (data) {
- ({ moreItems: { items, cursor } } = data)
- }
-
- return {
- props: {
- items,
- cursor
- }
- }
-}
-
-export default function Index ({ items, cursor }) {
- const router = useRouter()
+export default function Index ({ data: { moreItems: { items, cursor } } }) {
return (
)
diff --git a/pages/invites/index.js b/pages/invites/index.js
index 621d5bb3..82b403ed 100644
--- a/pages/invites/index.js
+++ b/pages/invites/index.js
@@ -148,7 +148,7 @@ export default function Invites () {
...InviteFields
}
}
- `)
+ `, { fetchPolicy: 'cache-and-network' })
const [active, inactive] = data && data.invites
? data.invites.reduce((result, invite) => {
diff --git a/pages/invoices/[id].js b/pages/invoices/[id].js
index 80daee96..909e8d4f 100644
--- a/pages/invoices/[id].js
+++ b/pages/invoices/[id].js
@@ -1,38 +1,24 @@
import { useQuery } from '@apollo/client'
-import gql from 'graphql-tag'
import { Invoice } from '../../components/invoice'
import { LnQRSkeleton } from '../../components/lnqr'
import LayoutCenter from '../../components/layout-center'
+import { useRouter } from 'next/router'
+import { INVOICE } from '../../fragments/wallet'
-export async function getServerSideProps ({ params: { id } }) {
- return {
- props: {
- id
- }
- }
-}
-
-export default function FullInvoice ({ id }) {
- const query = gql`
- {
- invoice(id: ${id}) {
- id
- bolt11
- msatsReceived
- cancelled
- confirmedAt
- expiresAt
- }
- }`
+export default function FullInvoice () {
return (
-
+
)
}
-function LoadInvoice ({ query }) {
- const { loading, error, data } = useQuery(query, { pollInterval: 1000 })
+function LoadInvoice () {
+ const router = useRouter()
+ const { loading, error, data } = useQuery(INVOICE, {
+ pollInterval: 1000,
+ variables: { id: router.query.id }
+ })
if (error) return error
if (!data || loading) {
return
diff --git a/pages/items/[id]/edit.js b/pages/items/[id]/edit.js
index 5c658b9f..c79c6813 100644
--- a/pages/items/[id]/edit.js
+++ b/pages/items/[id]/edit.js
@@ -1,38 +1,12 @@
-import { ITEM_FIELDS } from '../../../fragments/items'
-import { gql } from '@apollo/client'
-import getSSRApolloClient from '../../../api/ssrApollo'
+import { ITEM } from '../../../fragments/items'
+import { getGetServerSideProps } from '../../../api/ssrApollo'
import { DiscussionForm } from '../../../components/discussion-form'
import { LinkForm } from '../../../components/link-form'
import LayoutCenter from '../../../components/layout-center'
-export async function getServerSideProps ({ req, params: { id } }) {
- const client = await getSSRApolloClient(req)
- const { error, data: { item } } = await client.query({
- query:
- gql`
- ${ITEM_FIELDS}
- {
- item(id: ${id}) {
- ...ItemFields
- text
- }
- }`
- })
+export const getServerSideProps = getGetServerSideProps(ITEM)
- if (error || !item) {
- return {
- notFound: true
- }
- }
-
- return {
- props: {
- item
- }
- }
-}
-
-export default function PostEdit ({ item }) {
+export default function PostEdit ({ data: { item } }) {
const editThreshold = new Date(item.createdAt).getTime() + 10 * 60000
return (
diff --git a/pages/items/[id]/index.js b/pages/items/[id]/index.js
index 64093b7a..da7625b9 100644
--- a/pages/items/[id]/index.js
+++ b/pages/items/[id]/index.js
@@ -2,39 +2,14 @@ import Layout from '../../../components/layout'
import { ITEM_FULL } from '../../../fragments/items'
import Seo from '../../../components/seo'
import ItemFull from '../../../components/item-full'
-import getSSRApolloClient from '../../../api/ssrApollo'
+import { getGetServerSideProps } from '../../../api/ssrApollo'
import { useQuery } from '@apollo/client'
-import { useRouter } from 'next/router'
-export async function getServerSideProps ({ req, params: { id } }) {
- if (isNaN(id)) {
- return {
- notFound: true
- }
- }
+export const getServerSideProps = getGetServerSideProps(ITEM_FULL)
- const client = await getSSRApolloClient(req)
- const { error, data } = await client.query({
- query: ITEM_FULL(id)
- })
-
- if (error || !data?.item) {
- return {
- notFound: true
- }
- }
-
- return {
- props: {
- item: data.item
- }
- }
-}
-
-export default function AnItem ({ item }) {
- const router = useRouter()
- const { data } = useQuery(ITEM_FULL(item.id), {
- fetchPolicy: router.query.cache ? 'cache-first' : undefined
+export default function AnItem ({ data: { item } }) {
+ const { data } = useQuery(ITEM_FULL, {
+ variables: { id: item.id }
})
if (data) {
({ item } = data)
diff --git a/pages/notifications.js b/pages/notifications.js
index e78e2ab7..49fbe839 100644
--- a/pages/notifications.js
+++ b/pages/notifications.js
@@ -1,36 +1,16 @@
-import { useRouter } from 'next/router'
-import getSSRApolloClient from '../api/ssrApollo'
+import { getGetServerSideProps } from '../api/ssrApollo'
import Layout from '../components/layout'
import Notifications from '../components/notifications'
import { NOTIFICATIONS } from '../fragments/notifications'
-export async function getServerSideProps ({ req }) {
- const client = await getSSRApolloClient(req)
- const { data } = await client.query({
- query: NOTIFICATIONS
- })
+export const getServerSideProps = getGetServerSideProps(NOTIFICATIONS)
- let notifications, cursor, lastChecked
- if (data) {
- ({ notifications: { notifications, cursor, lastChecked } } = data)
- }
-
- return {
- props: {
- notifications,
- cursor,
- lastChecked
- }
- }
-}
-
-export default function NotificationPage ({ notifications, cursor, lastChecked }) {
- const router = useRouter()
+export default function NotificationPage ({ data: { notifications: { notifications, cursor, lastChecked } } }) {
return (
)
diff --git a/pages/post.js b/pages/post.js
index df69dbb3..12a01b23 100644
--- a/pages/post.js
+++ b/pages/post.js
@@ -6,12 +6,6 @@ import { useMe } from '../components/me'
import { DiscussionForm } from '../components/discussion-form'
import { LinkForm } from '../components/link-form'
-export async function getServerSideProps () {
- return {
- props: {}
- }
-}
-
export function PostForm () {
const router = useRouter()
const me = useMe()
diff --git a/pages/recent.js b/pages/recent.js
index f0480e9b..fa87db71 100644
--- a/pages/recent.js
+++ b/pages/recent.js
@@ -1,36 +1,17 @@
import Layout from '../components/layout'
import Items from '../components/items'
-import { useRouter } from 'next/router'
-import getSSRApolloClient from '../api/ssrApollo'
+import { getGetServerSideProps } from '../api/ssrApollo'
import { MORE_ITEMS } from '../fragments/items'
-export async function getServerSideProps ({ req }) {
- const client = await getSSRApolloClient(req)
- const { data } = await client.query({
- query: MORE_ITEMS,
- variables: { sort: 'recent' }
- })
+const variables = { sort: 'recent' }
+export const getServerSideProps = getGetServerSideProps(MORE_ITEMS, { sort: 'recent' })
- let items, cursor
- if (data) {
- ({ moreItems: { items, cursor } } = data)
- }
-
- return {
- props: {
- items,
- cursor
- }
- }
-}
-
-export default function Index ({ items, cursor }) {
- const router = useRouter()
+export default function Index ({ data: { moreItems: { items, cursor } } }) {
return (
)
diff --git a/pages/top/[[...within]].js b/pages/top/[[...within]].js
index b599ec43..4a0bbf28 100644
--- a/pages/top/[[...within]].js
+++ b/pages/top/[[...within]].js
@@ -1,34 +1,15 @@
import Layout from '../../components/layout'
import Items from '../../components/items'
import { useRouter } from 'next/router'
-import getSSRApolloClient from '../../api/ssrApollo'
+import { getGetServerSideProps } from '../../api/ssrApollo'
import { MORE_ITEMS } from '../../fragments/items'
import { Nav, Navbar } from 'react-bootstrap'
import styles from '../../components/header.module.css'
import Link from 'next/link'
-export async function getServerSideProps ({ req, params: { within } }) {
- const client = await getSSRApolloClient(req)
- console.log('called')
- const { data } = await client.query({
- query: MORE_ITEMS,
- variables: { sort: 'top', within: within?.pop() }
- })
+export const getServerSideProps = getGetServerSideProps(MORE_ITEMS, { sort: 'top'})
- let items, cursor
- if (data) {
- ({ moreItems: { items, cursor } } = data)
- }
-
- return {
- props: {
- items,
- cursor
- }
- }
-}
-
-export default function Index ({ items, cursor }) {
+export default function Index ({ data: { moreItems: { items, cursor } } }) {
const router = useRouter()
const path = router.asPath.split('?')[0]
@@ -88,7 +69,7 @@ export default function Index ({ items, cursor }) {
)
diff --git a/pages/wallet.js b/pages/wallet.js
index 6b3f6581..2c898403 100644
--- a/pages/wallet.js
+++ b/pages/wallet.js
@@ -13,12 +13,6 @@ import { useEffect, useState } from 'react'
import { requestProvider } from 'webln'
import { Alert } from 'react-bootstrap'
-export async function getServerSideProps () {
- return {
- props: {}
- }
-}
-
export default function Wallet () {
return (
diff --git a/pages/withdrawals/[id].js b/pages/withdrawals/[id].js
index 988da7bc..8171609e 100644
--- a/pages/withdrawals/[id].js
+++ b/pages/withdrawals/[id].js
@@ -1,32 +1,15 @@
import { useQuery } from '@apollo/client'
-import gql from 'graphql-tag'
import LayoutCenter from '../../components/layout-center'
import { CopyInput, Input, InputSkeleton } from '../../components/form'
import InputGroup from 'react-bootstrap/InputGroup'
import InvoiceStatus from '../../components/invoice-status'
+import { useRouter } from 'next/router'
+import { WITHDRAWL } from '../../fragments/wallet'
-export async function getServerSideProps ({ params: { id } }) {
- return {
- props: {
- id
- }
- }
-}
-
-export default function Withdrawl ({ id }) {
- const query = gql`
- {
- withdrawl(id: ${id}) {
- bolt11
- satsPaid
- satsFeePaying
- satsFeePaid
- status
- }
- }`
+export default function Withdrawl () {
return (
-
+
)
}
@@ -45,8 +28,12 @@ export function WithdrawlSkeleton ({ status }) {
)
}
-function LoadWithdrawl ({ query }) {
- const { loading, error, data } = useQuery(query, { pollInterval: 1000 })
+function LoadWithdrawl () {
+ const router = useRouter()
+ const { loading, error, data } = useQuery(WITHDRAWL, {
+ variables: { id: router.query.id },
+ pollInterval: 1000
+ })
if (error) return error
if (!data || loading) {
return