diff options
author | Joas Schilling <coding@schilljs.com> | 2023-07-25 09:25:46 +0200 |
---|---|---|
committer | Joas Schilling <coding@schilljs.com> | 2023-10-16 15:46:13 +0200 |
commit | 8ccf9a95c7ce5f96a077bbfcdc4fc3ea52418ed2 (patch) | |
tree | d90d2d4f4307499a63c7c5dc5bf1056ff9aef52c | |
parent | 5fe0cc5065cb9b9f8093d360b7fc1b8284b6e15e (diff) |
feat(captions): Add support for multiple files
Signed-off-by: Joas Schilling <coding@schilljs.com>
-rw-r--r-- | appinfo/routes/routesChatController.php | 2 | ||||
-rw-r--r-- | lib/Chat/Parser/SystemMessage.php | 29 | ||||
-rw-r--r-- | lib/Chat/SystemMessage/Listener.php | 8 | ||||
-rw-r--r-- | lib/Controller/ChatController.php | 67 | ||||
-rw-r--r-- | openapi.json | 214 |
5 files changed, 318 insertions, 2 deletions
diff --git a/appinfo/routes/routesChatController.php b/appinfo/routes/routesChatController.php index 921c5da3f..7428e91fa 100644 --- a/appinfo/routes/routesChatController.php +++ b/appinfo/routes/routesChatController.php @@ -60,6 +60,8 @@ return [ ['name' => 'Chat#mentions', 'url' => '/api/{apiVersion}/chat/{token}/mentions', 'verb' => 'GET', 'requirements' => $requirements], /** @see \OCA\Talk\Controller\ChatController::shareObjectToChat() */ ['name' => 'Chat#shareObjectToChat', 'url' => '/api/{apiVersion}/chat/{token}/share', 'verb' => 'POST', 'requirements' => $requirements], + /** @see \OCA\Talk\Controller\ChatController::shareMultipleFilesToChat() */ + ['name' => 'Chat#shareMultipleFilesToChat', 'url' => '/api/{apiVersion}/chat/{token}/share-files', 'verb' => 'POST', 'requirements' => $requirements], /** @see \OCA\Talk\Controller\ChatController::getObjectsSharedInRoomOverview() */ ['name' => 'Chat#getObjectsSharedInRoomOverview', 'url' => '/api/{apiVersion}/chat/{token}/share/overview', 'verb' => 'GET', 'requirements' => $requirements], /** @see \OCA\Talk\Controller\ChatController::getObjectsSharedInRoom() */ diff --git a/lib/Chat/Parser/SystemMessage.php b/lib/Chat/Parser/SystemMessage.php index be4aaf4b5..227376f4a 100644 --- a/lib/Chat/Parser/SystemMessage.php +++ b/lib/Chat/Parser/SystemMessage.php @@ -419,6 +419,35 @@ class SystemMessage { $parsedMessage = $this->l->t('You shared a file which is no longer available'); } } + } elseif ($message === 'multiple_files_shared') { + $chatMessage->setMessageType(ChatManager::VERB_MESSAGE); + + $parsedMessage = ''; + if (isset($parameters['caption']) && $parameters['caption'] !== '') { + $parsedMessage = $parameters['caption']; + } + + $foundShares = $missingShares = []; + foreach ($parameters['shares'] as $key => $shareId) { + try { + $foundShares['file-' . ($key + 1)] = $this->getFileFromShare($participant, $shareId); + } catch (\Exception) { + $missingShares['file-missing-' . ($key + 1)] = [ + 'type' => 'highlight', + 'id' => $shareId, + 'name' => $this->l->t('Deleted file'), + ]; + } + } + + if (empty($foundShares)) { + $parsedMessage = $this->l->t('{actor} shared files which are no longer available'); + if ($currentUserIsActor) { + $parsedMessage = $this->l->t('You shared files which are no longer available'); + } + } else { + $parsedParameters = array_merge($parsedParameters, $foundShares, $missingShares); + } } elseif ($message === 'object_shared') { $parsedParameters['object'] = $parameters['metaData']; $parsedParameters['object']['id'] = (string) $parsedParameters['object']['id']; diff --git a/lib/Chat/SystemMessage/Listener.php b/lib/Chat/SystemMessage/Listener.php index 806e6c707..549cc9cd6 100644 --- a/lib/Chat/SystemMessage/Listener.php +++ b/lib/Chat/SystemMessage/Listener.php @@ -385,7 +385,13 @@ class Listener implements IEventListener { } $metaData['mimeType'] = $share->getNode()->getMimeType(); - $metaData['caption'] = $metaData['caption'] ?? ''; + if (isset($metaData['caption'])) { + if (is_string($metaData['caption']) && trim($metaData['caption']) !== '') { + $metaData['caption'] = trim($metaData['caption']); + } else { + unset($metaData['caption']); + } + } $listener->sendSystemMessage($room, 'file_shared', ['share' => $share->getId(), 'metaData' => $metaData]); } diff --git a/lib/Controller/ChatController.php b/lib/Controller/ChatController.php index 0dcb77c0b..d4931f2bd 100644 --- a/lib/Controller/ChatController.php +++ b/lib/Controller/ChatController.php @@ -132,7 +132,7 @@ class ChatController extends AEnvironmentAwareController { } return [Attendee::ACTOR_GUESTS, $this->participant->getAttendee()->getActorId()]; } - + if ($this->userId === MatterbridgeManager::BRIDGE_BOT_USERID && $actorDisplayName) { return [Attendee::ACTOR_BRIDGED, str_replace(['/', '"'], '', $actorDisplayName)]; } @@ -305,6 +305,71 @@ class ChatController extends AEnvironmentAwareController { return $this->parseCommentToResponse($comment); } + /** + * Share multiple files and a caption into the chat + * + * @param int[] $shareIds The share IDs that should be shown with this message + * @param string $caption The message to send + * @param string $actorDisplayName for guests + * @param string $referenceId for the message to be able to later identify it again + * @return DataResponse<Http::STATUS_CREATED, ?TalkChatMessageWithParent, array{X-Chat-Last-Common-Read?: numeric-string}>|DataResponse<Http::STATUS_BAD_REQUEST|Http::STATUS_NOT_FOUND|Http::STATUS_REQUEST_ENTITY_TOO_LARGE, array<empty>, array{}> + * + * 201: Files shared successfully + * 400: Sharing files is not possible + * 404: Actor not found + * 404: Shares not found for actor + * 413: Message too long + */ + #[NoAdminRequired] + #[RequireModeratorOrNoLobby] + #[RequireLoggedInParticipant] + #[RequirePermission(permission: RequirePermission::CHAT)] + #[RequireReadWriteConversation] + public function shareMultipleFilesToChat(array $shareIds, string $caption, string $actorDisplayName = '', string $referenceId = ''): DataResponse { + [$actorType, $actorId] = $this->getActorInfo($actorDisplayName); + if (!$actorId) { + return new DataResponse([], Http::STATUS_NOT_FOUND); + } + + $numShares = count($shareIds); + if ($numShares > 64) { + return new DataResponse([], Http::STATUS_REQUEST_ENTITY_TOO_LARGE); + } + + $shares = $this->shareProvider->getSharesByIds($shareIds); + if (count($shares) !== $numShares) { + return new DataResponse([], Http::STATUS_NOT_FOUND); + } + + foreach ($shares as $share) { + // Only allowed to share your own shares + if ($share->getShareOwner() !== $actorId) { + return new DataResponse([], Http::STATUS_NOT_FOUND); + } + } + + $this->participantService->ensureOneToOneRoomIsFilled($this->room); + $creationDateTime = $this->timeFactory->getDateTime('now', new \DateTimeZone('UTC')); + + $message = json_encode([ + 'message' => 'multiple_files_shared', + 'parameters' => [ + 'shares' => $shareIds, + 'caption' => $caption, + ], + ]); + + try { + $comment = $this->chatManager->addSystemMessage($this->room, $actorType, $actorId, $message, $creationDateTime, true, $referenceId); + } catch (MessageTooLongException) { + return new DataResponse([], Http::STATUS_REQUEST_ENTITY_TOO_LARGE); + } catch (\Exception) { + return new DataResponse([], Http::STATUS_BAD_REQUEST); + } + + return $this->parseCommentToResponse($comment); + } + /* * Gather share IDs from the comments and preload share definitions * to avoid separate database query for each individual share. diff --git a/openapi.json b/openapi.json index 8a7f22e13..8b71ad267 100644 --- a/openapi.json +++ b/openapi.json @@ -6654,6 +6654,220 @@ } } }, + "/ocs/v2.php/apps/spreed/api/{apiVersion}/chat/{token}/share-files": { + "post": { + "operationId": "chat-share-multiple-files-to-chat", + "summary": "Share multiple files and a caption into the chat", + "tags": [ + "chat" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "shareIds[]", + "in": "query", + "description": "The share IDs that should be shown with this message", + "required": true, + "schema": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + } + } + }, + { + "name": "caption", + "in": "query", + "description": "The message to send", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "actorDisplayName", + "in": "query", + "description": "for guests", + "schema": { + "type": "string", + "default": "" + } + }, + { + "name": "referenceId", + "in": "query", + "description": "for the message to be able to later identify it again", + "schema": { + "type": "string", + "default": "" + } + }, + { + "name": "apiVersion", + "in": "path", + "required": true, + "schema": { + "type": "string", + "enum": [ + "v1" + ], + "default": "v1" + } + }, + { + "name": "token", + "in": "path", + "required": true, + "schema": { + "type": "string", + "pattern": "^[a-z0-9]{4,30}$" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "201": { + "description": "Files shared successfully", + "headers": { + "X-Chat-Last-Common-Read": { + "schema": { + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "$ref": "#/components/schemas/ChatMessageWithParent", + "nullable": true + } + } + } + } + } + } + } + }, + "400": { + "description": "Sharing files is not possible", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "404": { + "description": "Shares not found for actor", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "413": { + "description": "Message too long", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, "/ocs/v2.php/apps/spreed/api/{apiVersion}/chat/{token}/share/overview": { "get": { "operationId": "chat-get-objects-shared-in-room-overview", |