From 07fd562a55d243f5005e4bf7ae5f1738bf1d8028 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20H=C3=A4rtl?= Date: Mon, 10 Feb 2020 09:35:26 +0100 Subject: [PATCH] WIP: Comment reply MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Julius Härtl --- appinfo/routes.php | 3 + img/reply.svg | 1 + lib/Controller/CommentsApiController.php | 109 +++++++++++++++++++++++ src/services/CommentApi.js | 4 + 4 files changed, 117 insertions(+) create mode 100644 img/reply.svg create mode 100644 lib/Controller/CommentsApiController.php diff --git a/appinfo/routes.php b/appinfo/routes.php index d815fa013..6d019b3a3 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -122,6 +122,9 @@ return [ ['name' => 'attachment_api#delete', 'url' => '/api/v1.0/boards/{boardId}/stacks/{stackId}/cards/{cardId}/attachments/{attachmentId}', 'verb' => 'DELETE'], ['name' => 'attachment_api#restore', 'url' => '/api/v1.0/boards/{boardId}/stacks/{stackId}/cards/{cardId}/attachments/{attachmentId}/restore', 'verb' => 'PUT'], + ['name' => 'comments_api#list', 'url' => '/api/v1.0/boards/{boardId}/stacks/{stackId}/cards/{cardId}/comments', 'verb' => 'GET'], + + ['name' => 'board_api#preflighted_cors', 'url' => '/api/v1.0/{path}','verb' => 'OPTIONS', 'requirements' => ['path' => '.+']], ] ]; diff --git a/img/reply.svg b/img/reply.svg new file mode 100644 index 000000000..a198103b8 --- /dev/null +++ b/img/reply.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/lib/Controller/CommentsApiController.php b/lib/Controller/CommentsApiController.php new file mode 100644 index 000000000..058f660d7 --- /dev/null +++ b/lib/Controller/CommentsApiController.php @@ -0,0 +1,109 @@ + + * + * @author Julius Härtl + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCA\Deck\Controller; + + +use OCP\AppFramework\ApiController; +use OCP\AppFramework\Http\DataResponse; +use OCP\AppFramework\Http\JSONResponse; +use OCP\Comments\IComment; +use OCP\Comments\ICommentsManager; +use OCP\Comments\NotFoundException; +use OCP\ILogger; +use OCP\IRequest; +use OCP\IUserManager; + +class CommentsApiController extends ApiController { + + /** @var ICommentsManager */ + private $commentsManager; + /** @var IUserManager */ + private $userManager; + /** @var ILogger */ + private $logger; + + public function __construct( + $appName, IRequest $request, $corsMethods = 'PUT, POST, GET, DELETE, PATCH', $corsAllowedHeaders = 'Authorization, Content-Type, Accept', $corsMaxAge = 1728000, + ICommentsManager $commentsManager, + IUserManager $userManager, + ILogger $logger + ) { + parent::__construct($appName, $request, $corsMethods, $corsAllowedHeaders, $corsMaxAge); + + $this->commentsManager = $commentsManager; + $this->userManager = $userManager; + $this->logger = $logger; + } + + /** + * @NoAdminRequired + * @CORS + * @NoCSRFRequired + */ + public function list(int $cardId, $limit = 20, $offset = 0): JSONResponse { + $comments = $this->commentsManager->getForObject('deckCard', $cardId, $limit, $offset); + $result = []; + foreach ($comments as $comment) { + $formattedComment = $this->formatComment($comment); + try { + if ($comment->getParentId() !== '0' && $replyTo = $this->commentsManager->get($comment->getParentId())) { + $formattedComment['replyTo'] = $this->formatComment($replyTo); + } + } catch (NotFoundException $e) { + } + $result[] = $formattedComment; + } + return new JSONResponse($result); + } + + private function formatComment(IComment $comment): array { + $user = $this->userManager->get($comment->getActorId()); + $actorDisplayName = $user !== null ? $user->getDisplayName() : $comment->getActorId(); + + return [ + 'id' => $comment->getId(), + 'message' => $comment->getMessage(), + 'actorId' => $comment->getActorId(), + 'actorType' => $comment->getActorType(), + 'actorDisplayName' => $actorDisplayName, + 'mentions' => array_map(function($mention) { + try { + $displayName = $this->commentsManager->resolveDisplayName($mention['type'], $mention['id']); + } catch (\OutOfBoundsException $e) { + $this->logger->logException($e); + // No displayname, upon client's discretion what to display. + $displayName = ''; + } + + return [ + 'mentionId' => $mention['id'], + 'mentionType' => $mention['type'], + 'mentionDisplayName' => $displayName + ]; + }, $comment->getMentions()), + ]; + } + + +} diff --git a/src/services/CommentApi.js b/src/services/CommentApi.js index d47f2ea5a..b115716a7 100644 --- a/src/services/CommentApi.js +++ b/src/services/CommentApi.js @@ -32,6 +32,10 @@ export class CommentApi { } async loadComments({ cardId, limit, offset }) { + const api = await axios.get(OC.generateUrl(`/apps/deck/api/v1.0/boards/0/stacks/0/cards/${cardId}/comments`), { + headers: {'OCS-APIRequest': 'true'} + }) + return api.data const response = await axios({ method: 'REPORT', url: this.url(`${cardId}`),