diff --git a/components/favicon.js b/components/favicon.js new file mode 100644 index 00000000..47da0a74 --- /dev/null +++ b/components/favicon.js @@ -0,0 +1,48 @@ +import { createContext, useContext, useMemo, useState } from 'react' +import { useHasNewNotes } from './use-has-new-notes' +import Head from 'next/head' + +const FAVICONS = { + default: '/favicon.png', + notify: '/favicon-notify.png', + comments: '/favicon-comments.png', + notifyWithComments: '/favicon-notify-with-comments.png' +} + +const getFavicon = (hasNewNotes, hasNewComments) => { + if (hasNewNotes && hasNewComments) return FAVICONS.notifyWithComments + if (hasNewNotes) return FAVICONS.notify + if (hasNewComments) return FAVICONS.comments + return FAVICONS.default +} + +export const FaviconContext = createContext() + +export default function FaviconProvider ({ children }) { + const hasNewNotes = useHasNewNotes() + const [hasNewComments, setHasNewComments] = useState(false) + + const favicon = useMemo(() => + getFavicon(hasNewNotes, hasNewComments), + [hasNewNotes, hasNewComments]) + + const contextValue = useMemo(() => ({ + favicon, + hasNewNotes, + hasNewComments, + setHasNewComments + }), [favicon, hasNewNotes, hasNewComments, setHasNewComments]) + + return ( + + + + + {children} + + ) +} + +export function useFavicon () { + return useContext(FaviconContext) +} diff --git a/components/nav/common.js b/components/nav/common.js index f97db615..0e9d2e5f 100644 --- a/components/nav/common.js +++ b/components/nav/common.js @@ -23,7 +23,6 @@ import { useWalletIndicator } from '@/wallets/client/hooks' import SwitchAccountList, { nextAccount, useAccounts } from '@/components/account' import { useShowModal } from '@/components/modal' import { numWithUnits } from '@/lib/format' -import Head from 'next/head' export function Brand ({ className }) { return ( @@ -121,9 +120,6 @@ export function NavNotifications ({ className }) { return ( <> - - - diff --git a/components/use-comments-navigator.js b/components/use-comments-navigator.js index 5c4dd111..2eb46016 100644 --- a/components/use-comments-navigator.js +++ b/components/use-comments-navigator.js @@ -2,6 +2,7 @@ import { useCallback, useEffect, useRef, useState, startTransition, createContex import styles from './comment.module.css' import { useRouter } from 'next/router' import LongPressable from './long-pressable' +import { useFavicon } from './favicon' const CommentsNavigatorContext = createContext({ navigator: { @@ -28,6 +29,7 @@ export function useCommentsNavigatorContext () { export function useCommentsNavigator () { const router = useRouter() + const { setHasNewComments } = useFavicon() const [commentCount, setCommentCount] = useState(0) // refs in ref to not re-render on tracking const commentRefs = useRef([]) @@ -52,10 +54,12 @@ export function useCommentsNavigator () { const clearCommentRefs = useCallback(() => { commentRefs.current = [] startTransition?.(() => setCommentCount(0)) + setHasNewComments(false) }, []) // track a new comment const trackNewComment = useCallback((commentRef, createdAt) => { + setHasNewComments(true) try { window.requestAnimationFrame(() => { if (!commentRef?.current || !commentRef.current.isConnected) return @@ -89,6 +93,9 @@ export function useCommentsNavigator () { // remove a comment ref from the list const untrackNewComment = useCallback((commentRef, options = {}) => { + // we just need to read a single comment to clear the favicon + setHasNewComments(false) + const { includeDescendants = false, clearOutline = false } = options const refNode = commentRef.current diff --git a/pages/_app.js b/pages/_app.js index f57e6729..d76a88ac 100644 --- a/pages/_app.js +++ b/pages/_app.js @@ -20,6 +20,7 @@ import { ChainFeeProvider } from '@/components/chain-fee.js' import dynamic from 'next/dynamic' import { HasNewNotesProvider } from '@/components/use-has-new-notes' import WalletsProvider from '@/wallets/client/context' +import FaviconProvider from '@/components/favicon' const PWAPrompt = dynamic(() => import('react-ios-pwa-prompt'), { ssr: false }) @@ -121,24 +122,26 @@ export default function MyApp ({ Component, pageProps: { ...props } }) { - - - - - - - - - - {!router?.query?.disablePrompt && } - - - - - - - - + + + + + + + + + + + {!router?.query?.disablePrompt && } + + + + + + + + + diff --git a/public/favicon-comments.png b/public/favicon-comments.png new file mode 100644 index 00000000..4839ca04 Binary files /dev/null and b/public/favicon-comments.png differ diff --git a/public/favicon-notify-with-comments.png b/public/favicon-notify-with-comments.png new file mode 100644 index 00000000..0e711ca3 Binary files /dev/null and b/public/favicon-notify-with-comments.png differ