fix(threads): Remove read marker info from thread level as we can not keep it at the moment

Signed-off-by: Joas Schilling <coding@schilljs.com>
This commit is contained in:
Joas Schilling 2025-07-10 16:22:05 +02:00
parent 6c4bcc7454
commit 78573cc91c
No known key found for this signature in database
GPG key ID: F72FA5B49FFA96B0
6 changed files with 32 additions and 65 deletions

View file

@ -450,15 +450,9 @@ class ChatManager {
if (!empty($alreadyNotifiedUsers)) {
$userIds = array_column($alreadyNotifiedUsers, 'id');
$this->participantService->markUsersAsMentioned($chat, Attendee::ACTOR_USERS, $userIds, (int)$comment->getId(), $usersDirectlyMentioned);
if ($thread !== null) {
$this->threadService->markAttendeesAsMentioned($chat, Attendee::ACTOR_USERS, $userIds, (int)$comment->getId(), $usersDirectlyMentioned);
}
}
if (!empty($federatedUsersDirectlyMentioned)) {
$this->participantService->markUsersAsMentioned($chat, Attendee::ACTOR_FEDERATED_USERS, $federatedUsersDirectlyMentioned, (int)$comment->getId(), $federatedUsersDirectlyMentioned);
if ($thread !== null) {
$this->threadService->markAttendeesAsMentioned($chat, Attendee::ACTOR_FEDERATED_USERS, $federatedUsersDirectlyMentioned, (int)$comment->getId(), $federatedUsersDirectlyMentioned);
}
}
// User was not mentioned, send a normal notification

View file

@ -130,6 +130,9 @@ class ThreadController extends AEnvironmentAwareOCSController {
foreach ($threads as $thread) {
$firstMessage = $lastMessage = null;
$attendee = $attendees[$thread->getId()] ?? null;
if ($attendee === null) {
$attendee = ThreadAttendee::createFromParticipant($thread->getId(), $this->participant);
}
$first = $comments[$thread->getId()] ?? null;
if ($first !== null) {
@ -145,7 +148,7 @@ class ThreadController extends AEnvironmentAwareOCSController {
$list[] = [
'thread' => $thread->jsonSerialize(),
'attendee' => $attendee?->jsonSerialize(),
'attendee' => $attendee->jsonSerialize(),
'first' => $firstMessage?->toArray($this->getResponseFormat()),
'last' => $lastMessage?->toArray($this->getResponseFormat()),
];

View file

@ -45,6 +45,20 @@ class Version22000Date20250710124258 extends SimpleMigrationStep {
$table->addIndex(['last_activity'], 'talkthread_lastactive');
}
$table = $schema->getTable('talk_thread_attendees');
if ($table->hasColumn('last_read_message')) {
$table->dropColumn('last_read_message');
}
if ($table->hasColumn('last_mention_message')) {
$table->dropColumn('last_mention_message');
}
if ($table->hasColumn('last_mention_direct')) {
$table->dropColumn('last_mention_direct');
}
if ($table->hasColumn('read_privacy')) {
$table->dropColumn('read_privacy');
}
return $schema;
}
}

View file

@ -8,6 +8,7 @@ declare(strict_types=1);
namespace OCA\Talk\Model;
use OCA\Talk\Participant;
use OCA\Talk\ResponseDefinitions;
use OCP\AppFramework\Db\Entity;
use OCP\DB\Types;
@ -25,14 +26,6 @@ use OCP\DB\Types;
* @method string getActorId()
* @method void setNotificationLevel(int $notificationLevel)
* @method int getNotificationLevel()
* @method void setLastReadMessage(int $lastReadMessage)
* @method int getLastReadMessage()
* @method void setLastMentionMessage(int $lastMentionMessage)
* @method int getLastMentionMessage()
* @method void setLastMentionDirect(int $lastMentionDirect)
* @method int getLastMentionDirect()
* @method void setReadPrivacy(int $readPrivacy)
* @method int getReadPrivacy()
*
* @psalm-import-type TalkThreadAttendee from ResponseDefinitions
*/
@ -43,21 +36,25 @@ class ThreadAttendee extends Entity implements \JsonSerializable {
protected string $actorType = '';
protected string $actorId = '';
protected int $notificationLevel = 0;
protected int $lastReadMessage = 0;
protected int $lastMentionMessage = 0;
protected int $lastMentionDirect = 0;
protected int $readPrivacy = 0;
public function __construct() {
$this->addType('roomId', Types::BIGINT);
$this->addType('threadId', Types::BIGINT);
$this->addType('attendeeId', Types::BIGINT);
$this->addType('actorType', Types::STRING);
$this->addType('actorId', Types::STRING);
$this->addType('notificationLevel', Types::INTEGER);
$this->addType('lastReadMessage', Types::INTEGER);
$this->addType('lastMentionMessage', Types::INTEGER);
$this->addType('lastMentionDirect', Types::BIGINT);
$this->addType('readPrivacy', Types::SMALLINT);
}
public static function createFromParticipant(int $threadId, Participant $participant): ThreadAttendee {
$attendee = new ThreadAttendee();
$attendee->setRoomId($participant->getRoom()->getId());
$attendee->setThreadId($threadId);
$attendee->setAttendeeId($participant->getAttendee()->getId());
$attendee->setNotificationLevel(Participant::NOTIFY_DEFAULT);
$attendee->setActorType($participant->getAttendee()->getActorType());
$attendee->setActorId($participant->getAttendee()->getActorId());
return $attendee;
}
/**
@ -67,10 +64,6 @@ class ThreadAttendee extends Entity implements \JsonSerializable {
public function jsonSerialize(): array {
return [
'notificationLevel' => min(3, max(0, $this->getNotificationLevel())),
'lastReadMessage' => max(0, $this->getLastReadMessage()),
'lastMentionMessage' => max(0, $this->getLastMentionMessage()),
'lastMentionDirect' => max(0, $this->getLastMentionDirect()),
'readPrivacy' => min(1, max(0, $this->getReadPrivacy())),
];
}
}

View file

@ -456,15 +456,11 @@ namespace OCA\Talk;
*
* @psalm-type TalkThreadAttendee = array{
* notificationLevel: 0|1|2|3,
* lastReadMessage: non-negative-int,
* lastMentionMessage: non-negative-int,
* lastMentionDirect: non-negative-int,
* readPrivacy: 0|1,
* }
*
* @psalm-type TalkThreadInfo = array{
* thread: TalkThread,
* attendee: ?TalkThreadAttendee,
* attendee: TalkThreadAttendee,
* first: ?TalkChatMessage,
* last: ?TalkChatMessage,
* }

View file

@ -93,13 +93,6 @@ class ThreadService {
$threadAttendee->setActorType($attendee->getActorType());
$threadAttendee->setActorId($attendee->getActorId());
$threadAttendee->setNotificationLevel($attendee->getNotificationLevel());
$threadAttendee->setReadPrivacy($attendee->getReadPrivacy());
// We only copy the read marker for now.
// If we copied the last mention and direct ids as well, all threads
// created would be marked as unread with a mention,
// when the conversation had an unread mention.
$threadAttendee->setLastReadMessage($attendee->getLastReadMessage());
try {
$this->threadAttendeeMapper->insert($threadAttendee);
@ -142,32 +135,6 @@ class ThreadService {
$thread->setLastActivity($dateTime);
}
/**
* @param string[] $actorIds
* @param string[] $actorsDirectlyMentioned
*/
public function markAttendeesAsMentioned(Room $room, string $actorType, array $actorIds, int $messageId, array $actorsDirectlyMentioned): void {
$update = $this->connection->getQueryBuilder();
$update->update('talk_thread_attendees')
->set('last_mention_message', $update->createNamedParameter($messageId, IQueryBuilder::PARAM_INT))
->where($update->expr()->eq('room_id', $update->createNamedParameter($room->getId(), IQueryBuilder::PARAM_INT)))
->andWhere($update->expr()->eq('actor_type', $update->createNamedParameter($actorType)))
->andWhere($update->expr()->in('actor_id', $update->createNamedParameter($actorIds, IQueryBuilder::PARAM_STR_ARRAY)))
->andWhere($update->expr()->lt('last_mention_message', $update->createNamedParameter($messageId, IQueryBuilder::PARAM_INT)));
$update->executeStatement();
if (!empty($actorsDirectlyMentioned)) {
$update = $this->connection->getQueryBuilder();
$update->update('talk_thread_attendees')
->set('last_mention_direct', $update->createNamedParameter($messageId, IQueryBuilder::PARAM_INT))
->where($update->expr()->eq('room_id', $update->createNamedParameter($room->getId(), IQueryBuilder::PARAM_INT)))
->andWhere($update->expr()->eq('actor_type', $update->createNamedParameter($actorType)))
->andWhere($update->expr()->in('actor_id', $update->createNamedParameter($actorsDirectlyMentioned, IQueryBuilder::PARAM_STR_ARRAY)))
->andWhere($update->expr()->lt('last_mention_direct', $update->createNamedParameter($messageId, IQueryBuilder::PARAM_INT)));
$update->executeStatement();
}
}
public function deleteByRoom(Room $room): void {
$this->threadMapper->deleteByRoomId($room->getId());
$this->threadAttendeeMapper->deleteByRoomId($room->getId());