diff --git a/src/lib/server/db/index.ts b/src/lib/server/db/index.ts index 089130a..a97caef 100644 --- a/src/lib/server/db/index.ts +++ b/src/lib/server/db/index.ts @@ -16,6 +16,23 @@ async function storeMessage(client: cassandra.Client, channelName: string, conte VALUES (${id}, '${content}', ${now.getTime()}, ${sender})`); } +async function getMessages(client: cassandra.Client, channelName: string, limit: number) { + try { + const res = await client.execute(`SELECT * FROM channels.channel_${channelName} LIMIT ${limit}`); + + // We have to sort the rows within the function instead of an ORDER BY + // because of a limitation within Cassandra requiring a partition key + // to be specified by EQ or IN when using ORDER BY + res.rows.sort((a, b) => a.timestamp - b.timestamp); + + return res.rows; + } catch (e) { + // @ts-expect-error I don't like this thing yelling at me + // We all know it's gonna work + console.log(`Error fetching messages: ${e.message}`); + } +} + const client = new cassandra.Client({ contactPoints: ['localhost'], localDataCenter: 'datacenter1', @@ -27,4 +44,4 @@ await client.connect(); await client.execute(`CREATE KEYSPACE IF NOT EXISTS users WITH REPLICATION = {'class': 'SimpleStrategy', 'replication_factor': 1};`); await client.execute(`CREATE KEYSPACE IF NOT EXISTS channels WITH REPLICATION = {'class': 'SimpleStrategy', 'replication_factor': 1};`); -export { client, createChannel, storeMessage }; +export { client, createChannel, getMessages, storeMessage }; diff --git a/src/lib/websocketConfig.ts b/src/lib/websocketConfig.ts index 07a061d..26f2ad8 100644 --- a/src/lib/websocketConfig.ts +++ b/src/lib/websocketConfig.ts @@ -16,7 +16,7 @@ export function startupSocketIOServer(httpServer: HttpServer | null) { // Runs on message receive socket.on('message', async (msg) => { // If message not empty - if (msg.content !== "") { + if (msg.content !== '') { console.log(`[ws:kit] message from ${socket.id}: ${msg.content}`); // Store the message in the database await createChannel(client, '000'); diff --git a/src/routes/+page.server.ts b/src/routes/+page.server.ts new file mode 100644 index 0000000..f9672b3 --- /dev/null +++ b/src/routes/+page.server.ts @@ -0,0 +1,15 @@ +import type { PageLoad } from './$types'; +import type { TypeMessage } from '$lib'; +import { getMessages, client } from '../lib/server/db'; + +export const load: PageLoad = async () => { + const rows = await getMessages(client, '000', 5); + const messages: TypeMessage[] = rows + ? rows.map((value) => { + return { message: value.message_content, user: value.sender.toString(), imageSrc: 'https://thispersondoesnotexist.com' }; + }) + : []; + return { + serverMessages: messages, + }; +}; diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 86699a9..cb876c3 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -4,11 +4,13 @@ import { v4 as uuidv4 } from 'uuid'; import Message from '../lib/components/message.svelte'; import { type TypeMessage } from '../lib'; + import type { PageData } from './$types'; + let { data }: { data: PageData } = $props(); let user: string | undefined; let socket: ReturnType | null = null; - let log: TypeMessage[] = []; - let msg: string = ''; + let log: TypeMessage[] = $state([]); + let msg: string = $state(''); function logEvent(newMsg: TypeMessage) { log = [...log, newMsg]; @@ -36,18 +38,23 @@ }); +{#snippet message(messages: TypeMessage[])} + {#each messages as message} + + {/each} +{/snippet} +
-
+

SVChat


- {#each log as message} - - {/each} + {@render message(data.messages)} + {@render message(log)}
-
- + +
diff --git a/src/routes/+page.ts b/src/routes/+page.ts new file mode 100644 index 0000000..aeeb31a --- /dev/null +++ b/src/routes/+page.ts @@ -0,0 +1,6 @@ +import type { PageLoad } from './$types'; +export const load: PageLoad = async ({ data }) => { + return { + messages: data.serverMessages, + }; +};