diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx index fc35f1b..71ed4c0 100644 --- a/frontend/src/app/layout.tsx +++ b/frontend/src/app/layout.tsx @@ -1,5 +1,6 @@ import { Metadata } from 'next' +import Egg from '/src/components/Egg/Egg' import Settings from '/src/components/Settings/Settings' import { fallbackLng } from '/src/i18n/options' import { useTranslation } from '/src/i18n/server' @@ -31,6 +32,7 @@ const RootLayout = async ({ children }: { children: React.ReactNode }) => { {children} + } diff --git a/frontend/src/components/Egg/Egg.jsx b/frontend/src/components/Egg/Egg.jsx deleted file mode 100644 index b6ed7db..0000000 --- a/frontend/src/components/Egg/Egg.jsx +++ /dev/null @@ -1,21 +0,0 @@ -import { useState } from 'react' - -import { Loading } from '/src/components' -import { Image, Wrapper } from './Egg.styles' - -const Egg = ({ eggKey, onClose }) => { - const [isLoading, setIsLoading] = useState(true) - - return ( - onClose()}> - setIsLoading(true)} - onLoad={() => setIsLoading(false)} - /> - {isLoading && } - - ) -} - -export default Egg diff --git a/frontend/src/components/Egg/Egg.module.scss b/frontend/src/components/Egg/Egg.module.scss new file mode 100644 index 0000000..ee1313c --- /dev/null +++ b/frontend/src/components/Egg/Egg.module.scss @@ -0,0 +1,51 @@ +.modal { + background: none; + border: 0; + padding: 0; + outline: none; + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; + overflow: visible; + + &::backdrop { + background: rgba(0,0,0,.6); + } +} + +.image { + max-width: 80vw; + max-height: 80vh; + border-radius: 10px; + display: block; + position: absolute; +} + +@keyframes load { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +.loader { + height: 24px; + width: 24px; + border: 3px solid var(--primary); + border-left-color: transparent; + border-radius: 100px; + animation: load .5s linear infinite; + + @media (prefers-reduced-motion: reduce) { + animation: none; + border: 0; + + &::before { + content: 'loading...'; + } + } +} diff --git a/frontend/src/components/Egg/Egg.styles.js b/frontend/src/components/Egg/Egg.styles.js deleted file mode 100644 index 715dbed..0000000 --- a/frontend/src/components/Egg/Egg.styles.js +++ /dev/null @@ -1,23 +0,0 @@ -import { styled } from 'goober' - -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/frontend/src/components/Egg/Egg.tsx b/frontend/src/components/Egg/Egg.tsx new file mode 100644 index 0000000..d1ec88d --- /dev/null +++ b/frontend/src/components/Egg/Egg.tsx @@ -0,0 +1,60 @@ +'use client' + +import { useCallback, useEffect, useRef, useState } from 'react' + +import styles from './Egg.module.scss' + +const PATTERN = ['ArrowUp', 'ArrowUp', 'ArrowDown', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'ArrowLeft', 'ArrowRight', 'b', 'a'] +const API_URL = 'https://us-central1-flour-app-services.cloudfunctions.net/charliAPI?v=' + +const Egg = () => { + const ref = useRef(null) + const [isLoading, setIsLoading] = useState(true) + const [patternCompletion, setPatternCompletion] = useState(0) + const [url, setUrl] = useState('') + const [key, setKey] = useState(0) + + const keyHandler = useCallback((e: KeyboardEvent) => { + // Key pressed not next in pattern + if (PATTERN.indexOf(e.key) < 0 || e.key !== PATTERN[patternCompletion]) { + return setPatternCompletion(0) + } + + setPatternCompletion(patternCompletion + 1) + + // Pattern completed + if (PATTERN.length === patternCompletion + 1) { + setUrl(`${API_URL}${key}`) + setKey(key + 1) + setPatternCompletion(0) + setIsLoading(true) + ref.current?.showModal() + } + }, [patternCompletion, key]) + + // Listen to key presses + useEffect(() => { + document.addEventListener('keyup', keyHandler) + return () => document.removeEventListener('keyup', keyHandler) + }, [keyHandler]) + + return { + e.currentTarget.close() + setUrl('') + }} + className={styles.modal} + ref={ref} + > + A cute picture of Charli setIsLoading(true)} + onLoad={() => setIsLoading(false)} + /> + {isLoading &&
} +
+} + +export default Egg