feat: Sync chat presence with auth data
This commit is contained in:
parent
9a28fdcf13
commit
ee1eac23ab
2
.gitignore
vendored
2
.gitignore
vendored
@ -28,4 +28,4 @@ vite.config.js.timestamp-*
|
||||
vite.config.ts.timestamp-*
|
||||
|
||||
# Sqlite
|
||||
src/lib/server/db/users.db
|
||||
src/lib/server/db/users.db*
|
||||
|
2
TODO.md
2
TODO.md
@ -10,4 +10,4 @@ A more complex version of this list is available [here](https://trello.com/b/kJw
|
||||
- [ ] Reactive channels list
|
||||
- [ ] Show characters before message gets cut off in textarea
|
||||
- [x] User Auth
|
||||
- [ ] Usernames / Displaynames in chat
|
||||
- [x] Usernames / Displaynames in chat
|
||||
|
@ -3,6 +3,7 @@ import express from 'express';
|
||||
import { createServer } from 'http';
|
||||
import { Server } from 'socket.io';
|
||||
import { db } from './src/lib/server/db';
|
||||
import { authdb } from './src/lib/server/db/sqlite';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
const app = express();
|
||||
@ -19,10 +20,11 @@ io.on('connection', async (socket) => {
|
||||
console.log(`\x1b[35m[ws:kit]\x1b[0m message from ${socket.id}: ${msg.content}`);
|
||||
// Store the message in the database
|
||||
await db.sendMessage(msg.channel, msg.content, msg.id, uuidv4());
|
||||
const sender = authdb.getUser(msg.id);
|
||||
io!.emit('message', {
|
||||
user: msg.id,
|
||||
user: sender.username,
|
||||
message: msg.content,
|
||||
imageSrc: `https://api.dicebear.com/9.x/identicon/svg?seed=${msg.id}`,
|
||||
imageSrc: sender.image,
|
||||
channel: msg.channel,
|
||||
});
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
<script lang="ts">
|
||||
import type { PageData } from '../../routes/$types';
|
||||
import type { PageData } from '../../routes/(main)/$types';
|
||||
const { data }: { data: PageData } = $props();
|
||||
|
||||
const imageSrc = data.session?.user.image ?? `https://api.dicebear.com/9.x/identicon/svg?seed=${data.session?.user.name}`;
|
||||
const imageSrc = data.session?.user.image ?? `https://api.dicebear.com/9.x/identicon/svg?seed=${data.session?.user.id}`;
|
||||
</script>
|
||||
|
||||
{#if data.session}
|
||||
|
@ -4,6 +4,7 @@ import type { HttpServer } from 'vite';
|
||||
// file gets loaded as a vite plugin, it will crash
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { db } from '../server/db';
|
||||
import { authdb } from '../server/db/sqlite';
|
||||
|
||||
let io: SocketIOServer | undefined;
|
||||
|
||||
@ -28,10 +29,11 @@ export function startupSocketIOServer(httpServer: HttpServer | null) {
|
||||
console.log(`\x1b[35m[ws:kit]\x1b[0m message from ${socket.id}: ${msg.content}`);
|
||||
// Store the message in the database
|
||||
await db.sendMessage(msg.channel, msg.content, msg.id, uuidv4());
|
||||
const sender = authdb.getUser(msg.id);
|
||||
io!.emit('message', {
|
||||
user: msg.id,
|
||||
user: sender.username,
|
||||
message: msg.content,
|
||||
imageSrc: `https://api.dicebear.com/9.x/identicon/svg?seed=${msg.id}`,
|
||||
imageSrc: sender.image,
|
||||
channel: msg.channel,
|
||||
});
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ class Db {
|
||||
message_content TEXT,
|
||||
channel_name TEXT,
|
||||
timestamp TIMESTAMP,
|
||||
sender UUID,
|
||||
sender TEXT,
|
||||
PRIMARY KEY (channel_name, timestamp)
|
||||
) WITH CLUSTERING ORDER BY (timestamp DESC);`);
|
||||
} catch (e) {
|
||||
@ -67,7 +67,7 @@ class Db {
|
||||
sender,
|
||||
});
|
||||
} catch (e) {
|
||||
console.log(`Error storing messages: ${e as Error}`);
|
||||
console.log(`Error storing message: ${e as Error}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
28
src/lib/server/db/sqlite.ts
Normal file
28
src/lib/server/db/sqlite.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import Database from 'better-sqlite3';
|
||||
|
||||
interface Profile {
|
||||
username: string;
|
||||
image: string;
|
||||
}
|
||||
|
||||
class AuthDb {
|
||||
private client = new Database('./src/lib/server/db/users.db');
|
||||
|
||||
init() {
|
||||
// Set WAL pragma for preformance reasons
|
||||
this.client.pragma('journal_mode = WAL');
|
||||
}
|
||||
|
||||
getUser(userId: string): Profile {
|
||||
const row = this.client.prepare('SELECT username, image FROM user WHERE id = ?').get(userId);
|
||||
return {
|
||||
username: (row as Profile).username,
|
||||
image: (row as Profile).image ?? `https://api.dicebear.com/9.x/identicon/svg?seed=${userId}`,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const authdb = new AuthDb();
|
||||
authdb.init();
|
||||
|
||||
export { authdb };
|
@ -1,9 +1,10 @@
|
||||
import { db } from '$lib/server/db';
|
||||
import { authdb } from '$lib/server/db/sqlite.js';
|
||||
import type { TypeMessage } from '$lib/types';
|
||||
import { error, redirect } from '@sveltejs/kit';
|
||||
import { auth } from '$lib/server/db/auth';
|
||||
|
||||
export async function load({ params, request }): Promise<{ messages: TypeMessage[] }> {
|
||||
export async function load({ params, request }): Promise<{ messages: TypeMessage[]; currentUser: string }> {
|
||||
const session = await auth.api.getSession({
|
||||
headers: request.headers,
|
||||
});
|
||||
@ -18,10 +19,11 @@ export async function load({ params, request }): Promise<{ messages: TypeMessage
|
||||
if (rows.messages !== null) {
|
||||
messages = rows
|
||||
? rows.messages.map((value) => {
|
||||
const sender = authdb.getUser(value.sender);
|
||||
return {
|
||||
message: value.message_content,
|
||||
user: value.sender.toString(),
|
||||
imageSrc: `https://api.dicebear.com/9.x/identicon/svg?seed=${value.sender.toString()}`,
|
||||
user: sender.username,
|
||||
imageSrc: sender.image,
|
||||
channel: value.channel,
|
||||
};
|
||||
})
|
||||
@ -32,5 +34,6 @@ export async function load({ params, request }): Promise<{ messages: TypeMessage
|
||||
|
||||
return {
|
||||
messages: messages ?? [],
|
||||
currentUser: session.user.id!,
|
||||
};
|
||||
}
|
||||
|
@ -10,12 +10,10 @@
|
||||
import Send from 'lucide-svelte/icons/send';
|
||||
import { io } from 'socket.io-client';
|
||||
import { onMount } from 'svelte';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import type { PageData } from './$types';
|
||||
|
||||
const { data }: { data: PageData } = $props();
|
||||
|
||||
let user: string = uuidv4();
|
||||
let socket: Websocket | undefined = $state();
|
||||
let msg: string = $state('');
|
||||
let showDialog: boolean = $state(false);
|
||||
@ -25,7 +23,7 @@
|
||||
|
||||
function submit() {
|
||||
if (msg.length <= 2000) {
|
||||
socket?.sendMessage(user!, msg);
|
||||
socket?.sendMessage(data.currentUser, msg);
|
||||
if (textareaRef) textareaRef.style.height = '40px';
|
||||
msg = '';
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user