TitleNotifier.tsx 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. /**
  2. * This component is responsible for updating the title of the page when
  3. * different state changes occur.
  4. * If the stream live state changes, or chat messages come in while the
  5. * page is backgrounded, this component will update the title to reflect it. *
  6. * @component
  7. */
  8. import { FC, useEffect, useState } from 'react';
  9. import { useRecoilValue } from 'recoil';
  10. import Head from 'next/head';
  11. import { serverStatusState, chatMessagesAtom } from '../stores/ClientConfigStore';
  12. export type TitleNotifierProps = {
  13. name: string;
  14. };
  15. export const TitleNotifier: FC<TitleNotifierProps> = ({ name }) => {
  16. const chatMessages = useRecoilValue(chatMessagesAtom);
  17. const serverStatus = useRecoilValue(serverStatusState);
  18. const [backgrounded, setBackgrounded] = useState(false);
  19. const [title, setTitle] = useState(name);
  20. const { online } = serverStatus;
  21. const onBlur = () => {
  22. setBackgrounded(true);
  23. };
  24. const onFocus = () => {
  25. setBackgrounded(false);
  26. setTitle(name);
  27. };
  28. const listenForEvents = () => {
  29. // Listen for events that should update the title
  30. window.addEventListener('blur', onBlur);
  31. window.addEventListener('focus', onFocus);
  32. };
  33. const removeEvents = () => {
  34. window.removeEventListener('blur', onBlur);
  35. window.removeEventListener('focus', onFocus);
  36. };
  37. useEffect(() => {
  38. listenForEvents();
  39. setTitle(name);
  40. return () => {
  41. removeEvents();
  42. };
  43. }, [name]);
  44. useEffect(() => {
  45. if (!backgrounded || !online) {
  46. return;
  47. }
  48. // Only alert on real chat messages from people.
  49. const lastMessage = chatMessages.at(-1);
  50. if (!lastMessage || lastMessage.type !== 'CHAT') {
  51. return;
  52. }
  53. setTitle(`💬 :: ${name}`);
  54. }, [chatMessages, name]);
  55. useEffect(() => {
  56. if (!backgrounded) {
  57. return;
  58. }
  59. if (online) {
  60. setTitle(` 🟢 :: ${name}`);
  61. } else if (!online) {
  62. setTitle(` 🔴 :: ${name}`);
  63. }
  64. }, [online, name]);
  65. return (
  66. <Head>
  67. <title>{title}</title>
  68. </Head>
  69. );
  70. };