diff options
author | Julien Veyssier <eneiluj@posteo.net> | 2021-08-23 22:31:03 +0200 |
---|---|---|
committer | Joas Schilling <coding@schilljs.com> | 2022-05-02 09:26:20 +0200 |
commit | afc005b71c413de170f5b83930bf64fc625bb8f2 (patch) | |
tree | c1010160929d2b02072045184af6a6e834250bce | |
parent | e80d71e83165c8d39e9b5959c373a26eab740e2e (diff) |
register share location action in Maps app
Signed-off-by: Julien Veyssier <eneiluj@posteo.net>
-rw-r--r-- | lib/AppInfo/Application.php | 2 | ||||
-rw-r--r-- | lib/Maps/MapsPluginLoader.php | 54 | ||||
-rw-r--r-- | src/maps.js | 111 | ||||
-rw-r--r-- | webpack.js | 1 |
4 files changed, 168 insertions, 0 deletions
diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index c52c766b4..67446c369 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -58,6 +58,7 @@ use OCA\Talk\Listener\GroupMembershipListener; use OCA\Talk\Listener\RestrictStartingCalls as RestrictStartingCallsListener; use OCA\Talk\Listener\UserDeletedListener; use OCA\Talk\Listener\UserDisplayNameListener; +use OCA\Talk\Maps\MapsPluginLoader; use OCA\Talk\Middleware\CanUseTalkMiddleware; use OCA\Talk\Middleware\InjectionMiddleware; use OCA\Talk\Notification\Listener as NotificationListener; @@ -124,6 +125,7 @@ class Application extends App implements IBootstrap { $context->registerEventListener(\OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent::class, UnifiedSearchCSSLoader::class); $context->registerEventListener(UserChangedEvent::class, UserDisplayNameListener::class); $context->registerEventListener(\OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent::class, DeckPluginLoader::class); + $context->registerEventListener(\OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent::class, MapsPluginLoader::class); $context->registerEventListener(RegisterOperationsEvent::class, RegisterOperationsListener::class); $context->registerEventListener(AttendeesAddedEvent::class, SystemMessageListener::class); $context->registerEventListener(AttendeesRemovedEvent::class, SystemMessageListener::class); diff --git a/lib/Maps/MapsPluginLoader.php b/lib/Maps/MapsPluginLoader.php new file mode 100644 index 000000000..2689148f8 --- /dev/null +++ b/lib/Maps/MapsPluginLoader.php @@ -0,0 +1,54 @@ +<?php + +declare(strict_types=1); +/** + * @copyright Copyright (c) 2021 Julien Veyssier <julien@nextcloud.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\Maps; + +use OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent; +use OCP\EventDispatcher\Event; +use OCP\EventDispatcher\IEventListener; +use OCP\IRequest; +use OCP\Util; + +class MapsPluginLoader implements IEventListener { + /** @var IRequest */ + private $request; + + public function __construct(IRequest $request) { + $this->request = $request; + } + + public function handle(Event $event): void { + if (!($event instanceof BeforeTemplateRenderedEvent)) { + return; + } + + if (!$event->isLoggedIn()) { + return; + } + + if (strpos($this->request->getPathInfo(), '/apps/maps') === 0) { + Util::addScript('spreed', 'talk-collections'); + Util::addScript('spreed', 'talk-maps'); + } + } +} diff --git a/src/maps.js b/src/maps.js new file mode 100644 index 000000000..16f902cda --- /dev/null +++ b/src/maps.js @@ -0,0 +1,111 @@ +/* + * @copyright Copyright (c) 2021 Julien Veyssier <julien@nextcloud.com> + * + * @author Julien Veyssier <julien@nextcloud.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/>. + * + */ + +import Vue from 'vue' +import { generateFilePath, generateUrl } from '@nextcloud/router' +import { getRequestToken } from '@nextcloud/auth' +import { translate, translatePlural } from '@nextcloud/l10n' +import { showSuccess, showError } from '@nextcloud/dialogs' +import { postRichObjectToConversation } from './services/messagesService' +import RoomSelector from './views/RoomSelector' + +(function(OC, OCA, t, n) { + async function postLocationToRoom(location, token) { + try { + const response = await postRichObjectToConversation(token, { + objectType: 'geo-location', + objectId: location.id, + metaData: JSON.stringify(location), + }) + const messageId = response.data.ocs.data.id + const targetUrl = generateUrl('/call/{token}#message_{messageId}', { token, messageId }) + showSuccess(t('spreed', 'Location has been posted to the selected <a href="{link}">conversation</a>', { + link: targetUrl, + }), { + isHTML: true, + }) + } catch (exception) { + console.error('Error posting location to conversation', exception, exception.response?.status) + if (exception.response?.status === 403) { + showError(t('spreed', 'No permission to post messages in this conversation')) + } else { + showError(t('spreed', 'An error occurred while posting location to conversation')) + } + } + } + + function init() { + if (!OCA.Maps?.registerMapsAction) { + return + } + + OCA.Maps.registerMapsAction({ + label: t('spreed', 'Share to a conversation'), + icon: 'icon-talk', + callback: (location) => { + const container = document.createElement('div') + container.id = 'spreed-post-location-to-room-select' + const body = document.getElementById('body-user') + body.appendChild(container) + + const ComponentVM = Vue.extend(RoomSelector) + const vm = new ComponentVM({ + el: container, + propsData: { + dialogTitle: t('spreed', 'Share to conversation'), + showPostableOnly: true, + }, + }) + + vm.$root.$on('close', () => { + vm.$el.remove() + vm.$destroy() + }) + vm.$root.$on('select', (token) => { + vm.$el.remove() + vm.$destroy() + + postLocationToRoom(location, token) + }) + }, + }) + } + + // CSP config for webpack dynamic chunk loading + // eslint-disable-next-line + __webpack_nonce__ = btoa(getRequestToken()) + + // Correct the root of the app for chunk loading + // OC.linkTo matches the apps folders + // OC.generateUrl ensure the index.php (or not) + // We do not want the index.php since we're loading files + // eslint-disable-next-line + __webpack_public_path__ = generateFilePath('spreed', '', 'js/') + + Vue.prototype.t = translate + Vue.prototype.n = translatePlural + Vue.prototype.OC = OC + Vue.prototype.OCA = OCA + + document.addEventListener('DOMContentLoaded', init) + +})(window.OC, window.OCA, t, n) diff --git a/webpack.js b/webpack.js index cd0189af2..f8f8015e3 100644 --- a/webpack.js +++ b/webpack.js @@ -17,6 +17,7 @@ webpackConfig.entry = { flow: path.join(__dirname, 'src', 'flow.js'), dashboard: path.join(__dirname, 'src', 'dashboard.js'), deck: path.join(__dirname, 'src', 'deck.js'), + maps: path.join(__dirname, 'src', 'maps.js'), } webpackConfig.output.assetModuleFilename = '[name][ext]?v=[contenthash]' |