/* eslint-disable */ // @ts-nocheck "use client"; import React, { useEffect, useRef, useState } from "react"; import { XCUQuantumCipher } from "../lib/xcu-quantum-cipher"; interface Message { id: string; sender: string; text: string; timestamp: number; isSelf: boolean; isResonanceAudio?: boolean; } export const JumlahChat = ({ roomName, participantName, participantId, webTransport, onClose, }: { roomName: string; participantName: string; participantId: number; webTransport: { datagrams: { readable: ReadableStream, writable: WritableStream } } | null; onClose: () => void; }) => { const [messages, setMessages] = useState([]); const [input, setInput] = useState(""); const [typingHeat, setTypingHeat] = useState(0); const [isRecording, setIsRecording] = useState(false); const cipherRef = useRef(null); const chatEndRef = useRef(null); const typingTimeout = useRef(null); const mediaRecorderRef = useRef(null); const audioChunksRef = useRef([]); useEffect(() => { const initCipher = async () => { const cipher = new XCUQuantumCipher(roomName); await cipher.initialize(); cipherRef.current = cipher; }; initCipher(); }, [roomName]); useEffect(() => { chatEndRef.current?.scrollIntoView({ behavior: "smooth" }); }, [messages, typingHeat]); useEffect(() => { if (!webTransport || !webTransport.datagrams) return; let isActive = true; const readDatagrams = async () => { try { const reader = webTransport.datagrams.readable.getReader(); while (isActive) { const { value, done } = await reader.read(); if (done) break; if (value && value.length >= 8) { const type = value[0]; const senderId = new DataView(value.buffer).getUint16(2, true); if (senderId === participantId) continue; const payload = value.slice(8); if (type === 7 && cipherRef.current) { try { const dec = await cipherRef.current.decrypt(payload); const parsed = JSON.parse(dec); setMessages((prev) => [...prev, { id: crypto.randomUUID(), sender: parsed.sender, text: parsed.text, timestamp: parsed.timestamp, isSelf: false }]); } catch (e) {} } else if (type === 8) { setTypingHeat((prev) => Math.min(prev + 20, 100)); if (typingTimeout.current) clearTimeout(typingTimeout.current); typingTimeout.current = setTimeout(() => setTypingHeat(0), 1000); } else if (type === 9 && cipherRef.current) { try { const dec = await cipherRef.current.decrypt(payload); const parsed = JSON.parse(dec); setMessages((prev) => [...prev, { id: crypto.randomUUID(), sender: parsed.sender, text: parsed.audioBase64, timestamp: parsed.timestamp, isSelf: false, isResonanceAudio: true }]); } catch {} } } } } catch {} }; readDatagrams(); return () => { isActive = false; }; }, [webTransport, participantId]); const sendTypingResonance = async () => { if (!webTransport || !webTransport.datagrams) return; let writer: WritableStreamDefaultWriter | null = null; try { writer = webTransport.datagrams.writable.getWriter(); const buf = new Uint8Array(8); buf[0] = 8; new DataView(buf.buffer).setUint16(2, participantId, true); await writer.write(buf); } catch {} finally { if (writer) writer.releaseLock(); } }; const sendMessage = async (e: React.FormEvent) => { e.preventDefault(); if (!input.trim() || !cipherRef.current || !webTransport) return; const payloadStr = JSON.stringify({ sender: participantName, text: input, timestamp: Date.now() }); const encPayload = await cipherRef.current.encrypt(payloadStr); const header = new Uint8Array(8); header[0] = 7; new DataView(header.buffer).setUint16(2, participantId, true); const fullPacket = new Uint8Array(8 + encPayload.length); fullPacket.set(header, 0); fullPacket.set(encPayload, 8); let writer: WritableStreamDefaultWriter | null = null; try { writer = webTransport.datagrams.writable.getWriter(); if (writer) await writer.write(fullPacket); setMessages((prev) => [...prev, { id: crypto.randomUUID(), sender: participantName, text: input, timestamp: Date.now(), isSelf: true }]); } catch (e) {} finally { if (writer) writer.releaseLock(); } setInput(""); }; const startRecording = async () => { try { const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); const mediaRecorder = new MediaRecorder(stream, { mimeType: 'audio/webm;codecs=opus' }); mediaRecorderRef.current = mediaRecorder; audioChunksRef.current = []; mediaRecorder.ondataavailable = (e) => { if (e.data.size > 0) audioChunksRef.current.push(e.data); }; mediaRecorder.onstop = async () => { const audioBlob = new Blob(audioChunksRef.current, { type: 'audio/webm' }); const reader = new FileReader(); reader.readAsDataURL(audioBlob); reader.onloadend = async () => { const base64data = reader.result as string; if (cipherRef.current && webTransport) { const payloadStr = JSON.stringify({ sender: participantName, audioBase64: base64data, timestamp: Date.now() }); const encPayload = await cipherRef.current.encrypt(payloadStr); const header = new Uint8Array(8); header[0] = 9; new DataView(header.buffer).setUint16(2, participantId, true); const fullPacket = new Uint8Array(8 + encPayload.length); fullPacket.set(header, 0); fullPacket.set(encPayload, 8); let writer: WritableStreamDefaultWriter | null = null; try { writer = webTransport.datagrams.writable.getWriter(); if (writer) await writer.write(fullPacket); } catch (e) {} finally { if (writer) writer.releaseLock(); } setMessages((prev) => [...prev, { id: crypto.randomUUID(), sender: participantName, text: base64data, timestamp: Date.now(), isSelf: true, isResonanceAudio: true }]); } }; stream.getTracks().forEach(t => t.stop()); }; mediaRecorder.start(); setIsRecording(true); } catch (err) {} }; const stopRecording = () => { if (mediaRecorderRef.current && isRecording) { mediaRecorderRef.current.stop(); setIsRecording(false); } }; return (
{/* Header */}

In-Meeting Chat

BYOK XChaCha20
{/* Messages Area */}
{messages.length === 0 ? (

Kanal Transmisi Kuantum Aktif.
BYOK XChaCha20-Poly1305 E2EE.

) : ( messages.map((msg) => (
{msg.sender} {new Date(msg.timestamp).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}
{msg.isResonanceAudio ? (
)) )} {/* Telepathic Resonance Heatmap */} {typingHeat > 0 && (
Partisipan Mengetik
{[...Array(4)].map((_, i) => (
))}
)}
{/* Input Area */}
{ setInput(e.target.value); sendTypingResonance(); }} placeholder="Ketik pesan..." className="w-full bg-white/5 border border-white/5 rounded-2xl pl-4 pr-24 py-4 text-xs text-white placeholder-white/20 focus:outline-none focus:border-emerald-500/50 focus:bg-white/10 transition-all shadow-inner" />

Quantum Resonance Encryption Active

); };