summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoas Schilling <213943+nickvergessen@users.noreply.github.com>2021-06-21 18:53:58 +0200
committerGitHub <noreply@github.com>2021-06-21 18:53:58 +0200
commit9c5aad76f292601fd8d314a3ee351da49348f22c (patch)
tree92cddb581841e34e914b5c071140417eea0aaa33
parent334e6b03ce0fb323c188ae28252e3a1b00ba05b6 (diff)
parent37d037773f42c662c701c79a8b66284633e10e09 (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.md9
-rw-r--r--lib/Controller/RoomController.php51
-rw-r--r--src/components/ConversationIcon.vue12
-rw-r--r--src/services/conversationsService.js8
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)
}
/**