Allow to create talk rooms from calendar
Signed-off-by: Georg Ehrke <developer@georgehrke.com>
This commit is contained in:
parent
e13c352134
commit
7a8f32d124
|
@ -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'),
|
||||
]);
|
||||
}
|
||||
|
|
|
@ -5276,7 +5276,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"
|
||||
|
@ -5347,7 +5347,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"
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
/**
|
||||
* @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)
|
||||
}
|
|
@ -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
|
||||
},
|
||||
|
||||
|
|
|
@ -289,6 +289,7 @@ export default {
|
|||
showWeekends: getConfigValueFromHiddenInput('show-weekends') === 'true',
|
||||
showWeekNumbers: getConfigValueFromHiddenInput('show-week-numbers') === 'true',
|
||||
skipPopover: getConfigValueFromHiddenInput('skip-popover') === 'true',
|
||||
talkEnabled: getConfigValueFromHiddenInput('talk-enabled') === 'true',
|
||||
timezone: getConfigValueFromHiddenInput('timezone'),
|
||||
})
|
||||
this.$store.dispatch('initializeCalendarJsConfig')
|
||||
|
|
|
@ -29,4 +29,5 @@ style('calendar', 'calendar');
|
|||
<input type="hidden" id="config-show-weekends" value="<?php p($_['show_weekends'] ? 'true' : 'false'); ?>">
|
||||
<input type="hidden" id="config-show-week-numbers" value="<?php p($_['show_week_numbers'] ? 'true' : 'false'); ?>">
|
||||
<input type="hidden" id="config-skip-popover" value="<?php p($_['skip_popover'] ? 'true' : 'false'); ?>">
|
||||
<input type="hidden" id="config-talk-enabled" value="<?php p($_['talk_enabled'] ? 'true' : 'false'); ?>">
|
||||
<input type="hidden" id="config-timezone" value="<?php p($_['timezone']); ?>">
|
||||
|
|
|
@ -22,6 +22,7 @@ declare(strict_types=1);
|
|||
*/
|
||||
namespace OCA\Calendar\Controller;
|
||||
|
||||
use OCP\App\IAppManager;
|
||||
use OCP\AppFramework\Http\TemplateResponse;
|
||||
use OCP\IConfig;
|
||||
use OCP\IRequest;
|
||||
|
@ -35,6 +36,9 @@ class ViewControllerTest extends TestCase {
|
|||
/** @var IRequest|\PHPUnit_Framework_MockObject_MockObject */
|
||||
private $request;
|
||||
|
||||
/** @var IAppManager|\PHPUnit_Framework_MockObject_MockObject */
|
||||
private $appManager;
|
||||
|
||||
/** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */
|
||||
private $config;
|
||||
|
||||
|
@ -47,11 +51,12 @@ class ViewControllerTest extends TestCase {
|
|||
protected function setUp():void {
|
||||
$this->appName = 'calendar';
|
||||
$this->request = $this->createMock(IRequest::class);
|
||||
$this->appManager = $this->createMock(IAppManager::class);
|
||||
$this->config = $this->createMock(IConfig::class);
|
||||
$this->userId = 'user123';
|
||||
|
||||
$this->controller = new ViewController($this->appName, $this->request,
|
||||
$this->config, $this->userId);
|
||||
$this->config, $this->appManager, $this->userId);
|
||||
}
|
||||
|
||||
public function testIndex():void {
|
||||
|
@ -83,6 +88,10 @@ class ViewControllerTest extends TestCase {
|
|||
->method('getUserValue')
|
||||
->with('user123', 'calendar', 'timezone', 'automatic')
|
||||
->willReturn('Europe/Berlin');
|
||||
$this->appManager->expects($this->at(0))
|
||||
->method('isEnabledForUser')
|
||||
->with('spreed')
|
||||
->willReturn(true);
|
||||
|
||||
$response = $this->controller->index();
|
||||
|
||||
|
@ -94,6 +103,7 @@ class ViewControllerTest extends TestCase {
|
|||
'show_weekends' => true,
|
||||
'show_week_numbers' => true,
|
||||
'skip_popover' => true,
|
||||
'talk_enabled' => true,
|
||||
'timezone' => 'Europe/Berlin',
|
||||
], $response->getParams());
|
||||
$this->assertEquals('user', $response->getRenderAs());
|
||||
|
|
Loading…
Reference in New Issue