diff --git a/components/header.js b/components/header.js
deleted file mode 100644
index 59c4518a..00000000
--- a/components/header.js
+++ /dev/null
@@ -1,356 +0,0 @@
-import Dropdown from 'react-bootstrap/Dropdown'
-import Navbar from 'react-bootstrap/Navbar'
-import Nav from 'react-bootstrap/Nav'
-import Link from 'next/link'
-import styles from './header.module.css'
-import { useRouter } from 'next/router'
-import Button from 'react-bootstrap/Button'
-import Container from 'react-bootstrap/Container'
-import Price from './price'
-import { useMe } from './me'
-import Head from 'next/head'
-import { signOut } from 'next-auth/react'
-import { useCallback, useEffect } from 'react'
-import { randInRange } from '@/lib/rand'
-import { abbrNum, msatsToSats } from '@/lib/format'
-import NoteIcon from '@/svgs/notification-4-fill.svg'
-import { useQuery } from '@apollo/client'
-import LightningIcon from '@/svgs/bolt.svg'
-import SearchIcon from '@/svgs/search-line.svg'
-import BackArrow from '@/svgs/arrow-left-line.svg'
-import { BALANCE_LIMIT_MSATS, SSR } from '@/lib/constants'
-import { useLightning } from './lightning'
-import { HAS_NOTIFICATIONS } from '@/fragments/notifications'
-import AnonIcon from '@/svgs/spy-fill.svg'
-import Hat from './hat'
-import HiddenWalletSummary from './hidden-wallet-summary'
-import { clearNotifications } from '@/lib/badge'
-import { useServiceWorker } from './serviceworker'
-import SubSelect from './sub-select'
-
-function WalletSummary ({ me }) {
- if (!me) return null
- if (me.privates?.hideWalletBalance) {
- return
- }
- return `${abbrNum(me.privates?.sats)}`
-}
-
-function Back () {
- const router = useRouter()
-
- return router.asPath !== '/' &&
- {
- if (typeof window.navigation === 'undefined' || window.navigation.canGoBack === undefined || window?.navigation.canGoBack) {
- router.back()
- } else {
- router.push('/')
- }
- }}
- >
-
-
-}
-
-function NotificationBell () {
- const { data } = useQuery(HAS_NOTIFICATIONS, SSR
- ? {}
- : {
- pollInterval: 30000,
- nextFetchPolicy: 'cache-and-network',
- onCompleted: ({ hasNewNotes }) => {
- if (!hasNewNotes) {
- clearNotifications()
- }
- }
- })
-
- return (
- <>
-
-
-
-
-
-
- {data?.hasNewNotes &&
-
- {' '}
- }
-
-
- >
- )
-}
-
-function NavProfileMenu ({ me, dropNavKey }) {
- const { registration: swRegistration, togglePushSubscription } = useServiceWorker()
- return (
-
-
-
-
- {`@${me.name}`}
-
-
-
-
-
- profile
- {me && !me.bioId &&
-
- {' '}
-
}
-
-
-
- bookmarks
-
-
- wallet
-
-
- satistics
-
-
-
- referrals
-
-
-
-
- settings
-
-
-
- {
- try {
- // order is important because we need to be logged in to delete push subscription on server
- const pushSubscription = await swRegistration?.pushManager.getSubscription()
- if (pushSubscription) {
- await togglePushSubscription()
- }
- } catch (err) {
- // don't prevent signout because of an unsubscription error
- console.error(err)
- }
- await signOut({ callbackUrl: '/' })
- }}
- >logout
-
-
-
- {!me.bioId &&
-
- {' '}
- }
-
- )
-}
-
-function StackerCorner ({ dropNavKey }) {
- const me = useMe()
-
- const walletLimitReached = me.privates?.sats >= msatsToSats(BALANCE_LIMIT_MSATS)
-
- return (
-
-
-
-
-
-
-
-
-
-
-
- )
-}
-
-function LurkerCorner ({ path }) {
- const router = useRouter()
- const strike = useLightning()
-
- useEffect(() => {
- if (!window.localStorage.getItem('striked')) {
- const to = setTimeout(() => {
- strike()
- window.localStorage.setItem('striked', 'yep')
- }, randInRange(3000, 10000))
- return () => clearTimeout(to)
- }
- }, [])
-
- const handleLogin = useCallback(async pathname => await router.push({
- pathname,
- query: { callbackUrl: window.location.origin + router.asPath }
- }), [router])
-
- return path !== '/login' && path !== '/signup' && !path.startsWith('/invites') &&
-
-
-
-
-}
-
-const PREPEND_SUBS = ['home']
-const APPEND_SUBS = [{ label: '--------', items: ['create'] }]
-function NavItems ({ className, sub: subName, prefix }) {
- const sub = subName || 'home'
-
- return (
- <>
-
-
-
-
-
- hot
-
-
-
-
- recent
-
-
- {sub !== 'jobs' &&
-
-
- top
-
- }
- >
- )
-}
-
-function PostItem ({ className, prefix }) {
- const me = useMe()
-
- if (me) {
- return (
-
- post
-
- )
- }
-
- return (
-
- post
-
- )
-}
-
-export default function Header ({ sub }) {
- const router = useRouter()
- const path = router.asPath.split('?')[0]
- const prefix = sub ? `/~${sub}` : ''
- const topNavKey = path.split('/')[sub ? 2 : 1] ?? ''
- const dropNavKey = path.split('/').slice(sub ? 2 : 1).join('/')
- const me = useMe()
-
- return (
-
-
-
-
-
-
-
-
- )
-}
-
-export function HeaderStatic () {
- return (
-
-
-
-
-
- )
-}
diff --git a/components/navigation/common.js b/components/navigation/common.js
index 31bc4256..51f57013 100644
--- a/components/navigation/common.js
+++ b/components/navigation/common.js
@@ -6,10 +6,7 @@ import BackArrow from '../../svgs/arrow-left-line.svg'
import { useCallback, useEffect, useState } from 'react'
import Price from '../price'
import SubSelect from '../sub-select'
-import { useQuery } from '@apollo/client'
-import { HAS_NOTIFICATIONS } from '../../fragments/notifications'
-import { ANON_USER_ID, BALANCE_LIMIT_MSATS, SSR } from '../../lib/constants'
-import { clearNotifications } from '../../lib/badge'
+import { ANON_USER_ID, BALANCE_LIMIT_MSATS } from '../../lib/constants'
import Head from 'next/head'
import NoteIcon from '../../svgs/notification-4-fill.svg'
import { useMe } from '../me'
@@ -24,6 +21,7 @@ import LightningIcon from '../../svgs/bolt.svg'
import SearchIcon from '../../svgs/search-line.svg'
import classNames from 'classnames'
import SnIcon from '@/svgs/sn.svg'
+import { useHasNewNotes } from '../use-has-new-notes'
export function Brand ({ className }) {
return (
@@ -100,7 +98,7 @@ export function BackOrBrand ({ className }) {
export function SearchItem ({ prefix, className }) {
return (
-
+
@@ -132,27 +130,17 @@ export function NavSelect ({ sub: subName, className, size }) {
}
export function NavNotifications ({ className }) {
- const { data } = useQuery(HAS_NOTIFICATIONS, SSR
- ? {}
- : {
- pollInterval: 30000,
- nextFetchPolicy: 'cache-and-network',
- onCompleted: ({ hasNewNotes }) => {
- if (!hasNewNotes) {
- clearNotifications()
- }
- }
- })
+ const hasNewNotes = useHasNewNotes()
return (
<>
-
+
- {data?.hasNewNotes &&
+ {hasNewNotes &&
{' '}
}
diff --git a/components/use-has-new-notes.js b/components/use-has-new-notes.js
new file mode 100644
index 00000000..7ed393f2
--- /dev/null
+++ b/components/use-has-new-notes.js
@@ -0,0 +1,32 @@
+import { HAS_NOTIFICATIONS } from '@/fragments/notifications'
+import { clearNotifications } from '@/lib/badge'
+import { SSR } from '@/lib/constants'
+import { useQuery } from '@apollo/client'
+import React, { useContext } from 'react'
+
+export const HasNewNotesContext = React.createContext(false)
+
+export function HasNewNotesProvider ({ me, children }) {
+ const { data } = useQuery(HAS_NOTIFICATIONS,
+ SSR
+ ? {}
+ : {
+ pollInterval: 30000,
+ nextFetchPolicy: 'cache-and-network',
+ onCompleted: ({ hasNewNotes }) => {
+ if (!hasNewNotes) {
+ clearNotifications()
+ }
+ }
+ })
+
+ return (
+
+ {children}
+
+ )
+}
+
+export function useHasNewNotes () {
+ return useContext(HasNewNotesContext)
+}
diff --git a/pages/_app.js b/pages/_app.js
index 9e1e5d28..2b200f63 100644
--- a/pages/_app.js
+++ b/pages/_app.js
@@ -20,6 +20,7 @@ import { LoggerProvider } from '@/components/logger'
import { ChainFeeProvider } from '@/components/chain-fee.js'
import { WebLNProvider } from '@/components/webln'
import dynamic from 'next/dynamic'
+import { HasNewNotesProvider } from '@/components/use-has-new-notes'
const PWAPrompt = dynamic(() => import('react-ios-pwa-prompt'), { ssr: false })
@@ -102,28 +103,30 @@ export default function MyApp ({ Component, pageProps: { ...props } }) {
-
-
-
-
-
-
-
-
-
-
-
- {!router?.query?.disablePrompt && }
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+ {!router?.query?.disablePrompt && }
+
+
+
+
+
+
+
+
+
+
+