Fix title getting lost due to multiple callbacks firing. Closes #2351

This commit is contained in:
Gabe Kangas 2022-12-25 16:03:54 -08:00
parent a7da69b713
commit d4ffe02645
No known key found for this signature in database
GPG Key ID: 4345B2060657F330
2 changed files with 34 additions and 28 deletions

View File

@ -5,31 +5,33 @@
* page is backgrounded, this component will update the title to reflect it. * * page is backgrounded, this component will update the title to reflect it. *
* @component * @component
*/ */
import { FC, useEffect } from 'react'; import { FC, useEffect, useState } from 'react';
import { useRecoilValue } from 'recoil'; import { useRecoilValue } from 'recoil';
import { serverStatusState, chatMessagesAtom } from '../stores/ClientConfigStore'; import { serverStatusState, chatMessagesAtom } from '../stores/ClientConfigStore';
export const TitleNotifier: FC = () => { export type TitleNotifierProps = {
name: string;
};
export const TitleNotifier: FC<TitleNotifierProps> = ({ name }) => {
const chatMessages = useRecoilValue(chatMessagesAtom); const chatMessages = useRecoilValue(chatMessagesAtom);
const serverStatus = useRecoilValue(serverStatusState); const serverStatus = useRecoilValue(serverStatusState);
let backgrounded = false; const [backgrounded, setBackgrounded] = useState(false);
let defaultTitle = '';
const { online } = serverStatus;
const setTitle = (title: string) => { const setTitle = (title: string) => {
console.trace('Debug: Setting title to', title); document.title = title;
window.document.title = title;
}; };
const onBlur = () => { const onBlur = () => {
console.log('onBlur: Saving defaultTitle as', window.document.title); setBackgrounded(true);
backgrounded = true;
defaultTitle = window.document.title;
}; };
const onFocus = () => { const onFocus = () => {
backgrounded = false; setBackgrounded(false);
setTitle(defaultTitle); setTitle(name);
}; };
const listenForEvents = () => { const listenForEvents = () => {
@ -38,40 +40,44 @@ export const TitleNotifier: FC = () => {
window.addEventListener('focus', onFocus); window.addEventListener('focus', onFocus);
}; };
useEffect(() => { const removeEvents = () => {
console.log('useEffect: Saving defaultTitle as', window.document.title); window.removeEventListener('blur', onBlur);
window.removeEventListener('focus', onFocus);
};
defaultTitle = window.document.title; useEffect(() => {
listenForEvents(); listenForEvents();
return () => { return () => {
window.removeEventListener('focus', onFocus); removeEvents();
window.removeEventListener('blur', onBlur);
}; };
}, []); }, [name]);
useEffect(() => { useEffect(() => {
const { online } = serverStatus;
if (!backgrounded || !online) { if (!backgrounded || !online) {
return; return;
} }
setTitle(`💬 :: ${defaultTitle}`);
}, [chatMessages]); // Only alert on real chat messages from people.
const lastMessage = chatMessages[chatMessages.length - 1];
if (lastMessage.type !== 'CHAT') {
return;
}
setTitle(`💬 :: ${name}`);
}, [chatMessages, name]);
useEffect(() => { useEffect(() => {
if (!backgrounded) { if (!backgrounded) {
return; return;
} }
const { online } = serverStatus;
if (online) { if (online) {
setTitle(` 🟢 :: ${defaultTitle}`); setTitle(` 🟢 :: ${name}`);
} else if (!online) { } else if (!online) {
setTitle(` 🔴 :: ${defaultTitle}`); setTitle(` 🔴 :: ${name}`);
} }
}, [serverStatusState]); }, [online, name]);
return null; return null;
}; };

View File

@ -71,7 +71,7 @@ export const Main: FC = () => {
{isProduction ? ( {isProduction ? (
<Head> <Head>
{name ? <title>{name}</title> : <title>{`{{.Name}}`}</title>} {name ? <title>{name}</title> : <title>{'{{.Name}}'}</title>}
<meta name="description" content="{{.Summary}}" /> <meta name="description" content="{{.Summary}}" />
<meta property="og:title" content="{{.Name}}" /> <meta property="og:title" content="{{.Name}}" />
@ -108,7 +108,7 @@ export const Main: FC = () => {
)} )}
<ClientConfigStore /> <ClientConfigStore />
<TitleNotifier /> <TitleNotifier name={name} />
<Theme /> <Theme />
<Layout ref={layoutRef} style={{ minHeight: '100vh' }}> <Layout ref={layoutRef} style={{ minHeight: '100vh' }}>
<Header name={title || name} chatAvailable={isChatAvailable} chatDisabled={chatDisabled} /> <Header name={title || name} chatAvailable={isChatAvailable} chatDisabled={chatDisabled} />