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

Unverified Commit bcb7f1ad authored by Georg Ehrke's avatar Georg Ehrke Committed by GitHub
Browse files

Merge pull request #1732 from nextcloud/feature/noid/talk_integration

Allow to create talk rooms from calendar
parents 7206532b 7a8f32d1
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -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
@@ -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;
	}

	/**
@@ -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'),
		]);
	}
+2 −2
Original line number Diff line number Diff line
@@ -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"
@@ -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"
      }
+55 −0
Original line number Diff line number Diff line
@@ -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',
@@ -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
@@ -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 }) {
@@ -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>
+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)
}
+2 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ const state = {
	showWeekends: null,
	showWeekNumbers: null,
	skipPopover: null,
	talkEnabled: false,
	timezone: null,
}

@@ -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