diff --git a/lib/Contracts/IAvatarService.php b/lib/Contracts/IAvatarService.php index a40ba3bc6..e73e8d97b 100644 --- a/lib/Contracts/IAvatarService.php +++ b/lib/Contracts/IAvatarService.php @@ -27,4 +27,6 @@ interface IAvatarService { * @return array|null image data */ public function getAvatarImage(string $email, string $uid); + + public function getCachedAvatar(string $email, string $uid): Avatar|false|null; } diff --git a/lib/Contracts/IMailSearch.php b/lib/Contracts/IMailSearch.php index 3a67de5c1..4bee40bca 100644 --- a/lib/Contracts/IMailSearch.php +++ b/lib/Contracts/IMailSearch.php @@ -39,6 +39,7 @@ interface IMailSearch { * @param string|null $filter * @param int|null $cursor * @param int|null $limit + * @param string|null $userId * @param string|null $view * * @return Message[] @@ -52,6 +53,7 @@ interface IMailSearch { ?string $filter, ?int $cursor, ?int $limit, + ?string $userId, ?string $view): array; /** diff --git a/lib/Controller/MessagesController.php b/lib/Controller/MessagesController.php index a679a22c8..b08d7e8d8 100755 --- a/lib/Controller/MessagesController.php +++ b/lib/Controller/MessagesController.php @@ -156,6 +156,7 @@ class MessagesController extends Controller { $filter === '' ? null : $filter, $cursor, $limit, + $this->currentUserId, $view ); return new JSONResponse( diff --git a/lib/Db/Message.php b/lib/Db/Message.php index 7f029658f..278371a03 100644 --- a/lib/Db/Message.php +++ b/lib/Db/Message.php @@ -12,6 +12,7 @@ namespace OCA\Mail\Db; 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; @@ -136,6 +137,12 @@ class Message extends Entity implements JsonSerializable { /** @var Tag[] */ private $tags = []; + /** @var Avatar|null */ + private $avatar; + + /** @var bool */ + private $fetchAvatarFromClient = false; + public function __construct() { $this->from = new AddressList([]); $this->to = new AddressList([]); @@ -286,6 +293,24 @@ class Message extends Entity implements JsonSerializable { ); } } + /** + * @param Avatar|null $avatar + * @return void + */ + public function setAvatar(?Avatar $avatar): void { + $this->avatar = $avatar; + } + + public function setFetchAvatarFromClient(bool $fetchAvatarFromClient): void { + $this->fetchAvatarFromClient = $fetchAvatarFromClient; + } + + /** + * @return ?Avatar + */ + public function getAvatar(): ?Avatar { + return $this->avatar; + } #[\Override] #[ReturnTypeWillChange] @@ -332,6 +357,8 @@ class Message extends Entity implements JsonSerializable { 'summary' => $this->getSummary(), 'encrypted' => ($this->isEncrypted() === true), 'mentionsMe' => $this->getMentionsMe(), + 'avatar' => $this->avatar?->jsonSerialize(), + 'fetchAvatarFromClient' => $this->fetchAvatarFromClient, ]; } } diff --git a/lib/IMAP/PreviewEnhancer.php b/lib/IMAP/PreviewEnhancer.php index d9273bbfd..6d1343d86 100644 --- a/lib/IMAP/PreviewEnhancer.php +++ b/lib/IMAP/PreviewEnhancer.php @@ -15,6 +15,8 @@ use OCA\Mail\Db\Mailbox; use OCA\Mail\Db\Message; use OCA\Mail\Db\MessageMapper as DbMapper; use OCA\Mail\IMAP\MessageMapper as ImapMapper; +use OCA\Mail\Service\Avatar\Avatar; +use OCA\Mail\Service\AvatarService; use Psr\Log\LoggerInterface; use function array_key_exists; use function array_map; @@ -34,14 +36,19 @@ class PreviewEnhancer { /** @var LoggerInterface */ private $logger; + /** @var AvatarService */ + private $avatarService; + public function __construct(IMAPClientFactory $clientFactory, ImapMapper $imapMapper, DbMapper $dbMapper, - LoggerInterface $logger) { + LoggerInterface $logger, + AvatarService $avatarService) { $this->clientFactory = $clientFactory; $this->imapMapper = $imapMapper; $this->mapper = $dbMapper; $this->logger = $logger; + $this->avatarService = $avatarService; } /** @@ -49,7 +56,7 @@ class PreviewEnhancer { * * @return Message[] */ - public function process(Account $account, Mailbox $mailbox, array $messages): array { + public function process(Account $account, Mailbox $mailbox, array $messages, bool $preLoadAvatars = false, ?string $userId = null): array { $needAnalyze = array_reduce($messages, static function (array $carry, Message $message) { if ($message->getStructureAnalyzed()) { // Nothing to do @@ -59,6 +66,22 @@ class PreviewEnhancer { return array_merge($carry, [$message->getUid()]); }, []); + if ($preLoadAvatars) { + foreach ($messages as $message) { + $from = $message->getFrom()->first(); + if ($message->getAvatar() === null && $from !== null && $from->getEmail() !== null && $userId !== null) { + $avatar = $this->avatarService->getCachedAvatar($from->getEmail(), $userId); + if ($avatar === null) { + $message->setFetchAvatarFromClient(true); + } + if ($avatar instanceof Avatar) { + $message->setAvatar($avatar); + } + + } + } + } + if ($needAnalyze === []) { // Nothing to enhance return $messages; diff --git a/lib/Service/AvatarService.php b/lib/Service/AvatarService.php index 936544e14..50c2430d4 100644 --- a/lib/Service/AvatarService.php +++ b/lib/Service/AvatarService.php @@ -86,6 +86,10 @@ class AvatarService implements IAvatarService { } } + public function getCachedAvatar(string $email, string $uid): Avatar|false|null { + return $this->cache->get($email, $uid); + } + /** * @param string $email * @param string $uid diff --git a/lib/Service/Search/MailSearch.php b/lib/Service/Search/MailSearch.php index 2e468aa58..611fcf858 100644 --- a/lib/Service/Search/MailSearch.php +++ b/lib/Service/Search/MailSearch.php @@ -95,6 +95,7 @@ class MailSearch implements IMailSearch { ?string $filter, ?int $cursor, ?int $limit, + ?string $userId, ?string $view): array { if ($mailbox->hasLocks($this->timeFactory->getTime())) { throw MailboxLockedException::from($mailbox); @@ -125,7 +126,9 @@ class MailSearch implements IMailSearch { $this->messageMapper->findByIds($account->getUserId(), $this->getIdsLocally($account, $mailbox, $query, $sortOrder, $limit), $sortOrder, - ) + ), + true, + $userId ); } diff --git a/src/components/Avatar.vue b/src/components/Avatar.vue index b5c0aa8b7..c9ba554bc 100644 --- a/src/components/Avatar.vue +++ b/src/components/Avatar.vue @@ -17,6 +17,7 @@