Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 48184df1 authored by Jakob Röhrl's avatar Jakob Röhrl
Browse files

Create event from Talk message

parent 2d5f39be
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -24,10 +24,12 @@ declare(strict_types=1);
namespace OCA\Calendar\AppInfo;

use OCA\Calendar\Dashboard\CalendarWidget;
use OCA\Calendar\Listeners\BeforeTemplateRenderedListener;
use OCP\AppFramework\App;
use OCP\AppFramework\Bootstrap\IBootContext;
use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\Bootstrap\IRegistrationContext;
use OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent;

/**
 * Class Application
@@ -51,6 +53,7 @@ class Application extends App implements IBootstrap {
	 */
	public function register(IRegistrationContext $context): void {
		$context->registerDashboardWidget(CalendarWidget::class);
		$context->registerEventListener(BeforeTemplateRenderedEvent::class, BeforeTemplateRenderedListener::class);
	}

	/**
+57 −0
Original line number Diff line number Diff line
<?php
/**
 * @copyright Copyright (c) 2021 Jakob Röhrl <jakob.roehrl@web.de>
 *
 * @author Julius Härtl <jus@bitgrid.net>
 * @author Jakob Röhrl <jakob.roehrl@web.de>
 *
 * @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/>.
 *
 */

declare(strict_types=1);


namespace OCA\Calendar\Listeners;

use OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
use OCP\IRequest;
use OCP\Util;

class BeforeTemplateRenderedListener implements IEventListener {
	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;
		}

		$pathInfo = $this->request->getPathInfo();
		if (strpos($pathInfo, '/call/') === 0 || strpos($pathInfo, '/apps/spreed') === 0) {
			Util::addScript('calendar', 'talk');
		}
	}
}
 No newline at end of file
+135 −0
Original line number Diff line number Diff line
<!--
  - @copyright Copyright (c) 2021 Jakob Röhrl <jakob.roehrl@web.de>
  -
  - @author Julius Härtl <jus@bitgrid.net>
  - @author Jakob Röhrl <jakob.roehrl@web.de>
  -
  - @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/>.
  -
  -->

<template>
	<Modal class="card-selector" @close="close">
		<div class="modal-scroller">
			<div v-if="!creating && !created" id="modal-inner" :class="{ 'icon-loading': loading }">
				<h3>{{ t('calender', 'Create a new event') }}</h3>
			</div>
		</div>
	</Modal>
</template>

<script>

import Modal from '@nextcloud/vue/dist/Components/Modal'
// import Multiselect from '@nextcloud/vue/dist/Components/Multiselect'
// import EmptyContent from '@nextcloud/vue/dist/Components/EmptyContent'

export default {
	name: 'EventCreateDialog',
	components: {
		// EmptyContent,
		Modal,
		// Multiselect,
	},
	props: {
		title: {
			type: String,
			default: '',
		},
		description: {
			type: String,
			default: '',
		},
		action: {
			type: String,
			default: t('calender', 'Create event'),
		},
	},
	data() {
		return {

		}
	},

	methods: {

		close() {
			this.$root.$emit('close')
		},

	},

}
</script>

<style lang="scss" scoped>
	.modal-scroller {
		overflow: scroll;
		max-height: calc(80vh - 40px);
		margin: 10px;
	}

	#modal-inner {
		width: 90vw;
		max-width: 400px;
		padding: 10px;
		min-height: 200px;
	}

	.multiselect-board, .multiselect-list, input, textarea {
		width: 100%;
		margin-bottom: 10px !important;
	}

	ul {
		min-height: 100px;
	}

	li {
		padding: 6px;
		border: 1px solid transparent;
	}

	li:hover, li:focus {
		background-color: var(--color-background-dark);
	}

	.board-bullet {
		display: inline-block;
		width: 12px;
		height: 12px;
		border: none;
		border-radius: 50%;
		cursor: pointer;
	}

	.modal-buttons {
		display: flex;
		justify-content: flex-end;
	}

	.card-selector::v-deep .modal-container {
		overflow: visible !important;
	}

	.empty-content {
		margin-top: 5vh !important;

		&::v-deep h2 {
			margin-bottom: 5vh;
		}
	}
</style>
+48 −0
Original line number Diff line number Diff line
/*
 * @copyright Copyright (c) 2021 Jakob Röhrl <jakob.roehrl@web.de>
 *
 * @author Julius Härtl <jus@bitgrid.net>
 * @author Jakob Röhrl <jakob.roehrl@web.de>
 *
 * @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'

const buildSelector = (selector, propsData = {}) => {
	return new Promise((resolve, reject) => {
		const container = document.createElement('div')
		document.getElementById('body-user').append(container)
		const View = Vue.extend(selector)
		const ComponentVM = new View({
			propsData,
		}).$mount(container)
		ComponentVM.$root.$on('close', () => {
			ComponentVM.$el.remove()
			ComponentVM.$destroy()
			reject(new Error('Selection canceled'))
		})
		ComponentVM.$root.$on('select', (id) => {
			ComponentVM.$el.remove()
			ComponentVM.$destroy()
			resolve(id)
		})
	})
}

export {
	buildSelector,
}

src/talk.js

0 → 100644
+66 −0
Original line number Diff line number Diff line
/*
 * @copyright Copyright (c) 2021 Jakob Röhrl <jakob.roehrl@web.de>
 *
 * @author Julius Härtl <jus@bitgrid.net>
 * @author Jakob Röhrl <jakob.roehrl@web.de>
 *
 * @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 EventCreateDialog from './components/EventCreateDialog'
import { buildSelector } from './helpers/selector'

import { getRequestToken } from '@nextcloud/auth'
import { translate, translatePlural } from '@nextcloud/l10n'
import { generateUrl, generateFilePath } from '@nextcloud/router'

import Vue from 'vue'

// eslint-disable-next-line
__webpack_nonce__ = btoa(getRequestToken())

// eslint-disable-next-line
__webpack_public_path__ = generateFilePath('calendar', '', 'js/')

Vue.prototype.t = translate
Vue.prototype.n = translatePlural
Vue.prototype.OC = OC

window.addEventListener('DOMContentLoaded', () => {
	if (!window.OCA?.Talk?.registerMessageAction) {
		return
	}

	window.OCA.Talk.registerMessageAction({
		label: t('calendar', 'Create an event'),
		icon: 'icon-calendar-dark',
		async callback({ message: { message, actorDisplayName }, metadata: { name: conversationName, token: conversationToken } }) {
			const shortenedMessageCandidate = message.replace(/^(.{255}[^\s]*).*/, '$1')
			const shortenedMessage = shortenedMessageCandidate === '' ? message.substr(0, 255) : shortenedMessageCandidate
			try {
				await buildSelector(EventCreateDialog, {
					title: shortenedMessage,
					description: message + '\n\n' + '['
						+ t('calendar', 'Message from {author} in {conversationName}', { author: actorDisplayName, conversationName })
						+ '](' + generateUrl('/call/' + conversationToken) + ')',
				})
			} catch (e) {
				console.debug('Event creation dialog was canceled')
			}
		},
	})
})
Loading