diff options
author | Joas Schilling <coding@schilljs.com> | 2019-08-29 15:29:08 +0300 |
---|---|---|
committer | Joas Schilling <coding@schilljs.com> | 2019-08-29 15:29:08 +0300 |
commit | 3eb76168d33e088b810d63785e58ea7e7243179c (patch) | |
tree | c8a677aa28fea00acb008591555a47add7b09442 /lib | |
parent | d3ea6a6f0b7000b6b6abe16702db0473430b7872 (diff) |
Allow to include the last known message as well
Signed-off-by: Joas Schilling <coding@schilljs.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Chat/ChatManager.php | 12 | ||||
-rw-r--r-- | lib/Chat/CommentsManager.php | 92 | ||||
-rw-r--r-- | lib/Controller/ChatController.php | 7 |
3 files changed, 103 insertions, 8 deletions
diff --git a/lib/Chat/ChatManager.php b/lib/Chat/ChatManager.php index 36550ef4a..9f830c904 100644 --- a/lib/Chat/ChatManager.php +++ b/lib/Chat/ChatManager.php @@ -225,12 +225,13 @@ class ChatManager { * @param Room $chat * @param int $offset Last known message id * @param int $limit + * @param bool $includeLastKnown * @return IComment[] the messages found (only the id, actor type and id, * creation date and message are relevant), or an empty array if the * timeout expired. */ - public function getHistory(Room $chat, $offset, $limit): array { - return $this->commentsManager->getForObjectSince('chat', (string) $chat->getId(), $offset, 'desc', $limit); + public function getHistory(Room $chat, int $offset, int $limit, bool $includeLastKnown): array { + return $this->commentsManager->getForObjectSince('chat', (string) $chat->getId(), $offset, 'desc', $limit, $includeLastKnown); } /** @@ -248,23 +249,24 @@ class ChatManager { * @param int $limit * @param int $timeout * @param IUser|null $user + * @param bool $includeLastKnown * @return IComment[] the messages found (only the id, actor type and id, * creation date and message are relevant), or an empty array if the * timeout expired. */ - public function waitForNewMessages(Room $chat, int $offset, int $limit, int $timeout, ?IUser $user): array { + public function waitForNewMessages(Room $chat, int $offset, int $limit, int $timeout, ?IUser $user, bool $includeLastKnown): array { if ($user instanceof IUser) { $this->notifier->markMentionNotificationsRead($chat, $user->getUID()); } $elapsedTime = 0; - $comments = $this->commentsManager->getForObjectSince('chat', (string) $chat->getId(), $offset, 'asc', $limit); + $comments = $this->commentsManager->getForObjectSince('chat', (string) $chat->getId(), $offset, 'asc', $limit, $includeLastKnown); while (empty($comments) && $elapsedTime < $timeout) { sleep(1); $elapsedTime++; - $comments = $this->commentsManager->getForObjectSince('chat', (string) $chat->getId(), $offset, 'asc', $limit); + $comments = $this->commentsManager->getForObjectSince('chat', (string) $chat->getId(), $offset, 'asc', $limit, $includeLastKnown); } return $comments; diff --git a/lib/Chat/CommentsManager.php b/lib/Chat/CommentsManager.php index da57e74f2..7ccfdc785 100644 --- a/lib/Chat/CommentsManager.php +++ b/lib/Chat/CommentsManager.php @@ -60,6 +60,98 @@ class CommentsManager extends Manager { } /** + * @param string $objectType the object type, e.g. 'files' + * @param string $objectId the id of the object + * @param int $lastKnownCommentId the last known comment (will be used as offset) + * @param string $sortDirection direction of the comments (`asc` or `desc`) + * @param int $limit optional, number of maximum comments to be returned. if + * set to 0, all comments are returned. + * @param bool $includeLastKnown + * @return IComment[] + * @return array + */ + public function getForObjectSince( + string $objectType, + string $objectId, + int $lastKnownCommentId, + string $sortDirection = 'asc', + int $limit = 30, + bool $includeLastKnown = false + ): array { + $comments = []; + + $query = $this->dbConn->getQueryBuilder(); + $query->select('*') + ->from('comments') + ->where($query->expr()->eq('object_type', $query->createNamedParameter($objectType))) + ->andWhere($query->expr()->eq('object_id', $query->createNamedParameter($objectId))) + ->orderBy('creation_timestamp', $sortDirection === 'desc' ? 'DESC' : 'ASC') + ->addOrderBy('id', $sortDirection === 'desc' ? 'DESC' : 'ASC'); + + if ($limit > 0) { + $query->setMaxResults($limit); + } + + $lastKnownComment = $lastKnownCommentId > 0 ? $this->getLastKnownComment( + $objectType, + $objectId, + $lastKnownCommentId + ) : null; + if ($lastKnownComment instanceof IComment) { + $lastKnownCommentDateTime = $lastKnownComment->getCreationDateTime(); + if ($sortDirection === 'desc') { + $idComparison = $includeLastKnown ? 'lte' : 'lt'; + $query->andWhere( + $query->expr()->orX( + $query->expr()->lt( + 'creation_timestamp', + $query->createNamedParameter($lastKnownCommentDateTime, IQueryBuilder::PARAM_DATE), + IQueryBuilder::PARAM_DATE + ), + $query->expr()->andX( + $query->expr()->eq( + 'creation_timestamp', + $query->createNamedParameter($lastKnownCommentDateTime, IQueryBuilder::PARAM_DATE), + IQueryBuilder::PARAM_DATE + ), + $query->expr()->$idComparison('id', $query->createNamedParameter($lastKnownCommentId)) + ) + ) + ); + } else { + $idComparison = $includeLastKnown ? 'gte' : 'gt'; + $query->andWhere( + $query->expr()->orX( + $query->expr()->gt( + 'creation_timestamp', + $query->createNamedParameter($lastKnownCommentDateTime, IQueryBuilder::PARAM_DATE), + IQueryBuilder::PARAM_DATE + ), + $query->expr()->andX( + $query->expr()->eq( + 'creation_timestamp', + $query->createNamedParameter($lastKnownCommentDateTime, IQueryBuilder::PARAM_DATE), + IQueryBuilder::PARAM_DATE + ), + $query->expr()->$idComparison('id', $query->createNamedParameter($lastKnownCommentId)) + ) + ) + ); + } + } + + $resultStatement = $query->execute(); + while ($data = $resultStatement->fetch()) { + $comment = $this->getCommentFromData($data); + $this->cache($comment); + $comments[] = $comment; + } + $resultStatement->closeCursor(); + + return $comments; + } + + /** * @param string $objectType * @param string $objectId * @param string $verb diff --git a/lib/Controller/ChatController.php b/lib/Controller/ChatController.php index e06ce69eb..5ddde8396 100644 --- a/lib/Controller/ChatController.php +++ b/lib/Controller/ChatController.php @@ -230,6 +230,7 @@ class ChatController extends AEnvironmentAwareController { * @param int $timeout Number of seconds to wait for new messages (30 by default, 30 at most) * @param int $setReadMarker Automatically set the last read marker when 1, * if your client does this itself via chat/{token}/read set to 0 + * @param int $includeLastKnown Include the $lastKnownMessageId in the messages when 1 (default 0) * @return DataResponse an array of chat messages, "404 Not found" if the * room token was not valid or "304 Not modified" if there were no messages; * each chat message is an array with @@ -237,7 +238,7 @@ class ChatController extends AEnvironmentAwareController { * 'actorDisplayName', 'timestamp' (in seconds and UTC timezone) and * 'message'. */ - public function receiveMessages(int $lookIntoFuture, int $limit = 100, int $lastKnownMessageId = 0, int $timeout = 30, int $setReadMarker = 1): DataResponse { + public function receiveMessages(int $lookIntoFuture, int $limit = 100, int $lastKnownMessageId = 0, int $timeout = 30, int $setReadMarker = 1, int $includeLastKnown = 0): DataResponse { $limit = min(200, $limit); $timeout = min(30, $timeout); @@ -263,9 +264,9 @@ class ChatController extends AEnvironmentAwareController { $currentUser = $this->userManager->get($this->userId); if ($lookIntoFuture) { - $comments = $this->chatManager->waitForNewMessages($this->room, $lastKnownMessageId, $limit, $timeout, $currentUser); + $comments = $this->chatManager->waitForNewMessages($this->room, $lastKnownMessageId, $limit, $timeout, $currentUser, (bool) $includeLastKnown); } else { - $comments = $this->chatManager->getHistory($this->room, $lastKnownMessageId, $limit); + $comments = $this->chatManager->getHistory($this->room, $lastKnownMessageId, $limit, (bool) $includeLastKnown); } if (empty($comments)) { |