stacker.news/pages/_app.js

110 lines
3.4 KiB
JavaScript
Raw Normal View History

2021-04-14 00:57:32 +00:00
import '../styles/globals.scss'
import { ApolloProvider, gql, useQuery } from '@apollo/client'
2021-04-12 18:05:09 +00:00
import { Provider } from 'next-auth/client'
2021-11-09 17:38:58 +00:00
import { MeProvider } from '../components/me'
2021-07-15 20:49:13 +00:00
import PlausibleProvider from 'next-plausible'
import { LightningProvider } from '../components/lightning'
2021-09-30 15:46:58 +00:00
import getApolloClient from '../lib/apollo'
2021-11-13 13:28:08 +00:00
import NextNProgress from 'nextjs-progressbar'
2021-11-28 17:29:17 +00:00
import { PriceProvider } from '../components/price'
2022-05-19 16:50:38 +00:00
import Head from 'next/head'
import { useRouter } from 'next/dist/client/router'
import { useEffect } from 'react'
import Moon from '../svgs/moon-fill.svg'
import Layout from '../components/layout'
import { ShowModalProvider } from '../components/modal'
2023-02-08 21:56:43 +00:00
import ErrorBoundary from '../components/error-boundary'
function CSRWrapper ({ Component, apollo, ...props }) {
const { data, error } = useQuery(gql`${apollo.query}`, { variables: apollo.variables, fetchPolicy: 'cache-first' })
if (error) {
return (
<div className='d-flex font-weight-bold justify-content-center mt-3 mb-1'>
{error.toString()}
</div>
)
}
if (!data) {
return (
<Layout>
<div className='d-flex justify-content-center mt-3 mb-1'>
<Moon className='spin fill-grey' />
</div>
</Layout>
)
}
return <Component {...props} data={data} />
}
2021-03-22 20:36:10 +00:00
2021-09-30 15:46:58 +00:00
function MyApp ({ Component, pageProps: { session, ...props } }) {
2021-10-26 20:49:37 +00:00
const client = getApolloClient()
const router = useRouter()
2022-11-06 17:28:58 +00:00
useEffect(() => {
// HACK: 'cause there's no way to tell Next to skip SSR
// So every page load, we modify the route in browser history
// to point to the same page but without SSR, ie ?nodata=true
// this nodata var will get passed to the server on back/foward and
// 1. prevent data from reloading and 2. perserve scroll
// (2) is not possible while intercepting nav with beforePopState
2022-11-15 20:51:55 +00:00
if (router.isReady) {
router.replace({
pathname: router.pathname,
query: { ...router.query, nodata: true }
}, router.asPath, { ...router.options, scroll: false })
}
}, [router.asPath])
2021-11-09 22:43:56 +00:00
2021-10-26 20:49:37 +00:00
/*
If we are on the client, we populate the apollo cache with the
ssr data
*/
const { apollo, data, me, price } = props
2022-11-24 19:22:58 +00:00
if (apollo && data) {
client.writeQuery({
query: gql`${apollo.query}`,
data: data,
variables: apollo.variables
})
2021-10-26 20:49:37 +00:00
}
2021-04-12 18:05:09 +00:00
return (
2021-11-13 13:28:08 +00:00
<>
<NextNProgress
color='var(--primary)'
startPosition={0.3}
stopDelayMs={200}
height={2}
showOnShallow
options={{ showSpinner: false }}
/>
2022-05-19 16:50:38 +00:00
<Head>
<meta name='viewport' content='initial-scale=1.0, width=device-width' />
</Head>
2023-02-08 21:56:43 +00:00
<ErrorBoundary>
<PlausibleProvider domain='stacker.news' trackOutboundLinks>
<Provider session={session}>
<ApolloProvider client={client}>
<MeProvider me={me}>
<PriceProvider price={price}>
<LightningProvider>
<ShowModalProvider>
{data || !apollo?.query
? <Component {...props} />
: <CSRWrapper Component={Component} {...props} />}
</ShowModalProvider>
</LightningProvider>
</PriceProvider>
</MeProvider>
</ApolloProvider>
</Provider>
</PlausibleProvider>
</ErrorBoundary>
2021-11-13 13:28:08 +00:00
</>
2021-04-12 18:05:09 +00:00
)
2021-03-22 20:36:10 +00:00
}
export default MyApp