Добавил управление пользователями в чатах
This commit is contained in:
parent
5ebb8ff2ea
commit
7a468a6337
13 changed files with 399 additions and 28 deletions
|
|
@ -11,6 +11,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/node": "^5.1.2",
|
"@astrojs/node": "^5.1.2",
|
||||||
|
"@material-design-icons/font": "^0.14.8",
|
||||||
"@noble/hashes": "^1.3.0",
|
"@noble/hashes": "^1.3.0",
|
||||||
"@popperjs/core": "^2.11.7",
|
"@popperjs/core": "^2.11.7",
|
||||||
"@prisma/client": "4.14.0",
|
"@prisma/client": "4.14.0",
|
||||||
|
|
|
||||||
7
pnpm-lock.yaml
generated
7
pnpm-lock.yaml
generated
|
|
@ -4,6 +4,9 @@ dependencies:
|
||||||
'@astrojs/node':
|
'@astrojs/node':
|
||||||
specifier: ^5.1.2
|
specifier: ^5.1.2
|
||||||
version: 5.1.2(astro@2.4.1)
|
version: 5.1.2(astro@2.4.1)
|
||||||
|
'@material-design-icons/font':
|
||||||
|
specifier: ^0.14.8
|
||||||
|
version: 0.14.8
|
||||||
'@noble/hashes':
|
'@noble/hashes':
|
||||||
specifier: ^1.3.0
|
specifier: ^1.3.0
|
||||||
version: 1.3.0
|
version: 1.3.0
|
||||||
|
|
@ -618,6 +621,10 @@ packages:
|
||||||
resolution: {integrity: sha512-4/RWEeXDO6bocPONheFe6gX/oQdP/bEpv0oL4HqjPP5DCenBSt0mHgahppY49N0CpsaqffdwPq+TlX9CYOq2Dw==}
|
resolution: {integrity: sha512-4/RWEeXDO6bocPONheFe6gX/oQdP/bEpv0oL4HqjPP5DCenBSt0mHgahppY49N0CpsaqffdwPq+TlX9CYOq2Dw==}
|
||||||
dev: false
|
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:
|
/@noble/hashes@1.3.0:
|
||||||
resolution: {integrity: sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg==}
|
resolution: {integrity: sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
|
||||||
|
|
@ -75,8 +75,8 @@ model chat_message {
|
||||||
id String @id @default(uuid())
|
id String @id @default(uuid())
|
||||||
text String
|
text String
|
||||||
|
|
||||||
user users @relation(fields: [userId], references: [id])
|
user users @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||||
chat chat @relation(fields: [chatId], references: [id])
|
chat chat @relation(fields: [chatId], references: [id], onDelete: Cascade)
|
||||||
|
|
||||||
sendAt DateTime @default(now())
|
sendAt DateTime @default(now())
|
||||||
|
|
||||||
|
|
@ -88,7 +88,8 @@ model user_in_chat {
|
||||||
id Int @id @default(autoincrement())
|
id Int @id @default(autoincrement())
|
||||||
chatId String
|
chatId String
|
||||||
userId Int
|
userId Int
|
||||||
|
creator Boolean @default(false)
|
||||||
|
|
||||||
chat chat @relation(fields: [chatId], references: [id])
|
chat chat @relation(fields: [chatId], references: [id], onDelete: Cascade)
|
||||||
user users @relation(fields: [userId], references: [id])
|
user users @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
1
public/assets/css/hystmodal.min.css
vendored
Normal file
1
public/assets/css/hystmodal.min.css
vendored
Normal file
|
|
@ -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}}
|
||||||
1
public/assets/js/hystmodal.min.js
vendored
Normal file
1
public/assets/js/hystmodal.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -1,6 +1,7 @@
|
||||||
---
|
---
|
||||||
import type { users } from "@prisma/client";
|
import type { users } from "@prisma/client";
|
||||||
import type { CompositeChat } from "../db";
|
import type { CompositeChat } from "../db";
|
||||||
|
import { getUsersNotInChat, isUserChatCreator } from "../db";
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
user: users;
|
user: users;
|
||||||
|
|
@ -28,14 +29,80 @@ if (chat.messages.length > 0) {
|
||||||
lastMessageAt = chat.messages[chat.messages.length - 1].sendAt;
|
lastMessageAt = chat.messages[chat.messages.length - 1].sendAt;
|
||||||
lastMessageAt.setSeconds(lastMessageAt.getSeconds() + 1);
|
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);
|
||||||
---
|
---
|
||||||
|
|
||||||
|
<div class="hystmodal" id="settingsModal" aria-hidden="true">
|
||||||
|
<div class="hystmodal__wrap">
|
||||||
|
<div class="hystmodal__window card p-2" role="dialog" aria-modal="true">
|
||||||
|
<button data-hystclose class="hystmodal__close">Закрыть</button>
|
||||||
|
|
||||||
|
{
|
||||||
|
!userIsCreator ? (
|
||||||
|
<button class="btn btn-sm btn-warning w-100 dlg-btn-dlt-usr" data-userId={`${user.id}`}>Выйти из чата</button>
|
||||||
|
): (
|
||||||
|
<button id="btn-delete-chat" class="btn btn-sm btn-danger w-100" data-chatId={`${chat.chat.id}`}>Удалить чат</button>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
<hr>
|
||||||
|
<h3>Пользователи в чате</h3>
|
||||||
|
<ul class="list-group">
|
||||||
|
{
|
||||||
|
uics.map((e) => (
|
||||||
|
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||||
|
<div class="d-flex flex-row align-items-center">
|
||||||
|
{e.user.fullName ?? e.user.login}
|
||||||
|
<a class="material-icons ms-2 fs-6 text-decoration-none" href={`/user/${e.user.login}`} target="_blank">open_in_new</a>
|
||||||
|
</div>
|
||||||
|
{userIsCreator && e.userId !== user.id ? (
|
||||||
|
<span class="badge bg-danger rounded-pill material-icons dlg-btn-dlt-usr" role="button" data-userId={`${e.userId}`}>
|
||||||
|
delete
|
||||||
|
</span>
|
||||||
|
) : null}
|
||||||
|
{userIsCreator && e.userId === user.id ? (
|
||||||
|
<span class="badge bg-success rounded-pill user-select-none material-icons-outlined">
|
||||||
|
shield
|
||||||
|
</span>
|
||||||
|
) : null}
|
||||||
|
</li>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
{userIsCreator ? (
|
||||||
|
<hr />
|
||||||
|
<h3>Пользователи не в чате</h3>
|
||||||
|
<ul class="list-group">
|
||||||
|
{
|
||||||
|
others.map((e) => (
|
||||||
|
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||||
|
<div class="d-flex flex-row align-items-center">
|
||||||
|
{e.fullName ?? e.login}
|
||||||
|
<a class="material-icons ms-2 fs-6 text-decoration-none" href={`/user/${e.login}`} target="_blank">open_in_new</a>
|
||||||
|
</div>
|
||||||
|
<span class="badge bg-primary rounded-pill material-icons dlg-btn-add-usr" role="button" data-userId={`${e.id}`}>
|
||||||
|
add
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="col d-flex flex-column" data-chatId={chat.chat.id}>
|
<div class="col d-flex flex-column" data-chatId={chat.chat.id}>
|
||||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div>
|
<div>
|
||||||
<p class="mb-1">Чат "{chat.chat.title}"</p>
|
<p class="mb-1">Чат "{chat.chat.title}"</p>
|
||||||
<button data-micromodal-trigger="modal-1">1</button>
|
<div class="d-flex flex-row align-items-center">
|
||||||
|
<button id="openUsersModalBtn" class="btn btn-sm me-2 material-icons" data-hystmodal="#settingsModal">settings</button>
|
||||||
<small class="text-muted" id="usersPart">
|
<small class="text-muted" id="usersPart">
|
||||||
Пользователи: {
|
Пользователи: {
|
||||||
chat.chat.user_in_chat
|
chat.chat.user_in_chat
|
||||||
|
|
@ -46,6 +113,7 @@ if (chat.messages.length > 0) {
|
||||||
</small>
|
</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<div id="chatHolder" class="flex-grow-1" data-lastMessageAt={lastMessageAt}>
|
<div id="chatHolder" class="flex-grow-1" data-lastMessageAt={lastMessageAt}>
|
||||||
{
|
{
|
||||||
|
|
@ -69,7 +137,6 @@ if (chat.messages.length > 0) {
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import type { CompositeChat } from "../db";
|
import type { CompositeChat } from "../db";
|
||||||
import MicroModal from "micromodal";
|
|
||||||
|
|
||||||
const attr = (attrName: string) => document.querySelector(`[${attrName}]`)!.getAttribute(attrName)!;
|
const attr = (attrName: string) => document.querySelector(`[${attrName}]`)!.getAttribute(attrName)!;
|
||||||
const chatId = () => attr("data-chatId");
|
const chatId = () => attr("data-chatId");
|
||||||
|
|
@ -146,6 +213,10 @@ if (chat.messages.length > 0) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
if (e instanceof Error) {
|
if (e instanceof Error) {
|
||||||
alert(`Ошибка загрузки сообщений: ${e.message}`);
|
alert(`Ошибка загрузки сообщений: ${e.message}`);
|
||||||
|
if (e.message.startsWith("Нет доступа к чату")) {
|
||||||
|
location.href = "/chats";
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -170,20 +241,15 @@ if (chat.messages.length > 0) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
if (e instanceof Error) {
|
if (e instanceof Error) {
|
||||||
alert(`Ошибка отправки сообщения: ${e.message}`);
|
alert(`Ошибка отправки сообщения: ${e.message}`);
|
||||||
|
if (e.message.startsWith("Нет доступа к чату")) {
|
||||||
|
location.href = "/chats";
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function showUsers() {
|
|
||||||
const cid = chatId();
|
|
||||||
alert(cid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", () => {
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
MicroModal.init();
|
|
||||||
|
|
||||||
document.getElementById("usersPart")?.addEventListener("click", () => showUsers());
|
|
||||||
|
|
||||||
const messageText = document.getElementById("messageText")! as HTMLInputElement;
|
const messageText = document.getElementById("messageText")! as HTMLInputElement;
|
||||||
const sendMessageBtn = document.getElementById("sendMessage")!;
|
const sendMessageBtn = document.getElementById("sendMessage")!;
|
||||||
|
|
||||||
|
|
@ -219,3 +285,117 @@ if (chat.messages.length > 0) {
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="/assets/css/hystmodal.min.css" />
|
||||||
|
<script is:inline src="/assets/js/hystmodal.min.js"></script>
|
||||||
|
<script is:inline>
|
||||||
|
const attr = (attrName) => document.querySelector(`[${attrName}]`).getAttribute(attrName);
|
||||||
|
const chatId = () => attr("data-chatId");
|
||||||
|
|
||||||
|
async function deleteUserFromChat(userId) {
|
||||||
|
try {
|
||||||
|
const resp = await fetch("/chatapi/removeUserFromChat", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({
|
||||||
|
chatId: chatId(),
|
||||||
|
userId
|
||||||
|
}),
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const json = await resp.json();
|
||||||
|
if (json.ok) {
|
||||||
|
location.hash = "chatSettings";
|
||||||
|
location.reload();
|
||||||
|
} else {
|
||||||
|
throw new Error(json.reason);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
if (e instanceof Error) {
|
||||||
|
alert(`Ошибка удаления пользователя из чата: ${e.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function addUserToChat(userId) {
|
||||||
|
try {
|
||||||
|
const resp = await fetch("/chatapi/addUserToChat", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({
|
||||||
|
chatId: chatId(),
|
||||||
|
userId
|
||||||
|
}),
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const json = await resp.json();
|
||||||
|
if (json.ok) {
|
||||||
|
location.hash = "chatSettings";
|
||||||
|
location.reload();
|
||||||
|
} else {
|
||||||
|
throw new Error(json.reason);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
if (e instanceof Error) {
|
||||||
|
alert(`Ошибка добавления пользователя в чат: ${e.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deleteChat() {
|
||||||
|
try {
|
||||||
|
const resp = await fetch("/chatapi/deleteChat", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({
|
||||||
|
chatId: chatId()
|
||||||
|
}),
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const json = await resp.json();
|
||||||
|
if (json.ok) {
|
||||||
|
location.href = "/chats"
|
||||||
|
} else {
|
||||||
|
throw new Error(json.reason);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
if (e instanceof Error) {
|
||||||
|
alert(`Ошибка удаления чата: ${e.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
const modalsController = new HystModal({
|
||||||
|
linkAttributeName: "data-hystmodal",
|
||||||
|
});
|
||||||
|
if (location.hash === "#chatSettings") {
|
||||||
|
modalsController.open("#settingsModal");
|
||||||
|
location.hash = "";
|
||||||
|
history.pushState("", document.title, window.location.pathname
|
||||||
|
+ window.location.search);
|
||||||
|
}
|
||||||
|
|
||||||
|
document.querySelectorAll(".dlg-btn-dlt-usr").forEach(e => {
|
||||||
|
const userId = parseInt(e.getAttribute("data-userId"));
|
||||||
|
if (!Number.isInteger(userId)) return;
|
||||||
|
|
||||||
|
e.addEventListener("click", () => deleteUserFromChat(userId));
|
||||||
|
});
|
||||||
|
document.querySelectorAll(".dlg-btn-add-usr").forEach(e => {
|
||||||
|
const userId = parseInt(e.getAttribute("data-userId"));
|
||||||
|
if (!Number.isInteger(userId)) return;
|
||||||
|
|
||||||
|
e.addEventListener("click", () => addUserToChat(userId));
|
||||||
|
});
|
||||||
|
document.getElementById("btn-delete-chat")?.addEventListener("click", () => {
|
||||||
|
deleteChat();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
|
||||||
37
src/db.ts
37
src/db.ts
|
|
@ -451,7 +451,7 @@ export async function createChatMessage(chatId: string, userId: number, message:
|
||||||
return msg;
|
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({
|
const chat = await client.chat.create({
|
||||||
data: {
|
data: {
|
||||||
title: title,
|
title: title,
|
||||||
|
|
@ -460,6 +460,7 @@ export async function createChat(title: string, userIds: number[]) {
|
||||||
data: userIds.map((x) => {
|
data: userIds.map((x) => {
|
||||||
return {
|
return {
|
||||||
userId: x,
|
userId: x,
|
||||||
|
creator: x == creatorId,
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
|
@ -498,3 +499,37 @@ export async function removeUserFromChat(userId: number, chatId: string) {
|
||||||
});
|
});
|
||||||
return chat !== null;
|
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;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,8 @@ const { title } = Astro.props;
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
<style is:global>
|
<style is:global>
|
||||||
|
@import "@material-design-icons/font";
|
||||||
|
|
||||||
img.rendered-image {
|
img.rendered-image {
|
||||||
max-height: 300px;
|
max-height: 300px;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
46
src/pages/chatapi/addUserToChat.ts
Normal file
46
src/pages/chatapi/addUserToChat.ts
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
import type { APIContext } from "astro";
|
||||||
|
import { getSessionUser, addUserToChat, isUserChatCreator } from "../../db";
|
||||||
|
import { Prisma } from "@prisma/client";
|
||||||
|
|
||||||
|
export async function post({ request, cookies }: APIContext) {
|
||||||
|
const response: { ok: boolean; reason?: string } = {
|
||||||
|
ok: true,
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
const sessId = cookies.get("session").value!;
|
||||||
|
const user = (await getSessionUser(sessId))!;
|
||||||
|
|
||||||
|
const json = await request.json();
|
||||||
|
const chatId = json.chatId as string;
|
||||||
|
const userId = json.userId;
|
||||||
|
console.log(chatId, userId, user.id);
|
||||||
|
if (chatId === null || chatId.length === 0 || !Number.isInteger(userId)) {
|
||||||
|
throw new Error("Предоставлены некорректные данные для изменения чата");
|
||||||
|
}
|
||||||
|
|
||||||
|
const isCreator = await isUserChatCreator(user.id, chatId);
|
||||||
|
if (!isCreator) {
|
||||||
|
throw new Error("Не создатель не может добавлять других пользователей!");
|
||||||
|
}
|
||||||
|
|
||||||
|
const ok = await addUserToChat(userId, chatId);
|
||||||
|
if (!ok) {
|
||||||
|
throw new Error("Неизвестная ошибка");
|
||||||
|
}
|
||||||
|
|
||||||
|
response.ok = true;
|
||||||
|
} catch (e: any) {
|
||||||
|
response.ok = false;
|
||||||
|
if (e instanceof Prisma.PrismaClientKnownRequestError) {
|
||||||
|
response.reason = `Неизвестная ошибка базы данных. Код ${e.code}`;
|
||||||
|
} else if (e instanceof Error) {
|
||||||
|
response.reason = e.message.trim();
|
||||||
|
} else {
|
||||||
|
response.reason = e.toString().trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
body: JSON.stringify(response),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -17,7 +17,7 @@ export async function post({ request, cookies }: APIContext) {
|
||||||
throw new Error("Предоставлены некорректные данные для создания чата");
|
throw new Error("Предоставлены некорректные данные для создания чата");
|
||||||
}
|
}
|
||||||
|
|
||||||
await createChat(title.toString(), [...selectedUsers, user.id]);
|
await createChat(title.toString(), user.id, [...selectedUsers, user.id]);
|
||||||
|
|
||||||
response.ok = true;
|
response.ok = true;
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
|
|
|
||||||
44
src/pages/chatapi/deleteChat.ts
Normal file
44
src/pages/chatapi/deleteChat.ts
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
import type { APIContext } from "astro";
|
||||||
|
import { getSessionUser, deleteChat, isUserChatCreator } from "../../db";
|
||||||
|
import { Prisma } from "@prisma/client";
|
||||||
|
|
||||||
|
export async function post({ request, cookies }: APIContext) {
|
||||||
|
const response: { ok: boolean; reason?: string } = {
|
||||||
|
ok: true,
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
const sessId = cookies.get("session").value!;
|
||||||
|
const user = (await getSessionUser(sessId))!;
|
||||||
|
|
||||||
|
const json = await request.json();
|
||||||
|
const chatId = json.chatId as string;
|
||||||
|
if (chatId === null || chatId.length === 0) {
|
||||||
|
throw new Error("Предоставлены некорректные данные для удаления чата");
|
||||||
|
}
|
||||||
|
|
||||||
|
const isCreator = await isUserChatCreator(user.id, chatId);
|
||||||
|
if (!isCreator) {
|
||||||
|
throw new Error("Не создатель не может удалять других пользователей!");
|
||||||
|
}
|
||||||
|
|
||||||
|
const ok = await deleteChat(chatId);
|
||||||
|
if (!ok) {
|
||||||
|
throw new Error("Неизвестная ошибка");
|
||||||
|
}
|
||||||
|
|
||||||
|
response.ok = true;
|
||||||
|
} catch (e: any) {
|
||||||
|
response.ok = false;
|
||||||
|
if (e instanceof Prisma.PrismaClientKnownRequestError) {
|
||||||
|
response.reason = `Неизвестная ошибка базы данных. Код ${e.code}`;
|
||||||
|
} else if (e instanceof Error) {
|
||||||
|
response.reason = e.message.trim();
|
||||||
|
} else {
|
||||||
|
response.reason = e.toString().trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
body: JSON.stringify(response),
|
||||||
|
};
|
||||||
|
}
|
||||||
49
src/pages/chatapi/removeUserFromChat.ts
Normal file
49
src/pages/chatapi/removeUserFromChat.ts
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
import type { APIContext } from "astro";
|
||||||
|
import { getSessionUser, removeUserFromChat, isUserChatCreator } from "../../db";
|
||||||
|
import { Prisma } from "@prisma/client";
|
||||||
|
|
||||||
|
export async function post({ request, cookies }: APIContext) {
|
||||||
|
const response: { ok: boolean; reason?: string } = {
|
||||||
|
ok: true,
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
const sessId = cookies.get("session").value!;
|
||||||
|
const user = (await getSessionUser(sessId))!;
|
||||||
|
|
||||||
|
const json = await request.json();
|
||||||
|
const chatId = json.chatId as string;
|
||||||
|
const userId = json.userId;
|
||||||
|
if (chatId === null || chatId.length === 0 || !Number.isInteger(userId)) {
|
||||||
|
throw new Error("Предоставлены некорректные данные для изменения чата");
|
||||||
|
}
|
||||||
|
|
||||||
|
const isCreator = await isUserChatCreator(user.id, chatId);
|
||||||
|
if (!isCreator && userId !== user.id) {
|
||||||
|
throw new Error("Не создатель не может удалять других пользователей!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isCreator && userId === user.id) {
|
||||||
|
throw new Error("Нельзя удалить самого себя из чата, если Вы создатель!");
|
||||||
|
}
|
||||||
|
|
||||||
|
const ok = await removeUserFromChat(userId, chatId);
|
||||||
|
if (!ok) {
|
||||||
|
throw new Error("Неизвестная ошибка");
|
||||||
|
}
|
||||||
|
|
||||||
|
response.ok = true;
|
||||||
|
} catch (e: any) {
|
||||||
|
response.ok = false;
|
||||||
|
if (e instanceof Prisma.PrismaClientKnownRequestError) {
|
||||||
|
response.reason = `Неизвестная ошибка базы данных. Код ${e.code}`;
|
||||||
|
} else if (e instanceof Error) {
|
||||||
|
response.reason = e.message.trim();
|
||||||
|
} else {
|
||||||
|
response.reason = e.toString().trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
body: JSON.stringify(response),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -22,6 +22,10 @@ let openChat: CompositeChat | null = null;
|
||||||
if (Astro.url.searchParams.has("openChat")) {
|
if (Astro.url.searchParams.has("openChat")) {
|
||||||
let openChatId = Astro.url.searchParams.get("openChat")!;
|
let openChatId = Astro.url.searchParams.get("openChat")!;
|
||||||
openChat = await getChatMessages(openChatId);
|
openChat = await getChatMessages(openChatId);
|
||||||
|
|
||||||
|
if (openChat.chat === null) {
|
||||||
|
return Astro.redirect("/chats");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const sessId = Astro.cookies.get("session").value!;
|
const sessId = Astro.cookies.get("session").value!;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue