summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorJoas Schilling <coding@schilljs.com>2024-03-13 16:57:53 +0100
committerJoas Schilling <coding@schilljs.com>2024-03-14 09:47:20 +0100
commitec2ce3b97e0a8017b6209b70533331ae3478f05d (patch)
tree3d0073dfc6fce56184789419c1d3d1b24a9cc7db /lib
parent6d5de533a6f00e950c4b5ce202c5587e59ca9ba0 (diff)
fix(federation): Fix unread marker handling in federated chats
Signed-off-by: Joas Schilling <coding@schilljs.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/Federation/BackendNotifier.php2
-rw-r--r--lib/Federation/CloudFederationProviderTalk.php4
-rw-r--r--lib/Federation/FederationManager.php1
-rw-r--r--lib/Federation/Proxy/TalkV1/Controller/ChatController.php9
-rw-r--r--lib/Federation/Proxy/TalkV1/Notifier/MessageSentListener.php3
-rw-r--r--lib/Model/Attendee.php12
-rw-r--r--lib/Model/AttendeeMapper.php2
-rw-r--r--lib/Model/SelectHelper.php2
-rw-r--r--lib/Notification/FederationChatNotifier.php2
-rw-r--r--lib/Service/ParticipantService.php7
-rw-r--r--lib/Service/RoomFormatter.php13
11 files changed, 43 insertions, 14 deletions
diff --git a/lib/Federation/BackendNotifier.php b/lib/Federation/BackendNotifier.php
index cb2102afe..c45bedff6 100644
--- a/lib/Federation/BackendNotifier.php
+++ b/lib/Federation/BackendNotifier.php
@@ -292,7 +292,7 @@ class BackendNotifier {
* Sent from Host server to Remote participant server
*
* @param array{remoteMessageId: int, actorType: string, actorId: string, actorDisplayName: string, messageType: string, systemMessage: string, expirationDatetime: string, message: string, messageParameter: string, creationDatetime: string, metaData: string} $messageData
- * @param array{unreadMessages: int, unreadMention: bool, unreadMentionDirect: bool} $unreadInfo
+ * @param array{unreadMessages: int, unreadMention: bool, unreadMentionDirect: bool, lastReadMessage: int} $unreadInfo
*/
public function sendMessageUpdate(
string $remoteServer,
diff --git a/lib/Federation/CloudFederationProviderTalk.php b/lib/Federation/CloudFederationProviderTalk.php
index 8b3340388..cb161b119 100644
--- a/lib/Federation/CloudFederationProviderTalk.php
+++ b/lib/Federation/CloudFederationProviderTalk.php
@@ -215,6 +215,7 @@ class CloudFederationProviderTalk implements ICloudFederationProvider {
if (!empty($notification['displayName'])) {
$attendee->setDisplayName($notification['displayName']);
+ $attendee->setState(Invitation::STATE_ACCEPTED);
$this->attendeeMapper->update($attendee);
}
@@ -325,7 +326,7 @@ class CloudFederationProviderTalk implements ICloudFederationProvider {
/**
* @param int $remoteAttendeeId
- * @param array{remoteServerUrl: string, sharedSecret: string, remoteToken: string, messageData: array{remoteMessageId: int, actorType: string, actorId: string, actorDisplayName: string, messageType: string, systemMessage: string, expirationDatetime: string, message: string, messageParameter: string, creationDatetime: string, metaData: string}, unreadInfo: array{unreadMessages: int, unreadMention: bool, unreadMentionDirect: bool}} $notification
+ * @param array{remoteServerUrl: string, sharedSecret: string, remoteToken: string, messageData: array{remoteMessageId: int, actorType: string, actorId: string, actorDisplayName: string, messageType: string, systemMessage: string, expirationDatetime: string, message: string, messageParameter: string, creationDatetime: string, metaData: string}, unreadInfo: array{unreadMessages: int, unreadMention: bool, unreadMentionDirect: bool, lastReadMessage: int}} $notification
* @return array
* @throws ActionNotSupportedException
* @throws AuthenticationFailedException
@@ -416,6 +417,7 @@ class CloudFederationProviderTalk implements ICloudFederationProvider {
$notification['unreadInfo']['unreadMessages'],
$notification['unreadInfo']['unreadMention'],
$notification['unreadInfo']['unreadMentionDirect'],
+ $notification['unreadInfo']['lastReadMessage'],
);
$this->federationChatNotifier->handleChatMessage($room, $participant, $message, $notification);
diff --git a/lib/Federation/FederationManager.php b/lib/Federation/FederationManager.php
index 88b56f4ca..d5753aad8 100644
--- a/lib/Federation/FederationManager.php
+++ b/lib/Federation/FederationManager.php
@@ -147,6 +147,7 @@ class FederationManager {
'accessToken' => $invitation->getAccessToken(),
'remoteId' => $invitation->getRemoteAttendeeId(),
'invitedCloudId' => $invitation->getLocalCloudId(),
+ 'lastReadMessage' => $room->getLastMessageId(),
]
];
$attendees = $this->participantService->addUsers($room, $participant, $user);
diff --git a/lib/Federation/Proxy/TalkV1/Controller/ChatController.php b/lib/Federation/Proxy/TalkV1/Controller/ChatController.php
index 366c4bd55..4ceb5a4a3 100644
--- a/lib/Federation/Proxy/TalkV1/Controller/ChatController.php
+++ b/lib/Federation/Proxy/TalkV1/Controller/ChatController.php
@@ -173,7 +173,12 @@ class ChatController {
);
if ($lookIntoFuture && $setReadMarker) {
- $this->participantService->updateUnreadInfoForProxyParticipant($participant, 0, false, false);
+ $this->participantService->updateUnreadInfoForProxyParticipant($participant,
+ 0,
+ false,
+ false,
+ (int) ($proxy->getHeader('X-Chat-Last-Given') ?: $lastKnownMessageId),
+ );
}
if ($proxy->getStatusCode() === Http::STATUS_NOT_MODIFIED) {
@@ -384,6 +389,7 @@ class ChatController {
$data['unreadMessages'],
$data['unreadMention'],
$data['unreadMentionDirect'],
+ $data['lastReadMessage'],
);
$headers = $lastCommonRead = [];
@@ -424,6 +430,7 @@ class ChatController {
$data['unreadMessages'],
$data['unreadMention'],
$data['unreadMentionDirect'],
+ $data['lastReadMessage'],
);
$headers = $lastCommonRead = [];
diff --git a/lib/Federation/Proxy/TalkV1/Notifier/MessageSentListener.php b/lib/Federation/Proxy/TalkV1/Notifier/MessageSentListener.php
index 7c12c9b32..6f1277c1b 100644
--- a/lib/Federation/Proxy/TalkV1/Notifier/MessageSentListener.php
+++ b/lib/Federation/Proxy/TalkV1/Notifier/MessageSentListener.php
@@ -114,9 +114,10 @@ class MessageSentListener implements IEventListener {
$lastMentionDirect = $attendee->getLastMentionDirect();
$unreadInfo = [
+ 'lastReadMessage' => $lastReadMessage,
'unreadMessages' => $this->chatManager->getUnreadCount($event->getRoom(), $lastReadMessage),
'unreadMention' => $lastMention !== 0 && $lastReadMessage < $lastMention,
- 'unreadMentionDirect' => $lastMentionDirect !== 0 && $lastReadMessage < $lastMentionDirect
+ 'unreadMentionDirect' => $lastMentionDirect !== 0 && $lastReadMessage < $lastMentionDirect,
];
$success = $this->backendNotifier->sendMessageUpdate(
diff --git a/lib/Model/Attendee.php b/lib/Model/Attendee.php
index dc2fd2dc6..823ac6fe7 100644
--- a/lib/Model/Attendee.php
+++ b/lib/Model/Attendee.php
@@ -66,6 +66,10 @@ use OCP\AppFramework\Db\Entity;
* @method null|string getPhoneNumber()
* @method void setCallId(?string $callId)
* @method null|string getCallId()
+ * @method void setState(int $state)
+ * @method int getState()
+ * @method void setUnreadMessages(int $unreadMessages)
+ * @method int getUnreadMessages()
*/
class Attendee extends Entity {
public const ACTOR_USERS = 'users';
@@ -168,6 +172,12 @@ class Attendee extends Entity {
/** @var null|string */
protected $callId;
+ /** @var int */
+ protected $state;
+
+ /** @var int */
+ protected $unreadMessages;
+
public function __construct() {
$this->addType('roomId', 'int');
$this->addType('actorType', 'string');
@@ -189,6 +199,8 @@ class Attendee extends Entity {
$this->addType('invitedCloudId', 'string');
$this->addType('phoneNumber', 'string');
$this->addType('callId', 'string');
+ $this->addType('state', 'int');
+ $this->addType('unreadMessages', 'int');
}
public function getDisplayName(): string {
diff --git a/lib/Model/AttendeeMapper.php b/lib/Model/AttendeeMapper.php
index 268f5eab9..2cdab0b19 100644
--- a/lib/Model/AttendeeMapper.php
+++ b/lib/Model/AttendeeMapper.php
@@ -299,6 +299,8 @@ class AttendeeMapper extends QBMapper {
'invited_cloud_id' => (string) $row['invited_cloud_id'],
'phone_number' => $row['phone_number'],
'call_id' => $row['call_id'],
+ 'state' => (int) $row['state'],
+ 'unread_messages' => (int) $row['unread_messages'],
]);
}
}
diff --git a/lib/Model/SelectHelper.php b/lib/Model/SelectHelper.php
index a2513dda7..11304a0de 100644
--- a/lib/Model/SelectHelper.php
+++ b/lib/Model/SelectHelper.php
@@ -87,6 +87,8 @@ class SelectHelper {
->addSelect($alias . 'invited_cloud_id')
->addSelect($alias . 'phone_number')
->addSelect($alias . 'call_id')
+ ->addSelect($alias . 'state')
+ ->addSelect($alias . 'unread_messages')
->selectAlias($alias . 'id', 'a_id');
}
diff --git a/lib/Notification/FederationChatNotifier.php b/lib/Notification/FederationChatNotifier.php
index ef56078b1..08b6fc094 100644
--- a/lib/Notification/FederationChatNotifier.php
+++ b/lib/Notification/FederationChatNotifier.php
@@ -45,7 +45,7 @@ class FederationChatNotifier {
}
/**
- * @param array{remoteServerUrl: string, sharedSecret: string, remoteToken: string, messageData: array{remoteMessageId: int, actorType: string, actorId: string, actorDisplayName: string, messageType: string, systemMessage: string, expirationDatetime: string, message: string, messageParameter: string, creationDatetime: string, metaData: string}, unreadInfo: array{unreadMessages: int, unreadMention: bool, unreadMentionDirect: bool}} $inboundNotification
+ * @param array{remoteServerUrl: string, sharedSecret: string, remoteToken: string, messageData: array{remoteMessageId: int, actorType: string, actorId: string, actorDisplayName: string, messageType: string, systemMessage: string, expirationDatetime: string, message: string, messageParameter: string, creationDatetime: string, metaData: string}, unreadInfo: array{unreadMessages: int, unreadMention: bool, unreadMentionDirect: bool, lastReadMessage: int}} $inboundNotification
*/
public function handleChatMessage(Room $room, Participant $participant, ProxyCacheMessage $message, array $inboundNotification): void {
/** @var array{silent?: bool, last_edited_time?: int, last_edited_by_type?: string, last_edited_by_id?: string, replyToActorType?: string, replyToActorId?: string} $metaData */
diff --git a/lib/Service/ParticipantService.php b/lib/Service/ParticipantService.php
index 5060e8040..d68ed521b 100644
--- a/lib/Service/ParticipantService.php
+++ b/lib/Service/ParticipantService.php
@@ -249,9 +249,10 @@ class ParticipantService {
$this->attendeeMapper->update($attendee);
}
- public function updateUnreadInfoForProxyParticipant(Participant $participant, int $unreadMessageCount, bool $hasMention, bool $hadDirectMention): void {
+ public function updateUnreadInfoForProxyParticipant(Participant $participant, int $unreadMessageCount, bool $hasMention, bool $hadDirectMention, int $lastReadMessageId): void {
$attendee = $participant->getAttendee();
- $attendee->setLastReadMessage($unreadMessageCount);
+ $attendee->setUnreadMessages($unreadMessageCount);
+ $attendee->setLastReadMessage($lastReadMessageId);
$attendee->setLastMentionMessage($hasMention ? 1 : 0);
$attendee->setLastMentionDirect($hadDirectMention ? 1 : 0);
$this->attendeeMapper->update($attendee);
@@ -505,7 +506,7 @@ class ParticipantService {
}
$attendee->setParticipantType($participant['participantType'] ?? Participant::USER);
$attendee->setPermissions(Attendee::PERMISSIONS_DEFAULT);
- $attendee->setLastReadMessage($lastMessage);
+ $attendee->setLastReadMessage($participant['lastReadMessage'] ?? $lastMessage);
$attendee->setReadPrivacy($readPrivacy);
$attendees[] = $attendee;
}
diff --git a/lib/Service/RoomFormatter.php b/lib/Service/RoomFormatter.php
index a14ce1957..1f6fee7b7 100644
--- a/lib/Service/RoomFormatter.php
+++ b/lib/Service/RoomFormatter.php
@@ -292,12 +292,11 @@ class RoomFormatter {
if ($attendee->getActorType() === Attendee::ACTOR_USERS) {
$currentUser = $this->userManager->get($attendee->getActorId());
- if ($room->getRemoteServer() !== '') {
- // For proxy conversations the information is the real counter,
- // not the message ID requiring math afterward.
- $roomData['unreadMessages'] = $attendee->getLastReadMessage();
- $roomData['unreadMention'] = (bool) $attendee->getLastMentionMessage();
- $roomData['unreadMentionDirect'] = (bool) $attendee->getLastMentionDirect();
+ if ($room->isFederatedConversation()) {
+ $roomData['lastReadMessage'] = $attendee->getLastReadMessage();
+ $roomData['unreadMention'] = (bool)$attendee->getLastMentionMessage();
+ $roomData['unreadMentionDirect'] = (bool)$attendee->getLastMentionDirect();
+ $roomData['unreadMessages'] = $attendee->getUnreadMessages();
} elseif ($currentUser instanceof IUser) {
$lastReadMessage = $attendee->getLastReadMessage();
if ($lastReadMessage === -1) {
@@ -338,6 +337,7 @@ class RoomFormatter {
$lastReadMessage = $attendee->getLastReadMessage();
$lastMention = $attendee->getLastMentionMessage();
$lastMentionDirect = $attendee->getLastMentionDirect();
+ $roomData['lastReadMessage'] = $lastReadMessage;
$roomData['unreadMessages'] = $this->chatManager->getUnreadCount($room, $lastReadMessage);
$roomData['unreadMention'] = $lastMention !== 0 && $lastReadMessage < $lastMention;
$roomData['unreadMentionDirect'] = $lastMentionDirect !== 0 && $lastReadMessage < $lastMentionDirect;
@@ -388,6 +388,7 @@ class RoomFormatter {
$lastMessage,
);
} elseif ($room->getRemoteServer() !== '') {
+ $roomData['lastCommonReadMessage'] = 0;
try {
$cachedMessage = $this->proxyCacheMessageMapper->findByRemote(
$room->getRemoteServer(),