fix(threads): add thread info to last message

Signed-off-by: Anna Larch <anna@nextcloud.com>
This commit is contained in:
Anna Larch 2025-09-08 18:22:56 +02:00 committed by Joas Schilling
parent 8f3bc3b36d
commit 7a5b843531
No known key found for this signature in database
GPG key ID: F72FA5B49FFA96B0
4 changed files with 51 additions and 5 deletions

View file

@ -52,6 +52,7 @@ use OCA\Talk\Middleware\Attribute\RequireRoom;
use OCA\Talk\Model\Attendee;
use OCA\Talk\Model\BreakoutRoom;
use OCA\Talk\Model\Session;
use OCA\Talk\Model\Thread;
use OCA\Talk\Participant;
use OCA\Talk\ResponseDefinitions;
use OCA\Talk\Room;
@ -66,6 +67,7 @@ use OCA\Talk\Service\RecordingService;
use OCA\Talk\Service\RoomFormatter;
use OCA\Talk\Service\RoomService;
use OCA\Talk\Service\SessionService;
use OCA\Talk\Service\ThreadService;
use OCA\Talk\Settings\UserPreference;
use OCA\Talk\Share\Helper\Preloader;
use OCA\Talk\TalkSession;
@ -85,6 +87,7 @@ use OCP\Calendar\CalendarEventStatus;
use OCP\Calendar\Exceptions\CalendarException;
use OCP\Calendar\ICreateFromString;
use OCP\Calendar\IManager as ICalendarManager;
use OCP\Comments\IComment;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Federation\ICloudIdManager;
use OCP\IConfig;
@ -149,6 +152,7 @@ class RoomController extends AEnvironmentAwareOCSController {
protected BanService $banService,
protected IURLGenerator $url,
protected IL10N $l,
protected ThreadService $threadService,
) {
parent::__construct($appName, $request);
}
@ -294,13 +298,15 @@ class RoomController extends AEnvironmentAwareOCSController {
if ($includeLastMessage) {
$lastMessages = array_filter(array_map(static fn (Room $room) => $room->getLastMessage()?->getVerb() === 'object_shared' ? $room->getLastMessage() : null, $rooms));
$potentialThreads = array_map(static fn (IComment $lastMessage) => (int)$lastMessage->getTopmostParentId(), $lastMessages);
$this->sharePreloader->preloadShares($lastMessages);
$threads = $this->threadService->preloadThreads($potentialThreads);
}
$return = [];
foreach ($rooms as $room) {
try {
$return[] = $this->formatRoom($room, $this->participantService->getParticipant($room, $this->userId), $statuses, skipLastMessage: !$includeLastMessage);
$return[] = $this->formatRoom($room, $this->participantService->getParticipant($room, $this->userId), $statuses, skipLastMessage: !$includeLastMessage, thread: $threads[$room->getId()] ?? null);
} catch (ParticipantNotFoundException $e) {
// for example in case the room was deleted concurrently,
// the user is not a participant anymore
@ -530,6 +536,7 @@ class RoomController extends AEnvironmentAwareOCSController {
bool $isSIPBridgeRequest = false,
bool $isListingBreakoutRooms = false,
bool $skipLastMessage = false,
?Thread $thread = null,
): array {
return $this->roomFormatter->formatRoom(
$this->getResponseFormat(),
@ -540,6 +547,7 @@ class RoomController extends AEnvironmentAwareOCSController {
$isSIPBridgeRequest,
$isListingBreakoutRooms,
$skipLastMessage,
$thread,
);
}

View file

@ -70,6 +70,24 @@ class ThreadMapper extends QBMapper {
return $this->findEntities($query);
}
/**
* @param list<non-negative-int> $threadIds
* @return list<Thread>
*/
public function getForIds(array $threadIds): array {
$query = $this->db->getQueryBuilder();
$query->select('*')
->from($this->getTableName())
->where($query->expr()->in(
'id',
$query->createNamedParameter($threadIds, IQueryBuilder::PARAM_INT_ARRAY),
IQueryBuilder::PARAM_INT,
));
return $this->findEntities($query);
}
/**
* @param int<1, 50> $limit
* @return list<Thread>

View file

@ -14,6 +14,7 @@ use OCA\Talk\Federation\Proxy\TalkV1\UserConverter;
use OCA\Talk\Model\Attendee;
use OCA\Talk\Model\BreakoutRoom;
use OCA\Talk\Model\Session;
use OCA\Talk\Model\Thread;
use OCA\Talk\Participant;
use OCA\Talk\ResponseDefinitions;
use OCA\Talk\Room;
@ -51,6 +52,7 @@ class RoomFormatter {
protected UserConverter $userConverter,
protected IL10N $l10n,
protected ?string $userId,
protected ThreadService $threadService,
) {
}
@ -66,6 +68,7 @@ class RoomFormatter {
bool $isSIPBridgeRequest = false,
bool $isListingBreakoutRooms = false,
bool $skipLastMessage = false,
?Thread $thread = null,
): array {
return $this->formatRoomV4(
$responseFormat,
@ -76,6 +79,7 @@ class RoomFormatter {
$isSIPBridgeRequest,
$isListingBreakoutRooms,
$skipLastMessage,
$thread,
);
}
@ -92,6 +96,7 @@ class RoomFormatter {
bool $isSIPBridgeRequest,
bool $isListingBreakoutRooms,
bool $skipLastMessage,
?Thread $thread = null,
): array {
$roomData = [
'id' => $room->getId(),
@ -397,12 +402,13 @@ class RoomFormatter {
$skipLastMessage = $skipLastMessage || $attendee->isSensitive();
$lastMessage = $skipLastMessage ? null : $room->getLastMessage();
if (!$room->isFederatedConversation() && $lastMessage instanceof IComment) {
if ($lastMessage instanceof IComment && !$room->isFederatedConversation()) {
$lastMessageData = $this->formatLastMessage(
$responseFormat,
$room,
$currentParticipant,
$lastMessage,
$thread,
);
if ($lastMessageData !== null) {
$roomData['lastMessage'] = $lastMessageData;
@ -448,6 +454,7 @@ class RoomFormatter {
Room $room,
Participant $participant,
IComment $lastMessage,
?Thread $thread = null,
): ?array {
$message = $this->messageParser->createMessage($room, $participant, $lastMessage, $this->l10n);
$this->messageParser->parseMessage($message, true);
@ -457,11 +464,11 @@ class RoomFormatter {
}
$now = $this->timeFactory->getDateTime();
$expireDate = $message->getComment()->getExpireDate();
$expireDate = $message->getComment()?->getExpireDate();
if ($expireDate instanceof \DateTime && $expireDate < $now) {
return null;
}
return $message->toArray($responseFormat, null);
return $message->toArray($responseFormat, $thread);
}
}

View file

@ -56,7 +56,7 @@ class ThreadService {
/**
* @param non-negative-int $roomId
* @param list<non-negative-int> $threadId
* @param list<non-negative-int> $threadIds
* @return array<int, Thread> Map with thread id as key
*/
public function findByThreadIds(int $roomId, array $threadIds): array {
@ -68,6 +68,19 @@ class ThreadService {
return $result;
}
/**
* @param list<non-negative-int> $threadIds
* @return array<int, Thread> Map with room id as key
*/
public function preloadThreads(array $threadIds): array {
$threads = $this->threadMapper->getForIds($threadIds);
$result = [];
foreach ($threads as $thread) {
$result[$thread->getRoomId()] = $thread;
}
return $result;
}
/**
* @throws \InvalidArgumentException When the title is empty
*/