diff options
author | Joas Schilling <213943+nickvergessen@users.noreply.github.com> | 2021-06-21 18:53:58 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-21 18:53:58 +0200 |
commit | 9c5aad76f292601fd8d314a3ee351da49348f22c (patch) | |
tree | 92cddb581841e34e914b5c071140417eea0aaa33 | |
parent | 334e6b03ce0fb323c188ae28252e3a1b00ba05b6 (diff) | |
parent | 37d037773f42c662c701c79a8b66284633e10e09 (diff) |
Merge pull request #5828 from nextcloud/feature/noid/populate-user-status-for-one-to-one-conversations-via-the-backend-call-already
Populate user status for one to one conversations via the backend call already
-rw-r--r-- | docs/conversation.md | 9 | ||||
-rw-r--r-- | lib/Controller/RoomController.php | 51 | ||||
-rw-r--r-- | src/components/ConversationIcon.vue | 12 | ||||
-rw-r--r-- | src/services/conversationsService.js | 8 |
4 files changed, 72 insertions, 8 deletions
diff --git a/docs/conversation.md b/docs/conversation.md index e4713b138..d998ee0d4 100644 --- a/docs/conversation.md +++ b/docs/conversation.md @@ -9,6 +9,12 @@ * Method: `GET` * Endpoint: `/room` +* Data: + + field | type | Description + ---|---|--- + `noStatusUpdate` | int | Whether the "online" user status of the current user should be "kept-alive" (`1`) or not (`0`) (defaults to `0`) + `includeStatus` | bool | Whether the user status information of all one-to-one conversations should be loaded (default false) * Response: - Status code: @@ -66,6 +72,9 @@ `lastMessage` | message | v1 | | Last message in a conversation if available, otherwise empty `objectType` | string | v1 | | The type of object that the conversation is associated with; "share:password" if the conversation is used to request a password for a share, otherwise empty `objectId` | string | v1 | | Share token if "objectType" is "share:password", otherwise empty + `status` | string | v4 | | Optional: Only available for one-to-one conversations and when `includeStatus=true` is set + `statusIcon` | string | v4 | | Optional: Only available for one-to-one conversations and when `includeStatus=true` is set + `statusMessage` | string | v4 | | Optional: Only available for one-to-one conversations and when `includeStatus=true` is set `participants` | array | v1 | v2 | **Removed** `guestList` | string | v1 | v2 | **Removed** diff --git a/lib/Controller/RoomController.php b/lib/Controller/RoomController.php index dfc042aca..32f5e82a6 100644 --- a/lib/Controller/RoomController.php +++ b/lib/Controller/RoomController.php @@ -175,9 +175,10 @@ class RoomController extends AEnvironmentAwareController { * @NoAdminRequired * * @param int $noStatusUpdate When the user status should not be automatically set to online set to 1 (default 0) + * @param bool $includeStatus * @return DataResponse */ - public function getRooms(int $noStatusUpdate = 0): DataResponse { + public function getRooms(int $noStatusUpdate = 0, bool $includeStatus = false): DataResponse { $event = new UserEvent($this->userId); $this->dispatcher->dispatch(self::EVENT_BEFORE_ROOMS_GET, $event); @@ -208,10 +209,29 @@ class RoomController extends AEnvironmentAwareController { $this->commonReadMessages = $this->participantService->getLastCommonReadChatMessageForMultipleRooms($roomIds); } + $statuses = []; + if ($this->userId !== null + && $includeStatus + && $this->appManager->isEnabledForUser('user_status')) { + $userIds = array_filter(array_map(function (Room $room) { + if ($room->getType() === Room::ONE_TO_ONE_CALL) { + $participants = json_decode($room->getName(), true); + foreach ($participants as $participant) { + if ($participant !== $this->userId) { + return $participant; + } + } + } + return null; + }, $rooms)); + + $statuses = $this->statusManager->getUserStatuses($userIds); + } + $return = []; foreach ($rooms as $room) { try { - $return[] = $this->formatRoom($room, $room->getParticipant($this->userId)); + $return[] = $this->formatRoom($room, $room->getParticipant($this->userId), $statuses); } catch (RoomNotFoundException $e) { } catch (ParticipantNotFoundException $e) { // for example in case the room was deleted concurrently, @@ -277,7 +297,7 @@ class RoomController extends AEnvironmentAwareController { } } - return new DataResponse($this->formatRoom($room, $participant, $isSIPBridgeRequest), Http::STATUS_OK, $this->getTalkHashHeader()); + return new DataResponse($this->formatRoom($room, $participant, [], $isSIPBridgeRequest), Http::STATUS_OK, $this->getTalkHashHeader()); } catch (RoomNotFoundException $e) { return new DataResponse([], Http::STATUS_NOT_FOUND); } @@ -328,22 +348,24 @@ class RoomController extends AEnvironmentAwareController { /** * @param Room $room * @param Participant|null $currentParticipant + * @param array $statuses * @param bool $isSIPBridgeRequest * @return array * @throws RoomNotFoundException */ - protected function formatRoom(Room $room, ?Participant $currentParticipant, bool $isSIPBridgeRequest = false): array { - return $this->formatRoomV4($room, $currentParticipant, $isSIPBridgeRequest); + protected function formatRoom(Room $room, ?Participant $currentParticipant, array $statuses = [], bool $isSIPBridgeRequest = false): array { + return $this->formatRoomV4($room, $currentParticipant, $statuses, $isSIPBridgeRequest); } /** * @param Room $room * @param Participant|null $currentParticipant + * @param array $statuses * @param bool $isSIPBridgeRequest * @return array * @throws RoomNotFoundException */ - protected function formatRoomV4(Room $room, ?Participant $currentParticipant, bool $isSIPBridgeRequest = false): array { + protected function formatRoomV4(Room $room, ?Participant $currentParticipant, array $statuses, bool $isSIPBridgeRequest): array { $roomData = [ 'id' => $room->getId(), 'token' => $room->getToken(), @@ -540,6 +562,18 @@ class RoomController extends AEnvironmentAwareController { foreach ($participants as $participant) { if ($participant !== $attendee->getActorId()) { $roomData['name'] = $participant; + + if (isset($statuses[$participant])) { + $roomData['status'] = $statuses[$participant]->getStatus(); + $roomData['statusIcon'] = $statuses[$participant]->getIcon(); + $roomData['statusMessage'] = $statuses[$participant]->getMessage(); + $roomData['statusClearAt'] = $statuses[$participant]->getClearAt(); + } elseif (!empty($statuses)) { + $roomData['status'] = IUserStatus::OFFLINE; + $roomData['statusIcon'] = null; + $roomData['statusMessage'] = null; + $roomData['statusClearAt'] = null; + } } } } @@ -950,6 +984,11 @@ class RoomController extends AEnvironmentAwareController { $result['statusIcon'] = $statuses[$userId]->getIcon(); $result['statusMessage'] = $statuses[$userId]->getMessage(); $result['statusClearAt'] = $statuses[$userId]->getClearAt(); + } elseif (isset($headers['X-Nextcloud-Has-User-Statuses'])) { + $result['status'] = IUserStatus::OFFLINE; + $result['statusIcon'] = null; + $result['statusMessage'] = null; + $result['statusClearAt'] = null; } } elseif ($participant->getAttendee()->getActorType() === Attendee::ACTOR_GUESTS) { if ($result['lastPing'] <= $maxPingAge) { diff --git a/src/components/ConversationIcon.vue b/src/components/ConversationIcon.vue index 156806dfd..5c8d06ccc 100644 --- a/src/components/ConversationIcon.vue +++ b/src/components/ConversationIcon.vue @@ -28,6 +28,7 @@ :size="44" :user="item.name" :display-name="item.displayName" + :preloaded-user-status="preloadedUserStatus" menu-container="#content-vue" menu-position="left" class="conversation-icon__avatar" /> @@ -101,6 +102,17 @@ export default { return '' }, + preloadedUserStatus() { + if (Object.prototype.hasOwnProperty.call(this.item, 'statusMessage')) { + // We preloaded the status + return { + status: this.item.status || null, + message: this.item.statusMessage || null, + icon: this.item.statusIcon || null, + } + } + return undefined + }, }, } </script> diff --git a/src/services/conversationsService.js b/src/services/conversationsService.js index f74b7d07e..b83b53648 100644 --- a/src/services/conversationsService.js +++ b/src/services/conversationsService.js @@ -26,9 +26,13 @@ import { CONVERSATION, SHARE } from '../constants' /** * Fetches the conversations from the server. + * @param {object} options options */ -const fetchConversations = async function() { - return axios.get(generateOcsUrl('apps/spreed/api/v4/room')) +const fetchConversations = async function(options) { + options = options || {} + options.params = options.params || {} + options.params.includeStatus = true + return await axios.get(generateOcsUrl('apps/spreed/api/v4/room'), options) } /** |