Loading lib/Controller/ViewController.php +11 −0 Original line number Diff line number Diff line Loading @@ -22,11 +22,13 @@ declare(strict_types=1); */ namespace OCA\Calendar\Controller; use OCP\App\IAppManager; use OCP\AppFramework\Controller; use OCP\AppFramework\Http\TemplateResponse; use OCP\IConfig; use OCP\IRequest; use OCP\IURLGenerator; use OCP\Notification\IApp; /** * Class ViewController Loading @@ -45,19 +47,27 @@ class ViewController extends Controller { */ private $userId; /** * @var IAppManager */ private $appManager; /** * @param string $appName * @param IRequest $request an instance of the request * @param IAppManager $appManager * @param IConfig $config * @param string $userId */ public function __construct(string $appName, IRequest $request, IConfig $config, IAppManager $appManager, string $userId) { parent::__construct($appName, $request); $this->config = $config; $this->userId = $userId; $this->appManager = $appManager; } /** Loading @@ -76,6 +86,7 @@ class ViewController extends Controller { 'show_weekends' => $this->config->getUserValue($this->userId, $this->appName, 'showWeekends', 'yes') === 'yes', 'show_week_numbers' => $this->config->getUserValue($this->userId, $this->appName, 'showWeekNr', 'no') === 'yes', 'skip_popover' => $this->config->getUserValue($this->userId, $this->appName, 'skipPopover', 'no') === 'yes', 'talk_enabled' => $this->appManager->isEnabledForUser('spreed'), 'timezone' => $this->config->getUserValue($this->userId, $this->appName, 'timezone', 'automatic'), ]); } Loading package-lock.json +2 −2 Original line number Diff line number Diff line Loading @@ -5188,7 +5188,7 @@ }, "calendar-js": { "version": "git+https://github.com/georgehrke/calendar-js.git#c1bf1a23b0422416390c58aede640f280cdc1c78", "from": "git+https://github.com/georgehrke/calendar-js.git#c1bf1a23b0422416390c58aede640f280cdc1c78", "from": "git+https://github.com/georgehrke/calendar-js.git", "requires": { "ical.js": "^1.3.0", "uuid": "^3.3.3" Loading Loading @@ -5259,7 +5259,7 @@ }, "cdav-library": { "version": "github:nextcloud/cdav-library#723e23686b20fb095a36a56ba69032c08318abfc", "from": "github:nextcloud/cdav-library#723e23686b20fb095a36a56ba69032c08318abfc", "from": "github:nextcloud/cdav-library", "requires": { "@babel/polyfill": "^7.7.0" } Loading src/components/Editor/Invitees/InviteesList.vue +55 −0 Original line number Diff line number Diff line Loading @@ -43,15 +43,23 @@ v-if="!isReadOnly && isListEmpty && hasUserEmailAddress" /> <OrganizerNoEmailError v-if="!isReadOnly && isListEmpty && !hasUserEmailAddress" /> <button v-if="isCreateTalkRoomButtonVisible" :disabled="isCreateTalkRoomButtonDisabled" @click="createTalkRoom"> {{ $t('calendar', 'Create Talk room for this event') }} </button> </div> </template> <script> import { mapState } from 'vuex' import InviteesListSearch from './InviteesListSearch' import InviteesListItem from './InviteesListItem' import OrganizerListItem from './OrganizerListItem' import NoInviteesView from './NoInviteesView.vue' import OrganizerNoEmailError from './OrganizerNoEmailError.vue' import { createTalkRoom, doesDescriptionContainTalkLink } from '../../../services/talkService.js' export default { name: 'InviteesList', Loading @@ -72,7 +80,15 @@ export default { required: true, }, }, data() { return { creatingTalkRoom: false, } }, computed: { ...mapState({ talkEnabled: state => state.settings.talkEnabled, }), inviteesWithoutOrganizer() { if (!this.calendarObjectInstance.organizer) { return this.calendarObjectInstance.attendees Loading Loading @@ -127,6 +143,20 @@ export default { return !!principal.emailAddress }, isCreateTalkRoomButtonVisible() { return this.talkEnabled }, isCreateTalkRoomButtonDisabled() { if (this.creatingTalkRoom) { return true } if (doesDescriptionContainTalkLink(this.calendarObjectInstance.description)) { return true } return false }, }, methods: { addAttendee({ commonName, email, calendarUserType, language, timezoneId }) { Loading Loading @@ -161,6 +191,31 @@ export default { attendee, }) }, async createTalkRoom() { const NEW_LINE = '\r\n' try { this.creatingTalkRoom = true const url = await createTalkRoom(this.calendarObjectInstance.title) let newDescription if (!this.calendarObjectInstance.description) { newDescription = url + NEW_LINE } else { newDescription = this.calendarObjectInstance.description + NEW_LINE + NEW_LINE + url + NEW_LINE } this.$store.commit('changeDescription', { calendarObjectInstance: this.calendarObjectInstance, description: newDescription, }) this.$toast.success(this.$t('calendar', 'Successfully appended link to talk room to description.')) } catch (error) { this.$toast.error(this.$t('calendar', 'Error creating Talk room')) } finally { this.creatingTalkRoom = false } }, }, } </script> src/services/talkService.js 0 → 100644 +75 −0 Original line number Diff line number Diff line /** * @copyright Copyright (c) 2019 Georg Ehrke * * @author Team Popcorn <teampopcornberlin@gmail.com> * @author Georg Ehrke <oc.list@georgehrke.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 HTTPClient from '@nextcloud/axios' import { translate as t } from '@nextcloud/l10n' import { generateUrl, generateOcsUrl } from '@nextcloud/router' /** * Creates a new public talk room * * @param {String?} eventTitle Title of the event * @returns {Promise<String>} */ export async function createTalkRoom(eventTitle = null) { let response try { response = await HTTPClient.post(generateOcsUrl('apps/spreed/api/v1', 2) + `room`, { roomType: 3, roomName: eventTitle || t('calendar', 'Chat room for event'), }) const conversation = response.data.ocs.data const token = conversation.token return generateURLForToken(token) } catch (error) { console.debug(error) } } /** * Checks whether the description already contains a talk link * * @param {String?} description Description of event * @returns {boolean} */ export function doesDescriptionContainTalkLink(description) { if (!description) { return false } // TODO: there is most definitely a more reliable way, // but this works for now const fakeUrl = generateURLForToken() return description.includes(fakeUrl) } /** * Generates an absolute URL to the talk room based on the token * * @param {String} token The token to the call room * @returns {string} */ function generateURLForToken(token = '') { return window.location.protocol + '//' + window.location.host + generateUrl('/call/' + token) } src/store/settings.js +2 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ const state = { showWeekends: null, showWeekNumbers: null, skipPopover: null, talkEnabled: false, timezone: null, } Loading Loading @@ -90,6 +91,7 @@ const mutations = { state.showWeekNumbers = settings.showWeekNumbers state.showWeekends = settings.showWeekends state.skipPopover = settings.skipPopover state.talkEnabled = settings.talkEnabled state.timezone = settings.timezone }, Loading Loading
lib/Controller/ViewController.php +11 −0 Original line number Diff line number Diff line Loading @@ -22,11 +22,13 @@ declare(strict_types=1); */ namespace OCA\Calendar\Controller; use OCP\App\IAppManager; use OCP\AppFramework\Controller; use OCP\AppFramework\Http\TemplateResponse; use OCP\IConfig; use OCP\IRequest; use OCP\IURLGenerator; use OCP\Notification\IApp; /** * Class ViewController Loading @@ -45,19 +47,27 @@ class ViewController extends Controller { */ private $userId; /** * @var IAppManager */ private $appManager; /** * @param string $appName * @param IRequest $request an instance of the request * @param IAppManager $appManager * @param IConfig $config * @param string $userId */ public function __construct(string $appName, IRequest $request, IConfig $config, IAppManager $appManager, string $userId) { parent::__construct($appName, $request); $this->config = $config; $this->userId = $userId; $this->appManager = $appManager; } /** Loading @@ -76,6 +86,7 @@ class ViewController extends Controller { 'show_weekends' => $this->config->getUserValue($this->userId, $this->appName, 'showWeekends', 'yes') === 'yes', 'show_week_numbers' => $this->config->getUserValue($this->userId, $this->appName, 'showWeekNr', 'no') === 'yes', 'skip_popover' => $this->config->getUserValue($this->userId, $this->appName, 'skipPopover', 'no') === 'yes', 'talk_enabled' => $this->appManager->isEnabledForUser('spreed'), 'timezone' => $this->config->getUserValue($this->userId, $this->appName, 'timezone', 'automatic'), ]); } Loading
package-lock.json +2 −2 Original line number Diff line number Diff line Loading @@ -5188,7 +5188,7 @@ }, "calendar-js": { "version": "git+https://github.com/georgehrke/calendar-js.git#c1bf1a23b0422416390c58aede640f280cdc1c78", "from": "git+https://github.com/georgehrke/calendar-js.git#c1bf1a23b0422416390c58aede640f280cdc1c78", "from": "git+https://github.com/georgehrke/calendar-js.git", "requires": { "ical.js": "^1.3.0", "uuid": "^3.3.3" Loading Loading @@ -5259,7 +5259,7 @@ }, "cdav-library": { "version": "github:nextcloud/cdav-library#723e23686b20fb095a36a56ba69032c08318abfc", "from": "github:nextcloud/cdav-library#723e23686b20fb095a36a56ba69032c08318abfc", "from": "github:nextcloud/cdav-library", "requires": { "@babel/polyfill": "^7.7.0" } Loading
src/components/Editor/Invitees/InviteesList.vue +55 −0 Original line number Diff line number Diff line Loading @@ -43,15 +43,23 @@ v-if="!isReadOnly && isListEmpty && hasUserEmailAddress" /> <OrganizerNoEmailError v-if="!isReadOnly && isListEmpty && !hasUserEmailAddress" /> <button v-if="isCreateTalkRoomButtonVisible" :disabled="isCreateTalkRoomButtonDisabled" @click="createTalkRoom"> {{ $t('calendar', 'Create Talk room for this event') }} </button> </div> </template> <script> import { mapState } from 'vuex' import InviteesListSearch from './InviteesListSearch' import InviteesListItem from './InviteesListItem' import OrganizerListItem from './OrganizerListItem' import NoInviteesView from './NoInviteesView.vue' import OrganizerNoEmailError from './OrganizerNoEmailError.vue' import { createTalkRoom, doesDescriptionContainTalkLink } from '../../../services/talkService.js' export default { name: 'InviteesList', Loading @@ -72,7 +80,15 @@ export default { required: true, }, }, data() { return { creatingTalkRoom: false, } }, computed: { ...mapState({ talkEnabled: state => state.settings.talkEnabled, }), inviteesWithoutOrganizer() { if (!this.calendarObjectInstance.organizer) { return this.calendarObjectInstance.attendees Loading Loading @@ -127,6 +143,20 @@ export default { return !!principal.emailAddress }, isCreateTalkRoomButtonVisible() { return this.talkEnabled }, isCreateTalkRoomButtonDisabled() { if (this.creatingTalkRoom) { return true } if (doesDescriptionContainTalkLink(this.calendarObjectInstance.description)) { return true } return false }, }, methods: { addAttendee({ commonName, email, calendarUserType, language, timezoneId }) { Loading Loading @@ -161,6 +191,31 @@ export default { attendee, }) }, async createTalkRoom() { const NEW_LINE = '\r\n' try { this.creatingTalkRoom = true const url = await createTalkRoom(this.calendarObjectInstance.title) let newDescription if (!this.calendarObjectInstance.description) { newDescription = url + NEW_LINE } else { newDescription = this.calendarObjectInstance.description + NEW_LINE + NEW_LINE + url + NEW_LINE } this.$store.commit('changeDescription', { calendarObjectInstance: this.calendarObjectInstance, description: newDescription, }) this.$toast.success(this.$t('calendar', 'Successfully appended link to talk room to description.')) } catch (error) { this.$toast.error(this.$t('calendar', 'Error creating Talk room')) } finally { this.creatingTalkRoom = false } }, }, } </script>
src/services/talkService.js 0 → 100644 +75 −0 Original line number Diff line number Diff line /** * @copyright Copyright (c) 2019 Georg Ehrke * * @author Team Popcorn <teampopcornberlin@gmail.com> * @author Georg Ehrke <oc.list@georgehrke.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 HTTPClient from '@nextcloud/axios' import { translate as t } from '@nextcloud/l10n' import { generateUrl, generateOcsUrl } from '@nextcloud/router' /** * Creates a new public talk room * * @param {String?} eventTitle Title of the event * @returns {Promise<String>} */ export async function createTalkRoom(eventTitle = null) { let response try { response = await HTTPClient.post(generateOcsUrl('apps/spreed/api/v1', 2) + `room`, { roomType: 3, roomName: eventTitle || t('calendar', 'Chat room for event'), }) const conversation = response.data.ocs.data const token = conversation.token return generateURLForToken(token) } catch (error) { console.debug(error) } } /** * Checks whether the description already contains a talk link * * @param {String?} description Description of event * @returns {boolean} */ export function doesDescriptionContainTalkLink(description) { if (!description) { return false } // TODO: there is most definitely a more reliable way, // but this works for now const fakeUrl = generateURLForToken() return description.includes(fakeUrl) } /** * Generates an absolute URL to the talk room based on the token * * @param {String} token The token to the call room * @returns {string} */ function generateURLForToken(token = '') { return window.location.protocol + '//' + window.location.host + generateUrl('/call/' + token) }
src/store/settings.js +2 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ const state = { showWeekends: null, showWeekNumbers: null, skipPopover: null, talkEnabled: false, timezone: null, } Loading Loading @@ -90,6 +91,7 @@ const mutations = { state.showWeekNumbers = settings.showWeekNumbers state.showWeekends = settings.showWeekends state.skipPopover = settings.skipPopover state.talkEnabled = settings.talkEnabled state.timezone = settings.timezone }, Loading