diff --git a/public/images/minecoin.png b/public/images/minecoin.png new file mode 100644 index 00000000..af868fa3 Binary files /dev/null and b/public/images/minecoin.png differ diff --git a/src/app/App.tsx b/src/app/App.tsx index e66623ee..68612315 100644 --- a/src/app/App.tsx +++ b/src/app/App.tsx @@ -1,11 +1,16 @@ import type { RouterOnChangeArgs } from 'preact-router' import { Router } from 'preact-router' +import { useCallback, useEffect, useMemo, useState } from 'preact/hooks' import '../styles/global.css' import '../styles/nodes.css' import { Analytics } from './Analytics.js' -import { cleanUrl } from './Utils.js' import { Header } from './components/index.js' +import { TextComponent } from './components/TextComponent.jsx' import { Changelog, Customized, Generator, Generators, Guide, Guides, Home, LegacyPartners, Partners, Sounds, Transformation, Versions, WhatsNew, Worldgen } from './pages/index.js' +import { cleanUrl } from './Utils.js' + +const DEMO_KEY = 'misode_demo_2024' +const DEMO_INITIAL_SECONDS = 300 export function App() { const changeRoute = (e: RouterOnChangeArgs) => { @@ -14,6 +19,33 @@ export function App() { setTimeout(() => Analytics.pageview(cleanUrl(e.url))) } + const [demoTimer, setDemoTimer] = useState(DEMO_INITIAL_SECONDS) + + useEffect(() => { + const storedKey = localStorage.getItem(DEMO_KEY) + if (storedKey !== null) { + setDemoTimer(parseInt(storedKey)) + } + const interval = setInterval(() => { + setDemoTimer(timer => { + const newTimer = Math.max(0, timer - 1) + localStorage.setItem(DEMO_KEY, newTimer.toFixed()) + return newTimer + }) + }, 1000) + return () => clearInterval(interval) + }, []) + + const resetDemo = useCallback(() => { + setDemoTimer(DEMO_INITIAL_SECONDS) + }, []) + + const formattedRemainingTime = useMemo(() => { + const minutes = Math.floor(demoTimer / 60).toFixed().padStart(2, '0') + const seconds = (demoTimer % 60).toFixed().padStart(2, '0') + return `${minutes}:${seconds}` + }, [demoTimer]) + return <>
@@ -32,5 +64,19 @@ export function App() { +
0 ? 'bottom-1' : 'top-1/2 -translate-y-1/2'} left-1/2 -translate-x-1/2 max-w-[100vw]`}> +
0 ? 'px-2 py-1' : 'p-6'} flex flex-col items-center item-tooltip ${0 < demoTimer && demoTimer < 60 ? 'motion-safe:animate-bounce' : ''} `}> + {demoTimer > 0 ? <> + + + : <> + +
+ Minecoin + +
+ } +
+
}