diff --git a/client/.yarn/install-state.gz b/client/.yarn/install-state.gz index e1d822b..8aac8da 100644 Binary files a/client/.yarn/install-state.gz and b/client/.yarn/install-state.gz differ diff --git a/client/app/components.d.ts b/client/app/components.d.ts index 88eb6f6..d90c971 100644 --- a/client/app/components.d.ts +++ b/client/app/components.d.ts @@ -13,17 +13,19 @@ declare module 'vue' { PrimeButton: typeof import('primevue/button')['default'] PrimeButtonGroup: typeof import('primevue/buttongroup')['default'] PrimeCard: typeof import('primevue/card')['default'] - PrimeDivider: typeof import('primevue/divider')['default'] PrimeFloatLabel: typeof import('primevue/floatlabel')['default'] PrimeInputText: typeof import('primevue/inputtext')['default'] PrimePassword: typeof import('primevue/password')['default'] - PrimeProgressBar: typeof import('primevue/progressbar')['default'] PrimeScrollPanel: typeof import('primevue/scrollpanel')['default'] - PrimeSelect: typeof import('primevue/select')['default'] PrimeSelectButton: typeof import('primevue/selectbutton')['default'] PrimeSlider: typeof import('primevue/slider')['default'] + PrimeTab: typeof import('primevue/tab')['default'] + PrimeTabList: typeof import('primevue/tablist')['default'] + PrimeTabPanel: typeof import('primevue/tabpanel')['default'] + PrimeTabPanels: typeof import('primevue/tabpanels')['default'] + PrimeTabs: typeof import('primevue/tabs')['default'] + PrimeTextarea: typeof import('primevue/textarea')['default'] PrimeToast: typeof import('primevue/toast')['default'] - PrimeToggleSwitch: typeof import('primevue/toggleswitch')['default'] RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] } diff --git a/client/app/components/chat/ChatEditor.vue b/client/app/components/chat/ChatEditor.vue new file mode 100644 index 0000000..d8d1de0 --- /dev/null +++ b/client/app/components/chat/ChatEditor.vue @@ -0,0 +1,28 @@ + + + + + diff --git a/client/app/components/chat/ChatMessage.vue b/client/app/components/chat/ChatMessage.vue new file mode 100644 index 0000000..e52f7ed --- /dev/null +++ b/client/app/components/chat/ChatMessage.vue @@ -0,0 +1,27 @@ + + + + + diff --git a/client/app/components/chat/ChatWidget.vue b/client/app/components/chat/ChatWidget.vue new file mode 100644 index 0000000..10ed74e --- /dev/null +++ b/client/app/components/chat/ChatWidget.vue @@ -0,0 +1,33 @@ + + + + + diff --git a/client/app/composables/use-chat.ts b/client/app/composables/use-chat.ts new file mode 100644 index 0000000..3b66579 --- /dev/null +++ b/client/app/composables/use-chat.ts @@ -0,0 +1,44 @@ +import { createGlobalState } from '@vueuse/core' + +interface ChatMessage { + id: string + username: string + message: string +} + +interface ChatChannel { + id: number + name: string +} + +export const useChat = createGlobalState(() => { + const messages = ref([ + { + id: '1337', + username: 'Yes', + message: 'Fisting is 300 bucks', + createdAt: Date.now(), + }, + ]) + + const channel = ref(0) + + async function sendMsg(channelId: ChatChannel['id'], msg: ChatMessage['message']) { + console.log('Trying to send message', channelId, msg) + } + + watch(channel, async (id) => { + await console.log('Yes', id) + }, { + immediate: true, + }) + + return { + channel, + + channels, + messages, + + sendMsg, + } +}) diff --git a/client/app/pages/index.vue b/client/app/pages/index.vue index ab276f5..e98da71 100644 --- a/client/app/pages/index.vue +++ b/client/app/pages/index.vue @@ -3,7 +3,7 @@
diff --git a/client/src-tauri/src/lib.rs b/client/src-tauri/src/lib.rs index f0bf59b..0f33475 100644 --- a/client/src-tauri/src/lib.rs +++ b/client/src-tauri/src/lib.rs @@ -4,7 +4,7 @@ pub fn run() { .plugin(tauri_plugin_global_shortcut::Builder::new().build()) .plugin(tauri_plugin_process::init()) .plugin(tauri_plugin_updater::Builder::new().build()) - .plugin(tauri_plugin_single_instance::init(|_, _, _| {})) +// .plugin(tauri_plugin_single_instance::init(|_, _, _| {})) .setup(|app| { if cfg!(debug_assertions) { app.handle().plugin( diff --git a/node_modules/.yarn-integrity b/node_modules/.yarn-integrity new file mode 100644 index 0000000..c8ffeba --- /dev/null +++ b/node_modules/.yarn-integrity @@ -0,0 +1,12 @@ +{ + "systemParams": "win32-x64-137", + "modulesFolders": [ + "node_modules" + ], + "flags": [], + "linkedModules": [], + "topLevelPatterns": [], + "lockfileEntries": {}, + "files": [], + "artifacts": {} +} \ No newline at end of file diff --git a/server/modules/chat/index.ts b/server/modules/chat/index.ts new file mode 100644 index 0000000..c035914 --- /dev/null +++ b/server/modules/chat/index.ts @@ -0,0 +1,22 @@ +import client from '../../prisma/client.ts' + +export async function chatInit() { + const existing = client.chatChannel.findFirst({ + where: { + id: 0, + }, + }) + + if (!existing) { + await client.chatChannel.create({ + create: { + id: 0, + name: 'Main channel', + }, + update: null, + where: { + id: 0, + }, + }) + } +} diff --git a/server/prisma/migrations/20251226183651_minus_nahuy/migration.sql b/server/prisma/migrations/20251226183651_minus_nahuy/migration.sql new file mode 100644 index 0000000..e9931e2 --- /dev/null +++ b/server/prisma/migrations/20251226183651_minus_nahuy/migration.sql @@ -0,0 +1,20 @@ +/* + Warnings: + + - You are about to drop the column `volumes` on the `UserPreferences` table. All the data in the column will be lost. + +*/ +-- RedefineTables +PRAGMA defer_foreign_keys=ON; +PRAGMA foreign_keys=OFF; +CREATE TABLE "new_UserPreferences" ( + "userId" TEXT NOT NULL PRIMARY KEY, + "toggleInputHotkey" TEXT DEFAULT '', + "toggleOutputHotkey" TEXT DEFAULT '', + CONSTRAINT "UserPreferences_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User" ("id") ON DELETE CASCADE ON UPDATE CASCADE +); +INSERT INTO "new_UserPreferences" ("toggleInputHotkey", "toggleOutputHotkey", "userId") SELECT "toggleInputHotkey", "toggleOutputHotkey", "userId" FROM "UserPreferences"; +DROP TABLE "UserPreferences"; +ALTER TABLE "new_UserPreferences" RENAME TO "UserPreferences"; +PRAGMA foreign_keys=ON; +PRAGMA defer_foreign_keys=OFF; diff --git a/server/prisma/migrations/20251226190516_chat/migration.sql b/server/prisma/migrations/20251226190516_chat/migration.sql new file mode 100644 index 0000000..515418e --- /dev/null +++ b/server/prisma/migrations/20251226190516_chat/migration.sql @@ -0,0 +1,18 @@ +-- CreateTable +CREATE TABLE "ChatMessage" ( + "id" TEXT NOT NULL PRIMARY KEY, + "userId" TEXT NOT NULL, + "channelId" TEXT NOT NULL, + "content" TEXT NOT NULL DEFAULT '', + CONSTRAINT "ChatMessage_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User" ("id") ON DELETE RESTRICT ON UPDATE CASCADE, + CONSTRAINT "ChatMessage_channelId_fkey" FOREIGN KEY ("channelId") REFERENCES "ChatChannel" ("id") ON DELETE CASCADE ON UPDATE CASCADE +); + +-- CreateTable +CREATE TABLE "ChatChannel" ( + "id" TEXT NOT NULL PRIMARY KEY, + "name" TEXT NOT NULL +); + +-- CreateIndex +CREATE UNIQUE INDEX "ChatChannel_name_key" ON "ChatChannel"("name"); diff --git a/server/prisma/migrations/20251226194252_more_chat_wip/migration.sql b/server/prisma/migrations/20251226194252_more_chat_wip/migration.sql new file mode 100644 index 0000000..eefb751 --- /dev/null +++ b/server/prisma/migrations/20251226194252_more_chat_wip/migration.sql @@ -0,0 +1,34 @@ +/* + Warnings: + + - The primary key for the `ChatChannel` table will be changed. If it partially fails, the table could be left without primary key constraint. + - You are about to alter the column `id` on the `ChatChannel` table. The data in that column could be lost. The data in that column will be cast from `String` to `Int`. + - You are about to alter the column `channelId` on the `ChatMessage` table. The data in that column could be lost. The data in that column will be cast from `String` to `Int`. + - Added the required column `createdAt` to the `ChatMessage` table without a default value. This is not possible if the table is not empty. + +*/ +-- RedefineTables +PRAGMA defer_foreign_keys=ON; +PRAGMA foreign_keys=OFF; +CREATE TABLE "new_ChatChannel" ( + "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + "name" TEXT NOT NULL +); +INSERT INTO "new_ChatChannel" ("id", "name") SELECT "id", "name" FROM "ChatChannel"; +DROP TABLE "ChatChannel"; +ALTER TABLE "new_ChatChannel" RENAME TO "ChatChannel"; +CREATE UNIQUE INDEX "ChatChannel_name_key" ON "ChatChannel"("name"); +CREATE TABLE "new_ChatMessage" ( + "id" TEXT NOT NULL PRIMARY KEY, + "userId" TEXT NOT NULL, + "channelId" INTEGER NOT NULL, + "content" TEXT NOT NULL DEFAULT '', + "createdAt" DATETIME NOT NULL, + CONSTRAINT "ChatMessage_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User" ("id") ON DELETE RESTRICT ON UPDATE CASCADE, + CONSTRAINT "ChatMessage_channelId_fkey" FOREIGN KEY ("channelId") REFERENCES "ChatChannel" ("id") ON DELETE CASCADE ON UPDATE CASCADE +); +INSERT INTO "new_ChatMessage" ("channelId", "content", "id", "userId") SELECT "channelId", "content", "id", "userId" FROM "ChatMessage"; +DROP TABLE "ChatMessage"; +ALTER TABLE "new_ChatMessage" RENAME TO "ChatMessage"; +PRAGMA foreign_keys=ON; +PRAGMA defer_foreign_keys=OFF; diff --git a/server/prisma/migrations/20251226194927_more_chat_wip/migration.sql b/server/prisma/migrations/20251226194927_more_chat_wip/migration.sql new file mode 100644 index 0000000..87af6c4 --- /dev/null +++ b/server/prisma/migrations/20251226194927_more_chat_wip/migration.sql @@ -0,0 +1,17 @@ +-- RedefineTables +PRAGMA defer_foreign_keys=ON; +PRAGMA foreign_keys=OFF; +CREATE TABLE "new_ChatMessage" ( + "id" TEXT NOT NULL PRIMARY KEY, + "userId" TEXT NOT NULL, + "channelId" INTEGER NOT NULL, + "content" TEXT NOT NULL, + "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + CONSTRAINT "ChatMessage_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User" ("id") ON DELETE RESTRICT ON UPDATE CASCADE, + CONSTRAINT "ChatMessage_channelId_fkey" FOREIGN KEY ("channelId") REFERENCES "ChatChannel" ("id") ON DELETE CASCADE ON UPDATE CASCADE +); +INSERT INTO "new_ChatMessage" ("channelId", "content", "createdAt", "id", "userId") SELECT "channelId", "content", "createdAt", "id", "userId" FROM "ChatMessage"; +DROP TABLE "ChatMessage"; +ALTER TABLE "new_ChatMessage" RENAME TO "ChatMessage"; +PRAGMA foreign_keys=ON; +PRAGMA defer_foreign_keys=OFF; diff --git a/server/prisma/schema.prisma b/server/prisma/schema.prisma index 8477571..3f15326 100644 --- a/server/prisma/schema.prisma +++ b/server/prisma/schema.prisma @@ -18,6 +18,8 @@ model User { Session Session[] UserPreferences UserPreferences? + + ChatMessage ChatMessage[] } model Session { @@ -34,7 +36,26 @@ model UserPreferences { userId String @id toggleInputHotkey String? @default("") toggleOutputHotkey String? @default("") - volumes Json? @default("{}") user User @relation(fields: [userId], references: [id], onDelete: Cascade) +} + +model ChatMessage { + id String @id + + userId String + channelId Int + content String + + createdAt DateTime @default(now()) + + user User @relation(fields: [userId], references: [id], onDelete: Restrict) + channel ChatChannel @relation(fields: [channelId], references: [id], onDelete: Cascade) +} + +model ChatChannel { + id Int @id + name String @unique + + messages ChatMessage[] } \ No newline at end of file diff --git a/server/routes/chat.ts b/server/routes/chat.ts new file mode 100644 index 0000000..ee2aded --- /dev/null +++ b/server/routes/chat.ts @@ -0,0 +1,23 @@ +import type { FastifyInstance } from 'fastify' +import prisma from '../prisma/client.ts' + +export default function (fastify: FastifyInstance) { + fastify.get('/chats', async (req, reply) => { + if (req.user) { + return prisma.chatChannel.findMany() + } + + reply.code(401).send(false) + }) + + fastify.get('/chats/:id', async (req, reply) => { + if (req.user) { + console.log('Trying to fetch chat with id', req.body.id) + + // return prisma.userPreferences.findFirst({ where: { userId: req.user.id } }) + return true + } + + reply.code(401).send(false) + }) +} diff --git a/server/server.ts b/server/server.ts index 53ab88c..2a73772 100644 --- a/server/server.ts +++ b/server/server.ts @@ -4,6 +4,7 @@ import FastifyAutoLoad from '@fastify/autoload' import FastifyCookie from '@fastify/cookie' import FastifyCors from '@fastify/cors' import Fastify from 'fastify' +import { chatInit } from './modules/chat/index.ts' import prisma from './prisma/client.ts' const __filename = fileURLToPath(import.meta.url) @@ -43,6 +44,8 @@ fastify.register(FastifyAutoLoad, { await prisma.$connect() fastify.log.info('Testing DB Connection. OK') + + await chatInit() } catch (err) { fastify.log.error(err) diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..fb57ccd --- /dev/null +++ b/yarn.lock @@ -0,0 +1,4 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + +