feat: Add support for mutiple channels
This commit is contained in:
parent
edfd65335c
commit
39bb7418c9
@ -1,5 +1,10 @@
|
||||
import cassandra from 'cassandra-driver';
|
||||
|
||||
interface Messages {
|
||||
messages: cassandra.types.Row[] | null;
|
||||
error: Error | null;
|
||||
}
|
||||
|
||||
class Db {
|
||||
private client: cassandra.Client;
|
||||
|
||||
@ -47,15 +52,21 @@ class Db {
|
||||
}
|
||||
|
||||
// Get messages method
|
||||
async getMessages(channelName: string, limit: number): Promise<cassandra.types.Row[] | undefined> {
|
||||
async getMessages(channelName: string, limit: number): Promise<Messages> {
|
||||
try {
|
||||
const res = await this.client.execute(
|
||||
`SELECT * FROM channels.${channelName} WHERE channel_name = '${channelName}' ORDER BY timestamp DESC LIMIT ${limit}`,
|
||||
);
|
||||
return res.rows;
|
||||
return {
|
||||
messages: res.rows,
|
||||
error: null,
|
||||
};
|
||||
} catch (e) {
|
||||
console.log(`Error fetching messages: ${(e as Error).message}`);
|
||||
return;
|
||||
return {
|
||||
messages: null,
|
||||
error: e as Error,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -85,4 +96,4 @@ try {
|
||||
const db = new Db(client);
|
||||
await db.createChannel('general');
|
||||
|
||||
export { db };
|
||||
export { db, type Messages };
|
||||
|
@ -1,19 +1,5 @@
|
||||
import type { TypeMessage } from '$lib';
|
||||
import { db } from '$lib/server/db';
|
||||
import { redirect } from '@sveltejs/kit';
|
||||
|
||||
export async function load(): Promise<{ messages: TypeMessage[] }> {
|
||||
const rows = await db.getMessages('general', 50);
|
||||
const messages: TypeMessage[] = rows
|
||||
? rows.map((value) => {
|
||||
return {
|
||||
message: value.message_content,
|
||||
user: value.sender.toString(),
|
||||
imageSrc: `https://api.dicebear.com/9.x/identicon/svg?seed=${value.sender.toString()}`,
|
||||
};
|
||||
})
|
||||
: [];
|
||||
|
||||
return {
|
||||
messages: messages ?? [],
|
||||
};
|
||||
export function load(): void {
|
||||
redirect(308, '/channel/general');
|
||||
}
|
||||
|
@ -1,58 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { io } from 'socket.io-client';
|
||||
import { onMount } from 'svelte';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { type TypeMessage } from '$lib';
|
||||
import type { PageData } from './$types';
|
||||
import { Input } from '$lib/components/ui/input/index';
|
||||
import { Button } from '$lib/components/ui/button/index';
|
||||
import Send from 'lucide-svelte/icons/send';
|
||||
import Message from '$lib/components/message.svelte';
|
||||
|
||||
let { data }: { data: PageData } = $props();
|
||||
let user: string | undefined;
|
||||
let socket: ReturnType<typeof io> | null = null;
|
||||
let log: TypeMessage[] = $state([]);
|
||||
let msg: string = $state('');
|
||||
|
||||
function logEvent(newMsg: TypeMessage) {
|
||||
log = [newMsg, ...log];
|
||||
}
|
||||
|
||||
function establishSocketIOConnection() {
|
||||
if (socket) return;
|
||||
socket = io();
|
||||
|
||||
socket.on('message', (data: TypeMessage) => {
|
||||
console.log('[ws] message received', data);
|
||||
logEvent(data);
|
||||
});
|
||||
}
|
||||
|
||||
function sendMessage() {
|
||||
if (!socket) return;
|
||||
socket.emit('message', { id: user, content: msg });
|
||||
msg = '';
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
establishSocketIOConnection();
|
||||
user = uuidv4();
|
||||
});
|
||||
</script>
|
||||
|
||||
{#snippet message(messages: TypeMessage[])}
|
||||
{#each messages as message}
|
||||
<Message imageSrc={message.imageSrc} user={message.user} message={message.message} />
|
||||
{/each}
|
||||
{/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(data.messages)}
|
||||
</div>
|
||||
<form class="flex gap-1 w-full" onsubmit={sendMessage}>
|
||||
<Input type="text" placeholder="Type Here" bind:value={msg} />
|
||||
<Button class="h-9 w-14"><Send class="size-full" /></Button>
|
||||
</form>
|
||||
</div>
|
26
src/routes/channel/[channel]/+page.server.ts
Normal file
26
src/routes/channel/[channel]/+page.server.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import type { TypeMessage } from '$lib';
|
||||
import { error } from '@sveltejs/kit';
|
||||
import { db } from '$lib/server/db';
|
||||
|
||||
export async function load({ params }): Promise<{ messages: TypeMessage[] }> {
|
||||
let messages: TypeMessage[];
|
||||
const rows = await db.getMessages(params.channel, 50);
|
||||
|
||||
if (rows.messages !== null) {
|
||||
messages = rows
|
||||
? rows.messages.map((value) => {
|
||||
return {
|
||||
message: value.message_content,
|
||||
user: value.sender.toString(),
|
||||
imageSrc: `https://api.dicebear.com/9.x/identicon/svg?seed=${value.sender.toString()}`,
|
||||
};
|
||||
})
|
||||
: [];
|
||||
} else {
|
||||
return error(404, `Channel '${params.channel}' does not exist`);
|
||||
}
|
||||
|
||||
return {
|
||||
messages: messages ?? [],
|
||||
};
|
||||
}
|
58
src/routes/channel/[channel]/+page.svelte
Normal file
58
src/routes/channel/[channel]/+page.svelte
Normal file
@ -0,0 +1,58 @@
|
||||
<script lang="ts">
|
||||
import { io } from 'socket.io-client';
|
||||
import { onMount } from 'svelte';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { type TypeMessage } from '$lib';
|
||||
import type { PageData } from './$types';
|
||||
import { Input } from '$lib/components/ui/input/index';
|
||||
import { Button } from '$lib/components/ui/button/index';
|
||||
import Send from 'lucide-svelte/icons/send';
|
||||
import Message from '$lib/components/message.svelte';
|
||||
|
||||
let { data }: { data: PageData } = $props();
|
||||
let user: string | undefined;
|
||||
let socket: ReturnType<typeof io> | null = null;
|
||||
let log: TypeMessage[] = $state([]);
|
||||
let msg: string = $state('');
|
||||
|
||||
function logEvent(newMsg: TypeMessage) {
|
||||
log = [newMsg, ...log];
|
||||
}
|
||||
|
||||
function establishSocketIOConnection() {
|
||||
if (socket) return;
|
||||
socket = io();
|
||||
|
||||
socket.on('message', (data: TypeMessage) => {
|
||||
console.log('[ws] message received', data);
|
||||
logEvent(data);
|
||||
});
|
||||
}
|
||||
|
||||
function sendMessage() {
|
||||
if (!socket) return;
|
||||
socket.emit('message', { id: user, content: msg });
|
||||
msg = '';
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
establishSocketIOConnection();
|
||||
user = uuidv4();
|
||||
});
|
||||
</script>
|
||||
|
||||
{#snippet message(messages: TypeMessage[])}
|
||||
{#each messages as message}
|
||||
<Message imageSrc={message.imageSrc} user={message.user} message={message.message} />
|
||||
{/each}
|
||||
{/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(data.messages)}
|
||||
</div>
|
||||
<form class="flex gap-1 w-full" onsubmit={sendMessage}>
|
||||
<Input type="text" placeholder="Type Here" bind:value={msg} />
|
||||
<Button class="h-9 w-14"><Send class="size-full" /></Button>
|
||||
</form>
|
||||
</div>
|
Loading…
Reference in New Issue
Block a user