Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/spreed.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJoas Schilling <coding@schilljs.com>2019-07-12 17:26:49 +0300
committerJoas Schilling <coding@schilljs.com>2019-07-30 10:33:41 +0300
commita1b17d282f5c9d886ad9320aa4178d16a153e9ea (patch)
tree1dd12245c483ca12a0925663360f94031f16cf6f /lib
parentece3c74e7cf9bbcc48ac55e8592a9e0090620b10 (diff)
Allow to reply to messages and return the parent on the message endpoints
Signed-off-by: Joas Schilling <coding@schilljs.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/Chat/ChatManager.php23
-rw-r--r--lib/Controller/ChatController.php119
2 files changed, 116 insertions, 26 deletions
diff --git a/lib/Chat/ChatManager.php b/lib/Chat/ChatManager.php
index 11a101f46..b7ce645fd 100644
--- a/lib/Chat/ChatManager.php
+++ b/lib/Chat/ChatManager.php
@@ -138,10 +138,11 @@ class ChatManager {
* @param string $actorType
* @param string $actorId
* @param string $message
+ * @param IComment|null $replyTo
* @param \DateTime $creationDateTime
* @return IComment
*/
- public function sendMessage(Room $chat, Participant $participant, string $actorType, string $actorId, string $message, \DateTime $creationDateTime): IComment {
+ public function sendMessage(Room $chat, Participant $participant, string $actorType, string $actorId, string $message, \DateTime $creationDateTime, ?IComment $replyTo): IComment {
$comment = $this->commentsManager->create($actorType, $actorId, 'chat', (string) $chat->getId());
$comment->setMessage($message, self::MAX_CHAT_LENGTH);
$comment->setCreationDateTime($creationDateTime);
@@ -149,6 +150,10 @@ class ChatManager {
// comment
$comment->setVerb('comment');
+ if ($replyTo instanceof IComment) {
+ $comment->setParentId($replyTo->getId());
+ }
+
$this->dispatcher->dispatch(self::class . '::preSendMessage', new GenericEvent($chat, [
'comment' => $comment,
'room' => $chat,
@@ -180,6 +185,22 @@ class ChatManager {
return $comment;
}
+ /**
+ * @param Room $chat
+ * @param string $parentId
+ * @return IComment
+ * @throws NotFoundException
+ */
+ public function getParentComment(Room $chat, string $parentId): IComment {
+ $comment = $this->commentsManager->get($parentId);
+
+ if ($comment->getObjectType() !== 'chat' || $comment->getObjectId() !== (string) $chat->getId()) {
+ throw new NotFoundException('Parent not found in the right context');
+ }
+
+ return $comment;
+ }
+
public function getLastReadMessageFromLegacy(Room $chat, IUser $user): int {
$marker = $this->commentsManager->getReadMark('chat', $chat->getId(), $user);
if ($marker === null) {
diff --git a/lib/Controller/ChatController.php b/lib/Controller/ChatController.php
index 155b0528f..c06d41c6c 100644
--- a/lib/Controller/ChatController.php
+++ b/lib/Controller/ChatController.php
@@ -28,6 +28,7 @@ use OCA\Spreed\Chat\AutoComplete\Sorter;
use OCA\Spreed\Chat\ChatManager;
use OCA\Spreed\Chat\MessageParser;
use OCA\Spreed\GuestManager;
+use OCA\Spreed\Model\Message;
use OCA\Spreed\Room;
use OCA\Spreed\TalkSession;
use OCP\AppFramework\Http;
@@ -37,6 +38,7 @@ use OCP\Collaboration\AutoComplete\IManager;
use OCP\Collaboration\Collaborators\ISearchResult;
use OCP\Comments\IComment;
use OCP\Comments\MessageTooLongException;
+use OCP\Comments\NotFoundException;
use OCP\IL10N;
use OCP\IRequest;
use OCP\IUserManager;
@@ -118,11 +120,12 @@ class ChatController extends AEnvironmentAwareController {
*
* @param string $message the message to send
* @param string $actorDisplayName for guests
+ * @param int $replyTo Parent id which this message is a reply to
* @return DataResponse the status code is "201 Created" if successful, and
* "404 Not found" if the room or session for a guest user was not
* found".
*/
- public function sendMessage(string $message, string $actorDisplayName = ''): DataResponse {
+ public function sendMessage(string $message, string $actorDisplayName = '', int $replyTo = 0): DataResponse {
if ($this->userId === null) {
$actorType = 'guests';
@@ -146,11 +149,21 @@ class ChatController extends AEnvironmentAwareController {
return new DataResponse([], Http::STATUS_NOT_FOUND);
}
+ $parent = $parentMessage = null;
+ if ($replyTo !== 0) {
+ try {
+ $parent = $this->chatManager->getParentComment($this->room, (string) $replyTo);
+ } catch (NotFoundException $e) {
+ // Someone is trying to reply cross-rooms or to a non-existing message
+ return new DataResponse([], Http::STATUS_BAD_REQUEST);
+ }
+ }
+
$this->room->ensureOneToOneRoomIsFilled();
$creationDateTime = $this->timeFactory->getDateTime('now', new \DateTimeZone('UTC'));
try {
- $comment = $this->chatManager->sendMessage($this->room, $this->participant, $actorType, $actorId, $message, $creationDateTime);
+ $comment = $this->chatManager->sendMessage($this->room, $this->participant, $actorType, $actorId, $message, $creationDateTime, $parent);
} catch (MessageTooLongException $e) {
return new DataResponse([], Http::STATUS_REQUEST_ENTITY_TOO_LARGE);
} catch (\Exception $e) {
@@ -164,17 +177,11 @@ class ChatController extends AEnvironmentAwareController {
return new DataResponse([], Http::STATUS_CREATED);
}
- return new DataResponse([
- 'id' => (int) $comment->getId(),
- 'token' => $this->room->getToken(),
- 'actorType' => $chatMessage->getActorType(),
- 'actorId' => $chatMessage->getActorId(),
- 'actorDisplayName' => $chatMessage->getActorDisplayName(),
- 'timestamp' => $comment->getCreationDateTime()->getTimestamp(),
- 'message' => $chatMessage->getMessage(),
- 'messageParameters' => $chatMessage->getMessageParameters(),
- 'systemMessage' => $chatMessage->getMessageType() === 'system' ? $comment->getMessage() : '',
- ], Http::STATUS_CREATED);
+ $data = $this->messageToData($chatMessage);
+ if ($parentMessage instanceof Message) {
+ $data['parent'] = $this->messageToData($parentMessage);
+ }
+ return new DataResponse($data, Http::STATUS_CREATED);
}
/**
@@ -241,28 +248,76 @@ class ChatController extends AEnvironmentAwareController {
return new DataResponse([], Http::STATUS_NOT_MODIFIED);
}
- $messages = [];
+ $i = 0;
+ $messages = $commentIdToIndex = $parentIds = [];
foreach ($comments as $comment) {
+ $id = (int) $comment->getId();
$message = $this->messageParser->createMessage($this->room, $this->participant, $comment, $this->l);
$this->messageParser->parseMessage($message);
if (!$message->getVisibility()) {
+ $commentIdToIndex[$id] = null;
continue;
}
- $messages[] = [
- 'id' => (int) $comment->getId(),
- 'token' => $this->room->getToken(),
- 'actorType' => $message->getActorType(),
- 'actorId' => $message->getActorId(),
- 'actorDisplayName' => $message->getActorDisplayName(),
- 'timestamp' => $comment->getCreationDateTime()->getTimestamp(),
- 'message' => $message->getMessage(),
- 'messageParameters' => $message->getMessageParameters(),
- 'systemMessage' => $message->getMessageType() === 'system' ? $comment->getMessage() : '',
- ];
+ if ($comment->getParentId() !== '0') {
+ $parentIds[$id] = $comment->getParentId();
+ }
+
+ $messages[] = $this->messageToData($message);
+ $commentIdToIndex[$id] = $i;
+ $i++;
}
+ /**
+ * Set the parent for reply-messages
+ */
+ $loadedParents = [];
+ foreach ($parentIds as $commentId => $parentId) {
+ $commentKey = $commentIdToIndex[$commentId];
+
+ // Parent is already parsed in the message list
+ if (!empty($commentIdToIndex[$parentId])) {
+ $parentKey = $commentIdToIndex[$parentId];
+ $messages[$commentKey]['parent'] = $messages[$parentKey];
+
+ // We don't show nested parents…
+ unset($messages[$commentKey]['parent']['parent']);
+ continue;
+ }
+
+ // Parent was already loaded manually for another comment
+ if (!empty($loadedParents[$parentId])) {
+ $messages[$commentKey]['parent'] = $loadedParents[$parentId];
+ continue;
+ }
+
+ // Parent was not skipped due to visibility, so we need to manually grab it.
+ if (!isset($commentIdToIndex[$parentId])) {
+ try {
+ $comment = $this->chatManager->getParentComment($this->room, $parentId);
+ $message = $this->messageParser->createMessage($this->room, $this->participant, $comment, $this->l);
+ $this->messageParser->parseMessage($message);
+
+ if ($message->getVisibility()) {
+ $loadedParents[$parentId] = $this->messageToData($message);
+ $messages[$commentKey]['parent'] = $loadedParents[$parentId];
+ } else {
+ $loadedParents[$parentId] = [
+ 'id' => $parentId,
+ 'deleted' => true,
+ ];
+ }
+ } catch (NotFoundException $e) {
+ }
+ }
+
+ // Message is not visible to the user
+ $messages[$commentKey]['parent'] = [
+ 'id' => $parentId,
+ 'deleted' => true,
+ ];
+ }
$response = new DataResponse($messages, Http::STATUS_OK);
@@ -277,6 +332,20 @@ class ChatController extends AEnvironmentAwareController {
return $response;
}
+ protected function messageToData(Message $message): array {
+ return [
+ 'id' => (int) $message->getComment()->getId(),
+ 'token' => $message->getRoom()->getToken(),
+ 'actorType' => $message->getActorType(),
+ 'actorId' => $message->getActorId(),
+ 'actorDisplayName' => $message->getActorDisplayName(),
+ 'timestamp' => $message->getComment()->getCreationDateTime()->getTimestamp(),
+ 'message' => $message->getMessage(),
+ 'messageParameters' => $message->getMessageParameters(),
+ 'systemMessage' => $message->getMessageType() === 'system' ? $message->getComment()->getMessage() : '',
+ ];
+ }
+
/**
* @NoAdminRequired
* @RequireParticipant