135 lines
8.0 KiB
TypeScript
135 lines
8.0 KiB
TypeScript
|
|
'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>
|
||
|
|
)
|
||
|
|
}
|