add support for deleting chats

This commit is contained in:
Cogent Apps
2023-03-17 20:45:27 +00:00
parent 6415e3032c
commit 1be33f5d0b
10 changed files with 193 additions and 29 deletions

View File

@@ -12,4 +12,6 @@ export default abstract class Database {
public abstract insertMessages(userID: string, messages: any[]): Promise<void>;
public abstract createShare(userID: string|null, id: string): Promise<boolean>;
public abstract setTitle(userID: string, chatID: string, title: string): Promise<void>;
public abstract deleteChat(userID: string, chatID: string): Promise<any>;
public abstract getDeletedChatIDs(userID: string): Promise<string[]>;
}

View File

@@ -46,6 +46,12 @@ export class SQLiteAdapter extends Database {
title TEXT
)`);
db.run(`CREATE TABLE IF NOT EXISTS deleted_chats (
id TEXT PRIMARY KEY,
user_id TEXT,
deleted_at DATETIME
)`);
db.run(`CREATE TABLE IF NOT EXISTS messages (
id TEXT PRIMARY KEY,
user_id TEXT,
@@ -170,4 +176,25 @@ export class SQLiteAdapter extends Database {
});
});
}
public async deleteChat(userID: string, chatID: string): Promise<any> {
db.serialize(() => {
db.run(`DELETE FROM chats WHERE id = ? AND user_id = ?`, [chatID, userID]);
db.run(`DELETE FROM messages WHERE chat_id = ? AND user_id = ?`, [chatID, userID]);
db.run(`INSERT INTO deleted_chats (id, user_id, deleted_at) VALUES (?, ?, ?)`, [chatID, userID, new Date()]);
console.log(`[database:sqlite] deleted chat ${chatID}`);
});
}
public async getDeletedChatIDs(userID: string): Promise<string[]> {
return new Promise((resolve, reject) => {
db.all(`SELECT * FROM deleted_chats WHERE user_id = ?`, [userID], (err: any, rows: any) => {
if (err) {
reject(err);
} else {
resolve(rows.map((row: any) => row.id));
}
});
});
}
}

View File

@@ -0,0 +1,13 @@
import express from 'express';
import RequestHandler from "./base";
export default class DeleteChatRequestHandler extends RequestHandler {
async handler(req: express.Request, res: express.Response) {
await this.context.database.deleteChat(this.userID!, req.body.id);
res.json({ status: 'ok' });
}
public isProtected() {
return true;
}
}

View File

@@ -3,9 +3,10 @@ import RequestHandler from "./base";
export default class SyncRequestHandler extends RequestHandler {
async handler(req: express.Request, res: express.Response) {
const [chats, messages] = await Promise.all([
const [chats, messages, deletedChatIDs] = await Promise.all([
this.context.database.getChats(this.userID!),
this.context.database.getMessages(this.userID!),
this.context.database.getDeletedChatIDs(this.userID!),
]);
const output: Record<string, any> = {};
@@ -26,6 +27,12 @@ export default class SyncRequestHandler extends RequestHandler {
output[c.id] = chat;
}
for (const chatID of deletedChatIDs) {
output[chatID] = {
deleted: true
};
}
res.json(output);
}

View File

@@ -20,6 +20,7 @@ import SessionRequestHandler from './endpoints/session';
import GetShareRequestHandler from './endpoints/get-share';
import { configurePassport } from './passport';
import { configureAuth0 } from './auth0';
import DeleteChatRequestHandler from './endpoints/delete-chat';
process.on('unhandledRejection', (reason, p) => {
console.error('Unhandled Rejection at: Promise', p, 'reason:', reason);
@@ -77,6 +78,7 @@ export default class ChatServer {
this.app.get('/chatapi/session', (req, res) => new SessionRequestHandler(this, req, res));
this.app.post('/chatapi/messages', (req, res) => new MessagesRequestHandler(this, req, res));
this.app.post('/chatapi/title', (req, res) => new TitleRequestHandler(this, req, res));
this.app.post('/chatapi/delete', (req, res) => new DeleteChatRequestHandler(this, req, res));
this.app.post('/chatapi/sync', (req, res) => new SyncRequestHandler(this, req, res));
this.app.get('/chatapi/share/:id', (req, res) => new GetShareRequestHandler(this, req, res));
this.app.post('/chatapi/share', (req, res) => new ShareRequestHandler(this, req, res));