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 Send from 'lucide-svelte/icons/send';
|
||||||
import Message from '$lib/components/message.svelte';
|
import Message from '$lib/components/message.svelte';
|
||||||
import { page } from '$app/state';
|
import { page } from '$app/state';
|
||||||
|
import Websocket from '$lib/clientWebsocket.svelte';
|
||||||
|
|
||||||
let { data }: { data: PageData } = $props();
|
const { data }: { data: PageData } = $props();
|
||||||
let user: string | undefined;
|
|
||||||
let socket: ReturnType<typeof io> | null = null;
|
let user: string = uuidv4();
|
||||||
let log: TypeMessage[] = $state([]);
|
let socket: Websocket | undefined = $state();
|
||||||
let msg: string = $state('');
|
let msg: string = $state('');
|
||||||
const channel = $derived(page.params.channel);
|
const channel = $derived(page.params.channel);
|
||||||
|
|
||||||
function logEvent(newMsg: TypeMessage) {
|
// Connect on page load
|
||||||
log = [
|
onMount(() => {
|
||||||
{
|
socket = new Websocket(io());
|
||||||
message: newMsg.message,
|
socket.connect();
|
||||||
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 = [];
|
|
||||||
});
|
});
|
||||||
|
|
||||||
onMount(() => {
|
// Update channel on page refresh
|
||||||
establishSocketIOConnection();
|
$effect(() => {
|
||||||
user = uuidv4();
|
if (socket) socket.updateChannel(channel);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -65,10 +37,15 @@
|
|||||||
{/snippet}
|
{/snippet}
|
||||||
<div class="flex flex-1 flex-col items-center justify-center rounded-lg shadow-sm gap-1 h-full">
|
<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">
|
<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)}
|
{@render message(data.messages)}
|
||||||
</div>
|
</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} />
|
<Input type="text" placeholder="Type Here" bind:value={msg} />
|
||||||
<Button class="h-9 w-14"><Send class="size-full" /></Button>
|
<Button class="h-9 w-14"><Send class="size-full" /></Button>
|
||||||
</form>
|
</form>
|
||||||
|
Loading…
Reference in New Issue
Block a user