From b8a5021dd5ff6bb5b6b1b44192625e04a578b2da Mon Sep 17 00:00:00 2001 From: Dragory Date: Sun, 11 Mar 2018 22:27:52 +0200 Subject: [PATCH] Add thread suspending --- CHANGELOG.md | 3 +++ README.md | 2 ++ src/data/Thread.js | 30 ++++++++++++++++++++++++++++++ src/data/constants.js | 3 ++- src/data/threads.js | 14 ++++++++++++++ src/main.js | 20 ++++++++++++++++++++ src/threadUtils.js | 2 +- 7 files changed, 72 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 443ffe8..58768a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +## v2.4.0 +* Add thread suspending. A modmail thread can now be suspended with `!suspend`. Suspended threads will function as closed until unsuspended with `!unsuspend`. + ## v2.3.2 * Auto-close threads if their modmail channel is deleted diff --git a/README.md b/README.md index 0158752..088be6c 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,8 @@ See [CHANGELOG.md](CHANGELOG.md) `!!shortcut` Reply with a snippet. Replace `shortcut` with the snippet's actual shortcut. `!move ` If `allowMove` is enabled, moves the thread channel to the specified category `!loglink` Shows the link to the current thread's log +`!suspend` Suspend a thread. The thread will act as closed and not receive any messages until unsuspended. +`!unsuspend` Unsuspend a thread To automatically reply without using !reply or !r, enable `alwaysReply` in the config. `alwaysReplyAnon` sets whether to reply anonymously. If you do not wish to reply, it will ignore any message starting in the prefix (which defaults to !), such as !note diff --git a/src/data/Thread.js b/src/data/Thread.js index dea79c8..0ba9c23 100644 --- a/src/data/Thread.js +++ b/src/data/Thread.js @@ -307,6 +307,11 @@ class Thread { } } + /** + * @param {String} time + * @param {Eris~User} user + * @returns {Promise} + */ async scheduleClose(time, user) { await knex('threads') .where('id', this.id) @@ -317,6 +322,9 @@ class Thread { }); } + /** + * @returns {Promise} + */ async cancelScheduledClose() { await knex('threads') .where('id', this.id) @@ -327,6 +335,28 @@ class Thread { }); } + /** + * @returns {Promise} + */ + async suspend() { + await knex('threads') + .where('id', this.id) + .update({ + status: THREAD_STATUS.SUSPENDED + }); + } + + /** + * @returns {Promise} + */ + async unsuspend() { + await knex('threads') + .where('id', this.id) + .update({ + status: THREAD_STATUS.OPEN + }); + } + /** * @returns {Promise} */ diff --git a/src/data/constants.js b/src/data/constants.js index 60e3277..db811fa 100644 --- a/src/data/constants.js +++ b/src/data/constants.js @@ -1,7 +1,8 @@ module.exports = { THREAD_STATUS: { OPEN: 1, - CLOSED: 2 + CLOSED: 2, + SUSPENDED: 3 }, THREAD_MESSAGE_TYPE: { diff --git a/src/data/threads.js b/src/data/threads.js index 5bab7f6..9a0f498 100644 --- a/src/data/threads.js +++ b/src/data/threads.js @@ -154,6 +154,19 @@ async function findOpenThreadByChannelId(channelId) { return (thread ? new Thread(thread) : null); } +/** + * @param {String} channelId + * @returns {Promise} + */ +async function findSuspendedThreadByChannelId(channelId) { + const thread = await knex('threads') + .where('channel_id', channelId) + .where('status', THREAD_STATUS.SUSPENDED) + .first(); + + return (thread ? new Thread(thread) : null); +} + /** * @param {String} userId * @returns {Promise} @@ -203,6 +216,7 @@ module.exports = { findOpenThreadByUserId, findByChannelId, findOpenThreadByChannelId, + findSuspendedThreadByChannelId, createNewThreadForUser, getClosedThreadsByUserId, findOrCreateThreadForUser, diff --git a/src/main.js b/src/main.js index 1714d24..d46dada 100644 --- a/src/main.js +++ b/src/main.js @@ -414,6 +414,26 @@ addInboxServerCommand('loglink', async (msg, args, thread) => { thread.postNonLogMessage(`Log URL: ${logUrl}`); }); +addInboxServerCommand('suspend', async (msg, args, thread) => { + if (! thread) return; + await thread.suspend(); + thread.postSystemMessage(`**Thread suspended!** This thread will act as closed until unsuspended with \`!unsuspend\``); +}); + +addInboxServerCommand('unsuspend', async (msg, args) => { + const thread = await threads.findSuspendedThreadByChannelId(msg.channel.id); + if (! thread) return; + + const otherOpenThread = await threads.findOpenThreadByUserId(thread.user_id); + if (otherOpenThread) { + thread.postSystemMessage(`Cannot unsuspend; there is another open thread with this user: <#${otherOpenThread.channel_id}>`); + return; + } + + await thread.unsuspend(); + thread.postSystemMessage(`**Thread unsuspended!**`); +}); + module.exports = { async start() { // Load plugins diff --git a/src/threadUtils.js b/src/threadUtils.js index 632de08..16b98e0 100644 --- a/src/threadUtils.js +++ b/src/threadUtils.js @@ -14,7 +14,7 @@ function addInboxServerCommand(bot, cmd, commandHandler, opts) { if (! utils.messageIsOnInboxServer(msg)) return; if (! utils.isStaff(msg.member)) return; - const thread = await threads.findByChannelId(msg.channel.id); + const thread = await threads.findOpenThreadByChannelId(msg.channel.id); commandHandler(msg, args, thread); }, opts); }