From ad8b5858bf2e06176ee4be3bbcf35ec0677cf855 Mon Sep 17 00:00:00 2001 From: RemainingDev <161089154+RemainingDev@users.noreply.github.com> Date: Fri, 7 Feb 2025 16:24:59 +0100 Subject: [PATCH 1/4] Add message storing in DB --- src/extensions/chat/index.ts | 42 +++++++++++++++++------------- src/extensions/chat/static/chat.js | 6 ++--- src/extensions/chat/tables.ts | 26 ++++++++++++++++++ 3 files changed, 53 insertions(+), 21 deletions(-) create mode 100644 src/extensions/chat/tables.ts diff --git a/src/extensions/chat/index.ts b/src/extensions/chat/index.ts index bf0dafa..d14f182 100644 --- a/src/extensions/chat/index.ts +++ b/src/extensions/chat/index.ts @@ -1,50 +1,56 @@ -import { ExtensionBase } from "../../modules.ts" +import { ExtensionBase, Knex } from "../../modules.ts" +import { unpack } from "../../util.ts" -type message = {user: {name: any, pfp_code: any}, time: any, content: any} +type message = {name: any, pfp_code: any, created_at: any, content: any} export default class extends ExtensionBase { override name = 'chat' override title = 'Chat' + override tables = true private MessageStore = class { - messages: message[] = [{ - user: {name:'SYSTEM',pfp_code:'seed=SYSTEM'}, - time:(new Date()).toLocaleTimeString('en-US', {hour12: false}), - content: 'Welcome to the chatroom!' - }] onPushListeners: Set<(msg: message) => void> = new Set() - push(ctx: Context, content: string) { + async push(ctx: Context, content: string, knex : Knex){ const message: message = { - user: { - name: ctx.context.user?.name, - pfp_code: `${ctx.context.dicebear_host}?${ctx.context.user?.pfp_code}`, - }, - time: (new Date()).toLocaleTimeString('en-US', {hour12: false}), + name: ctx.context.user?.name, + pfp_code: `${ctx.context.dicebear_host}?${ctx.context.user?.pfp_code}`, + created_at: (new Date()).toLocaleTimeString('en-US', {hour12: false}), content, } - this.messages.push(message) + let userID = Number(ctx.context.user?.id) + await knex.query('_message') + // @ts-expect-error + .insert({user_id: userID, created_at: message.created_at, content: message.content}) + this.onPushListeners.forEach((listener) => listener(message)) } } message_store = new this.MessageStore() - override handle: Extension['handle'] = (ctx) => { + override handle: Extension['handle'] = async (ctx) => { const location = ctx.path.shift() + let [knex]: [Knex] = this.get_dependencies('Knex') switch (location) { case '': case undefined: { if (ctx.data && ctx.data.form.message) { const message = ctx.data.form.message.substring(0,255) - this.message_store.push(ctx, message) + this.message_store.push(ctx, message, knex) } - ctx.context.chat = this.message_store.messages return this.return_html(ctx, 'index') } case 'history': { // Should at some point return history by request - return this.return_data(ctx, JSON.stringify({messages: this.message_store.messages})) + + let [message_list, err] = await knex + .query('_message') + .select('_message.created_at', '_message.content', 'user.name', 'user.pfp_code') + .join('user', '_message.user_id', '=', 'user.id') + .then(unpack) + + return this.return_data(ctx, JSON.stringify({messages: message_list})) } case 'new_message_event': { const {req, res} = ctx diff --git a/src/extensions/chat/static/chat.js b/src/extensions/chat/static/chat.js index 6d87125..0898ad3 100644 --- a/src/extensions/chat/static/chat.js +++ b/src/extensions/chat/static/chat.js @@ -31,11 +31,11 @@ function addMessage(msg) { } const row = messages.insertRow(-1) const img_col = row.insertCell(-1) - img_col.innerHTML = '' + img_col.innerHTML = '' const col = row.insertCell(-1) const info_col = col.appendChild(document.createElement('div')) - info_col.appendChild(field(msg.user.name)) - info_col.appendChild(field(msg.time)) + info_col.appendChild(field(msg.name)) + info_col.appendChild(field(msg.created_at)) const msg_col = col.appendChild(document.createElement('div')) msg_col.appendChild(field(msg.content)) } diff --git a/src/extensions/chat/tables.ts b/src/extensions/chat/tables.ts new file mode 100644 index 0000000..7518072 --- /dev/null +++ b/src/extensions/chat/tables.ts @@ -0,0 +1,26 @@ +import { MigrationMap, Tables, VersionMap } from '../../classes/tables.ts' +import { Knex } from '../../modules.ts' + +export default class extends Tables { + override versions(versions: VersionMap) { + versions.set('message', 0) + + return versions + } + + override migrations(knex: Knex, migrations: MigrationMap) { + migrations.set('message', { + 0: async ()=>{ + await knex.schema() + .createTable('_message', (table) => { + table.increments('id').primary() + table.string('user_id').notNullable() + table.string('created_at').notNullable().defaultTo(knex.raw('CURRENT_TIMESTAMP')) + table.timestamp('content').notNullable() + }) + }, + }) + + return migrations + } +} From b5c11da18b7115047d468ef8a9aca9a318e7e93f Mon Sep 17 00:00:00 2001 From: RemainingDev <161089154+RemainingDev@users.noreply.github.com> Date: Mon, 10 Feb 2025 15:56:28 +0100 Subject: [PATCH 2/4] Add invite link generation and storage --- src/extensions/chat/tables.ts | 4 +- src/extensions/invite/index.html | 30 +++++++++++++++ src/extensions/invite/index.ts | 52 ++++++++++++++++++++++++++ src/extensions/invite/static/index.css | 17 +++++++++ src/extensions/invite/tables.ts | 26 +++++++++++++ 5 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 src/extensions/invite/index.html create mode 100644 src/extensions/invite/index.ts create mode 100644 src/extensions/invite/static/index.css create mode 100644 src/extensions/invite/tables.ts diff --git a/src/extensions/chat/tables.ts b/src/extensions/chat/tables.ts index 7518072..1af6e8f 100644 --- a/src/extensions/chat/tables.ts +++ b/src/extensions/chat/tables.ts @@ -15,8 +15,8 @@ export default class extends Tables { .createTable('_message', (table) => { table.increments('id').primary() table.string('user_id').notNullable() - table.string('created_at').notNullable().defaultTo(knex.raw('CURRENT_TIMESTAMP')) - table.timestamp('content').notNullable() + table.timestamp('created_at').notNullable().defaultTo(knex.raw('CURRENT_TIMESTAMP')) + table.string('content').notNullable() }) }, }) diff --git a/src/extensions/invite/index.html b/src/extensions/invite/index.html new file mode 100644 index 0000000..017474f --- /dev/null +++ b/src/extensions/invite/index.html @@ -0,0 +1,30 @@ +{% extends "extension.html" %} + +{% block head %} + +{% endblock %} + + +{% block body %} + + + + + + + + + + + {% for link in invite_links %} + + + + + + + {% endfor %} + +
IDLinkCreated atUsed
{{link.id}}{{link.link}}{{link.created_at}}{{"Yes" if link.used else "No"}}
+Create Invite +{% endblock %} diff --git a/src/extensions/invite/index.ts b/src/extensions/invite/index.ts new file mode 100644 index 0000000..ba576d3 --- /dev/null +++ b/src/extensions/invite/index.ts @@ -0,0 +1,52 @@ +import { ExtensionBase, Knex } from '../../modules.ts' +import { unpack } from '../../util.ts' + +export default class extends ExtensionBase { + override name = 'invite' + override title = 'Invite' + override tables = true + override admin_only = true + + invite_URL = 'http://127.0.0.1:8000/invite/register/' + + override handle: Extension['handle'] = async (ctx) => { + let [knex]: [Knex] = this.get_dependencies('Knex') + var location = ctx.path.shift() + + switch (location) { + case '': + case undefined:{ + + var [invite_links, err] = await knex + .query('_invite') + .select('*') + .then(unpack) + + ctx.context.invite_links = invite_links + return this.return_html(ctx, 'index') + } + case 'create': + + const chars = 'abcdefghijklmnopqrstuvwxyz0123456789' + let random_chars = 'r' + for (let i = 0; i < 8; i++) { + random_chars += chars.charAt(Math.floor(Math.random() * chars.length)); + } + + let invite_link = this.invite_URL + random_chars + Date.now(); + const time = new Date().toLocaleTimeString('en-US', {hour12: false}); + + await knex.query('_invite') + // @ts-expect-error + .insert({link: invite_link, created_at: new Date().toLocaleTimeString('en-US', {hour12: false})}) + + ctx.context.invite_links = invite_links + + return this.return(ctx, undefined, location='/invite') + default: { + return this.return_file(ctx, location) + } + } + + } +} diff --git a/src/extensions/invite/static/index.css b/src/extensions/invite/static/index.css new file mode 100644 index 0000000..fc35974 --- /dev/null +++ b/src/extensions/invite/static/index.css @@ -0,0 +1,17 @@ + +table { + margin: 2%; + padding-bottom: 5%; + text-align: center; +} + +table th, td{ + border: 1px solid; + padding: 10px; +} + +.used{ + color: rgb(165, 165, 165); + font-style: italic; + font-weight: lighter; +} \ No newline at end of file diff --git a/src/extensions/invite/tables.ts b/src/extensions/invite/tables.ts new file mode 100644 index 0000000..ac25d49 --- /dev/null +++ b/src/extensions/invite/tables.ts @@ -0,0 +1,26 @@ +import { MigrationMap, Tables, VersionMap } from '../../classes/tables.ts' +import { Knex } from '../../modules.ts' + +export default class extends Tables { + override versions(versions: VersionMap) { + versions.set('invite', 0) + + return versions + } + + override migrations(knex: Knex, migrations: MigrationMap) { + migrations.set('invite', { + 0: async ()=>{ + await knex.schema() + .createTable('_invite', (table) => { + table.increments('id').primary() + table.string('link').notNullable() + table.timestamp('created_at').notNullable().defaultTo(knex.raw('CURRENT_TIMESTAMP')) + table.boolean('used').notNullable().defaultTo(false) + }) + }, + }) + + return migrations + } +} From ad846170b1942e8ab65190800f81cccc432891cb Mon Sep 17 00:00:00 2001 From: RemainingDev <161089154+RemainingDev@users.noreply.github.com> Date: Mon, 10 Feb 2025 16:28:17 +0100 Subject: [PATCH 3/4] Add new line --- src/extensions/invite/static/index.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/extensions/invite/static/index.css b/src/extensions/invite/static/index.css index fc35974..5a73836 100644 --- a/src/extensions/invite/static/index.css +++ b/src/extensions/invite/static/index.css @@ -14,4 +14,4 @@ table th, td{ color: rgb(165, 165, 165); font-style: italic; font-weight: lighter; -} \ No newline at end of file +} From 37ec710ce86bc4696a0d9cb2398aa71e1811d17f Mon Sep 17 00:00:00 2001 From: RemainingDev <161089154+RemainingDev@users.noreply.github.com> Date: Mon, 10 Feb 2025 20:44:16 +0100 Subject: [PATCH 4/4] Resolve Issue --- src/extensions/chat/tables.ts | 3 ++- src/extensions/invite/static/index.css | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/extensions/chat/tables.ts b/src/extensions/chat/tables.ts index 1af6e8f..6d39123 100644 --- a/src/extensions/chat/tables.ts +++ b/src/extensions/chat/tables.ts @@ -14,7 +14,8 @@ export default class extends Tables { await knex.schema() .createTable('_message', (table) => { table.increments('id').primary() - table.string('user_id').notNullable() + table.integer('user_id').notNullable() + table.foreign('user_id', 'fk_user_id').references('_root_user.id') table.timestamp('created_at').notNullable().defaultTo(knex.raw('CURRENT_TIMESTAMP')) table.string('content').notNullable() }) diff --git a/src/extensions/invite/static/index.css b/src/extensions/invite/static/index.css index 5a73836..ee2f0db 100644 --- a/src/extensions/invite/static/index.css +++ b/src/extensions/invite/static/index.css @@ -11,7 +11,7 @@ table th, td{ } .used{ - color: rgb(165, 165, 165); + color: #a5a5a5; font-style: italic; font-weight: lighter; }