59 lines
2.6 KiB
TypeScript
59 lines
2.6 KiB
TypeScript
import { type ReactNode, useEffect, useState } from 'react'
|
|
import { ScrollContext } from '../../functions/Context'
|
|
import HeaderMessage from '../layout/HeaderMessage'
|
|
import HeaderError from '../layout/HeaderError'
|
|
|
|
import ViewAnimation from '../views/Animation'
|
|
import ViewHomepage from '../views/Homepage'
|
|
import ViewPersonal from '../views/Personal'
|
|
import ViewSearch from '../views/Search'
|
|
import ViewSettings from '../views/Settings'
|
|
import ViewText from '../views/Text'
|
|
import ViewUpload from '../views/Upload'
|
|
|
|
export default function PaneContent() {
|
|
const [mainElem, setMainElem] = useState<HTMLElement | null>(null)
|
|
const [path, setPath] = useState(window.location.pathname)
|
|
const [key, setKey] = useState(window.location.href)
|
|
|
|
// Track Path
|
|
useEffect(() => {
|
|
const onPop = () => {
|
|
setPath(window.location.pathname)
|
|
setKey(window.location.href)
|
|
}
|
|
window.addEventListener('popstate', onPop)
|
|
return () => window.removeEventListener('popstate', onPop)
|
|
}, [])
|
|
|
|
// Match Component
|
|
const views = new Array<{ route: RegExp; scroll: boolean; component: (m: RegExpMatchArray) => ReactNode }>(
|
|
{ route: /^\/art\/([0-9]+)$/, scroll: false, component: (m) => <ViewAnimation key={key} id={m[1]} /> },
|
|
{ route: /^\/text\/([a-z-]+)$/, scroll: true, component: (m) => <ViewText key={key} id={m[1]} /> },
|
|
{ route: /^\/personal$/, scroll: true, component: (_) => <ViewPersonal /> },
|
|
{ route: /^\/upload$/, scroll: false, component: (_) => <ViewUpload key={key} /> },
|
|
{ route: /^\/settings$/, scroll: true, component: (_) => <ViewSettings key={key} /> },
|
|
{ route: /^\/search$/, scroll: true, component: (_) => <ViewSearch key={key} /> },
|
|
{ route: /^\/$/, scroll: true, component: (_) => <ViewHomepage key={key} /> },
|
|
)
|
|
|
|
const match = views.map((v) => ({ v, m: path.match(v.route) })).find(({ m }) => m !== null)
|
|
const relevant = match ? { ...match.v, component: match.v.component(match.m!) } : null
|
|
|
|
// Render Content
|
|
return (
|
|
<ScrollContext.Provider value={mainElem}>
|
|
<main ref={setMainElem} className={`layout-content ${relevant?.scroll ? 'layout-scrolling' : ''}`}>
|
|
{relevant ? (
|
|
relevant.component
|
|
) : (
|
|
<>
|
|
<HeaderMessage label="System Message" />
|
|
<HeaderError reason="The page you requested was not found." />
|
|
</>
|
|
)}
|
|
</main>
|
|
</ScrollContext.Provider>
|
|
)
|
|
}
|