import './style.scss' import { Canvas, useFrame } from '@react-three/fiber'; import Notes from './components/notes'; import Player from './components/player'; import Ground from './components/ground'; import React, { Suspense, useContext, useEffect, useRef, useState } from 'react'; import { Physics } from '@react-three/rapier'; import Sun from './components/sun'; import * as everforest from './_everforest.module.scss' import { useGLTF } from '@react-three/drei'; import terrainModelURL from './assets/terrain.glb'; import messageBubbleModelURL from './assets/message-bubble.glb'; export const AppContext = React.createContext(null); function KeyPressedClearer() { const { keysPressed } = useContext(AppContext); useFrame((_s, _d) => keysPressed.current = [], -1); return <> } function App() { const keys = useRef([]); const keysPressed = useRef([]); const [messages, setMessages] = useState(); const apiToken = useRef(); const playerKeyDown = (event) => { if (!keys.current.includes(event.code)) { keysPressed.current.push(event.code); } keys.current.push(event.code); } const playerKeyUp = (event) => { keys.current = keys.current.filter(k => k != event.code); } useEffect(() => { window.addEventListener('keydown', playerKeyDown); window.addEventListener('keyup', playerKeyUp); return () => { window.removeEventListener('keydown', playerKeyDown); window.removeEventListener('keyup', playerKeyUp); }; }, []); useEffect(() => { const token = window.localStorage.getItem("token"); if (token == null) { fetch('/api/gen_token').then((res) => res.json()).then((data) => { window.localStorage.setItem("token", data.token); apiToken.current = data.token; }); } else { apiToken.current = token; } fetch('/api/message').then((res) => res.json()).then((data) => { setMessages(data); }); },[]); useGLTF.preload(terrainModelURL); useGLTF.preload(messageBubbleModelURL); return ( <>

E - read
LMB - write
X - delete

) } export default App;