From 8be385e02ef3039e692ff62cf171e8a29ea5879e Mon Sep 17 00:00:00 2001 From: "Alex.exe" <40430040+NfoAlex@users.noreply.github.com> Date: Sun, 14 Jul 2024 22:40:27 +0900 Subject: [PATCH] Edit message (#53) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [add] - メッセージ編集用の関数とSocketハンドラ作成 * [add] - メッセージを編集したかどうかのカラム追加 * [fix] - typo * [add] - メッセージInterfaceに編集したかどうか値追加 * [add] - 編集したかどうかカラム用のmigration追加 * [add] - メッセのパースに編集したかどうかを追加 * [fix] - migrationファイル用の日付間違い * [change] - メッセージの編集データをそのチャンネル参加者に送るように * [change] - メッセージ編集時、メッセデータを渡しつつクライアントへの返し方も更新 * [add] - 編集適用時内容が一緒なら停止 --- src/actionHandler/Message/editMessage.ts | 66 +++++++++++++++++++++++ src/actionHandler/Message/fetchHistory.ts | 1 + src/actionHandler/Message/fetchMessage.ts | 1 + src/actionHandler/Message/saveMessage.ts | 3 +- src/db/InitMessage.ts | 3 ++ src/db/migration/Message/20240709.ts | 23 ++++++++ src/socketHandler/Message.ts | 46 ++++++++++++++++ src/type/Message.ts | 2 + 8 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 src/actionHandler/Message/editMessage.ts create mode 100644 src/db/migration/Message/20240709.ts diff --git a/src/actionHandler/Message/editMessage.ts b/src/actionHandler/Message/editMessage.ts new file mode 100644 index 00000000..b0ca4800 --- /dev/null +++ b/src/actionHandler/Message/editMessage.ts @@ -0,0 +1,66 @@ +import sqlite3 from "sqlite3"; +const db = new sqlite3.Database("./records/MESSAGE.db"); +import fetchMessage from "./fetchMessage"; + +import type { IMessage } from "../../type/Message"; + +/** + * メッセージの編集 + * @param channelId + * @param messageId + * @param userIdBy + * @returns + */ +export default async function editMessage( + channelId: string, + messageId: string, + contentUpdating: string, + userIdBy: string, +):Promise { + try { + + //もし更新内容が空なら停止 + if (contentUpdating === "" || contentUpdating === null) return null; + + //編集するメッセージを取得 + const messageEditing = await fetchMessage(channelId, messageId); + if (messageEditing === null) return null; + + //もし現在のテキストと編集内容が一緒なら停止 + if (messageEditing.content === contentUpdating) return null; + + //操作者とメッセ主が違うならエラーで停止 + if (messageEditing.userId !== userIdBy) return null; + + return new Promise((resolve) => { + db.run( + ` + UPDATE C` + channelId + ` SET + content=?, + isEdited=? + WHERE messageId='` + messageId + `' + `, + [contentUpdating, true], + (err:Error) => { + if (err) { + console.log("editMessage :: db : エラー->", err); + resolve(null); + return; + } else { + //取得したメッセデータも上書きして結果として渡す + messageEditing.content = contentUpdating; + messageEditing.isEdited = true; + resolve(messageEditing); + return; + } + } + ); + }); + + } catch(e) { + + console.log("editMessage :: エラー->", e); + return null; + + } +} diff --git a/src/actionHandler/Message/fetchHistory.ts b/src/actionHandler/Message/fetchHistory.ts index 6370e690..86ce0d28 100644 --- a/src/actionHandler/Message/fetchHistory.ts +++ b/src/actionHandler/Message/fetchHistory.ts @@ -160,6 +160,7 @@ export default async function fetchHistory( historyParsed.push({ ...history[index], + isEdited: history[index].isEdited===1?true:false, linkData: linkDataParsed, reaction: JSON.parse(history[index].reaction) }); diff --git a/src/actionHandler/Message/fetchMessage.ts b/src/actionHandler/Message/fetchMessage.ts index 266b8816..2ca18d51 100644 --- a/src/actionHandler/Message/fetchMessage.ts +++ b/src/actionHandler/Message/fetchMessage.ts @@ -31,6 +31,7 @@ export default function fetchMessage( //生メッセージデータを扱える形にパースする const messageParsed:IMessage = { ...message[0], + isEdited: message[0].isEdited===1?true:false, linkData: message[0].linkData!==undefined?JSON.parse(message[0].linkData):{}, reaction: message[0].reaction!==undefined?JSON.parse(message[0].reaction):{} }; diff --git a/src/actionHandler/Message/saveMessage.ts b/src/actionHandler/Message/saveMessage.ts index 56978c5d..50dff344 100644 --- a/src/actionHandler/Message/saveMessage.ts +++ b/src/actionHandler/Message/saveMessage.ts @@ -26,10 +26,11 @@ export default async function saveMessage( messageId: "", channelId: message.channelId, userId: userId, + isEdited: false, content: message.content, linkData: {}, time: "", - reaction: {} + reaction: {}, }; //もしメッセージ長がサーバー設定より長ければエラー diff --git a/src/db/InitMessage.ts b/src/db/InitMessage.ts index 5debe4ac..49cb8fbd 100644 --- a/src/db/InitMessage.ts +++ b/src/db/InitMessage.ts @@ -2,10 +2,12 @@ import sqlite3 from "sqlite3"; const db = new sqlite3.Database("./records/MESSAGE.db"); import migration20240603 from "./migration/Message/20240603"; +import migrationMessage20240709 from "./migration/Message/20240709"; db.serialize(() => { //migration migration20240603(); + migrationMessage20240709(); //randomチャンネル用のテーブル作成 db.run( @@ -14,6 +16,7 @@ db.serialize(() => { channelId TEXT NOT NULL, userId TEXT NOT NULL, content TEXT NOT NULL, + isEdited BOOLEAN NOT NULL DEFAULT '0', linkData TEXT DEFAULT '{}', time TEXT NOT NULL DEFAULT (DATETIME('now', 'localtime')), reaction TEXT NOT NULL diff --git a/src/db/migration/Message/20240709.ts b/src/db/migration/Message/20240709.ts new file mode 100644 index 00000000..586d65b0 --- /dev/null +++ b/src/db/migration/Message/20240709.ts @@ -0,0 +1,23 @@ +import sqlite3 from "sqlite3"; +const db = new sqlite3.Database("./records/MESSAGE.db"); + +/** + * すべてのチャンネル履歴テーブルへisEditedカラムを追加 + */ +export default async function migrationMessage20240709() { + //チャンネル分のテーブルへisEditedカラムを追加 + db.all( + ` + SELECT name FROM sqlite_master WHERE type='table'; + `, + (err:Error, tables:[{name:string}]) => { + //console.log("20240709 :: tables->", tables); + + //ループしてisEditedカラムを追加 + for (let channelName of tables) { + db.run(`ALTER TABLE ` + channelName.name + ` ADD isEdited BOLEAN NOT NULL DEFAULT '0'`, (err:Error)=>{}); + } + return; + } + ); +} diff --git a/src/socketHandler/Message.ts b/src/socketHandler/Message.ts index 27b2cf78..3d8ac62d 100644 --- a/src/socketHandler/Message.ts +++ b/src/socketHandler/Message.ts @@ -11,6 +11,7 @@ import genLinkPreview from "../util/genLinkPreview"; import type IRequestSender from "../type/requestSender"; import type { IMessage, IMessageReadTime } from "../type/Message"; +import editMessage from "../actionHandler/Message/editMessage"; module.exports = (io:Server) => { io.on("connection", (socket:Socket) => { @@ -146,6 +147,51 @@ module.exports = (io:Server) => { } }); + //メッセージの編集 + socket.on("editMessage", async ( + dat:{ + RequestSender: IRequestSender, + channelId: string, + messageId: string, + contentUpdating: string, + } + ) => { + //セッション認証 + if (!(await checkSession(dat.RequestSender))) { + socket.emit("RESULT::editMessage", { result:"ERROR_SESSION_ERROR", data:null }); + return; + } + + try { + const msgEditResult = await editMessage( + dat.channelId, + dat.messageId, + dat.contentUpdating, + dat.RequestSender.userId + ); + + //結果に応じてデータを送信 + if (msgEditResult !== null) { + //編集の結果 + socket.emit("RESULT::editMessage", { result:"SUCCESS", data:null }); + //編集したメッセージそのものをチャンネル参加者へ送信 + io.to(dat.channelId).emit( + "updateMessage", + { + result: "SUCCESS", + data: msgEditResult + } + ); + } else { + socket.emit("RESULT::editMessage", { result:"ERROR_DB_THING", data:null }); + return; + } + } catch(e) { + socket.emit("RESULT::editMessage", { result:"ERROR_INTERNAL_THING", data:null }); + return; + } + }) + //履歴の取得 socket.on("fetchHistory", async ( dat: { diff --git a/src/type/Message.ts b/src/type/Message.ts index 02e94218..21bf3bd7 100644 --- a/src/type/Message.ts +++ b/src/type/Message.ts @@ -4,6 +4,7 @@ export interface IMessageBeforeParsing { channelId: string, userId: string, content: string, + isEdited: 1|0, linkData: string, time: string, reaction: string @@ -14,6 +15,7 @@ export interface IMessage { messageId: string, channelId: string, userId: string, + isEdited: boolean, content: string, linkData: { [key: string]: