From 75e68255312f2357b3e8e604ce18ea73f651a8dd Mon Sep 17 00:00:00 2001 From: Ben Grant Date: Tue, 13 Apr 2021 21:18:14 +1000 Subject: [PATCH] =?UTF-8?q?Easter=20egg=20=F0=9F=90=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit shh --- crabfit-frontend/src/App.tsx | 48 +++++++++++++++++-- crabfit-frontend/src/components/Egg/Egg.tsx | 21 ++++++++ .../src/components/Egg/eggStyle.ts | 23 +++++++++ crabfit-frontend/src/components/index.ts | 1 + 4 files changed, 89 insertions(+), 4 deletions(-) create mode 100644 crabfit-frontend/src/components/Egg/Egg.tsx create mode 100644 crabfit-frontend/src/components/Egg/eggStyle.ts diff --git a/crabfit-frontend/src/App.tsx b/crabfit-frontend/src/App.tsx index 19fe3e0..76a2e39 100644 --- a/crabfit-frontend/src/App.tsx +++ b/crabfit-frontend/src/App.tsx @@ -1,4 +1,4 @@ -import { useState, useEffect, Suspense, lazy } from 'react'; +import { useState, useEffect, useCallback, Suspense, lazy } from 'react'; import { BrowserRouter, Switch, @@ -6,11 +6,13 @@ import { } from 'react-router-dom'; import { ThemeProvider, Global } from '@emotion/react'; -import { Settings, Loading } from 'components'; +import { Settings, Loading, Egg } from 'components'; import { useSettingsStore } from 'stores'; import theme from 'theme'; +const EGG_PATTERN = ['ArrowUp', 'ArrowUp', 'ArrowDown', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'ArrowLeft', 'ArrowRight', 'b', 'a']; + const Home = lazy(() => import('pages/Home/Home')); const Event = lazy(() => import('pages/Event/Event')); @@ -20,13 +22,49 @@ const App = () => { const [isDark, setIsDark] = useState(darkQuery.matches); const [offline, setOffline] = useState(!window.navigator.onLine); + const [eggCount, setEggCount] = useState(0); + const [eggVisible, setEggVisible] = useState(false); + const [eggKey, setEggKey] = useState(0); + + const eggHandler = useCallback( + event => { + if (EGG_PATTERN.indexOf(event.key) < 0 || event.key !== EGG_PATTERN[eggCount]) { + setEggCount(0); + return; + } + setEggCount(eggCount+1); + if (EGG_PATTERN.length === eggCount+1) { + setEggKey(eggKey+1); + setEggCount(0); + setEggVisible(true); + } + }, + [eggCount, eggKey] + ); + darkQuery.addListener(e => colortheme === 'System' && setIsDark(e.matches)); useEffect(() => { - window.addEventListener('offline', () => setOffline(true)); - window.addEventListener('online', () => setOffline(false)); + const onOffline = () => setOffline(true); + const onOnline = () => setOffline(false); + + window.addEventListener('offline', onOffline, false); + window.addEventListener('online', onOnline, false); + + return () => { + window.removeEventListener('offline', onOffline, false); + window.removeEventListener('online', onOnline, false); + }; }, []); + useEffect(() => { + document.addEventListener('keyup', eggHandler, false); + + return () => { + document.removeEventListener('keyup', eggHandler, false); + }; + }, [eggHandler]); + useEffect(() => { setIsDark(colortheme === 'System' ? darkQuery.matches : colortheme === 'Dark'); }, [colortheme, darkQuery.matches]); @@ -84,6 +122,8 @@ const App = () => { + + {eggVisible && setEggVisible(false)} />} ); diff --git a/crabfit-frontend/src/components/Egg/Egg.tsx b/crabfit-frontend/src/components/Egg/Egg.tsx new file mode 100644 index 0000000..afa2e82 --- /dev/null +++ b/crabfit-frontend/src/components/Egg/Egg.tsx @@ -0,0 +1,21 @@ +import { useState } from 'react'; + +import { Loading } from 'components'; +import { Image, Wrapper } from './eggStyle'; + +const Egg = ({ eggKey, onClose }) => { + const [isLoading, setIsLoading] = useState(true); + + return ( + onClose()}> + setIsLoading(true)} + onLoad={() => setIsLoading(false)} + /> + {isLoading && } + + ); +} + +export default Egg; diff --git a/crabfit-frontend/src/components/Egg/eggStyle.ts b/crabfit-frontend/src/components/Egg/eggStyle.ts new file mode 100644 index 0000000..19ac1f3 --- /dev/null +++ b/crabfit-frontend/src/components/Egg/eggStyle.ts @@ -0,0 +1,23 @@ +import styled from '@emotion/styled'; + +export const Wrapper = styled.div` + position: fixed; + background: rgba(0,0,0,.6); + top: 0; + left: 0; + right: 0; + bottom: 0; + height: 100%; + width: 100%; + display: flex; + justify-content: center; + align-items: center; + z-index: 1000; + cursor: pointer; +`; + +export const Image = styled.img` + max-width: 80%; + max-height: 80%; + position: absolute; +`; diff --git a/crabfit-frontend/src/components/index.ts b/crabfit-frontend/src/components/index.ts index dc7571c..ada1a57 100644 --- a/crabfit-frontend/src/components/index.ts +++ b/crabfit-frontend/src/components/index.ts @@ -14,3 +14,4 @@ export { default as Loading } from './Loading/Loading'; export { default as Center } from './Center/Center'; export { default as Donate } from './Donate/Donate'; export { default as Settings } from './Settings/Settings'; +export { default as Egg } from './Egg/Egg';