'use client';
import { useEffect, useState, useRef } from 'react';
import { io, Socket } from 'socket.io-client';
import { AETHEX } from '@/config/aethex';
import {
SceneOakdale,
SceneForge,
ScenePassport,
SceneOffline,
} from '@/components/scenes';
// ── Inline scenes for Live / Music / Kael ──────────────────────────────────
function SceneLive({ videoId }: { videoId: string | null }) {
return (
LIVE NOW
MRPIGLR ON AIR
{videoId ? (
) : (
Connecting to stream…
)}
);
}
function SceneMusic() {
return (
NOW PLAYING
RANCH RECORDS
Frank Tango · Independent Country
🎵 Music interlude in progress
);
}
function SceneKael({ kaelResponse }: { kaelResponse: string }) {
return (
AETHEX AI
KAEL
Ask KAEL anything — type /kael [question]
{kaelResponse && (
)}
);
}
// ── Types ──────────────────────────────────────────────────────────────────
type Scene = 'live' | 'music' | 'kael' | 'oakdale' | 'forge' | 'offline' | 'passport';
interface ChatMessage {
id: string;
username: string;
message: string;
type: 'chat' | 'command';
timestamp: number;
}
// ── Main Page ──────────────────────────────────────────────────────────────
export default function LivePage() {
const [scene, setScene] = useState('offline');
const [liveVideoId, setLiveVideoId] = useState(null);
const [viewers, setViewers] = useState(0);
const [messages, setMessages] = useState([]);
const [input, setInput] = useState('');
const [username] = useState(() => 'viewer' + Math.floor(Math.random() * 9000 + 1000));
const [kaelResponse, setKaelResponse] = useState('');
const socketRef = useRef(null);
const chatRef = useRef(null);
useEffect(() => {
const socket = io({ path: '/socket.io' });
socketRef.current = socket;
socket.on('state:init', ({ scene, liveVideoId }) => {
setScene(scene);
setLiveVideoId(liveVideoId);
});
socket.on('scene:change', ({ scene, liveVideoId }) => {
setScene(scene);
if (liveVideoId !== undefined) setLiveVideoId(liveVideoId);
});
socket.on('viewers:update', (count: number) => setViewers(count));
socket.on('chat:message', (msg: ChatMessage) => {
setMessages(prev => [...prev.slice(-49), msg]);
});
socket.on('kael:response', ({ text }: { text: string }) => {
setKaelResponse(text);
});
return () => { socket.disconnect(); };
}, []);
useEffect(() => {
if (chatRef.current) {
chatRef.current.scrollTop = chatRef.current.scrollHeight;
}
}, [messages]);
function sendMessage(e: React.FormEvent) {
e.preventDefault();
if (!input.trim() || !socketRef.current) return;
socketRef.current.emit('chat:send', { message: input.trim(), username });
setInput('');
}
function renderScene() {
switch (scene) {
case 'live': return ;
case 'music': return ;
case 'kael': return ;
case 'oakdale': return ;
case 'forge': return ;
case 'passport':return ;
default: return ;
}
}
return (
{/* Header bar */}
⬡
AeThex LIVE
{AETHEX.scenes.map(s => (
))}
👁 {viewers}
{scene === 'live' && ● LIVE}
{/* Main scene */}
{renderScene()}
{/* Chat overlay */}
{/* Trinity footer bar */}
);
}