Browse Source

Add unread message count to the room list

Signed-off-by: Joas Schilling <coding@schilljs.com>
pull/806/head
Joas Schilling 8 years ago
parent
commit
47255e543d
No known key found for this signature in database GPG Key ID: 7076EA9751AACDDA
  1. 1
      docs/api-v1.md
  2. 4
      js/views/roomlistview.js
  3. 23
      lib/Chat/ChatManager.php
  4. 3
      lib/Controller/ChatController.php
  5. 12
      lib/Controller/RoomController.php
  6. 17
      tests/php/Chat/ChatManagerTest.php
  7. 47
      tests/php/Controller/ChatControllerTest.php

1
docs/api-v1.md

@ -120,6 +120,7 @@ Base endpoint is: `/ocs/v2.php/apps/spreed/api/v1`
`sessionId` | string | `'0'` if not connected, otherwise a 512 character long string `sessionId` | string | `'0'` if not connected, otherwise a 512 character long string
`hasPassword` | bool | Flag if the room has a password `hasPassword` | bool | Flag if the room has a password
`hasCall` | bool | Flag if the room has an active call `hasCall` | bool | Flag if the room has an active call
`unreadMessages` | int | Number of unread chat messages in the room (only available with `chat-v2` capability)
### Get single room (also for guests) ### Get single room (also for guests)

4
js/views/roomlistview.js

@ -37,6 +37,7 @@
var ITEM_TEMPLATE = '<a class="app-navigation-entry-link" href="#{{id}}" data-token="{{token}}"><div class="avatar" data-user="{{name}}" data-user-display-name="{{displayName}}"></div> {{displayName}}</a>'+ var ITEM_TEMPLATE = '<a class="app-navigation-entry-link" href="#{{id}}" data-token="{{token}}"><div class="avatar" data-user="{{name}}" data-user-display-name="{{displayName}}"></div> {{displayName}}</a>'+
'<div class="app-navigation-entry-utils">'+ '<div class="app-navigation-entry-utils">'+
'<ul>'+ '<ul>'+
'{{#if unreadMessages}}<li class="app-navigation-entry-utils-counter">{{unreadMessages}}</li>{{/if}}'+
'<li class="app-navigation-entry-utils-menu-button"><button></button></li>'+ '<li class="app-navigation-entry-utils-menu-button"><button></button></li>'+
'</ul>'+ '</ul>'+
'</div>'+ '</div>'+
@ -80,6 +81,9 @@
'change:participantType': function() { 'change:participantType': function() {
this.render(); this.render();
}, },
'change:unreadMessages': function() {
this.render();
},
'change:type': function() { 'change:type': function() {
this.render(); this.render();
} }

23
lib/Chat/ChatManager.php

@ -25,6 +25,7 @@ namespace OCA\Spreed\Chat;
use OCP\Comments\IComment; use OCP\Comments\IComment;
use OCP\Comments\ICommentsManager; use OCP\Comments\ICommentsManager;
use OCP\IUser;
/** /**
* Basic polling chat manager. * Basic polling chat manager.
@ -76,6 +77,16 @@ class ChatManager {
$this->notifier->notifyMentionedUsers($comment); $this->notifier->notifyMentionedUsers($comment);
} }
/**
* @param string $chatId
* @param IUser $userId
* @return int
*/
public function getUnreadCount($chatId, IUser $user) {
$unreadSince = $this->commentsManager->getReadMark('chat', $chatId, $user);
return $this->commentsManager->getNumberOfCommentsForObject('chat', $chatId, $unreadSince);
}
/** /**
* Receive the history of a chat * Receive the history of a chat
* *
@ -104,13 +115,15 @@ class ChatManager {
* @param int $offset Last known message id * @param int $offset Last known message id
* @param int $limit * @param int $limit
* @param int $timeout * @param int $timeout
* @param string $userId
* @param IUser|null $user
* @return IComment[] the messages found (only the id, actor type and id, * @return IComment[] the messages found (only the id, actor type and id,
* creation date and message are relevant), or an empty array if the * creation date and message are relevant), or an empty array if the
* timeout expired. * timeout expired.
*/ */
public function waitForNewMessages($chatId, $offset, $limit, $timeout, $userId) {
$this->notifier->markMentionNotificationsRead($chatId, $userId);
public function waitForNewMessages($chatId, $offset, $limit, $timeout, $user) {
if ($user instanceof IUser) {
$this->notifier->markMentionNotificationsRead($chatId, $user->getUID());
}
$elapsedTime = 0; $elapsedTime = 0;
$comments = $this->commentsManager->getForObjectSinceTalkVersion('chat', $chatId, $offset, 'asc', $limit); $comments = $this->commentsManager->getForObjectSinceTalkVersion('chat', $chatId, $offset, 'asc', $limit);
@ -122,6 +135,10 @@ class ChatManager {
$comments = $this->commentsManager->getForObjectSinceTalkVersion('chat', $chatId, $offset, 'asc', $limit); $comments = $this->commentsManager->getForObjectSinceTalkVersion('chat', $chatId, $offset, 'asc', $limit);
} }
if ($user instanceof IUser) {
$this->commentsManager->setReadMark('chat', $chatId, new \DateTime(), $user);
}
return $comments; return $comments;
} }

3
lib/Controller/ChatController.php

@ -219,7 +219,8 @@ class ChatController extends OCSController {
$timeout = min(60, $timeout); $timeout = min(60, $timeout);
if ($lookIntoFuture) { if ($lookIntoFuture) {
$comments = $this->chatManager->waitForNewMessages((string) $room->getId(), $lastKnownMessageId, $limit, $timeout, $this->userId);
$currentUser = $this->userManager->get($this->userId);
$comments = $this->chatManager->waitForNewMessages((string) $room->getId(), $lastKnownMessageId, $limit, $timeout, $currentUser);
} else { } else {
$comments = $this->chatManager->getHistory((string) $room->getId(), $lastKnownMessageId, $limit); $comments = $this->chatManager->getHistory((string) $room->getId(), $lastKnownMessageId, $limit);
} }

12
lib/Controller/RoomController.php

@ -25,6 +25,7 @@
namespace OCA\Spreed\Controller; namespace OCA\Spreed\Controller;
use OCA\Spreed\Chat\ChatManager;
use OCA\Spreed\Exceptions\InvalidPasswordException; use OCA\Spreed\Exceptions\InvalidPasswordException;
use OCA\Spreed\Exceptions\ParticipantNotFoundException; use OCA\Spreed\Exceptions\ParticipantNotFoundException;
use OCA\Spreed\Exceptions\RoomNotFoundException; use OCA\Spreed\Exceptions\RoomNotFoundException;
@ -59,6 +60,8 @@ class RoomController extends OCSController {
private $manager; private $manager;
/** @var GuestManager */ /** @var GuestManager */
private $guestManager; private $guestManager;
/** @var ChatManager */
private $chatManager;
/** @var IL10N */ /** @var IL10N */
private $l10n; private $l10n;
@ -72,6 +75,7 @@ class RoomController extends OCSController {
* @param ILogger $logger * @param ILogger $logger
* @param Manager $manager * @param Manager $manager
* @param GuestManager $guestManager * @param GuestManager $guestManager
* @param ChatManager $chatManager
* @param IL10N $l10n * @param IL10N $l10n
*/ */
public function __construct($appName, public function __construct($appName,
@ -83,6 +87,7 @@ class RoomController extends OCSController {
ILogger $logger, ILogger $logger,
Manager $manager, Manager $manager,
GuestManager $guestManager, GuestManager $guestManager,
ChatManager $chatManager,
IL10N $l10n) { IL10N $l10n) {
parent::__construct($appName, $request); parent::__construct($appName, $request);
$this->session = $session; $this->session = $session;
@ -92,6 +97,7 @@ class RoomController extends OCSController {
$this->logger = $logger; $this->logger = $logger;
$this->manager = $manager; $this->manager = $manager;
$this->guestManager = $guestManager; $this->guestManager = $guestManager;
$this->chatManager = $chatManager;
$this->l10n = $l10n; $this->l10n = $l10n;
} }
@ -170,6 +176,7 @@ class RoomController extends OCSController {
'count' => $room->getNumberOfParticipants(false, time() - 30), 'count' => $room->getNumberOfParticipants(false, time() - 30),
'hasPassword' => $room->hasPassword(), 'hasPassword' => $room->hasPassword(),
'hasCall' => $room->getActiveSince() instanceof \DateTimeInterface, 'hasCall' => $room->getActiveSince() instanceof \DateTimeInterface,
'unreadMessages' => 0,
]; ];
if (!$participant instanceof Participant) { if (!$participant instanceof Participant) {
@ -186,6 +193,11 @@ class RoomController extends OCSController {
return $roomData; return $roomData;
} }
$currentUser = $this->userManager->get($this->userId);
if ($currentUser instanceof IUser) {
$roomData['unreadMessages'] = $this->chatManager->getUnreadCount($room->getId(), $currentUser);
}
// Sort by lastPing // Sort by lastPing
/** @var array[] $participants */ /** @var array[] $participants */
$participants = $room->getParticipants(); $participants = $room->getParticipants();

17
tests/php/Chat/ChatManagerTest.php

@ -28,6 +28,7 @@ use OCA\Spreed\Chat\CommentsManager;
use OCA\Spreed\Chat\Notifier; use OCA\Spreed\Chat\Notifier;
use OCP\Comments\IComment; use OCP\Comments\IComment;
use OCP\Comments\ICommentsManager; use OCP\Comments\ICommentsManager;
use OCP\IUser;
class ChatManagerTest extends \Test\TestCase { class ChatManagerTest extends \Test\TestCase {
@ -140,7 +141,13 @@ class ChatManagerTest extends \Test\TestCase {
->method('markMentionNotificationsRead') ->method('markMentionNotificationsRead')
->with('testChatId', 'userId'); ->with('testChatId', 'userId');
$comments = $this->chatManager->waitForNewMessages('testChatId', $offset, $limit, $timeout, 'userId');
/** @var IUser|\PHPUnit_Framework_MockObject_MockObject $user */
$user = $this->createMock(IUser::class);
$user->expects($this->any())
->method('getUID')
->willReturn('userId');
$comments = $this->chatManager->waitForNewMessages('testChatId', $offset, $limit, $timeout, $user);
$this->assertEquals($expected, $comments); $this->assertEquals($expected, $comments);
} }
@ -167,7 +174,13 @@ class ChatManagerTest extends \Test\TestCase {
->method('markMentionNotificationsRead') ->method('markMentionNotificationsRead')
->with('testChatId', 'userId'); ->with('testChatId', 'userId');
$comments = $this->chatManager->waitForNewMessages('testChatId', $offset, $limit, $timeout, 'userId');
/** @var IUser|\PHPUnit_Framework_MockObject_MockObject $user */
$user = $this->createMock(IUser::class);
$user->expects($this->any())
->method('getUID')
->willReturn('userId');
$comments = $this->chatManager->waitForNewMessages('testChatId', $offset, $limit, $timeout, $user);
$this->assertEquals($expected, $comments); $this->assertEquals($expected, $comments);
} }

47
tests/php/Controller/ChatControllerTest.php

@ -571,12 +571,20 @@ class ChatControllerTest extends \Test\TestCase {
->method('getId') ->method('getId')
->willReturn(1234); ->willReturn(1234);
$testUser = $this->createMock(IUser::class);
$testUser->expects($this->any())
->method('getUID')
->willReturn('testUser');
$testUser->expects($this->exactly(2))
->method('getDisplayName')
->willReturn('Test User');
$offset = 23; $offset = 23;
$limit = 4; $limit = 4;
$timeout = 10; $timeout = 10;
$this->chatManager->expects($this->once()) $this->chatManager->expects($this->once())
->method('waitForNewMessages') ->method('waitForNewMessages')
->with('1234', $offset, $limit, $timeout, $this->userId)
->with('1234', $offset, $limit, $timeout, $testUser)
->willReturn([ ->willReturn([
$this->newComment(108, 'users', 'testUser', new \DateTime('@' . 1000000004), 'testMessage1'), $this->newComment(108, 'users', 'testUser', new \DateTime('@' . 1000000004), 'testMessage1'),
$this->newComment(109, 'guests', 'testSpreedSession', new \DateTime('@' . 1000000008), 'testMessage2'), $this->newComment(109, 'guests', 'testSpreedSession', new \DateTime('@' . 1000000008), 'testMessage2'),
@ -584,15 +592,12 @@ class ChatControllerTest extends \Test\TestCase {
$this->newComment(111, 'users', 'testUser', new \DateTime('@' . 1000000016), 'testMessage4'), $this->newComment(111, 'users', 'testUser', new \DateTime('@' . 1000000016), 'testMessage4'),
]); ]);
$testUser = $this->createMock(IUser::class);
$testUser->expects($this->exactly(2))
->method('getDisplayName')
->willReturn('Test User');
$this->userManager->expects($this->exactly(3))
$this->userManager->expects($this->any())
->method('get') ->method('get')
->withConsecutive(['testUser'], ['testUnknownUser'], ['testUser'])
->willReturn($testUser, null, $testUser);
->willReturnMap([
['testUser', $testUser],
['testUnknownUser', null]
]);
$response = $this->controller->receiveMessages('testToken', 1, $limit, $offset, $timeout); $response = $this->controller->receiveMessages('testToken', 1, $limit, $offset, $timeout);
$expected = new DataResponse([ $expected = new DataResponse([
@ -624,14 +629,24 @@ class ChatControllerTest extends \Test\TestCase {
->method('getId') ->method('getId')
->willReturn(1234); ->willReturn(1234);
$testUser = $this->createMock(IUser::class);
$testUser->expects($this->any())
->method('getUID')
->willReturn('testUser');
$offset = 23; $offset = 23;
$limit = 4; $limit = 4;
$timeout = 3; $timeout = 3;
$this->chatManager->expects($this->once()) $this->chatManager->expects($this->once())
->method('waitForNewMessages') ->method('waitForNewMessages')
->with('1234', $offset, $limit, $timeout, $this->userId)
->with('1234', $offset, $limit, $timeout, $testUser)
->willReturn([]); ->willReturn([]);
$this->userManager->expects($this->any())
->method('get')
->with('testUser')
->willReturn($testUser);
$response = $this->controller->receiveMessages('testToken', 1, $limit, $offset, $timeout); $response = $this->controller->receiveMessages('testToken', 1, $limit, $offset, $timeout);
$expected = new DataResponse([], Http::STATUS_NOT_MODIFIED); $expected = new DataResponse([], Http::STATUS_NOT_MODIFIED);
@ -656,15 +671,25 @@ class ChatControllerTest extends \Test\TestCase {
->method('getId') ->method('getId')
->willReturn(1234); ->willReturn(1234);
$testUser = $this->createMock(IUser::class);
$testUser->expects($this->any())
->method('getUID')
->willReturn('testUser');
$offset = 23; $offset = 23;
$timeout = 100000; $timeout = 100000;
$maximumTimeout = 60; $maximumTimeout = 60;
$limit = 4; $limit = 4;
$this->chatManager->expects($this->once()) $this->chatManager->expects($this->once())
->method('waitForNewMessages') ->method('waitForNewMessages')
->with('1234', $offset, $limit, $maximumTimeout, $this->userId)
->with('1234', $offset, $limit, $maximumTimeout, $testUser)
->willReturn([]); ->willReturn([]);
$this->userManager->expects($this->any())
->method('get')
->with('testUser')
->willReturn($testUser);
$response = $this->controller->receiveMessages('testToken', 1, $limit, $offset, $timeout); $response = $this->controller->receiveMessages('testToken', 1, $limit, $offset, $timeout);
$expected = new DataResponse([], Http::STATUS_NOT_MODIFIED); $expected = new DataResponse([], Http::STATUS_NOT_MODIFIED);

Loading…
Cancel
Save