From eb7f9ab2985f303b051a491c54e362a813f2d997 Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Thu, 30 Jan 2020 10:52:29 +0200 Subject: [PATCH 1/4] Implement channel history clearing on the server --- src/client.js | 22 +++++++++++++++++ src/plugins/messageStorage/sqlite.js | 14 +++++++++++ src/plugins/messageStorage/text.js | 36 ++++++++++++++++++++++++---- src/server.js | 6 +++++ 4 files changed, 74 insertions(+), 4 deletions(-) diff --git a/src/client.js b/src/client.js index b188fafa..ee5f8de5 100644 --- a/src/client.js +++ b/src/client.js @@ -501,6 +501,28 @@ Client.prototype.more = function(data) { }; }; +Client.prototype.clearHistory = function(data) { + const client = this; + const target = client.find(data.target); + + if (!target) { + return; + } + + target.chan.messages = []; + target.chan.unread = 0; + target.chan.highlight = 0; + target.chan.firstUnread = 0; + + if (!target.chan.isLoggable()) { + return; + } + + for (const messageStorage of this.messageStorage) { + messageStorage.deleteChannel(target.network, target.chan); + } +}; + Client.prototype.open = function(socketId, target) { // Due to how socket.io works internally, normal events may arrive later than // the disconnect event, and because we can't control this timing precisely, diff --git a/src/plugins/messageStorage/sqlite.js b/src/plugins/messageStorage/sqlite.js index a1c56cd9..f54dba93 100644 --- a/src/plugins/messageStorage/sqlite.js +++ b/src/plugins/messageStorage/sqlite.js @@ -144,6 +144,20 @@ class MessageStorage { ); } + deleteChannel(network, channel) { + if (!this.isEnabled) { + return; + } + + this.database.serialize(() => + this.database.run( + "DELETE FROM messages WHERE network = ? AND channel = ?", + network.uuid, + channel.name.toLowerCase() + ) + ); + } + /** * Load messages for given channel on a given network and resolve a promise with loaded messages. * diff --git a/src/plugins/messageStorage/text.js b/src/plugins/messageStorage/text.js index 0feebe8a..90044468 100644 --- a/src/plugins/messageStorage/text.js +++ b/src/plugins/messageStorage/text.js @@ -100,11 +100,35 @@ class TextFileMessageStorage { line += "\n"; - fs.appendFile(path.join(logPath, `${cleanFilename(channel.name)}.log`), line, (e) => { - if (e) { - log.error("Failed to write user log", e); + fs.appendFile( + path.join(logPath, TextFileMessageStorage.getChannelFileName(channel)), + line, + (e) => { + if (e) { + log.error("Failed to write user log", e); + } } - }); + ); + } + + deleteChannel() { + /* TODO: Truncating text logs is disabled, until we figure out some UI for it + if (!this.isEnabled) { + return; + } + + const logPath = path.join( + Helper.getUserLogsPath(), + this.client.name, + TextFileMessageStorage.getNetworkFolderName(network), + TextFileMessageStorage.getChannelFileName(channel) + ); + + fs.truncate(logPath, 0, (e) => { + if (e) { + log.error("Failed to truncate user log", e); + } + });*/ } getMessages() { @@ -125,6 +149,10 @@ class TextFileMessageStorage { return `${networkName}-${network.uuid.substring(networkName.length + 1)}`; } + + static getChannelFileName(channel) { + return `${cleanFilename(channel.name)}.log`; + } } module.exports = TextFileMessageStorage; diff --git a/src/server.js b/src/server.js index 6827daa7..6b5281bd 100644 --- a/src/server.js +++ b/src/server.js @@ -420,6 +420,12 @@ function initializeClient(socket, client, token, lastMessage, openChannel) { network.edit(client, data); }); + socket.on("history:clear", (data) => { + if (typeof data === "object") { + client.clearHistory(data); + } + }); + if (!Helper.config.public && !Helper.config.ldap.enable) { socket.on("change-password", (data) => { if (typeof data === "object") { From 7216b8124b9f558afb36168ebb6d4b25932a8bf1 Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Thu, 30 Jan 2020 10:57:38 +0200 Subject: [PATCH 2/4] Add context menu to clear channel history --- client/css/style.css | 1 + client/js/helpers/contextMenu.js | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/client/css/style.css b/client/css/style.css index c79224e8..73cae3ff 100644 --- a/client/css/style.css +++ b/client/css/style.css @@ -349,6 +349,7 @@ p { .context-menu-action-voice::before { content: "\f067"; /* http://fontawesome.io/icon/plus/ */ } .context-menu-network::before { content: "\f233"; /* https://fontawesome.com/icons/server?style=solid */ } .context-menu-edit::before { content: "\f303"; /* https://fontawesome.com/icons/pencil-alt?style=solid */ } +.context-menu-clear-history::before { content: "\f1f8"; /* https://fontawesome.com/icons/trash?style=solid */ } .channel-list-item .not-secure-icon::before { content: "\f071"; /* https://fontawesome.com/icons/exclamation-triangle?style=solid */ diff --git a/client/js/helpers/contextMenu.js b/client/js/helpers/contextMenu.js index 5c7d9066..0ca7b493 100644 --- a/client/js/helpers/contextMenu.js +++ b/client/js/helpers/contextMenu.js @@ -129,6 +129,27 @@ export function generateChannelContextMenu($root, channel, network) { }); } + if (channel.type === "channel" || channel.type === "query") { + items.push({ + label: "Clear history", + type: "item", + class: "clear-history", + action() { + // TODO: Confirmation window + + channel.messages = []; + channel.unread = 0; + channel.highlight = 0; + channel.firstUnread = 0; + channel.moreHistoryAvailable = false; + + socket.emit("history:clear", { + target: channel.id, + }); + }, + }); + } + // Add close menu item items.push({ label: closeMap[channel.type], From 44a8925b8c43b263944533a485ea76c0f35e20e1 Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Tue, 25 Feb 2020 11:16:05 +0200 Subject: [PATCH 3/4] Create a generic confirmation dialog --- client/components/App.vue | 3 ++ client/components/ConfirmDialog.vue | 84 +++++++++++++++++++++++++++++ client/components/ContextMenu.vue | 12 +---- client/css/style.css | 4 ++ client/js/helpers/contextMenu.js | 58 ++++++++------------ client/js/vue.js | 31 ++++++----- 6 files changed, 131 insertions(+), 61 deletions(-) create mode 100644 client/components/ConfirmDialog.vue diff --git a/client/components/App.vue b/client/components/App.vue index 9cab17f3..fbbe9ccf 100644 --- a/client/components/App.vue +++ b/client/components/App.vue @@ -5,6 +5,7 @@ +
@@ -18,6 +19,7 @@ import storage from "../js/localStorage"; import Sidebar from "./Sidebar.vue"; import ImageViewer from "./ImageViewer.vue"; import ContextMenu from "./ContextMenu.vue"; +import ConfirmDialog from "./ConfirmDialog.vue"; export default { name: "App", @@ -25,6 +27,7 @@ export default { Sidebar, ImageViewer, ContextMenu, + ConfirmDialog, }, computed: { viewportClasses() { diff --git a/client/components/ConfirmDialog.vue b/client/components/ConfirmDialog.vue new file mode 100644 index 00000000..c7ca473c --- /dev/null +++ b/client/components/ConfirmDialog.vue @@ -0,0 +1,84 @@ + + + + + diff --git a/client/components/ContextMenu.vue b/client/components/ContextMenu.vue index 81011443..a1cfefc2 100644 --- a/client/components/ContextMenu.vue +++ b/client/components/ContextMenu.vue @@ -38,11 +38,7 @@