|
- import cn from 'classnames'
- import { useEffect, useRef, useState } from 'react'
- import { BrowserRouter,
- Link,
- Navigate,
- Route,
- Routes,
- useLocation } from 'react-router-dom'
-
- import bgmSrc from '@/assets/music.mp3'
- import ThreadListPage from '@/pages/threads/ThreadListPage'
- import ThreadDetailPage from '@/pages/threads/ThreadDetailPage'
-
- const colours = ['bg-fuchsia-500 dark:bg-fuchsia-900',
- 'bg-lime-500 dark:bg-lime-900',
- 'bg-cyan-500 dark:bg-cyan-900',
- 'bg-orange-500 dark:bg-orange-900',
- 'bg-pink-500 dark:bg-pink-900',
- 'bg-red-500 dark:bg-red-900',
- 'bg-blue-500 dark:bg-blue-900',
- 'bg-green-500 dark:bg-green-900',
- 'bg-yellow-500 dark:bg-yellow-900'] as const
-
-
- const ScrollToTop = () => {
- const { pathname } = useLocation ()
-
- useEffect (() => {
- scrollTo (0, 0)
- }, [pathname])
-
- return null
- }
-
-
- export default () => {
- const bgmRef = useRef<HTMLAudioElement | null> (null)
-
- const [colourIndex, setColourIndex] = useState (0)
- const [mute, setMute] = useState (false)
- const [playing, setPlaying] = useState (false)
-
- useEffect (() => {
- bgmRef.current = new Audio (bgmSrc)
- bgmRef.current.loop = true
- bgmRef.current.volume = 1
-
- const playBGM = async () => {
- if (playing || !(bgmRef.current))
- return
-
- try
- {
- await bgmRef.current.play ()
- setPlaying (true)
- }
- catch
- {
- setPlaying (false)
- }
- }
-
- const bgmInterval = setInterval (playBGM, 1000)
- document.addEventListener ('click', playBGM)
- document.addEventListener ('touchstart', playBGM)
-
- const changeColour = () => {
- setColourIndex (Math.floor (Math.random () * colours.length))
- }
- changeColour ()
- const colouringInterval = setInterval (changeColour, 3000)
-
- return () => {
- clearInterval (bgmInterval)
- clearInterval (colouringInterval)
- }
- }, [])
-
- return (
- <BrowserRouter>
- <ScrollToTop />
- <div className={cn ('w-screen min-h-screen',
- colours[colourIndex],
- 'transition-colors duration-[3s] ease-linear')}>
- <div className="mx-auto max-w-[960px] px-4">
- <header className="pt-6 mb-8">
- <h1 className="text-center">
- <Link to="/"
- className="text-7xl text-transparent whitespace-nowrap
- bg-[linear-gradient(90deg,#ff0000,#ff8800,#ffff00,#00ff00,#00ffff,#0000ff,#ff00ff,#ff0000)]
- bg-clip-text [transform:skewX(-13.5deg)]
- inline-block bg-[length:200%_100%] animate-rainbow-scroll drop-shadow-[0_0_6px_black]
- font-serif hover:text-transparent dark:hover:text-transparent">
- クソ掲示板
- </Link>
- </h1>
- <div className="text-center my-6">
- {playing && (
- <a href="#" onClick={ev => {
- ev.preventDefault ()
- bgmRef.current && setMute (bgmRef.current.muted = !(mute))
- }}>
- {mute ? 'やっぱり BGM が恋しい人用' : 'BGM がうるさい人用'}
- </a>)}
- </div>
- </header>
- <main className="mb-8">
- <Routes>
- <Route path="/" element={<Navigate to="/threads" replace />} />
- <Route path="/threads" element={<ThreadListPage />} />
- <Route path="/threads/:id" element={<ThreadDetailPage />} />
- </Routes>
- </main>
- <hr />
- <footer className="text-center mt-8 pb-12 text-base text-gray-500 dark:text-gray-300">
- © このペィジへの投稿は,すべて,パブリック・ドメインとします.
- </footer>
- </div>
- </div>
- </BrowserRouter>)
- }
|