feat: floating fading footer (#3008)

Co-authored-by: thisProjects <wibbet@wobbet.com>
Co-authored-by: Gabe Kangas <gabek@real-ity.com>
This commit is contained in:
Nathan 2023-05-12 22:52:54 +01:00 committed by GitHub
parent 3941bc1a70
commit 3bd45d09f3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 53 additions and 9 deletions

View file

@ -22,3 +22,17 @@
}
}
}
.fadeIn {
animation: fadein 2s;
}
@keyframes fadein {
from {
opacity: 0;
}
to {
opacity: 1;
}
}

View file

@ -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<ClientConfig>(clientConfigStateAtom);
const clientStatus = useRecoilValue<ServerStatus>(serverStatusState);
const { name } = clientConfig;
@ -54,7 +55,6 @@ export const Main: FC = () => {
const appState = useRecoilValue<AppStateOptions>(appStateAtom);
const isMobile = useRecoilValue<boolean | undefined>(isMobileAtom);
const isChatVisible = useRecoilValue<boolean>(isChatVisibleSelector);
const layoutRef = useRef<HTMLDivElement>(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 = () => {
<TitleNotifier name={name} />
<Theme />
<Script strategy="afterInteractive" src="/customjavascript" />
<Layout ref={layoutRef} className={styles.layout}>
<Header
name={headerText}
@ -171,11 +196,13 @@ export const Main: FC = () => {
{fatalError && (
<FatalErrorStateModal title={fatalError.title} message={fatalError.message} />
)}
<div style={{ paddingRight: dynamicPadding }}>
<Footer version={version} />
<div
style={displayFooter ? { display: 'flex' } : { display: 'none' }}
className={styles.fadeIn}
>
<Footer version={version} dynamicPadding={dynamicPadding} />
</div>
</Layout>
<Noscript />
</>
);

View file

@ -16,6 +16,8 @@
font-weight: 400;
border-top: 1px solid rgba(214, 211, 211, 0.5);
width: 100%;
position: fixed;
bottom: 0;
@include screen(tablet) {
font-size: 10px;

View file

@ -3,10 +3,11 @@ import styles from './Footer.module.scss';
export type FooterProps = {
version: string;
dynamicPadding: string;
};
export const Footer: FC<FooterProps> = ({ version }) => (
<footer className={styles.footer} id="footer">
export const Footer: FC<FooterProps> = ({ version, dynamicPadding }) => (
<footer className={styles.footer} id="footer" style={{ paddingRight: dynamicPadding }}>
<span>
Powered by <a href="https://owncast.online">Owncast v{version}</a>
</span>