Reinstate the egg
This commit is contained in:
parent
90352503b3
commit
00c7ae16f2
|
|
@ -1,5 +1,6 @@
|
||||||
import { Metadata } from 'next'
|
import { Metadata } from 'next'
|
||||||
|
|
||||||
|
import Egg from '/src/components/Egg/Egg'
|
||||||
import Settings from '/src/components/Settings/Settings'
|
import Settings from '/src/components/Settings/Settings'
|
||||||
import { fallbackLng } from '/src/i18n/options'
|
import { fallbackLng } from '/src/i18n/options'
|
||||||
import { useTranslation } from '/src/i18n/server'
|
import { useTranslation } from '/src/i18n/server'
|
||||||
|
|
@ -31,6 +32,7 @@ const RootLayout = async ({ children }: { children: React.ReactNode }) => {
|
||||||
<body>
|
<body>
|
||||||
<Settings />
|
<Settings />
|
||||||
{children}
|
{children}
|
||||||
|
<Egg />
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 (
|
|
||||||
<Wrapper title="Click anywhere to close" onClick={() => onClose()}>
|
|
||||||
<Image
|
|
||||||
src={`https://us-central1-flour-app-services.cloudfunctions.net/charliAPI?v=${eggKey}`}
|
|
||||||
onLoadStart={() => setIsLoading(true)}
|
|
||||||
onLoad={() => setIsLoading(false)}
|
|
||||||
/>
|
|
||||||
{isLoading && <Loading />}
|
|
||||||
</Wrapper>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Egg
|
|
||||||
51
frontend/src/components/Egg/Egg.module.scss
Normal file
51
frontend/src/components/Egg/Egg.module.scss
Normal file
|
|
@ -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...';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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;
|
|
||||||
`
|
|
||||||
60
frontend/src/components/Egg/Egg.tsx
Normal file
60
frontend/src/components/Egg/Egg.tsx
Normal file
|
|
@ -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<HTMLDialogElement>(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 <dialog
|
||||||
|
onClick={e => {
|
||||||
|
e.currentTarget.close()
|
||||||
|
setUrl('')
|
||||||
|
}}
|
||||||
|
className={styles.modal}
|
||||||
|
ref={ref}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
className={styles.image}
|
||||||
|
src={url}
|
||||||
|
alt="A cute picture of Charli"
|
||||||
|
onLoadStart={() => setIsLoading(true)}
|
||||||
|
onLoad={() => setIsLoading(false)}
|
||||||
|
/>
|
||||||
|
{isLoading && <div className={styles.loader} />}
|
||||||
|
</dialog>
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Egg
|
||||||
Loading…
Reference in a new issue