135 lines
8.0 KiB
TypeScript
Raw Permalink Normal View History

2026-04-03 12:35:13 +02:00
'use client'
/* eslint-disable @typescript-eslint/no-explicit-any */
import React, { useEffect, useRef, useState } from 'react'
import { Socket } from 'socket.io';
import { io } from 'socket.io-client';
import { socket } from './socket';
import Link from 'next/link';
// https://www.baeldung.com/webrtc
export default function ChatWS() {
const [session, setSession] = useState<{
who: string,
room?: string
}>()
const [messages, setMessages] = useState<{
who: string,
msg: string
}[]>([])
const nameRef = useRef<HTMLInputElement | null>(null)
useEffect(() => {
socket.onAny((ev, data) => {
console.log(`ANY`, ev, data)
// setMessages(prevMessages => [...prevMessages, data]);
});
socket.on('chat message', (data) => {
// console.log(`chat message`,data)
setMessages(prevMessages => [...prevMessages, data]);
});
// Clean up the listener when the component unmounts
return () => {
socket.off('chat message');
};
}, [])
if (!session?.who) return <div
style={{ 'background': 'conic-gradient(from 210deg, #c6bcb9 0.000deg, #c6bcb9 24.000deg, #b9b6b9 calc(24.000deg + 0.1deg), #b9b6b9 48.000deg, #aab0b8 calc(48.000deg + 0.1deg), #aab0b8 72.000deg, #9ba9b6 calc(72.000deg + 0.1deg), #9ba9b6 96.000deg, #8ca2b4 calc(96.000deg + 0.1deg), #8ca2b4 120.000deg, #7e99b0 calc(120.000deg + 0.1deg), #7e99b0 144.000deg, #7191ac calc(144.000deg + 0.1deg), #7191ac 168.000deg, #6688a7 calc(168.000deg + 0.1deg), #6688a7 192.000deg, #5d7fa2 calc(192.000deg + 0.1deg), #5d7fa2 216.000deg, #56769c calc(216.000deg + 0.1deg), #56769c 240.000deg, #526d95 calc(240.000deg + 0.1deg), #526d95 264.000deg, #50648e calc(264.000deg + 0.1deg), #50648e 288.000deg, #515b86 calc(288.000deg + 0.1deg), #515b86 312.000deg, #55547e calc(312.000deg + 0.1deg), #55547e 336.000deg, #5c4c75 calc(336.000deg + 0.1deg) 360.000deg)' }}
className='bg-gray-100 h-svh w-screen z-30 fixed flex items-center justify-center align-middle'>
<div
// onSubmit={ev => {
// ev.preventDefault()
// const form = new FormData(ev.target)
// alert(form.get(`name`))
// setSession((s: any) => {
// return {
// ...s,
// who: form.get(`name`)
// }
// })
// }}
className='bg-white/10 backdrop-blur-lg w-96 h-64 flex flex-col border border-white/20 shadow-lg p-2'>
<div className='grow font-black text-center'>
Enter a name to use in this chat
</div>
<div className='grow'>
<input
ref={nameRef}
className='w-full focus:p-2 transition-all focus:bg-white'
autoFocus
name='name'
placeholder='Your name' />
</div>
<button type='button'
onClick={() => {
setSession((s: any) => {
return {
...s,
who: nameRef.current?.value
}
})
}} className='shadow p-2'>Next</button>
</div>
</div>
return (
<div
/* https://grabient.com/HQNgrAHANMYIxhgJjAFigWlgTkVsaM2AzHJsMRAAzlKrTBwhJRwVgv4gjnYDsfcsWzpQSYq2BVpUKkA?style=angularSwatches&angle=210&steps=15 */
// background: conic-gradient(from 210deg, #7c6f6f 0.000deg, #7c6f6f 24.000deg, #6e6b6d calc(24.000deg + 0.1deg), #6e6b6d 48.000deg, #5f666a calc(48.000deg + 0.1deg), #5f666a 72.000deg, #505f67 calc(72.000deg + 0.1deg), #505f67 96.000deg, #3f5862 calc(96.000deg + 0.1deg), #3f5862 120.000deg, #2f515e calc(120.000deg + 0.1deg), #2f515e 144.000deg, #204858 calc(144.000deg + 0.1deg), #204858 168.000deg, #123f52 calc(168.000deg + 0.1deg), #123f52 192.000deg, #05364b calc(192.000deg + 0.1deg), #05364b 216.000deg, #002c43 calc(216.000deg + 0.1deg), #002c43 240.000deg, #00233b calc(240.000deg + 0.1deg), #00233b 264.000deg, #001933 calc(264.000deg + 0.1deg), #001933 288.000deg, #000f2a calc(288.000deg + 0.1deg), #000f2a 312.000deg, #000621 calc(312.000deg + 0.1deg), #000621 336.000deg, #000017 calc(336.000deg + 0.1deg) 360.000deg);
style={{ 'background': 'black' }}
// style={{ 'background': 'conic-gradient(from 210deg, #c6bcb9 0.000deg, #c6bcb9 24.000deg, #b9b6b9 calc(24.000deg + 0.1deg), #b9b6b9 48.000deg, #aab0b8 calc(48.000deg + 0.1deg), #aab0b8 72.000deg, #9ba9b6 calc(72.000deg + 0.1deg), #9ba9b6 96.000deg, #8ca2b4 calc(96.000deg + 0.1deg), #8ca2b4 120.000deg, #7e99b0 calc(120.000deg + 0.1deg), #7e99b0 144.000deg, #7191ac calc(144.000deg + 0.1deg), #7191ac 168.000deg, #6688a7 calc(168.000deg + 0.1deg), #6688a7 192.000deg, #5d7fa2 calc(192.000deg + 0.1deg), #5d7fa2 216.000deg, #56769c calc(216.000deg + 0.1deg), #56769c 240.000deg, #526d95 calc(240.000deg + 0.1deg), #526d95 264.000deg, #50648e calc(264.000deg + 0.1deg), #50648e 288.000deg, #515b86 calc(288.000deg + 0.1deg), #515b86 312.000deg, #55547e calc(312.000deg + 0.1deg), #55547e 336.000deg, #5c4c75 calc(336.000deg + 0.1deg) 360.000deg)' }}
// style={{ 'background': 'conic-gradient(from 210deg, #7c6f6f 0.000deg, #7c6f6f 24.000deg, #6e6b6d calc(24.000deg + 0.1deg), #6e6b6d 48.000deg, #5f666a calc(48.000deg + 0.1deg), #5f666a 72.000deg, #505f67 calc(72.000deg + 0.1deg), #505f67 96.000deg, #3f5862 calc(96.000deg + 0.1deg), #3f5862 120.000deg, #2f515e calc(120.000deg + 0.1deg), #2f515e 144.000deg, #204858 calc(144.000deg + 0.1deg), #204858 168.000deg, #123f52 calc(168.000deg + 0.1deg), #123f52 192.000deg, #05364b calc(192.000deg + 0.1deg), #05364b 216.000deg, #002c43 calc(216.000deg + 0.1deg), #002c43 240.000deg, #00233b calc(240.000deg + 0.1deg), #00233b 264.000deg, #001933 calc(264.000deg + 0.1deg), #001933 288.000deg, #000f2a calc(288.000deg + 0.1deg), #000f2a 312.000deg, #000621 calc(312.000deg + 0.1deg), #000621 336.000deg, #000017 calc(336.000deg + 0.1deg) 360.000deg)' }}
className='flex flex-col h-svh w-screen'>
<div className='bg-purple-900 shadow-sm shadow-purple-800'>
<Link href={`/`}>
<button className='bg-purple-950 text-white p-2 shadow hover:bg-purple-700'>Close Chat</button>
</Link>
</div>
<div className='grow flex flex-col overflow-auto gap-2'>
{messages.map((msg, i) =>
<div
className={`w-1/2 flex flex-col bg-gray-100 p-2 rounded-2xl shadow ${msg.who === session.who ? 'self-start' : 'self-end'}`}
key={`message-${i}`}>
<small>{msg.who}</small>
{msg.msg}
</div>
)}
</div>
{/* {JSON.stringify(messages)} */}
<div className='text-center text-amber-600 bg-amber-100'>
All message are removed once you leave this chat
</div>
<form onSubmit={ev => {
ev.preventDefault()
const form = new FormData(ev.target)
if (!form.get('msg')) return
socket.emit('chat message', {
who: session!.who ?? 'Annonymous',
msg: form.get('msg') as string
})
ev.currentTarget.reset()
}}
className='flex p-2 bg-gray-100 shadow-2xl opacity-90'
>
<input placeholder='Message' name='msg' className='grow' />
<button
className='shadow p-2 bg-gray-300'
onClick={() => {
// socket.emit('chat message', {
// who: 'Clint',
// msg: `Hello`
// })
// socket.send(`Hello MSG`)
}
}>Send</button>
</form>
</div>
)
}