From e76643ac999d1a42825af8cfc384582315c4b380 Mon Sep 17 00:00:00 2001 From: Hamza Mahjoubi Date: Thu, 12 Dec 2024 19:41:03 +0700 Subject: [PATCH 1/7] perf: reduce number of avatar requests Signed-off-by: Hamza Mahjoubi --- appinfo/routes.php | 5 --- lib/Controller/AvatarsController.php | 37 ---------------------- lib/Db/Message.php | 18 +++++++++++ lib/IMAP/PreviewEnhancer.php | 24 +++++++++++++-- src/components/Avatar.vue | 20 +++++++----- src/components/Envelope.vue | 2 +- src/components/OutboxMessageListItem.vue | 2 +- src/components/ThreadEnvelope.vue | 1 + src/service/AvatarService.js | 39 ------------------------ 9 files changed, 54 insertions(+), 94 deletions(-) delete mode 100644 src/service/AvatarService.js diff --git a/appinfo/routes.php b/appinfo/routes.php index eddd1a5ee3..d5980a1ffa 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -275,11 +275,6 @@ 'url' => '/api/messages/{messageId}/smartreply', 'verb' => 'GET' ], - [ - 'name' => 'avatars#url', - 'url' => '/api/avatars/url/{email}', - 'verb' => 'GET' - ], [ 'name' => 'avatars#image', 'url' => '/api/avatars/image/{email}', diff --git a/lib/Controller/AvatarsController.php b/lib/Controller/AvatarsController.php index 4dc20790b6..4659cb3c30 100644 --- a/lib/Controller/AvatarsController.php +++ b/lib/Controller/AvatarsController.php @@ -34,43 +34,6 @@ public function __construct(string $appName, $this->uid = $UserId; } - /** - * @NoAdminRequired - * @NoCSRFRequired - * - * @param string $email - * @return JSONResponse - */ - #[TrapError] - public function url(string $email): JSONResponse { - if (empty($email)) { - return new JSONResponse([], Http::STATUS_BAD_REQUEST); - } - - if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { - return new JSONResponse([], Http::STATUS_BAD_REQUEST); - } - - $avatar = $this->avatarService->getAvatar($email, $this->uid); - if (is_null($avatar)) { - // No avatar found - $response = new JSONResponse([], Http::STATUS_NOT_FOUND); - - // Debounce this a bit - // (cache for one day) - $response->cacheFor(24 * 60 * 60, false, true); - - return $response; - } - - $response = new JSONResponse($avatar); - - // Let the browser cache this for a week - $response->cacheFor(7 * 24 * 60 * 60, false, true); - - return $response; - } - /** * @NoAdminRequired * @NoCSRFRequired diff --git a/lib/Db/Message.php b/lib/Db/Message.php index 229c26f395..4d5b0a941b 100644 --- a/lib/Db/Message.php +++ b/lib/Db/Message.php @@ -12,6 +12,7 @@ use Horde_Mail_Rfc822_Identification; use JsonSerializable; use OCA\Mail\AddressList; +use OCA\Mail\Service\Avatar\Avatar; use OCP\AppFramework\Db\Entity; use ReturnTypeWillChange; use function in_array; @@ -133,6 +134,8 @@ class Message extends Entity implements JsonSerializable { /** @var Tag[] */ private $tags = []; + /** @var Avatar|null */ + private $avatar; public function __construct() { $this->from = new AddressList([]); $this->to = new AddressList([]); @@ -283,6 +286,20 @@ public function setFlag(string $flag, bool $value = true) { ); } } + /** + * @param Avatar|null $avatar + * @return void + */ + public function setAvatar(?Avatar $avatar): void { + $this->avatar = $avatar; + } + + /** + * @return Avatar + */ + public function getAvatar(): ?Avatar { + return $this->avatar; + } #[ReturnTypeWillChange] public function jsonSerialize() { @@ -327,6 +344,7 @@ static function (Tag $tag) { 'previewText' => $this->getPreviewText(), 'encrypted' => ($this->isEncrypted() === true), 'mentionsMe' => $this->getMentionsMe(), + 'avatar' => $this->avatar ? $this->avatar->jsonSerialize() : null, ]; } } diff --git a/lib/IMAP/PreviewEnhancer.php b/lib/IMAP/PreviewEnhancer.php index d9273bbfd3..989a10601a 100644 --- a/lib/IMAP/PreviewEnhancer.php +++ b/lib/IMAP/PreviewEnhancer.php @@ -15,6 +15,7 @@ use OCA\Mail\Db\Message; use OCA\Mail\Db\MessageMapper as DbMapper; use OCA\Mail\IMAP\MessageMapper as ImapMapper; +use OCA\Mail\Service\AvatarService; use Psr\Log\LoggerInterface; use function array_key_exists; use function array_map; @@ -34,14 +35,24 @@ class PreviewEnhancer { /** @var LoggerInterface */ private $logger; + /** @var AvatarService */ + private $avatarService; + + /** @var string */ + private $UserId; + public function __construct(IMAPClientFactory $clientFactory, ImapMapper $imapMapper, DbMapper $dbMapper, - LoggerInterface $logger) { + LoggerInterface $logger, + AvatarService $avatarService, + string $UserId) { $this->clientFactory = $clientFactory; $this->imapMapper = $imapMapper; $this->mapper = $dbMapper; $this->logger = $logger; + $this->avatarService = $avatarService; + $this->UserId = $UserId; } /** @@ -50,9 +61,13 @@ public function __construct(IMAPClientFactory $clientFactory, * @return Message[] */ public function process(Account $account, Mailbox $mailbox, array $messages): array { - $needAnalyze = array_reduce($messages, static function (array $carry, Message $message) { + $needAnalyze = array_reduce($messages, function (array $carry, Message $message) { if ($message->getStructureAnalyzed()) { // Nothing to do + if ($message->getAvatar() === null) { + $avatar = $this->avatarService->getAvatar($message->getFrom()->first()->getEmail(), $this->UserId); + $message->setAvatar($avatar); + } return $carry; } @@ -83,7 +98,7 @@ public function process(Account $account, Mailbox $mailbox, array $messages): ar $client->logout(); } - return $this->mapper->updatePreviewDataBulk(...array_map(static function (Message $message) use ($data) { + return $this->mapper->updatePreviewDataBulk(...array_map(function (Message $message) use ($data) { if (!array_key_exists($message->getUid(), $data)) { // Nothing to do return $message; @@ -97,6 +112,9 @@ public function process(Account $account, Mailbox $mailbox, array $messages): ar $message->setEncrypted($structureData->isEncrypted()); $message->setMentionsMe($structureData->getMentionsMe()); + $avatar = $this->avatarService->getAvatar($message->getFrom()->first()->getEmail(), $this->UserId); + $message->setAvatar($avatar); + return $message; }, $messages)); } diff --git a/src/components/Avatar.vue b/src/components/Avatar.vue index cb809cd31b..543f0772b4 100644 --- a/src/components/Avatar.vue +++ b/src/components/Avatar.vue @@ -17,7 +17,7 @@