feat: Create 'Websocket' class for client side websockets
This commit is contained in:
parent
42d50bf90d
commit
2c523c6940
46
src/lib/clientWebsocket.svelte.ts
Normal file
46
src/lib/clientWebsocket.svelte.ts
Normal file
@ -0,0 +1,46 @@
|
||||
import type { TypeMessage, TypeFullMessage } from '$lib';
|
||||
import type { Socket } from 'socket.io-client';
|
||||
|
||||
class Websocket {
|
||||
private socket: Socket;
|
||||
public messages: TypeMessage[] = $state([]);
|
||||
private channel: string = '';
|
||||
|
||||
constructor(socket: Socket) {
|
||||
this.socket = socket;
|
||||
}
|
||||
|
||||
connect() {
|
||||
this.socket.on('message', (data: TypeFullMessage) => {
|
||||
console.log('[ws] message received', data);
|
||||
if (data.channel == this.channel) {
|
||||
this.loadMessage(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Change the current channel
|
||||
updateChannel(newChannel: string) {
|
||||
this.channel = newChannel;
|
||||
this.messages = [];
|
||||
}
|
||||
|
||||
// Add message to local messages array
|
||||
loadMessage(newMsg: TypeMessage) {
|
||||
this.messages = [
|
||||
{
|
||||
message: newMsg.message,
|
||||
imageSrc: newMsg.imageSrc,
|
||||
user: newMsg.user,
|
||||
},
|
||||
...this.messages,
|
||||
];
|
||||
}
|
||||
|
||||
// Send a message
|
||||
sendMessage(user: string, msg: string) {
|
||||
if (this.socket) this.socket.emit('message', { id: user, content: msg, channel: this.channel });
|
||||
}
|
||||
}
|
||||
|
||||
export default Websocket;
|
@ -9,52 +9,24 @@
|
||||
import Send from 'lucide-svelte/icons/send';
|
||||
import Message from '$lib/components/message.svelte';
|
||||
import { page } from '$app/state';
|
||||
import Websocket from '$lib/clientWebsocket.svelte';
|
||||
|
||||
let { data }: { data: PageData } = $props();
|
||||
let user: string | undefined;
|
||||
let socket: ReturnType<typeof io> | null = null;
|
||||
let log: TypeMessage[] = $state([]);
|
||||
const { data }: { data: PageData } = $props();
|
||||
|
||||
let user: string = uuidv4();
|
||||
let socket: Websocket | undefined = $state();
|
||||
let msg: string = $state('');
|
||||
const channel = $derived(page.params.channel);
|
||||
|
||||
function logEvent(newMsg: TypeMessage) {
|
||||
log = [
|
||||
{
|
||||
message: newMsg.message,
|
||||
imageSrc: newMsg.imageSrc,
|
||||
user: newMsg.user,
|
||||
},
|
||||
...log,
|
||||
];
|
||||
}
|
||||
|
||||
function establishSocketIOConnection() {
|
||||
if (socket) return;
|
||||
socket = io();
|
||||
|
||||
socket.on('message', (data: TypeFullMessage) => {
|
||||
console.log('[ws] message received', data);
|
||||
if (data.channel == channel) {
|
||||
logEvent(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function sendMessage() {
|
||||
if (!socket) return;
|
||||
socket.emit('message', { id: user, content: msg, channel: channel });
|
||||
msg = '';
|
||||
}
|
||||
|
||||
// Clear the log whenever the channel changes
|
||||
$effect(() => {
|
||||
console.info(`Channel changed to ${channel}`);
|
||||
log = [];
|
||||
// Connect on page load
|
||||
onMount(() => {
|
||||
socket = new Websocket(io());
|
||||
socket.connect();
|
||||
});
|
||||
|
||||
onMount(() => {
|
||||
establishSocketIOConnection();
|
||||
user = uuidv4();
|
||||
// Update channel on page refresh
|
||||
$effect(() => {
|
||||
if (socket) socket.updateChannel(channel);
|
||||
});
|
||||
</script>
|
||||
|
||||
@ -65,10 +37,15 @@
|
||||
{/snippet}
|
||||
<div class="flex flex-1 flex-col items-center justify-center rounded-lg shadow-sm gap-1 h-full">
|
||||
<div class="flex-grow flex-col-reverse flex flex-auto overflow-y-scroll overflow-x-hidden rounded-lg border w-full">
|
||||
{@render message(log)}
|
||||
{@render message(socket?.messages!)}
|
||||
{@render message(data.messages)}
|
||||
</div>
|
||||
<form class="flex gap-1 w-full" onsubmit={sendMessage}>
|
||||
<form
|
||||
class="flex gap-1 w-full"
|
||||
onsubmit={() => {
|
||||
socket?.sendMessage(user!, msg);
|
||||
msg = '';
|
||||
}}>
|
||||
<Input type="text" placeholder="Type Here" bind:value={msg} />
|
||||
<Button class="h-9 w-14"><Send class="size-full" /></Button>
|
||||
</form>
|
||||
|
Loading…
Reference in New Issue
Block a user