Browse Source

Merge pull request #6625 from nextcloud/bugfix/6621/recognize-shares-as-unread-messages

Recognize voice messages, object and file shares as unread messages
pull/6667/head
Joas Schilling 4 years ago
committed by GitHub
parent
commit
07048b2709
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 15
      lib/Chat/ChatManager.php
  2. 26
      lib/Chat/CommentsManager.php
  3. 7
      lib/Chat/MessageParser.php
  4. 3
      tests/integration/features/bootstrap/FeatureContext.php
  5. 135
      tests/integration/features/chat/unread-messages.feature
  6. 4
      tests/php/Chat/ChatManagerTest.php

15
lib/Chat/ChatManager.php

@ -64,7 +64,8 @@ class ChatManager {
public const GEO_LOCATION_VALIDATOR = '/^geo:-?\d{1,2}(\.\d+)?,-?\d{1,3}(\.\d+)?(,-?\d+(\.\d+)?)?(;crs=wgs84)?(;u=\d+(\.\d+)?)?$/i';
/** @var ICommentsManager */
/** @var ICommentsManager|CommentsManager
*/
private $commentsManager;
/** @var IEventDispatcher */
private $dispatcher;
@ -141,7 +142,15 @@ class ChatManager {
if ($parentId !== null) {
$comment->setParentId((string) $parentId);
}
$comment->setVerb('system');
$messageDecoded = json_decode($message, true);
$messageType = $messageDecoded['message'] ?? '';
if ($messageType === 'object_shared' || $messageType === 'file_shared') {
$comment->setVerb('object_shared');
} else {
$comment->setVerb('system');
}
$event = new ChatEvent($chat, $comment);
$this->dispatcher->dispatch(self::EVENT_BEFORE_SYSTEM_MESSAGE_SEND, $event);
@ -359,7 +368,7 @@ class ChatManager {
$key = $chat->getId() . '-' . $lastReadMessage;
$unreadCount = $this->unreadCountCache->get($key);
if ($unreadCount === null) {
$unreadCount = $this->commentsManager->getNumberOfCommentsForObjectSinceComment('chat', (string) $chat->getId(), $lastReadMessage, 'comment');
$unreadCount = $this->commentsManager->getNumberOfCommentsWithVerbsForObjectSinceComment('chat', (string) $chat->getId(), $lastReadMessage, ['comment', 'object_shared']);
$this->unreadCountCache->set($key, $unreadCount, 1800);
}
return $unreadCount;

26
lib/Chat/CommentsManager.php

@ -26,6 +26,7 @@ namespace OCA\Talk\Chat;
use OC\Comments\Comment;
use OC\Comments\Manager;
use OCP\Comments\IComment;
use OCP\DB\QueryBuilder\IQueryBuilder;
class CommentsManager extends Manager {
/**
@ -39,4 +40,29 @@ class CommentsManager extends Manager {
$comment->setMessage($message, ChatManager::MAX_CHAT_LENGTH);
return $comment;
}
/**
* TODO Remove when server version with https://github.com/nextcloud/server/pull/29921 is required
*
* @param string $objectType
* @param string $objectId
* @param int $lastRead
* @param string[] $verbs
* @return int
*/
public function getNumberOfCommentsWithVerbsForObjectSinceComment(string $objectType, string $objectId, int $lastRead, array $verbs): int {
$query = $this->dbConn->getQueryBuilder();
$query->select($query->func()->count('id', 'num_messages'))
->from('comments')
->where($query->expr()->eq('object_type', $query->createNamedParameter($objectType)))
->andWhere($query->expr()->eq('object_id', $query->createNamedParameter($objectId)))
->andWhere($query->expr()->gt('id', $query->createNamedParameter($lastRead)))
->andWhere($query->expr()->in('verb', $query->createNamedParameter($verbs, IQueryBuilder::PARAM_STR_ARRAY)));
$result = $query->executeQuery();
$data = $result->fetch();
$result->closeCursor();
return (int) ($data['num_messages'] ?? 0);
}
}

7
lib/Chat/MessageParser.php

@ -64,7 +64,12 @@ class MessageParser {
public function parseMessage(Message $message): void {
$message->setMessage($message->getComment()->getMessage(), []);
$message->setMessageType($message->getComment()->getVerb());
$verb = $message->getComment()->getVerb();
if ($verb === 'object_shared') {
$verb = 'system';
}
$message->setMessageType($verb);
$this->setActor($message);
$event = new ChatMessageEvent($message);

3
tests/integration/features/bootstrap/FeatureContext.php

@ -314,6 +314,9 @@ class FeatureContext implements Context, SnippetAcceptingContext {
if (isset($expectedRoom['lastMessage'])) {
$data['lastMessage'] = $room['lastMessage'] ? $room['lastMessage']['message'] : '';
}
if (isset($expectedRoom['unreadMessages'])) {
$data['unreadMessages'] = (int) $room['unreadMessages'];
}
if (isset($expectedRoom['unreadMention'])) {
$data['unreadMention'] = (int) $room['unreadMention'];
}

135
tests/integration/features/chat/unread-messages.feature

@ -0,0 +1,135 @@
Feature: chat/unread-messages
Background:
Given user "participant1" exists
Given user "participant2" exists
Scenario: sending a message clears unread counter for sender
Given user "participant1" creates room "group room" (v4)
| roomType | 2 |
| roomName | room |
And user "participant1" adds user "participant2" to room "group room" with 200 (v4)
When user "participant1" sends message "Message 1" to room "group room" with 201
Then user "participant1" is participant of room "group room" (v4)
| unreadMessages |
| 0 |
And user "participant2" is participant of room "group room" (v4)
| unreadMessages |
| 1 |
Scenario: sending several messages clears unread counter for sender
Given user "participant1" creates room "group room" (v4)
| roomType | 2 |
| roomName | room |
And user "participant1" adds user "participant2" to room "group room" with 200 (v4)
When user "participant1" sends message "Message 1" to room "group room" with 201
And user "participant1" sends message "Message 2" to room "group room" with 201
And user "participant1" sends message "Message 3" to room "group room" with 201
Then user "participant1" is participant of room "group room" (v4)
| unreadMessages |
| 0 |
And user "participant2" is participant of room "group room" (v4)
| unreadMessages |
| 3 |
Scenario: sending a message with previously unread messages clears unread counter for sender
Given user "participant1" creates room "group room" (v4)
| roomType | 2 |
| roomName | room |
And user "participant1" adds user "participant2" to room "group room" with 200 (v4)
And user "participant2" sends message "Message 1" to room "group room" with 201
And user "participant2" sends message "Message 2" to room "group room" with 201
When user "participant1" sends message "Message 3" to room "group room" with 201
Then user "participant1" is participant of room "group room" (v4)
| unreadMessages |
| 0 |
And user "participant2" is participant of room "group room" (v4)
| unreadMessages |
| 1 |
Scenario: reading all messages clears unread counter for reader
Given user "participant1" creates room "group room" (v4)
| roomType | 2 |
| roomName | room |
And user "participant1" adds user "participant2" to room "group room" with 200 (v4)
And user "participant1" sends message "Message 1" to room "group room" with 201
And user "participant1" sends message "Message 2" to room "group room" with 201
And user "participant1" sends message "Message 3" to room "group room" with 201
When user "participant2" reads message "Message 3" in room "group room" with 200
Then user "participant2" is participant of room "group room" (v4)
| unreadMessages |
| 0 |
Scenario: reading some messages reduces unread counter for reader
Given user "participant1" creates room "group room" (v4)
| roomType | 2 |
| roomName | room |
And user "participant1" adds user "participant2" to room "group room" with 200 (v4)
And user "participant1" sends message "Message 1" to room "group room" with 201
And user "participant1" sends message "Message 2" to room "group room" with 201
And user "participant1" sends message "Message 3" to room "group room" with 201
When user "participant2" reads message "Message 2" in room "group room" with 200
Then user "participant2" is participant of room "group room" (v4)
| unreadMessages |
| 1 |
Scenario: replies are taken into account in unread counter
Given user "participant1" creates room "group room" (v4)
| roomType | 2 |
| roomName | room |
And user "participant1" adds user "participant2" to room "group room" with 200 (v4)
And user "participant1" sends message "Message 1" to room "group room" with 201
When user "participant1" sends reply "Message 1-1" on message "Message 1" to room "group room" with 201
Then user "participant1" is participant of room "group room" (v4)
| unreadMessages |
| 0 |
And user "participant2" is participant of room "group room" (v4)
| unreadMessages |
| 2 |
Scenario: rich object messages are taken into account in unread counter
Given user "participant1" creates room "group room" (v4)
| roomType | 2 |
| roomName | room |
And user "participant1" adds user "participant2" to room "group room" with 200 (v4)
When user "participant1" shares rich-object "call" "R4nd0mT0k3n" '{"name":"Another room","call-type":"group"}' to room "group room" with 201 (v1)
Then user "participant1" is participant of room "group room" (v4)
| unreadMessages |
| 0 |
And user "participant2" is participant of room "group room" (v4)
| unreadMessages |
| 1 |
Scenario: shared file messages are taken into account in unread counter
Given user "participant1" creates room "group room" (v4)
| roomType | 2 |
| roomName | room |
And user "participant1" adds user "participant2" to room "group room" with 200 (v4)
When user "participant1" shares "welcome.txt" with room "group room"
# Unread counter for sender is not cleared in this case, as it is not
# possible to know whether the file was shared from Talk, which could clear
# the counter, or from the Files app, which should not clear it.
Then user "participant1" is participant of room "group room" (v4)
| unreadMessages |
| 1 |
And user "participant2" is participant of room "group room" (v4)
| unreadMessages |
| 1 |
Scenario: system messages are not taken into account in unread counter
Given user "participant1" creates room "group room" (v4)
| roomType | 2 |
| roomName | room |
And user "participant1" adds user "participant2" to room "group room" with 200 (v4)
When user "participant1" makes room "group room" private with 200 (v4)
Then user "participant1" is participant of room "group room" (v4)
| unreadMessages |
| 0 |
And user "participant2" is participant of room "group room" (v4)
| unreadMessages |
| 0 |

4
tests/php/Chat/ChatManagerTest.php

@ -369,8 +369,8 @@ class ChatManagerTest extends TestCase {
->willReturn(23);
$this->commentsManager->expects($this->once())
->method('getNumberOfCommentsForObjectSinceComment')
->with('chat', 23, 42, 'comment');
->method('getNumberOfCommentsWithVerbsForObjectSinceComment')
->with('chat', 23, 42, ['comment', 'object_shared']);
$this->chatManager->getUnreadCount($chat, 42);
}

Loading…
Cancel
Save