From 424fe4cf421d3a59085d58287b2d775f04fe26ce Mon Sep 17 00:00:00 2001 From: fucksophie Date: Mon, 5 Jan 2026 07:59:23 +0200 Subject: [PATCH] fix loads of errors, make messages have the actual username added to them aswell xd --- src/lib/components/app-sidebar.svelte | 15 +- src/lib/index.ts | 13 ++ src/lib/server/db/schema.ts | 1 + src/lib/utils.ts | 2 +- .../[[channelId]]/[[channelId]]/+server.ts | 70 +++++++--- src/routes/app/+page.svelte | 132 +++++++++++------- 6 files changed, 157 insertions(+), 76 deletions(-) diff --git a/src/lib/components/app-sidebar.svelte b/src/lib/components/app-sidebar.svelte index 7e6d602..25599ec 100644 --- a/src/lib/components/app-sidebar.svelte +++ b/src/lib/components/app-sidebar.svelte @@ -14,13 +14,18 @@ import Button, { buttonVariants } from './ui/button/button.svelte'; import User from './extra/User.svelte'; import type { SessionValidationResult } from '$lib/server/auth'; + import type { OverviewData } from '$lib'; let { currentPage = $bindable(), data, user, ...restProps - }: { currentPage: string | null; data: Data; user: SessionValidationResult['user'] } = $props(); + }: { + currentPage: string | null; + data: OverviewData; + user: SessionValidationResult['user']; + } = $props(); @@ -48,7 +53,7 @@ - + Add a friend @@ -132,7 +137,7 @@ - +
Create a group @@ -161,7 +166,7 @@ - + Join a server @@ -185,7 +190,7 @@ - + Create a server diff --git a/src/lib/index.ts b/src/lib/index.ts index c23c2f2..dc54252 100644 --- a/src/lib/index.ts +++ b/src/lib/index.ts @@ -23,6 +23,19 @@ export type OverviewUser = { image: string; dmId?: string; }; +export interface Message { + id: string; + authorId: string; + content: string; + timestamp: number; +} + +export interface ReturnMessage extends Message { + author: { + id: string; + name: string; + }; +} export type OverviewServer = { id: string; diff --git a/src/lib/server/db/schema.ts b/src/lib/server/db/schema.ts index 1b65b92..ec3b684 100644 --- a/src/lib/server/db/schema.ts +++ b/src/lib/server/db/schema.ts @@ -84,6 +84,7 @@ export const invite = sqliteTable('invite', { .references(() => server.id), code: text('code').notNull() }); + export type Session = typeof session.$inferSelect; export type User = typeof user.$inferSelect; export type Group = typeof group.$inferSelect; diff --git a/src/lib/utils.ts b/src/lib/utils.ts index cff89f1..357baae 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -5,7 +5,7 @@ export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); } -export function formatTimestamp(dateString: string) { +export function formatTimestamp(dateString: string | number | Date) { const date = new Date(dateString); const now = new Date(); diff --git a/src/routes/api/messages/[[grp_srv_dm]]/[[channelId]]/[[channelId]]/+server.ts b/src/routes/api/messages/[[grp_srv_dm]]/[[channelId]]/[[channelId]]/+server.ts index 665c0fa..1ba3abe 100644 --- a/src/routes/api/messages/[[grp_srv_dm]]/[[channelId]]/[[channelId]]/+server.ts +++ b/src/routes/api/messages/[[grp_srv_dm]]/[[channelId]]/[[channelId]]/+server.ts @@ -2,18 +2,11 @@ import { json } from '@sveltejs/kit'; import type { RequestHandler } from './$types'; import { db } from '$lib/server/db'; import * as table from '$lib/server/db/schema'; -import { DirectMessageID, GroupID, ServerID } from '$lib'; +import { DirectMessageID, GroupID, ServerID, type Message, type ReturnMessage } from '$lib'; import { eq, or } from 'drizzle-orm'; import { _sendToSubscribers } from '../../../../updates/+server'; import { and } from 'drizzle-orm'; -interface Message { - id: string; - authorId: string; - content: string; - timestamp: number; -} - export async function _findDm(member_one: string, member_two: string) { return await db .select() @@ -72,14 +65,14 @@ export const GET: RequestHandler = async ({ params, locals }) => { const g = (await db.select().from(table.group).where(eq(table.group.id, grp_srv_dm)))[0]; if (!g) return new Response('Group not found.', { status: 404 }); - messages = g.messages ?? []; + messages = g.messages as Message[]; } else if (ServerID.is(grp_srv_dm)) { type = 'server'; if (!channelId) return new Response('Missing channel ID.', { status: 400 }); const c = (await db.select().from(table.channel).where(eq(table.channel.id, channelId)))[0]; if (!c) return new Response('Channel not found.', { status: 404 }); - messages = c.messages; + messages = c.messages as Message[]; } else if (DirectMessageID.is(grp_srv_dm)) { type = 'dms'; const dm = ( @@ -88,13 +81,32 @@ export const GET: RequestHandler = async ({ params, locals }) => { if (!dm) return new Response('DM not found.', { status: 404 }); - messages = dm.messages; + messages = dm.messages as Message[]; } + const messages_resolved_users: ReturnMessage[] = ( + await Promise.all( + messages.map(async (z) => { + const author = await db.select().from(table.user).where(eq(table.user.id, z.authorId)); + + if (!author[0]) { + return; + } + + return { + ...z, + author: { + id: author[0].id, + name: author[0].username + } + }; + }) + ) + ).filter(Boolean) as ReturnMessage[]; return json({ type, id: grp_srv_dm, - messages + messages: messages_resolved_users }); }; @@ -103,7 +115,7 @@ export const POST: RequestHandler = async ({ params, request, locals }) => { return new Response('Unauthorized', { status: 401 }); } - let { grp_srv_dm, channelId } = params; + const { grp_srv_dm, channelId } = params; if (!grp_srv_dm) return new Response('Missing Group/Server/DM id.', { status: 400 }); const data = await request.json(); const { content } = data; @@ -113,7 +125,7 @@ export const POST: RequestHandler = async ({ params, request, locals }) => { let messages: Message[] = []; let type = ''; - const message = { + const message: Message = { id: crypto.randomUUID(), authorId: locals.user.id, content, @@ -124,7 +136,7 @@ export const POST: RequestHandler = async ({ params, request, locals }) => { type = 'group'; const g = (await db.select().from(table.group).where(eq(table.group.id, grp_srv_dm)))[0]; if (!g) return new Response('Group not found.', { status: 404 }); - messages = g.messages ?? []; + messages = (g.messages as Message[]) ?? []; messages.push(message); @@ -134,7 +146,7 @@ export const POST: RequestHandler = async ({ params, request, locals }) => { if (!channelId) return new Response('Missing channel ID.', { status: 400 }); const c = (await db.select().from(table.channel).where(eq(table.channel.id, channelId)))[0]; if (!c) return new Response('Channel not found.', { status: 404 }); - messages = c.messages ?? []; + messages = (c.messages as Message[]) ?? []; messages.push(message); @@ -147,17 +159,37 @@ export const POST: RequestHandler = async ({ params, request, locals }) => { if (!dm) return new Response('DM not found.', { status: 404 }); - messages = dm.messages ?? []; + messages = (dm.messages as Message[]) ?? []; messages.push(message); await db.update(table.directMessage).set({ messages }).where(eq(table.directMessage.id, dm.id)); - _sendToSubscribers(dm.id, { type: 'message', id: dm.id, message }); + _sendToSubscribers(dm.id, { + type: 'message', + id: dm.id, + message: { + ...message, + author: { + id: locals.user.id, + name: locals.user.username + } + } + }); return json({ type, id: dm.id, messages }); } - _sendToSubscribers(grp_srv_dm, { type: 'message', id: grp_srv_dm, message }); + _sendToSubscribers(grp_srv_dm, { + type: 'message', + id: grp_srv_dm, + message: { + ...message, + author: { + id: locals.user.id, + name: locals.user.username + } + } + }); return json({ type, id: grp_srv_dm, messages }); }; diff --git a/src/routes/app/+page.svelte b/src/routes/app/+page.svelte index 549090f..322445a 100644 --- a/src/routes/app/+page.svelte +++ b/src/routes/app/+page.svelte @@ -11,7 +11,8 @@ type OverviewUser, type OverviewGroup, type OverviewServer, - type UserWithStatus + type UserWithStatus, + type ReturnMessage } from '$lib'; import type { PageServerData } from './$types'; import AppSidebar from '$lib/components/app-sidebar.svelte'; @@ -22,17 +23,19 @@ import { formatTimestamp } from '$lib/utils'; import Input from '$lib/components/ui/input/input.svelte'; import { Button } from '$lib/components/ui/button'; + + import { SendHorizontal } from '@lucide/svelte'; let errorOpen = $state(true); let { form, data }: { form: ActionData; data: PageServerData } = $props(); let currentPageID: (UserId | GroupId | ServerId) | null = $state(null); let currentPage: OverviewUser | OverviewGroup | OverviewServer | undefined = $state(); - let messages = $state([]); + let messages: ReturnMessage[] = $state([]); let inputValue = $state(); let sessionId: string | undefined = $state(); - let previousSubscription: typeof currentPageID = $state(null); + let previousSubscription: UserId | GroupId | ServerId | null = $state(null); const overview_data: OverviewData = $state({ friends: [], @@ -59,21 +62,23 @@ if (ServerID.is(currentPageID)) return; async function getMessages() { - const req = await fetch('/api/messages/' + (currentPage!.dmId || currentPageID)); + const targetId = currentPage && 'dmId' in currentPage ? currentPage.dmId : currentPageID; + + const req = await fetch('/api/messages/' + targetId); const data = await req.json(); messages = data.messages; - if (previousSubscription && previousSubscription != (currentPage!.dmId || currentPageID)) { + if (previousSubscription && previousSubscription != targetId) { await fetch('/api/updates/' + sessionId, { body: JSON.stringify({ subscribeTo: previousSubscription }), method: 'DELETE' }); } - if (previousSubscription != (currentPage!.dmId || currentPageID)) { + if (previousSubscription != targetId) { await fetch('/api/updates/' + sessionId, { - body: JSON.stringify({ subscribeTo: currentPage!.dmId || currentPageID }), + body: JSON.stringify({ subscribeTo: targetId }), method: 'POST' }); } @@ -135,6 +140,7 @@ sse.addEventListener('message', (e) => { const json = JSON.parse(e.data) as | { type: 'connected'; sessionId: string } + | { type: 'message'; message: ReturnMessage } | { type: 'status'; id: string; status: 1 | 2 | 3 }; if (json.type == 'connected') { @@ -175,7 +181,7 @@ - +
{#if currentPageID && currentPage} @@ -206,56 +212,80 @@ {/if} {/if}
+
+ {#each messages as message, i (message.id)} + {#if i === 0 || messages[i - 1].authorId !== message.authorId} +
+ {message.author.name} - {#each messages as message, i (message.id)} - {#if i === 0 || messages[i - 1].authorId !== message.authorId} -
- {message.authorId} +
+
+ {message.author.name} + + {formatTimestamp(message.timestamp)} + +
-
-
- {message.authorId} - - {formatTimestamp(message.timestamp)} - +
{message.content}
- +
+ {:else} +
{message.content}
-
- {:else} -
-
{message.content}
-
- {/if} - {/each} - + {/if} + {/each} +
{#if currentPageID && currentPage} - - + const req = await fetch('/api/messages/' + targetId, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ content: message }) + }); + + if (!req.ok) { + console.error('Failed to send message'); + } + } + }} + placeholder="input box for messages (ignore how ugly it is right now please)" + class="flex-1" + /> + +
{/if}