diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/App.jsx | 28 | ||||
-rw-r--r-- | src/components/chatbubble.jsx | 51 | ||||
-rw-r--r-- | src/components/notes.jsx | 6 | ||||
-rw-r--r-- | src/components/player.jsx | 20 | ||||
-rw-r--r-- | src/components/sun.jsx | 7 | ||||
-rw-r--r-- | src/style.scss | 6 |
6 files changed, 93 insertions, 25 deletions
diff --git a/src/App.jsx b/src/App.jsx index 81436a8..fb72f6e 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -6,8 +6,10 @@ 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 { Fog } from 'three'; import * as everforest from './_everforest.module.scss' +import { Bloom, EffectComposer, GodRays, LensFlare, Noise, Vignette } from '@react-three/postprocessing'; +import { AdditiveBlending } from 'three'; +import { useGLTF } from '@react-three/drei'; export const AppContext = React.createContext(null); @@ -21,6 +23,7 @@ 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); @@ -39,23 +42,36 @@ function App() { }; }, []); 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 { + console.log("setting token"); + apiToken.current = token; + } fetch('/api/message').then((res) => res.json()).then((data) => { console.log(data); setMessages(data); }); - }, []); + },[]); + useGLTF.preload('../assets/terrain.glb'); + useGLTF.preload('../assets/message-bubble.glb'); return ( <> <div className='dot' /> <p className='unselectable hint'> - E - read<br/> - LMB - write + E - read<br /> + LMB - write<br /> + X - delete </p> - <AppContext.Provider value={{ keys: keys, keysPressed: keysPressed, messages: messages, setMessages: setMessages }}> + <AppContext.Provider value={{ apiToken: apiToken, keys: keys, keysPressed: keysPressed, messages: messages, setMessages: setMessages }}> <Canvas shadows> <KeyPressedClearer /> <Suspense> - <fog color={everforest.bg0} attach="fog" far={500}/> + <fog color={everforest.bg0} attach="fog" far={500} /> <Sun /> <Notes /> <Physics timeStep={1 / 60}> diff --git a/src/components/chatbubble.jsx b/src/components/chatbubble.jsx index c85f026..01dc6e5 100644 --- a/src/components/chatbubble.jsx +++ b/src/components/chatbubble.jsx @@ -7,12 +7,12 @@ import { AppContext } from '../App'; import Color from 'color'; import { Vector3 } from 'three'; -export default function ChatBubble({ position, text }) { +export default function ChatBubble({ id, position, text }) { const meshRef = useRef(); const [hovered, setHovered] = useState(false); const [activatable, setActivatable] = useState(false); const [active, setActive] = useState(false); - const { keysPressed } = useContext(AppContext); + const { keysPressed, setMessages, apiToken } = useContext(AppContext); useFrame((state, delta) => { if (active) { meshRef.current.rotation.y += delta; @@ -22,7 +22,7 @@ export default function ChatBubble({ position, text }) { setActive(false); } } - if(hovered) { + if (hovered) { let cameraPos = new Vector3(); state.camera.getWorldPosition(cameraPos); setActivatable(cameraPos.distanceToSquared(meshRef.current.position) < 25); @@ -32,6 +32,47 @@ export default function ChatBubble({ position, text }) { if (keysPressed.current.includes('KeyE') && activatable) { setActive(!active); } + + if (keysPressed.current.includes('KeyX') && activatable) { + if (confirm("are you sure you want to delete this message?")) { + let data = new FormData(); + data.append("token", apiToken.current); + data.append("message_id", id); + fetch('/api/remove_message', { + method: 'DELETE', + body: data, + }).then((res) => { + if (res.status == 204) { + fetch('/api/message').then((res) => res.json()).then((data) => { + setMessages(data); + }); + } else if (res.status == 401) { + alert('you are not allowed to delete this') + } + }); + } + } + if(keysPressed.current.includes('KeyR') && activatable) { + const newMesssage = prompt(); + if(newMesssage) { + let data = new FormData(); + data.append("token", apiToken.current); + data.append("message_id", id); + data.append("message", newMesssage); + fetch('/api/edit_message', { + method: 'PUT', + body: data, + }).then((res) => { + if (res.status == 204) { + fetch('/api/message').then((res) => res.json()).then((data) => { + setMessages(data); + }); + } else if (res.status == 401) { + alert('you are not allowed to delete this') + } + }); + } + } }, -2); const { nodes } = useGLTF('../assets/message-bubble.glb'); @@ -47,8 +88,8 @@ export default function ChatBubble({ position, text }) { geometry={nodes.Curve.geometry} onPointerOver={(_) => setHovered(true)} onPointerOut={(_) => setHovered(false)}> - <meshStandardMaterial color={color.toString()}/> - {active && <Html center position={[0, .5, 0]} className='unselectable textPopup'><span>{text}</span></Html>} + <meshStandardMaterial color={color.toString()} /> + {active && <Html center unselectable='on' position={[0, .5, 0]} className='textPopup'><span>{text}</span></Html>} </mesh> ) } diff --git a/src/components/notes.jsx b/src/components/notes.jsx index 027cd10..5f57b7f 100644 --- a/src/components/notes.jsx +++ b/src/components/notes.jsx @@ -5,8 +5,8 @@ import { AppContext } from "../App"; export default function Notes() { const { messages } = useContext(AppContext); return (<> - {messages.map((chatbubble, index) => - <ChatBubble key={index} position={chatbubble.position} text={chatbubble.message}/> - )} + {messages.map((chatbubble) => { + return <ChatBubble key={chatbubble._id.$oid} id={chatbubble._id.$oid} position={chatbubble.position} text={chatbubble.message}/>; + })} </>); } diff --git a/src/components/player.jsx b/src/components/player.jsx index a9ddad0..f0c1e3e 100644 --- a/src/components/player.jsx +++ b/src/components/player.jsx @@ -11,7 +11,7 @@ const _movespeed = 3.0; export default function Player() { const controlsRef = useRef(); - const { keys, setMessages } = useContext(AppContext); + const { keys, setMessages, apiToken } = useContext(AppContext); const rapier = useRapier(); const controller = useRef(); const collider = useRef(); @@ -31,7 +31,19 @@ export default function Player() { if (intersect && intersect.object.name === 'ground' && intersect.distance < 10 && controlsRef.current.isLocked) { const message = prompt(); if (message) { - setMessages(messages => [...messages, { position: intersect.point, message: message}]); + let data = new FormData(); + data.append("position", JSON.stringify(intersect.point.toArray())); + data.append("message", message); + data.append("token", apiToken.current); + fetch('/api/new_message', { + method: "POST", + body: data, + }).then(() => { + fetch('/api/message').then((res) => res.json()).then((data) => { + console.log(data); + setMessages(data); + }); + }); } controlsRef.current.lock(); } @@ -47,7 +59,7 @@ export default function Player() { c.setApplyImpulsesToDynamicBodies(true); c.setCharacterMass(0.2); controller.current = c; - }, [rapier]); + }, []); useFrame((_, delta) => { const fov_axis = +(keys.current.includes('Minus')) - +(keys.current.includes('Equal')); @@ -95,7 +107,7 @@ export default function Player() { return ( <RigidBody type="kinematicPosition" colliders={false} ref={rigidbody} position={[0, 2, 0]}> - <PerspectiveCamera makeDefault position={[0, .9, 0]} ref={camera} fov={80}/> + <PerspectiveCamera makeDefault position={[0, .9, 0]} ref={camera} fov={80} /> <PointerLockControls ref={controlsRef} /> <CapsuleCollider ref={collider} args={[1, 0.5]} /> </RigidBody> diff --git a/src/components/sun.jsx b/src/components/sun.jsx index 455a065..fe0a79b 100644 --- a/src/components/sun.jsx +++ b/src/components/sun.jsx @@ -1,7 +1,6 @@ -import { Matrix4 } from 'three'; import * as everforest from '../_everforest.module.scss' -export default function Sun() { +export default function Sun({ref}) { return (<> <directionalLight position={[1000, 1000, 1000]} @@ -10,8 +9,8 @@ export default function Sun() { color={everforest.red} /> <ambientLight intensity={Math.PI / 4} /> - <mesh position={[1000,1000,1000]}> - <icosahedronGeometry args={[100,100]}/> + <mesh position={[1000,1000,1000]} ref={ref}> + <icosahedronGeometry args={[50,50]}/> <meshStandardMaterial color={everforest.red} emissive={everforest.red} emissiveIntensity={1} fog={false}/> </mesh> </>); diff --git a/src/style.scss b/src/style.scss index aaa420d..a9f597f 100644 --- a/src/style.scss +++ b/src/style.scss @@ -108,14 +108,14 @@ pre table { } .textPopup { - /* text-align: center; */ + text-align: center; pointer-events: none; background-color: everforest.$bg1; color: everforest.$fg; border-radius: 5px; font-size: 15px; - width: 200px; - max-width: 50vw; + /* max-width: 25vw; */ + width: 15em; padding: 5px; } |