From 7a468a6337ae8e15735b52692e4a02d1ec6441b8 Mon Sep 17 00:00:00 2001 From: Artem VV Date: Thu, 25 May 2023 01:19:13 +0700 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20?= =?UTF-8?q?=D1=83=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5?= =?UTF-8?q?=D0=BB=D1=8F=D0=BC=D0=B8=20=D0=B2=20=D1=87=D0=B0=D1=82=D0=B0?= =?UTF-8?q?=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + pnpm-lock.yaml | 7 + prisma/schema.prisma | 15 +- public/assets/css/hystmodal.min.css | 1 + public/assets/js/hystmodal.min.js | 1 + src/components/ChatView.astro | 218 +++++++++++++++++++++--- src/db.ts | 37 +++- src/layouts/Layout.astro | 2 + src/pages/chatapi/addUserToChat.ts | 46 +++++ src/pages/chatapi/createChat.ts | 2 +- src/pages/chatapi/deleteChat.ts | 44 +++++ src/pages/chatapi/removeUserFromChat.ts | 49 ++++++ src/pages/chats.astro | 4 + 13 files changed, 399 insertions(+), 28 deletions(-) create mode 100644 public/assets/css/hystmodal.min.css create mode 100644 public/assets/js/hystmodal.min.js create mode 100644 src/pages/chatapi/addUserToChat.ts create mode 100644 src/pages/chatapi/deleteChat.ts create mode 100644 src/pages/chatapi/removeUserFromChat.ts diff --git a/package.json b/package.json index 5799622..414e3ca 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ }, "dependencies": { "@astrojs/node": "^5.1.2", + "@material-design-icons/font": "^0.14.8", "@noble/hashes": "^1.3.0", "@popperjs/core": "^2.11.7", "@prisma/client": "4.14.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9390d6c..34c46a4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,6 +4,9 @@ dependencies: '@astrojs/node': specifier: ^5.1.2 version: 5.1.2(astro@2.4.1) + '@material-design-icons/font': + specifier: ^0.14.8 + version: 0.14.8 '@noble/hashes': specifier: ^1.3.0 version: 1.3.0 @@ -618,6 +621,10 @@ packages: resolution: {integrity: sha512-4/RWEeXDO6bocPONheFe6gX/oQdP/bEpv0oL4HqjPP5DCenBSt0mHgahppY49N0CpsaqffdwPq+TlX9CYOq2Dw==} dev: false + /@material-design-icons/font@0.14.8: + resolution: {integrity: sha512-KQ/zk35qFYF+TLv83z0mt021G+CQhgUds+KZ0f65SR5wTu4UzHsXOrsWRhDwrncSP+BqVnk5xab9brwxUoK0rA==} + dev: false + /@noble/hashes@1.3.0: resolution: {integrity: sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg==} dev: false diff --git a/prisma/schema.prisma b/prisma/schema.prisma index df1b789..dc752f4 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -75,8 +75,8 @@ model chat_message { id String @id @default(uuid()) text String - user users @relation(fields: [userId], references: [id]) - chat chat @relation(fields: [chatId], references: [id]) + user users @relation(fields: [userId], references: [id], onDelete: Cascade) + chat chat @relation(fields: [chatId], references: [id], onDelete: Cascade) sendAt DateTime @default(now()) @@ -85,10 +85,11 @@ model chat_message { } model user_in_chat { - id Int @id @default(autoincrement()) - chatId String - userId Int + id Int @id @default(autoincrement()) + chatId String + userId Int + creator Boolean @default(false) - chat chat @relation(fields: [chatId], references: [id]) - user users @relation(fields: [userId], references: [id]) + chat chat @relation(fields: [chatId], references: [id], onDelete: Cascade) + user users @relation(fields: [userId], references: [id], onDelete: Cascade) } diff --git a/public/assets/css/hystmodal.min.css b/public/assets/css/hystmodal.min.css new file mode 100644 index 0000000..c385adb --- /dev/null +++ b/public/assets/css/hystmodal.min.css @@ -0,0 +1 @@ +.hystmodal__opened,.hystmodal__shadow{position:fixed;right:0;left:0;overflow:hidden}.hystmodal__shadow{border:none;display:block;width:100%;top:0;bottom:0;pointer-events:none;z-index:98;opacity:0;transition:opacity .15s ease;background-color:#000}.hystmodal__shadow--show{pointer-events:auto;opacity:.6}.hystmodal{position:fixed;top:0;bottom:0;right:0;left:0;overflow:hidden;overflow-y:auto;-webkit-overflow-scrolling:touch;opacity:1;pointer-events:none;display:flex;flex-flow:column nowrap;justify-content:flex-start;z-index:99;visibility:hidden}.hystmodal--active{opacity:1}.hystmodal--active,.hystmodal--moved{pointer-events:auto;visibility:visible}.hystmodal__wrap{flex-shrink:0;flex-grow:0;width:100%;min-height:100%;margin:auto;display:flex;flex-flow:column nowrap;align-items:center;justify-content:center}.hystmodal__window{margin:50px 0;box-sizing:border-box;flex-shrink:0;flex-grow:0;background:#fff;width:600px;max-width:100%;overflow:visible;transition:transform .2s ease 0s,opacity .2s ease 0s;transform:scale(.9);opacity:0}.hystmodal--active .hystmodal__window{transform:scale(1);opacity:1}.hystmodal__close{position:absolute;z-index:10;top:0;right:-40px;display:block;width:30px;height:30px;background-color:transparent;background-position:50%;background-repeat:no-repeat;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23fff' stroke='%23fff' stroke-linecap='square' stroke-miterlimit='50' stroke-width='2' d='M22 2L2 22'/%3E%3Cpath fill='none' stroke='%23fff' stroke-linecap='square' stroke-miterlimit='50' stroke-width='2' d='M2 2l20 20'/%3E%3C/svg%3E");background-size:100% 100%;border:none;font-size:0;cursor:pointer;outline:none}.hystmodal__close:focus{outline:2px dotted #afb3b9;outline-offset:2px}@media (max-width:767px){.hystmodal__close{top:10px;right:10px;width:24px;height:24px;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23fff' stroke='%23111' stroke-linecap='square' stroke-miterlimit='50' stroke-width='2' d='M22 2L2 22'/%3E%3Cpath fill='none' stroke='%23111' stroke-linecap='square' stroke-miterlimit='50' stroke-width='2' d='M2 2l20 20'/%3E%3C/svg%3E")}.hystmodal__window{margin:0}} \ No newline at end of file diff --git a/public/assets/js/hystmodal.min.js b/public/assets/js/hystmodal.min.js new file mode 100644 index 0000000..fc3d263 --- /dev/null +++ b/public/assets/js/hystmodal.min.js @@ -0,0 +1 @@ +!function(e){var t={};function n(i){if(t[i])return t[i].exports;var o=t[i]={i:i,l:!1,exports:{}};return e[i].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(i,o,function(t){return e[t]}.bind(null,o));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=1)}([function(e,t,n){"use strict";function i(){return(i=Object.assign||function(e){for(var t=1;t 0) { lastMessageAt = chat.messages[chat.messages.length - 1].sendAt; lastMessageAt.setSeconds(lastMessageAt.getSeconds() + 1); } + +const uics = chat.chat.user_in_chat; +const chatUsers = uics.map((e) => e.user); +const others = await getUsersNotInChat(chatUsers); + +const userIsCreator = await isUserChatCreator(user.id, chat.chat.id); --- + +
@@ -69,7 +137,6 @@ if (chat.messages.length > 0) { + diff --git a/src/db.ts b/src/db.ts index db618ea..b8ab7fc 100644 --- a/src/db.ts +++ b/src/db.ts @@ -451,7 +451,7 @@ export async function createChatMessage(chatId: string, userId: number, message: return msg; } -export async function createChat(title: string, userIds: number[]) { +export async function createChat(title: string, creatorId: number, userIds: number[]) { const chat = await client.chat.create({ data: { title: title, @@ -460,6 +460,7 @@ export async function createChat(title: string, userIds: number[]) { data: userIds.map((x) => { return { userId: x, + creator: x == creatorId, }; }), }, @@ -498,3 +499,37 @@ export async function removeUserFromChat(userId: number, chatId: string) { }); return chat !== null; } + +export async function getUsersNotInChat(chatUsers: users[]) { + const others = await client.users.findMany({ + where: { + id: { + notIn: chatUsers.map((e) => e.id), + }, + }, + }); + + return others; +} + +export async function isUserChatCreator(userId: number, chatId: string) { + const user = await client.user_in_chat.findFirst({ + where: { + chatId: chatId, + userId: userId, + creator: true, + }, + }); + + return user !== null; +} + +export async function deleteChat(chatId: string) { + const chat = await client.chat.delete({ + where: { + id: chatId, + }, + }); + + return chat !== null; +} diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro index ec27447..350ff01 100644 --- a/src/layouts/Layout.astro +++ b/src/layouts/Layout.astro @@ -26,6 +26,8 @@ const { title } = Astro.props;