From 3bd45d09f3a56e11b9a76678b2404ef3a9b0d5fc Mon Sep 17 00:00:00 2001 From: Nathan <34570423+thisprojects@users.noreply.github.com> Date: Fri, 12 May 2023 22:52:54 +0100 Subject: [PATCH] feat: floating fading footer (#3008) Co-authored-by: thisProjects Co-authored-by: Gabe Kangas --- web/components/layouts/Main/Main.module.scss | 14 +++++++ web/components/layouts/Main/Main.tsx | 41 ++++++++++++++++---- web/components/ui/Footer/Footer.module.scss | 2 + web/components/ui/Footer/Footer.tsx | 5 ++- 4 files changed, 53 insertions(+), 9 deletions(-) diff --git a/web/components/layouts/Main/Main.module.scss b/web/components/layouts/Main/Main.module.scss index 432006b40..25918819d 100644 --- a/web/components/layouts/Main/Main.module.scss +++ b/web/components/layouts/Main/Main.module.scss @@ -22,3 +22,17 @@ } } } + +.fadeIn { + animation: fadein 2s; +} + +@keyframes fadein { + from { + opacity: 0; + } + + to { + opacity: 1; + } +} diff --git a/web/components/layouts/Main/Main.tsx b/web/components/layouts/Main/Main.tsx index 938e40853..6c318fddf 100644 --- a/web/components/layouts/Main/Main.tsx +++ b/web/components/layouts/Main/Main.tsx @@ -3,7 +3,7 @@ /* eslint-disable react/no-unescaped-entities */ import { useRecoilValue } from 'recoil'; import Head from 'next/head'; -import { FC, useEffect, useRef } from 'react'; +import { FC, useEffect, useRef, useState } from 'react'; import { Layout } from 'antd'; import dynamic from 'next/dynamic'; import Script from 'next/script'; @@ -46,6 +46,7 @@ const FatalErrorStateModal = dynamic( ); export const Main: FC = () => { + const [displayFooter, setDisplayFooter] = useState(false); const clientConfig = useRecoilValue(clientConfigStateAtom); const clientStatus = useRecoilValue(serverStatusState); const { name } = clientConfig; @@ -54,7 +55,6 @@ export const Main: FC = () => { const appState = useRecoilValue(appStateAtom); const isMobile = useRecoilValue(isMobileAtom); const isChatVisible = useRecoilValue(isChatVisibleSelector); - const layoutRef = useRef(null); const { chatDisabled } = clientConfig; const { videoAvailable } = appState; @@ -62,12 +62,38 @@ export const Main: FC = () => { // accounts for sidebar width when online in desktop const showChat = online && !chatDisabled && isChatVisible; - const dynamicPadding = showChat && !isMobile ? '320px' : '0px'; + const dynamicPadding = showChat && !isMobile ? '340px' : '0px'; useEffect(() => { setupNoLinkReferrer(layoutRef.current); }, []); + const handleScroll = () => { + const documentHeight = document.body.scrollHeight; + const currentScroll = window.scrollY + window.innerHeight; + + // When the user is [modifier]px from the bottom, fire the event. + const modifier = 10; + if (currentScroll + modifier > documentHeight) { + if (!displayFooter) { + setDisplayFooter(true); + } + } else { + // eslint-disable-next-line no-lonely-if + if (displayFooter) { + setDisplayFooter(false); + } + } + }; + + useEffect(() => { + window.addEventListener('scroll', handleScroll); + + return () => { + window.removeEventListener('scroll', handleScroll); + }; + }, [displayFooter]); + const isProduction = process.env.NODE_ENV === 'production'; const headerText = online ? streamTitle || name : name; @@ -159,7 +185,6 @@ export const Main: FC = () => {