Browse Source

Add a mention-alike notification for replies

Signed-off-by: Joas Schilling <coding@schilljs.com>
pull/2000/head
Joas Schilling 7 years ago
parent
commit
e3e3e8e741
No known key found for this signature in database GPG Key ID: 7076EA9751AACDDA
  1. 13
      lib/Chat/ChatManager.php
  2. 48
      lib/Chat/Notifier.php
  3. 36
      lib/Notification/Notifier.php
  4. 48
      tests/php/Chat/NotifierTest.php
  5. 24
      tests/php/Controller/ChatControllerTest.php
  6. 2
      tests/php/Notification/NotifierTest.php

13
lib/Chat/ChatManager.php

@ -166,13 +166,18 @@ class ChatManager {
// Update last_message
$chat->setLastMessage($comment);
$mentionedUsers = $this->notifier->notifyMentionedUsers($chat, $comment);
if (!empty($mentionedUsers)) {
$chat->markUsersAsMentioned($mentionedUsers, (int) $comment->getId());
$alreadyNotifiedUsers = [];
if ($replyTo instanceof IComment) {
$alreadyNotifiedUsers = $this->notifier->notifyReplyToAuthor($chat, $comment, $replyTo);
}
$alreadyNotifiedUsers = $this->notifier->notifyMentionedUsers($chat, $comment, $alreadyNotifiedUsers);
if (!empty($alreadyNotifiedUsers)) {
$chat->markUsersAsMentioned($alreadyNotifiedUsers, (int) $comment->getId());
}
// User was not mentioned, send a normal notification
$this->notifier->notifyOtherParticipant($chat, $comment, $mentionedUsers);
$this->notifier->notifyOtherParticipant($chat, $comment, $alreadyNotifiedUsers);
$this->dispatcher->dispatch(self::class . '::sendMessage', new GenericEvent($chat, [
'comment' => $comment,

48
lib/Chat/Notifier.php

@ -76,9 +76,10 @@ class Notifier {
*
* @param Room $chat
* @param IComment $comment
* @param string[] $alreadyNotifiedUsers
* @return string[] Users that were mentioned
*/
public function notifyMentionedUsers(Room $chat, IComment $comment): array {
public function notifyMentionedUsers(Room $chat, IComment $comment, array $alreadyNotifiedUsers): array {
$mentionedUserIds = $this->getMentionedUserIds($comment);
if (empty($mentionedUserIds)) {
return [];
@ -92,13 +93,48 @@ class Notifier {
$notification = $this->createNotification($chat, $comment, 'mention');
foreach ($mentionedUserIds as $mentionedUserId) {
if (in_array($mentionedUserId, $alreadyNotifiedUsers, true)) {
continue;
}
if ($this->shouldUserBeNotified($mentionedUserId, $comment)) {
$notification->setUser($mentionedUserId);
$this->notificationManager->notify($notification);
$alreadyNotifiedUsers[] = $mentionedUserId;
}
}
return $mentionedUserIds;
return $alreadyNotifiedUsers;
}
/**
* Notifies the author that wrote the comment which was replied to
*
* The comment must be a chat message comment. That is, its "objectId" must
* be the room ID.
*
* The author of the message is notified only if he is still able to participate in the room
*
* @param Room $chat
* @param IComment $comment
* @param IComment $replyTo
* @return string[] Users that were mentioned
*/
public function notifyReplyToAuthor(Room $chat, IComment $comment, IComment $replyTo): array {
if ($replyTo->getActorType() !== 'users') {
// No reply notification when the replyTo-author was not a user
return [];
}
if (!$this->shouldUserBeNotified($replyTo->getActorId(), $comment)) {
return [];
}
$notification = $this->createNotification($chat, $comment, 'reply');
$notification->setUser($replyTo->getActorId());
$this->notificationManager->notify($notification);
return [$replyTo->getActorId()];
}
/**
@ -112,9 +148,9 @@ class Notifier {
*
* @param Room $chat
* @param IComment $comment
* @param string[] $mentionedUsers
* @param string[] $alreadyNotifiedUsers
*/
public function notifyOtherParticipant(Room $chat, IComment $comment, array $mentionedUsers): void {
public function notifyOtherParticipant(Room $chat, IComment $comment, array $alreadyNotifiedUsers): void {
$participants = $chat->getParticipantsByNotificationLevel(Participant::NOTIFY_ALWAYS);
$notification = $this->createNotification($chat, $comment, 'chat');
@ -128,7 +164,7 @@ class Notifier {
continue;
}
if (\in_array($participant->getUser(), $mentionedUsers, true)) {
if (\in_array($participant->getUser(), $alreadyNotifiedUsers, true)) {
continue;
}
@ -154,7 +190,7 @@ class Notifier {
continue;
}
if (\in_array($participant->getUser(), $mentionedUsers, true)) {
if (\in_array($participant->getUser(), $alreadyNotifiedUsers, true)) {
continue;
}

36
lib/Notification/Notifier.php

@ -165,7 +165,7 @@ class Notifier implements INotifier {
}
return $this->parseCall($notification, $room, $l);
}
if ($subject === 'mention' || $subject === 'chat') {
if ($subject === 'reply' || $subject === 'mention' || $subject === 'chat') {
return $this->parseChatMessage($notification, $room, $participant, $l);
}
@ -251,25 +251,31 @@ class Notifier implements INotifier {
if ($notification->getSubject() === 'chat') {
if ($room->getType() === Room::ONE_TO_ONE_CALL) {
$subject = $l->t('{user} sent you a private message');
} else if ($richSubjectUser) {
$subject = $l->t('{user} sent a message in conversation {call}');
} else if (!$isGuest) {
$subject = $l->t('A deleted user sent a message in conversation {call}');
} else {
if ($richSubjectUser) {
$subject = $l->t('{user} sent a message in conversation {call}');
} else if (!$isGuest) {
$subject = $l->t('A deleted user sent a message in conversation {call}');
} else {
$subject = $l->t('A guest sent a message in conversation {call}');
}
$subject = $l->t('A guest sent a message in conversation {call}');
}
} else if ($room->getType() === Room::ONE_TO_ONE_CALL) {
$subject = $l->t('{user} mentioned you in a private conversation');
} else {
if ($richSubjectUser) {
$subject = $l->t('{user} mentioned you in conversation {call}');
} else if ($notification->getSubject() === 'reply') {
if ($room->getType() === Room::ONE_TO_ONE_CALL) {
$subject = $l->t('{user} replied to your private message');
} else if ($richSubjectUser) {
$subject = $l->t('{user} replied to your message in conversation {call}');
} else if (!$isGuest) {
$subject = $l->t('A deleted user mentioned you in conversation {call}');
$subject = $l->t('A deleted user replied to your message in conversation {call}');
} else {
$subject = $l->t('A guest mentioned you in conversation {call}');
$subject = $l->t('A guest replied to your message in conversation {call}');
}
} else if ($room->getType() === Room::ONE_TO_ONE_CALL) {
$subject = $l->t('{user} mentioned you in a private conversation');
} else if ($richSubjectUser) {
$subject = $l->t('{user} mentioned you in conversation {call}');
} else if (!$isGuest) {
$subject = $l->t('A deleted user mentioned you in conversation {call}');
} else {
$subject = $l->t('A guest mentioned you in conversation {call}');
}
$notification = $this->addActionButton($notification, $l->t('View chat'), false);

48
tests/php/Chat/NotifierTest.php

@ -174,7 +174,35 @@ class NotifierTest extends \Test\TestCase {
->method('notify')
->with($notification);
$this->notifier->notifyMentionedUsers($room, $comment);
$this->notifier->notifyMentionedUsers($room, $comment, []);
}
public function testNotNotifyMentionedUserIfReplyToAuthor() {
$comment = $this->newComment(108, 'users', 'testUser', new \DateTime('@' . 1000000016), 'Mention @anotherUser');
$room = $this->createMock(Room::class);
$room->expects($this->any())
->method('getToken')
->willReturn('Token123');
$notification = $this->newNotification($room, $comment);
$this->notificationManager->expects($this->once())
->method('createNotification')
->willReturn($notification);
$notification->expects($this->never())
->method('setUser');
$notification->expects($this->once())
->method('setMessage')
->with('comment')
->willReturnSelf();
$this->notificationManager->expects($this->never())
->method('notify');
$this->notifier->notifyMentionedUsers($room, $comment, ['anotherUser']);
}
public function testNotifyMentionedUsersByGuest() {
@ -217,7 +245,7 @@ class NotifierTest extends \Test\TestCase {
->method('notify')
->with($notification);
$this->notifier->notifyMentionedUsers($room, $comment);
$this->notifier->notifyMentionedUsers($room, $comment, []);
}
public function testNotifyMentionedUsersWithLongMessageStartMention() {
@ -261,7 +289,7 @@ class NotifierTest extends \Test\TestCase {
->method('notify')
->with($notification);
$this->notifier->notifyMentionedUsers($room, $comment);
$this->notifier->notifyMentionedUsers($room, $comment, []);
}
public function testNotifyMentionedUsersWithLongMessageMiddleMention() {
@ -305,7 +333,7 @@ class NotifierTest extends \Test\TestCase {
->method('notify')
->with($notification);
$this->notifier->notifyMentionedUsers($room, $comment);
$this->notifier->notifyMentionedUsers($room, $comment, []);
}
public function testNotifyMentionedUsersWithLongMessageEndMention() {
@ -349,7 +377,7 @@ class NotifierTest extends \Test\TestCase {
->method('notify')
->with($notification);
$this->notifier->notifyMentionedUsers($room, $comment);
$this->notifier->notifyMentionedUsers($room, $comment, []);
}
public function testNotifyMentionedUsersToSelf() {
@ -369,7 +397,7 @@ class NotifierTest extends \Test\TestCase {
$this->notificationManager->expects($this->never())
->method('notify');
$this->notifier->notifyMentionedUsers($room, $comment);
$this->notifier->notifyMentionedUsers($room, $comment, []);
}
public function testNotifyMentionedUsersToUnknownUser() {
@ -390,7 +418,7 @@ class NotifierTest extends \Test\TestCase {
$this->notificationManager->expects($this->never())
->method('notify');
$this->notifier->notifyMentionedUsers($room, $comment);
$this->notifier->notifyMentionedUsers($room, $comment, []);
}
public function testNotifyMentionedUsersToUserNotInvitedToChat() {
@ -421,7 +449,7 @@ class NotifierTest extends \Test\TestCase {
$this->notificationManager->expects($this->never())
->method('notify');
$this->notifier->notifyMentionedUsers($room, $comment);
$this->notifier->notifyMentionedUsers($room, $comment, []);
}
public function testNotifyMentionedUsersNoMentions() {
@ -438,7 +466,7 @@ class NotifierTest extends \Test\TestCase {
$this->notificationManager->expects($this->never())
->method('notify');
$this->notifier->notifyMentionedUsers($room, $comment);
$this->notifier->notifyMentionedUsers($room, $comment, []);
}
public function testNotifyMentionedUsersSeveralMentions() {
@ -487,7 +515,7 @@ class NotifierTest extends \Test\TestCase {
[ $notification ]
);
$this->notifier->notifyMentionedUsers($room, $comment);
$this->notifier->notifyMentionedUsers($room, $comment, []);
}
public function testRemovePendingNotificationsForRoom() {

24
tests/php/Controller/ChatControllerTest.php

@ -436,6 +436,12 @@ class ChatControllerTest extends TestCase {
$chatMessage->expects($this->once())
->method('getVisibility')
->willReturn(true);
$chatMessage->expects($this->atLeastOnce())
->method('getComment')
->willReturn($comment);
$chatMessage->expects($this->once())
->method('getRoom')
->willReturn($room);
$i--;
return $chatMessage;
@ -508,6 +514,12 @@ class ChatControllerTest extends TestCase {
$chatMessage->expects($this->once())
->method('getVisibility')
->willReturn(true);
$chatMessage->expects($this->atLeastOnce())
->method('getComment')
->willReturn($comment);
$chatMessage->expects($this->once())
->method('getRoom')
->willReturn($room);
$i--;
return $chatMessage;
@ -583,6 +595,12 @@ class ChatControllerTest extends TestCase {
$chatMessage->expects($this->once())
->method('getVisibility')
->willReturn(true);
$chatMessage->expects($this->atLeastOnce())
->method('getComment')
->willReturn($comment);
$chatMessage->expects($this->once())
->method('getRoom')
->willReturn($room);
$i--;
return $chatMessage;
@ -666,6 +684,12 @@ class ChatControllerTest extends TestCase {
$chatMessage->expects($this->once())
->method('getVisibility')
->willReturn(true);
$chatMessage->expects($this->atLeastOnce())
->method('getComment')
->willReturn($comment);
$chatMessage->expects($this->once())
->method('getRoom')
->willReturn($room);
$i++;
return $chatMessage;

2
tests/php/Notification/NotifierTest.php

@ -686,7 +686,7 @@ class NotifierTest extends \Test\TestCase {
$notification->expects($this->once())
->method('getApp')
->willReturn('spreed');
$notification->expects($this->exactly(2))
$notification->expects($this->atLeast(2))
->method('getSubject')
->willReturn($isMention ? 'mention' : 'chat');
$notification->expects($this->once())

Loading…
Cancel
Save