diff options
-rw-r--r-- | css/unified-search.scss | 23 | ||||
-rw-r--r-- | lib/AppInfo/Application.php | 5 | ||||
-rw-r--r-- | lib/Search/ConversationSearch.php | 124 | ||||
-rw-r--r-- | lib/Search/ConversationSearchResult.php | 29 | ||||
-rw-r--r-- | lib/Search/UnifiedSearchCSSLoader.php | 42 | ||||
-rw-r--r-- | src/FilesSidebarCallViewApp.vue | 4 | ||||
-rw-r--r-- | src/collections.js | 2 | ||||
-rw-r--r-- | src/mainPublicShareAuthSidebar.js | 14 | ||||
-rw-r--r-- | src/mainPublicShareSidebar.js | 8 |
9 files changed, 237 insertions, 14 deletions
diff --git a/css/unified-search.scss b/css/unified-search.scss new file mode 100644 index 000000000..7dc9bec3c --- /dev/null +++ b/css/unified-search.scss @@ -0,0 +1,23 @@ +.unified-search { + .conversation-icon { + background-color: var(--color-background-darker); + background-size: 22px !important; + + // We always want to use the white icons, this is why we don't use var(--color-white) here. + &.icon-public { + background-image: url(icon-color-path('public', 'actions', 'fff', 1, true)); + } + &.icon-contacts { + background-image: url(icon-color-path('contacts', 'places', 'fff', 1, true)); + } + &.icon-password { + background-image: url(icon-color-path('password', 'actions', 'fff', 1, true)); + } + &.icon-file { + background-image: url(icon-color-path('text', 'filetypes', 'fff', 1, true)); + } + &.icon-mail { + background-image: url(icon-color-path('mail', 'actions', 'fff', 1, true)); + } + } +} diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index ade710667..d7d3be81a 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -53,6 +53,8 @@ use OCA\Talk\PublicShare\TemplateLoader as PublicShareTemplateLoader; use OCA\Talk\PublicShareAuth\Listener as PublicShareAuthListener; use OCA\Talk\PublicShareAuth\TemplateLoader as PublicShareAuthTemplateLoader; use OCA\Talk\Room; +use OCA\Talk\Search\ConversationSearch; +use OCA\Talk\Search\UnifiedSearchCSSLoader; use OCA\Talk\Settings\Personal; use OCA\Talk\Share\Listener as ShareListener; use OCA\Talk\Share\RoomShareProvider; @@ -90,6 +92,9 @@ class Application extends App implements IBootstrap { $context->registerEventListener(BeforeUserLoggedOutEvent::class, BeforeUserLoggedOutListener::class); $context->registerEventListener(BeforeTemplateRenderedEvent::class, PublicShareTemplateLoader::class); $context->registerEventListener(BeforeTemplateRenderedEvent::class, PublicShareAuthTemplateLoader::class); + $context->registerEventListener(\OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent::class, UnifiedSearchCSSLoader::class); + + $context->registerSearchProvider(ConversationSearch::class); } public function boot(IBootContext $context): void { diff --git a/lib/Search/ConversationSearch.php b/lib/Search/ConversationSearch.php new file mode 100644 index 000000000..040e60ef1 --- /dev/null +++ b/lib/Search/ConversationSearch.php @@ -0,0 +1,124 @@ +<?php + +declare(strict_types=1); +/** + * @copyright Copyright (c) 2020 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\Talk\Search; + +use OCA\Talk\Manager; +use OCA\Talk\Room; +use OCP\IL10N; +use OCP\IURLGenerator; +use OCP\IUser; +use OCP\Search\IProvider; +use OCP\Search\ISearchQuery; +use OCP\Search\SearchResult; + +class ConversationSearch implements IProvider { + + /** @var Manager */ + protected $manager; + /** @var IURLGenerator */ + protected $url; + /** @var IL10N */ + protected $l; + + public function __construct( + Manager $manager, + IURLGenerator $url, + IL10N $l + ) { + $this->manager = $manager; + $this->url = $url; + $this->l = $l; + } + + /** + * @inheritDoc + */ + public function getId(): string { + return 'talk_conversations'; + } + + /** + * @inheritDoc + */ + public function getName(): string { + return $this->l->t('Conversations'); + } + + /** + * @inheritDoc + */ + public function search(IUser $user, ISearchQuery $query): SearchResult { + $rooms = $this->manager->getRoomsForParticipant($user->getUID()); + + $result = []; + foreach ($rooms as $room) { + if ( + $room->getType() === Room::CHANGELOG_CONVERSATION || ( + stripos($room->getName(), $query->getTerm()) === false && + stripos($room->getDisplayName($user->getUID()), $query->getTerm()) === false + ) + ) { + continue; + } + + $icon = ''; + $iconClass = ''; + if ($room->getType() === Room::ONE_TO_ONE_CALL) { + $users = $room->getParticipantUserIds(); + foreach ($users as $participantId) { + if ($participantId !== $user->getUID()) { + $icon = $this->url->linkToRouteAbsolute('core.avatar.getAvatar', [ + 'userId' => $participantId, + 'size' => 128, + ]); + } + } + } elseif ($room->getObjectType() === 'file') { + $iconClass = 'conversation-icon icon-file'; + } elseif ($room->getObjectType() === 'share:password') { + $iconClass = 'conversation-icon icon-password'; + } elseif ($room->getObjectType() === 'emails') { + $iconClass = 'conversation-icon icon-mail'; + } elseif ($room->getType() === Room::PUBLIC_CALL) { + $iconClass = 'conversation-icon icon-public'; + } else { + $iconClass = 'conversation-icon icon-contacts'; + } + + $result[] = new ConversationSearchResult( + $icon, + $room->getDisplayName($user->getUID()), + '', + $this->url->linkToRouteAbsolute('spreed.Page.showCall', ['token' => $room->getToken()]), + $iconClass, + true + ); + } + + return SearchResult::complete( + $this->l->t('Conversations'), + $result + ); + } +} diff --git a/lib/Search/ConversationSearchResult.php b/lib/Search/ConversationSearchResult.php new file mode 100644 index 000000000..86dfca62a --- /dev/null +++ b/lib/Search/ConversationSearchResult.php @@ -0,0 +1,29 @@ +<?php + +declare(strict_types=1); +/** + * @copyright Copyright (c) 2020 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\Talk\Search; + +use OCP\Search\ASearchResultEntry; + +class ConversationSearchResult extends ASearchResultEntry { +} diff --git a/lib/Search/UnifiedSearchCSSLoader.php b/lib/Search/UnifiedSearchCSSLoader.php new file mode 100644 index 000000000..ebacc7673 --- /dev/null +++ b/lib/Search/UnifiedSearchCSSLoader.php @@ -0,0 +1,42 @@ +<?php + +declare(strict_types=1); +/** + * @copyright Copyright (c) 2020 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\Talk\Search; + +use OCA\Talk\AppInfo\Application; +use OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent; +use OCP\EventDispatcher\Event; +use OCP\EventDispatcher\IEventListener; +use OCP\Util; + +class UnifiedSearchCSSLoader implements IEventListener { + public function handle(Event $event): void { + if (!$event instanceof BeforeTemplateRenderedEvent) { + return; + } + + if ($event->isLoggedIn()) { + Util::addStyle(Application::APP_ID, 'unified-search'); + } + } +} diff --git a/src/FilesSidebarCallViewApp.vue b/src/FilesSidebarCallViewApp.vue index ce874bf61..91b4ea3d6 100644 --- a/src/FilesSidebarCallViewApp.vue +++ b/src/FilesSidebarCallViewApp.vue @@ -254,7 +254,7 @@ export default { } } - header.append(this.$el) + header.appendChild(this.$el) }, /** @@ -279,7 +279,7 @@ export default { const headerAction = document.querySelector('.app-sidebar-header__action') if (headerAction) { - headerAction.append(this.$el) + headerAction.appendChild(this.$el) } }, }, diff --git a/src/collections.js b/src/collections.js index 1eb6aa3ad..8d6b9cd79 100644 --- a/src/collections.js +++ b/src/collections.js @@ -41,7 +41,7 @@ import RoomSelector from './views/RoomSelector' const container = document.createElement('div') container.id = 'spreed-room-select' const body = document.getElementById('body-user') - body.append(container) + body.appendChild(container) const ComponentVM = new Vue({ render: h => h(RoomSelector), }) diff --git a/src/mainPublicShareAuthSidebar.js b/src/mainPublicShareAuthSidebar.js index 898450f56..287fdcfa8 100644 --- a/src/mainPublicShareAuthSidebar.js +++ b/src/mainPublicShareAuthSidebar.js @@ -65,7 +65,7 @@ function wrapBody() { const bodyWrapperElement = document.createElement('div') while (bodyElement.childNodes.length) { - bodyWrapperElement.append(bodyElement.childNodes[0]) + bodyWrapperElement.appendChild(bodyElement.childNodes[0]) } while (bodyElement.classList.length) { @@ -76,24 +76,24 @@ function wrapBody() { bodyWrapperElement.setAttribute('id', bodyElement.getAttribute('id')) bodyElement.removeAttribute('id') - bodyElement.append(bodyWrapperElement) + bodyElement.appendChild(bodyWrapperElement) } function adjustLayout() { const contentElement = document.createElement('div') contentElement.setAttribute('id', 'content') - document.querySelector('body').append(contentElement) + document.querySelector('body').appendChild(contentElement) - contentElement.append(document.querySelector('.wrapper')) - contentElement.append(document.querySelector('footer')) + contentElement.appendChild(document.querySelector('.wrapper')) + contentElement.appendChild(document.querySelector('footer')) const requestPasswordElement = document.createElement('div') requestPasswordElement.setAttribute('id', 'request-password') - document.querySelector('main').append(requestPasswordElement) + document.querySelector('main').appendChild(requestPasswordElement) const talkSidebarElement = document.createElement('div') talkSidebarElement.setAttribute('id', 'talk-sidebar') - document.querySelector('body').append(talkSidebarElement) + document.querySelector('body').appendChild(talkSidebarElement) wrapBody() diff --git a/src/mainPublicShareSidebar.js b/src/mainPublicShareSidebar.js index 4b89f1fbd..4be5bea4e 100644 --- a/src/mainPublicShareSidebar.js +++ b/src/mainPublicShareSidebar.js @@ -53,11 +53,11 @@ Vue.use(Vuex) Vue.use(VueShortKey, { prevent: ['input', 'textarea', 'div'] }) function adjustLayout() { - document.querySelector('#app-content').append(document.querySelector('footer')) + document.querySelector('#app-content').appendChild(document.querySelector('footer')) const talkSidebarElement = document.createElement('div') talkSidebarElement.setAttribute('id', 'talk-sidebar') - document.querySelector('#content').append(talkSidebarElement) + document.querySelector('#content').appendChild(talkSidebarElement) } adjustLayout() @@ -88,10 +88,10 @@ function addTalkSidebarTrigger() { if (!document.querySelector('.header-right')) { const headerRightElement = document.createElement('div') headerRightElement.setAttribute('class', 'header-right') - document.querySelector('#header').append(headerRightElement) + document.querySelector('#header').appendChild(headerRightElement) } - document.querySelector('.header-right').append(talkSidebarTriggerElement) + document.querySelector('.header-right').appendChild(talkSidebarTriggerElement) } addTalkSidebarTrigger() |