import { useContext, useRef, useState } from 'react' import * as everforest from '../_everforest.module.scss' import { useGLTF } from '@react-three/drei'; import { useFrame } from '@react-three/fiber'; import { Html } from '@react-three/drei'; import { AppContext } from '../App'; import Color from 'color'; import { Vector3 } from 'three'; import messageBubbleModelURL from '../assets/message-bubble.glb?url'; 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, setMessages, apiToken } = useContext(AppContext); useFrame((state, delta) => { if (active) { meshRef.current.rotation.y += delta; let cameraPos = new Vector3(); state.camera.getWorldPosition(cameraPos); if (cameraPos.distanceToSquared(meshRef.current.position) > 900) { setActive(false); } } if (hovered) { let cameraPos = new Vector3(); state.camera.getWorldPosition(cameraPos); setActivatable(cameraPos.distanceToSquared(meshRef.current.position) < 25); } else { setActivatable(false); } 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("edit message"); 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(messageBubbleModelURL); let color = Color(active ? everforest.blue : everforest.purple); if (activatable) { color = color.lighten(.1); } return ( setHovered(true)} onPointerOut={(_) => setHovered(false)}> {active && {text}} ) }