From bded3c0a34c0021851aabd8172f278e2d7047b67 Mon Sep 17 00:00:00 2001 From: Richard Steinmetz Date: Tue, 25 Feb 2025 21:54:29 +0100 Subject: [PATCH] perf: don't retransmit unchanged threads Signed-off-by: Richard Steinmetz --- appinfo/routes.php | 2 +- lib/Controller/MessagesController.php | 14 +++++++++++--- src/service/MessageService.js | 12 ++++++++++-- src/store/mainStore/actions.js | 16 ++++++++++------ 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/appinfo/routes.php b/appinfo/routes.php index eddd1a5ee3..b05ba3e383 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -233,7 +233,7 @@ [ 'name' => 'messages#getThread', 'url' => '/api/messages/{id}/thread', - 'verb' => 'GET' + 'verb' => 'POST' ], [ 'name' => 'messages#setFlags', diff --git a/lib/Controller/MessagesController.php b/lib/Controller/MessagesController.php index 7ee51858be..3676418b08 100755 --- a/lib/Controller/MessagesController.php +++ b/lib/Controller/MessagesController.php @@ -318,13 +318,13 @@ private function isSenderTrusted(Message $message): bool { * @NoAdminRequired * @NoCSRFRequired * - * @param int $id + * @param int[] $knownIds Known database ids of envelopes * * @return JSONResponse * @throws ClientException */ #[TrapError] - public function getThread(int $id): JSONResponse { + public function getThread(int $id, array $knownIds): JSONResponse { try { $message = $this->mailManager->getMessage($this->currentUserId, $id); $mailbox = $this->mailManager->getMailbox($this->currentUserId, $message->getMailboxId()); @@ -337,7 +337,15 @@ public function getThread(int $id): JSONResponse { return new JSONResponse([], Http::STATUS_NOT_FOUND); } - return new JSONResponse($this->mailManager->getThread($account, $message->getThreadRootId())); + $thread = $this->mailManager->getThread($account, $message->getThreadRootId()); + foreach ($thread as $envelope) { + if (!in_array($envelope->getId(), $knownIds)) { + // Thread changed -> send it + return new JSONResponse($thread); + } + } + + return new JSONResponse([], Http::STATUS_NO_CONTENT); } /** diff --git a/src/service/MessageService.js b/src/service/MessageService.js index 7ee429e576..df426a8d0e 100644 --- a/src/service/MessageService.js +++ b/src/service/MessageService.js @@ -58,11 +58,19 @@ export function fetchEnvelopes(accountId, mailboxId, query, cursor, limit) { throw convertAxiosError(error) }) } -export const fetchThread = async (id) => { +export const fetchThread = async (id, knownIds) => { const url = generateUrl('apps/mail/api/messages/{id}/thread', { id, }) - const resp = await axios.get(url) + const resp = await axios.post(url, { + knownIds, + }) + + // Thread is up to date + if (resp.status === 204) { + return [] + } + return resp.data } diff --git a/src/store/mainStore/actions.js b/src/store/mainStore/actions.js index 02cffdd26d..08fa04d8ac 100644 --- a/src/store/mainStore/actions.js +++ b/src/store/mainStore/actions.js @@ -1190,12 +1190,16 @@ export default function mainStoreActions() { }, async fetchThread(id) { return handleHttpAuthErrors(async () => { - const thread = await fetchThread(id) - this.addEnvelopeThreadMutation({ - id, - thread, - }) - return thread + const knownDatabaseIds = this.envelopes[id]?.thread ?? [] + const thread = await fetchThread(id, knownDatabaseIds) + if (thread.length > 0) { + this.addEnvelopeThreadMutation({ + id, + thread, + }) + } + + return this.getEnvelopeThread(id) }) }, async fetchMessage(id) {