diff --git a/src/components/LiveLeaderboard.tsx b/src/components/LiveLeaderboard.tsx index 349fb68..50deb6a 100644 --- a/src/components/LiveLeaderboard.tsx +++ b/src/components/LiveLeaderboard.tsx @@ -1,8 +1,9 @@ import { requestJSON } from '@/client/utils' import type { Room } from '@/db/model' -import { useEffect, useState } from 'preact/hooks' +import { useEffect, useRef, useState } from 'preact/hooks' import { Leaderboard } from './Leaderboard' import { computeScoreboardState } from '@/ggwp' +import clsx from 'clsx' type Props = { roomId: string @@ -50,5 +51,48 @@ export const LiveLeaderboard = ({ roomId }: Props) => { room.actions ) - return + const [autoscroll, setAutoscroll] = useState(false) + const timerRef = useRef(null) + + useEffect(() => { + if (autoscroll !== false) { + timerRef.current = setInterval(() => { + console.log('scrolling') + + window.scrollBy({ + top: autoscroll === 'down' ? 10 : -10, + behavior: 'smooth', + }) + + if (window.scrollY + window.innerHeight + 1 > document.body.scrollHeight) { + setAutoscroll('up') + } + + if (window.scrollY === 0) { + setAutoscroll('down') + } + }, 100) + + return () => { + if (timerRef.current) { + clearInterval(timerRef.current) + } + } + } + }, [autoscroll]) + + return ( + <> + + +
+ +
+ + ) } diff --git a/src/styles.css b/src/styles.css index 159110e..896bc10 100644 --- a/src/styles.css +++ b/src/styles.css @@ -24,6 +24,8 @@ img { :root { font-size: 18px; + --tint: oklch(from royalblue l 0 h); + --blue: oklch(from royalblue calc(l + 0.05) c h); --red: oklch(63.11% 0.2387 32.0573); --green: oklch(60.3% 0.3 134.48); @@ -42,7 +44,7 @@ body { justify-items: center; align-content: start; - padding: 3rem 1rem 12rem; + padding: 6rem 1rem 12rem; gap: 3rem; } @@ -234,6 +236,23 @@ a { height: 100%; } +.position-fixed { + position: fixed; + + &.top { + top: 1rem; + } + &.bottom { + bottom: 1rem; + } + &.left { + left: 1rem; + } + &.right { + right: 1rem; + } +} + .icon { font-family: 'Material Symbols Outlined Variable'; font-weight: 400; @@ -343,6 +362,11 @@ button { .icon { font-size: 20px; } + + &.active { + border-color: var(--blue); + color: var(--blue); + } } .leaderboard {