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
diff options
context:
space:
mode:
authorJoas Schilling <coding@schilljs.com>2018-04-25 14:01:29 +0300
committerJoas Schilling <coding@schilljs.com>2018-04-26 16:23:38 +0300
commitc761676e96974d3f9b3268294e1bf55f685fc216 (patch)
treed1dfaf1ba062174528139ec70839f5a9127c4af7
parentc4bd6092eabe40ec74f6d67bc44d3f5345f8e66b (diff)
Start autocomplete for mentions
Signed-off-by: Joas Schilling <coding@schilljs.com>
-rw-r--r--appinfo/routes.php9
-rw-r--r--lib/Chat/AutoComplete/SearchPlugin.php127
-rw-r--r--lib/Chat/AutoComplete/Sorter.php47
-rw-r--r--lib/Controller/ChatController.php75
4 files changed, 257 insertions, 1 deletions
diff --git a/appinfo/routes.php b/appinfo/routes.php
index f93bbb1a2..86ca86b23 100644
--- a/appinfo/routes.php
+++ b/appinfo/routes.php
@@ -129,6 +129,15 @@ return [
'token' => '^[a-z0-9]{4,30}$',
],
],
+ [
+ 'name' => 'Chat#autoComplete',
+ 'url' => '/api/{apiVersion}/chat/{token}/autocomplete',
+ 'verb' => 'GET',
+ 'requirements' => [
+ 'apiVersion' => 'v1',
+ 'token' => '^[a-z0-9]{4,30}$',
+ ],
+ ],
/**
* Room
diff --git a/lib/Chat/AutoComplete/SearchPlugin.php b/lib/Chat/AutoComplete/SearchPlugin.php
new file mode 100644
index 000000000..a6e99cf66
--- /dev/null
+++ b/lib/Chat/AutoComplete/SearchPlugin.php
@@ -0,0 +1,127 @@
+<?php
+/**
+ * @copyright Copyright (c) 2018 Joas Schilling <coding@schilljs.com>
+ *
+ * @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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\Spreed\Chat\AutoComplete;
+
+
+use OCA\Spreed\Room;
+use OCP\Collaboration\Collaborators\ISearchPlugin;
+use OCP\Collaboration\Collaborators\ISearchResult;
+use OCP\Collaboration\Collaborators\SearchResultType;
+use OCP\IUser;
+use OCP\IUserManager;
+
+class SearchPlugin implements ISearchPlugin {
+
+ /** @var IUserManager */
+ protected $userManager;
+
+ public function __construct(IUserManager $userManager) {
+ $this->userManager = $userManager;
+ }
+
+ /** @var Room */
+ protected $room;
+
+ public function setContext(array $context) {
+ $this->room = $context['room'];
+ }
+
+ /**
+ * @param string $search
+ * @param int $limit
+ * @param int $offset
+ * @param ISearchResult $searchResult
+ * @return bool whether the plugin has more results
+ * @since 13.0.0
+ */
+ public function search($search, $limit, $offset, ISearchResult $searchResult) {
+
+ $participants = $this->room->getParticipants();
+
+ $this->searchUsers($search, array_map('strval', array_keys($participants['users'])), $searchResult);
+
+ // FIXME Handle guests
+
+ return false;
+ }
+
+ protected function searchUsers($search, array $userIds, ISearchResult $searchResult) {
+ $matches = $exactMatches = [];
+ foreach ($userIds as $userId) {
+ if ($search === '') {
+ $matches[] = $this->createResult('user', $userId, '');
+ continue;
+ }
+
+ if ($userId === $search) {
+ $exactMatches[] = $this->createResult('user', $userId, '');
+ continue;
+ }
+
+ if (strpos($userId, $search) !== false) {
+ $matches[] = $this->createResult('user', $userId, '');
+ continue;
+ }
+
+ $user = $this->userManager->get($userId);
+ if (!$user instanceof IUser) {
+ continue;
+ }
+
+ if ($user->getDisplayName() === $search) {
+ $exactMatches[] = $this->createResult('user', $user->getUID(), $user->getDisplayName());
+ continue;
+ }
+
+ if (strpos($user->getDisplayName(), $search) !== false) {
+ $matches[] = $this->createResult('user', $user->getUID(), $user->getDisplayName());
+ continue;
+ }
+ }
+
+ $type = new SearchResultType('users');
+ $searchResult->addResultSet($type, $matches, $exactMatches);
+ }
+
+ /**
+ * @param string $type
+ * @param string $uid
+ * @param string $name
+ * @return array
+ */
+ public function createResult($type, $uid, $name) {
+ if ($type === 'user' && $name === '') {
+ $user = $this->userManager->get($uid);
+ if ($user instanceof IUser) {
+ $name = $user->getDisplayName();
+ }
+ }
+
+ return [
+ 'label' => $name,
+ 'value' => [
+ 'shareType' => $type,
+ 'shareWith' => $uid,
+ ],
+ ];
+ }
+}
diff --git a/lib/Chat/AutoComplete/Sorter.php b/lib/Chat/AutoComplete/Sorter.php
new file mode 100644
index 000000000..7514f4db4
--- /dev/null
+++ b/lib/Chat/AutoComplete/Sorter.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * @copyright Copyright (c) 2018 Joas Schilling <coding@schilljs.com>
+ *
+ * @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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\Spreed\Chat\AutoComplete;
+
+
+use OCP\Collaboration\AutoComplete\ISorter;
+
+class Sorter implements ISorter {
+
+ /**
+ * @return string The ID of the sorter, e.g. commenters
+ * @since 13.0.0
+ */
+ public function getId() {
+ return 'talk_chat_participants';
+ }
+
+ /**
+ * executes the sort action
+ *
+ * @param array $sortArray the array to be sorted, provided as reference
+ * @param array $context carries key 'itemType' and 'itemId' of the source object (e.g. a file)
+ * @since 13.0.0
+ */
+ public function sort(array &$sortArray, array $context) {
+ // TODO: Implement sort() method.
+ }
+}
diff --git a/lib/Controller/ChatController.php b/lib/Controller/ChatController.php
index 81a24116d..48f10299b 100644
--- a/lib/Controller/ChatController.php
+++ b/lib/Controller/ChatController.php
@@ -23,6 +23,8 @@
namespace OCA\Spreed\Controller;
+use OC\Collaboration\Collaborators\SearchResult;
+use OCA\Spreed\Chat\AutoComplete\SearchPlugin;
use OCA\Spreed\Chat\ChatManager;
use OCA\Spreed\Chat\RichMessageHelper;
use OCA\Spreed\Exceptions\ParticipantNotFoundException;
@@ -34,6 +36,8 @@ use OCA\Spreed\TalkSession;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\OCSController;
+use OCP\Collaboration\AutoComplete\IManager;
+use OCP\Collaboration\Collaborators\ISearchResult;
use OCP\Comments\IComment;
use OCP\IRequest;
use OCP\IUser;
@@ -68,6 +72,15 @@ class ChatController extends OCSController {
/** @var RichMessageHelper */
private $richMessageHelper;
+ /** @var IManager */
+ private $autoCompleteManager;
+
+ /** @var SearchPlugin */
+ private $searchPlugin;
+
+ /** @var ISearchResult */
+ private $searchResult;
+
/**
* @param string $appName
* @param string $UserId
@@ -77,6 +90,10 @@ class ChatController extends OCSController {
* @param Manager $manager
* @param ChatManager $chatManager
* @param GuestManager $guestManager
+ * @param RichMessageHelper $richMessageHelper
+ * @param IManager $autoCompleteManager
+ * @param SearchPlugin $searchPlugin
+ * @param SearchResult $searchResult
*/
public function __construct($appName,
$UserId,
@@ -86,7 +103,10 @@ class ChatController extends OCSController {
Manager $manager,
ChatManager $chatManager,
GuestManager $guestManager,
- RichMessageHelper $richMessageHelper) {
+ RichMessageHelper $richMessageHelper,
+ IManager $autoCompleteManager,
+ SearchPlugin $searchPlugin,
+ SearchResult $searchResult) {
parent::__construct($appName, $request);
$this->userId = $UserId;
@@ -96,6 +116,9 @@ class ChatController extends OCSController {
$this->chatManager = $chatManager;
$this->guestManager = $guestManager;
$this->richMessageHelper = $richMessageHelper;
+ $this->autoCompleteManager = $autoCompleteManager;
+ $this->searchPlugin = $searchPlugin;
+ $this->searchResult = $searchResult;
}
/**
@@ -274,4 +297,54 @@ class ChatController extends OCSController {
return $response;
}
+
+ /**
+ * @PublicPage
+ *
+ * @param string $token the room token
+ * @param string $search
+ * @param int $limit
+ * @return DataResponse
+ */
+ public function autoComplete($token, $search, $limit = 20) {
+ $room = $this->getRoom($token);
+ if ($room === null) {
+ return new DataResponse([], Http::STATUS_NOT_FOUND);
+ }
+
+ $this->searchPlugin->setContext([
+ 'itemType' => 'chat',
+ 'itemId' => $room->getId(),
+ 'room' => $room,
+ ]);
+ $this->searchPlugin->search((string) $search, $limit, 0, $this->searchResult);
+
+ $results = $this->searchResult->asArray();
+ $exactMatches = $results['exact'];
+ unset($results['exact']);
+ $results = array_merge_recursive($exactMatches, $results);
+
+ $this->autoCompleteManager->runSorters(['talk_chat_participants'], $results, [
+ 'itemType' => 'chat',
+ 'itemId' => $room->getId(),
+ ]);
+
+ $results = $this->prepareResultArray($results);
+ return new DataResponse($results);
+ }
+
+
+ protected function prepareResultArray(array $results) {
+ $output = [];
+ foreach ($results as $type => $subResult) {
+ foreach ($subResult as $result) {
+ $output[] = [
+ 'id' => $result['value']['shareWith'],
+ 'label' => $result['label'],
+ 'source' => $type,
+ ];
+ }
+ }
+ return $output;
+ }
}