MOBILE-3873 bbb: Initial implementation of BBB
parent
09a8d8fead
commit
322285e9ff
|
@ -0,0 +1,38 @@
|
||||||
|
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
|
import { CoreSharedModule } from '@/core/shared.module';
|
||||||
|
import { AddonModBBBComponentsModule } from './components/components.module';
|
||||||
|
import { AddonModBBBIndexPage } from './pages/index/index';
|
||||||
|
|
||||||
|
const routes: Routes = [
|
||||||
|
{
|
||||||
|
path: ':courseId/:cmId',
|
||||||
|
component: AddonModBBBIndexPage,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
RouterModule.forChild(routes),
|
||||||
|
CoreSharedModule,
|
||||||
|
AddonModBBBComponentsModule,
|
||||||
|
],
|
||||||
|
declarations: [
|
||||||
|
AddonModBBBIndexPage,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class AddonModBBBLazyModule {}
|
|
@ -0,0 +1,54 @@
|
||||||
|
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { APP_INITIALIZER, NgModule, Type } from '@angular/core';
|
||||||
|
import { Routes } from '@angular/router';
|
||||||
|
import { CoreContentLinksDelegate } from '@features/contentlinks/services/contentlinks-delegate';
|
||||||
|
import { CoreCourseModuleDelegate } from '@features/course/services/module-delegate';
|
||||||
|
import { CoreMainMenuTabRoutingModule } from '@features/mainmenu/mainmenu-tab-routing.module';
|
||||||
|
import { AddonModBBBComponentsModule } from './components/components.module';
|
||||||
|
import { AddonModBBBService } from './services/bigbluebuttonbn';
|
||||||
|
import { AddonModBBBIndexLinkHandler } from './services/handlers/index-link';
|
||||||
|
import { AddonModBBBListLinkHandler } from './services/handlers/list-link';
|
||||||
|
import { AddonModBBBModuleHandler, ADDON_MOD_BBB_MAIN_MENU_PAGE_NAME } from './services/handlers/module';
|
||||||
|
|
||||||
|
export const ADDON_MOD_BBB_SERVICES: Type<unknown>[] = [
|
||||||
|
AddonModBBBService,
|
||||||
|
];
|
||||||
|
|
||||||
|
const routes: Routes = [
|
||||||
|
{
|
||||||
|
path: ADDON_MOD_BBB_MAIN_MENU_PAGE_NAME,
|
||||||
|
loadChildren: () => import('./bigbluebuttonbn-lazy.module').then(m => m.AddonModBBBLazyModule),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
CoreMainMenuTabRoutingModule.forChild(routes),
|
||||||
|
AddonModBBBComponentsModule,
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
{
|
||||||
|
provide: APP_INITIALIZER,
|
||||||
|
multi: true,
|
||||||
|
useValue: () => {
|
||||||
|
CoreCourseModuleDelegate.registerHandler(AddonModBBBModuleHandler.instance);
|
||||||
|
CoreContentLinksDelegate.registerHandler(AddonModBBBIndexLinkHandler.instance);
|
||||||
|
CoreContentLinksDelegate.registerHandler(AddonModBBBListLinkHandler.instance);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class AddonModBBBModule {}
|
|
@ -0,0 +1,34 @@
|
||||||
|
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { AddonModBBBIndexComponent } from './index/index';
|
||||||
|
import { CoreSharedModule } from '@/core/shared.module';
|
||||||
|
import { CoreCourseComponentsModule } from '@features/course/components/components.module';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [
|
||||||
|
AddonModBBBIndexComponent,
|
||||||
|
],
|
||||||
|
imports: [
|
||||||
|
CoreSharedModule,
|
||||||
|
CoreCourseComponentsModule,
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
],
|
||||||
|
exports: [
|
||||||
|
AddonModBBBIndexComponent,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class AddonModBBBComponentsModule {}
|
|
@ -0,0 +1,40 @@
|
||||||
|
<!-- Buttons to add to the header. -->
|
||||||
|
<core-navbar-buttons slot="end">
|
||||||
|
<core-context-menu>
|
||||||
|
<core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate"
|
||||||
|
[href]="externalUrl" iconAction="fas-external-link-alt">
|
||||||
|
</core-context-menu-item>
|
||||||
|
<core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate"
|
||||||
|
(action)="expandDescription()" iconAction="fas-arrow-right">
|
||||||
|
</core-context-menu-item>
|
||||||
|
<core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}"
|
||||||
|
iconAction="far-newspaper" (action)="gotoBlog()">
|
||||||
|
</core-context-menu-item>
|
||||||
|
<core-context-menu-item *ngIf="loaded && isOnline" [priority]="700" [content]="'core.refresh' | translate"
|
||||||
|
(action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
|
||||||
|
</core-context-menu-item>
|
||||||
|
<core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600"
|
||||||
|
[content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon"
|
||||||
|
[closeOnClick]="false">
|
||||||
|
</core-context-menu-item>
|
||||||
|
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)"
|
||||||
|
[iconAction]="prefetchStatusIcon" [closeOnClick]="false">
|
||||||
|
</core-context-menu-item>
|
||||||
|
</core-context-menu>
|
||||||
|
</core-navbar-buttons>
|
||||||
|
|
||||||
|
<!-- Content. -->
|
||||||
|
<core-loading [hideUntil]="loaded" class="safe-area-page">
|
||||||
|
|
||||||
|
<!-- Activity info. -->
|
||||||
|
<core-course-module-info *ngIf="showCompletion" [module]="module" [showManualCompletion]="true"
|
||||||
|
(completionChanged)="onCompletionChange()">
|
||||||
|
</core-course-module-info>
|
||||||
|
|
||||||
|
<core-course-module-description [description]="description" [component]="component" [componentId]="componentId"
|
||||||
|
contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId">
|
||||||
|
</core-course-module-description>
|
||||||
|
|
||||||
|
<!-- TODO -->
|
||||||
|
<p>TODO: BBB native content</p>
|
||||||
|
</core-loading>
|
|
@ -0,0 +1,63 @@
|
||||||
|
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { Component, OnInit, Optional } from '@angular/core';
|
||||||
|
import { CoreCourseModuleMainActivityComponent } from '@features/course/classes/main-activity-component';
|
||||||
|
import { CoreCourseContentsPage } from '@features/course/pages/contents/contents';
|
||||||
|
import { IonContent } from '@ionic/angular';
|
||||||
|
import { AddonModBBBData, AddonModBBBService } from '../../services/bigbluebuttonbn';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component that displays a Big Blue Button activity.
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'addon-mod-bbb-index',
|
||||||
|
templateUrl: 'index.html',
|
||||||
|
})
|
||||||
|
export class AddonModBBBIndexComponent extends CoreCourseModuleMainActivityComponent implements OnInit {
|
||||||
|
|
||||||
|
component = AddonModBBBService.COMPONENT;
|
||||||
|
moduleName = 'bigbluebuttonbn';
|
||||||
|
bbb?: AddonModBBBData;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
protected content?: IonContent,
|
||||||
|
@Optional() courseContentsPage?: CoreCourseContentsPage,
|
||||||
|
) {
|
||||||
|
super('AddonModBBBIndexComponent', content, courseContentsPage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
async ngOnInit(): Promise<void> {
|
||||||
|
super.ngOnInit();
|
||||||
|
|
||||||
|
await this.loadContent();
|
||||||
|
|
||||||
|
// @todo
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
protected async fetchContent(refresh: boolean = false): Promise<void> {
|
||||||
|
try {
|
||||||
|
// @todo
|
||||||
|
} finally {
|
||||||
|
this.fillContextMenu(refresh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"view_error_unable_join_student": "BeeUnable to connect to the BigBlueButton server. Please contact your Teacher or the Administrator.p"
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
<ion-header>
|
||||||
|
<ion-toolbar>
|
||||||
|
<ion-buttons slot="start">
|
||||||
|
<ion-back-button [text]="'core.back' | translate"></ion-back-button>
|
||||||
|
</ion-buttons>
|
||||||
|
<h1>
|
||||||
|
<core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId">
|
||||||
|
</core-format-text>
|
||||||
|
</h1>
|
||||||
|
<ion-buttons slot="end">
|
||||||
|
<!-- The buttons defined by the component will be added in here. -->
|
||||||
|
</ion-buttons>
|
||||||
|
</ion-toolbar>
|
||||||
|
</ion-header>
|
||||||
|
<ion-content>
|
||||||
|
<ion-refresher slot="fixed" [disabled]="!activityComponent?.loaded" (ionRefresh)="activityComponent?.doRefresh($event.target)">
|
||||||
|
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
||||||
|
</ion-refresher>
|
||||||
|
|
||||||
|
<addon-mod-bbb-index [module]="module" [courseId]="courseId" (dataRetrieved)="updateData($event)"></addon-mod-bbb-index>
|
||||||
|
</ion-content>
|
|
@ -0,0 +1,30 @@
|
||||||
|
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { Component, ViewChild } from '@angular/core';
|
||||||
|
import { CoreCourseModuleMainActivityPage } from '@features/course/classes/main-activity-page';
|
||||||
|
import { AddonModBBBIndexComponent } from '../../components/index/index';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Page that displays a Big Blue Button activity.
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'page-addon-mod-bbb-index',
|
||||||
|
templateUrl: 'index.html',
|
||||||
|
})
|
||||||
|
export class AddonModBBBIndexPage extends CoreCourseModuleMainActivityPage<AddonModBBBIndexComponent> {
|
||||||
|
|
||||||
|
@ViewChild(AddonModBBBIndexComponent) activityComponent?: AddonModBBBIndexComponent;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,351 @@
|
||||||
|
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { CoreError } from '@classes/errors/error';
|
||||||
|
import { CoreWSError } from '@classes/errors/wserror';
|
||||||
|
import { CoreSite, CoreSiteWSPreSets } from '@classes/site';
|
||||||
|
import { CoreCourseCommonModWSOptions } from '@features/course/services/course';
|
||||||
|
import { CoreCourseLogHelper } from '@features/course/services/log-helper';
|
||||||
|
import { CoreSites, CoreSitesCommonWSOptions } from '@services/sites';
|
||||||
|
import { CoreWSExternalFile, CoreWSExternalWarning } from '@services/ws';
|
||||||
|
import { makeSingleton, Translate } from '@singletons';
|
||||||
|
|
||||||
|
const ROOT_CACHE_KEY = 'AddonModBBB:';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service that provides some features for Big Blue Button activity.
|
||||||
|
*/
|
||||||
|
@Injectable({ providedIn: 'root' })
|
||||||
|
export class AddonModBBBService {
|
||||||
|
|
||||||
|
static readonly COMPONENT = 'mmaModBigBlueButtonBN';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a BBB activity.
|
||||||
|
*
|
||||||
|
* @param courseId Course ID.
|
||||||
|
* @param cmId Course module ID.
|
||||||
|
* @param options Other options.
|
||||||
|
* @return Promise resolved when the activity is retrieved.
|
||||||
|
*/
|
||||||
|
async getBBB(courseId: number, cmId: number, options: CoreSitesCommonWSOptions = {}): Promise<AddonModBBBData> {
|
||||||
|
const site = await CoreSites.getSite(options.siteId);
|
||||||
|
|
||||||
|
const params: AddonModBBBGetBigBlueButtonBNsByCoursesWSParams = {
|
||||||
|
courseids: [courseId],
|
||||||
|
};
|
||||||
|
const preSets: CoreSiteWSPreSets = {
|
||||||
|
cacheKey: this.getBBBsCacheKey(courseId),
|
||||||
|
updateFrequency: CoreSite.FREQUENCY_RARELY,
|
||||||
|
component: AddonModBBBService.COMPONENT,
|
||||||
|
...CoreSites.getReadingStrategyPreSets(options.readingStrategy), // Include reading strategy preSets.
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await site.read<AddonModBBBGetBigBlueButtonBNsByCoursesWSResponse>(
|
||||||
|
'mod_bigbluebuttonbn_get_bigbluebuttonbns_by_courses',
|
||||||
|
params,
|
||||||
|
preSets,
|
||||||
|
);
|
||||||
|
|
||||||
|
const bbb = response.bigbluebuttonbns.find((bbb) => bbb.coursemodule == cmId);
|
||||||
|
if (bbb) {
|
||||||
|
return bbb;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new CoreError(Translate.instant('core.course.modulenotfound'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get cache key for get BBB WS call.
|
||||||
|
*
|
||||||
|
* @param courseId Course ID.
|
||||||
|
* @return Cache key.
|
||||||
|
*/
|
||||||
|
protected getBBBsCacheKey(courseId: number): string {
|
||||||
|
return ROOT_CACHE_KEY + 'bbb:' + courseId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get join URL for a BBB activity.
|
||||||
|
*
|
||||||
|
* @param cmId Course module ID.
|
||||||
|
* @param groupId Group ID, 0 means that the function will determine the user group.
|
||||||
|
* @param siteId Site ID. If not defined, current site.
|
||||||
|
* @return Promise resolved with the list of messages.
|
||||||
|
*/
|
||||||
|
async getJoinUrl(
|
||||||
|
cmId: number,
|
||||||
|
groupId: number = 0,
|
||||||
|
siteId?: string,
|
||||||
|
): Promise<string> {
|
||||||
|
const site = await CoreSites.getSite(siteId);
|
||||||
|
|
||||||
|
const params: AddonModBBBGetJoinUrlWSParams = {
|
||||||
|
cmid: cmId,
|
||||||
|
groupid: groupId,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Don't use cache.
|
||||||
|
const response = await site.write<AddonModBBBGetJoinUrlWSResponse>(
|
||||||
|
'mod_bigbluebuttonbn_get_join_url',
|
||||||
|
params,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response.warnings?.length) {
|
||||||
|
throw new CoreWSError(response.warnings[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!response.join_url) {
|
||||||
|
// Shouldn't happen, if there are no warning the app should always receive the URL.
|
||||||
|
throw new CoreError(
|
||||||
|
Translate.instant('addon.mod_bigbluebuttonbn.view_error_unable_join_studentview_error_unable_join_student'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.join_url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get meeting info for a BBB activity.
|
||||||
|
*
|
||||||
|
* @param id BBB ID.
|
||||||
|
* @param groupId Group ID, 0 means that the function will determine the user group.
|
||||||
|
* @param options Other options.
|
||||||
|
* @return Promise resolved with the list of messages.
|
||||||
|
*/
|
||||||
|
async getMeetingInfo(
|
||||||
|
id: number,
|
||||||
|
groupId: number = 0,
|
||||||
|
options: CoreCourseCommonModWSOptions = {},
|
||||||
|
): Promise<AddonModBBBMeetingInfoWSResponse> {
|
||||||
|
const site = await CoreSites.getSite(options.siteId);
|
||||||
|
|
||||||
|
const params: AddonModBBBMeetingInfoWSParams = {
|
||||||
|
bigbluebuttonbnid: id,
|
||||||
|
groupid: groupId,
|
||||||
|
};
|
||||||
|
const preSets: CoreSiteWSPreSets = {
|
||||||
|
cacheKey: this.getMeetingInfoCacheKey(id, groupId),
|
||||||
|
component: AddonModBBBService.COMPONENT,
|
||||||
|
componentId: options.cmId,
|
||||||
|
...CoreSites.getReadingStrategyPreSets(options.readingStrategy), // Include reading strategy preSets.
|
||||||
|
};
|
||||||
|
|
||||||
|
return await site.read<AddonModBBBMeetingInfoWSResponse>(
|
||||||
|
'mod_bigbluebuttonbn_meeting_info',
|
||||||
|
params,
|
||||||
|
preSets,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get cache key for meeting info WS call.
|
||||||
|
*
|
||||||
|
* @param id BBB ID.
|
||||||
|
* @param groupId Group ID, 0 means that the function will determine the user group.
|
||||||
|
* @return Cache key.
|
||||||
|
*/
|
||||||
|
protected getMeetingInfoCacheKey(id: number, groupId: number = 0): string {
|
||||||
|
return this.getMeetingInfoCacheKeyPrefix(id) + groupId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get cache key prefix for meeting info WS call.
|
||||||
|
*
|
||||||
|
* @param id BBB ID.
|
||||||
|
* @return Cache key prefix.
|
||||||
|
*/
|
||||||
|
protected getMeetingInfoCacheKeyPrefix(id: number): string {
|
||||||
|
return ROOT_CACHE_KEY + 'meetingInfo:' + id + ':';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report a BBB as being viewed.
|
||||||
|
*
|
||||||
|
* @param id BBB instance ID.
|
||||||
|
* @param name Name of the BBB.
|
||||||
|
* @param siteId Site ID. If not defined, current site.
|
||||||
|
* @return Promise resolved when the WS call is successful.
|
||||||
|
*/
|
||||||
|
async logView(id: number, name?: string, siteId?: string): Promise<void> {
|
||||||
|
const params: AddonModBBBViewBigBlueButtonBNWSParams = {
|
||||||
|
bigbluebuttonbnid: id,
|
||||||
|
};
|
||||||
|
|
||||||
|
await CoreCourseLogHelper.logSingle(
|
||||||
|
'mod_bigbluebuttonbn_view_bigbluebuttonbn',
|
||||||
|
params,
|
||||||
|
AddonModBBBService.COMPONENT,
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
'bigbluebuttonbn',
|
||||||
|
{},
|
||||||
|
siteId,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidate BBBs.
|
||||||
|
*
|
||||||
|
* @param courseId Course ID.
|
||||||
|
* @param siteId Site ID. If not defined, current site.
|
||||||
|
* @return Promise resolved when the data is invalidated.
|
||||||
|
*/
|
||||||
|
async invalidateBBBs(courseId: number, siteId?: string): Promise<void> {
|
||||||
|
const site = await CoreSites.getSite(siteId);
|
||||||
|
|
||||||
|
await site.invalidateWsCacheForKey(this.getBBBsCacheKey(courseId));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidate meeting info for a certain group.
|
||||||
|
*
|
||||||
|
* @param id BBB ID.
|
||||||
|
* @param groupId Group ID, 0 means that the function will determine the user group.
|
||||||
|
* @param siteId Site ID. If not defined, current site.
|
||||||
|
* @return Promise resolved when the data is invalidated.
|
||||||
|
*/
|
||||||
|
async invalidateMeetingInfo(id: number, groupId: number = 0, siteId?: string): Promise<void> {
|
||||||
|
const site = await CoreSites.getSite(siteId);
|
||||||
|
|
||||||
|
await site.invalidateWsCacheForKey(this.getMeetingInfoCacheKey(id, groupId));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidate meeting info for all groups.
|
||||||
|
*
|
||||||
|
* @param id BBB ID.
|
||||||
|
* @param siteId Site ID. If not defined, current site.
|
||||||
|
* @return Promise resolved when the data is invalidated.
|
||||||
|
*/
|
||||||
|
async invalidateAllGroupsMeetingInfo(id: number, siteId?: string): Promise<void> {
|
||||||
|
const site = await CoreSites.getSite(siteId);
|
||||||
|
|
||||||
|
await site.invalidateWsCacheForKeyStartingWith(this.getMeetingInfoCacheKeyPrefix(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not the BBB plugin is enabled for a certain site.
|
||||||
|
*
|
||||||
|
* @param siteId Site ID. If not defined, current site.
|
||||||
|
* @return Promise resolved with true if enabled, resolved with false or rejected otherwise.
|
||||||
|
* @since 4.0, but the WebServices were backported to the plugin so it can be supported in older versions.
|
||||||
|
*/
|
||||||
|
async isPluginEnabled(siteId?: string): Promise<boolean> {
|
||||||
|
const site = await CoreSites.getSite(siteId);
|
||||||
|
|
||||||
|
return site.wsAvailable('mod_bigbluebuttonbn_meeting_info');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AddonModBBB = makeSingleton(AddonModBBBService);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Params of mod_bigbluebuttonbn_get_bigbluebuttonbns_by_courses WS.
|
||||||
|
*/
|
||||||
|
export type AddonModBBBGetBigBlueButtonBNsByCoursesWSParams = {
|
||||||
|
courseids?: number[]; // Array of course ids.
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data returned by mod_bigbluebuttonbn_get_bigbluebuttonbns_by_courses WS.
|
||||||
|
*/
|
||||||
|
export type AddonModBBBGetBigBlueButtonBNsByCoursesWSResponse = {
|
||||||
|
bigbluebuttonbns: AddonModBBBData[];
|
||||||
|
warnings?: CoreWSExternalWarning[];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BBB data returned by mod_bigbluebuttonbn_get_bigbluebuttonbns_by_courses.
|
||||||
|
*/
|
||||||
|
export type AddonModBBBData = {
|
||||||
|
id: number; // Module id.
|
||||||
|
coursemodule: number; // Course module id.
|
||||||
|
course: number; // Course id.
|
||||||
|
name: string; // Name.
|
||||||
|
intro: string; // Description.
|
||||||
|
meetingid: string; // Meeting id.
|
||||||
|
introformat?: number; // Intro format (1 = HTML, 0 = MOODLE, 2 = PLAIN or 4 = MARKDOWN).
|
||||||
|
introfiles: CoreWSExternalFile[];
|
||||||
|
timemodified: number; // Last time the instance was modified.
|
||||||
|
section: number; // Course section id.
|
||||||
|
visible: number; // Module visibility.
|
||||||
|
groupmode: number; // Group mode.
|
||||||
|
groupingid: number; // Grouping id.
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Params of mod_bigbluebuttonbn_meeting_info WS.
|
||||||
|
*/
|
||||||
|
export type AddonModBBBMeetingInfoWSParams = {
|
||||||
|
bigbluebuttonbnid: number; // Bigbluebuttonbn instance id.
|
||||||
|
groupid?: number; // Bigbluebuttonbn group id.
|
||||||
|
updatecache?: boolean; // Update cache ?.
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data returned by mod_bigbluebuttonbn_meeting_info WS.
|
||||||
|
*/
|
||||||
|
export type AddonModBBBMeetingInfoWSResponse = {
|
||||||
|
cmid: number; // CM id.
|
||||||
|
userlimit: number; // User limit.
|
||||||
|
bigbluebuttonbnid: string; // Bigbluebuttonbn instance id.
|
||||||
|
meetingid: string; // Meeting id.
|
||||||
|
openingtime?: string; // Opening time.
|
||||||
|
closingtime?: string; // Closing time.
|
||||||
|
statusrunning?: boolean; // Status running.
|
||||||
|
statusclosed?: boolean; // Status closed.
|
||||||
|
statusopen?: boolean; // Status open.
|
||||||
|
statusmessage?: string; // Status message.
|
||||||
|
startedat?: number; // Started at.
|
||||||
|
moderatorcount?: number; // Moderator count.
|
||||||
|
participantcount?: number; // Participant count.
|
||||||
|
moderatorplural?: boolean; // Several moderators ?.
|
||||||
|
participantplural?: boolean; // Several participants ?.
|
||||||
|
canjoin: boolean; // Can join.
|
||||||
|
ismoderator: boolean; // Is moderator.
|
||||||
|
presentations: {
|
||||||
|
url: string; // Presentation URL.
|
||||||
|
iconname: string; // Icon name.
|
||||||
|
icondesc: string; // Icon text.
|
||||||
|
name: string; // Presentation name.
|
||||||
|
}[];
|
||||||
|
joinurl: string; // Join URL.
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Params of mod_bigbluebuttonbn_get_join_url WS.
|
||||||
|
*/
|
||||||
|
export type AddonModBBBGetJoinUrlWSParams = {
|
||||||
|
cmid: number; // Course module id.
|
||||||
|
groupid?: number; // Bigbluebuttonbn group id.
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data returned by mod_bigbluebuttonbn_get_join_url WS.
|
||||||
|
*/
|
||||||
|
export type AddonModBBBGetJoinUrlWSResponse = {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||||
|
join_url?: string; // Can join session.
|
||||||
|
warnings?: CoreWSExternalWarning[];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Params of mod_bigbluebuttonbn_view_bigbluebuttonbn WS.
|
||||||
|
*/
|
||||||
|
export type AddonModBBBViewBigBlueButtonBNWSParams = {
|
||||||
|
bigbluebuttonbnid: number; // Bigbluebuttonbn instance id.
|
||||||
|
};
|
|
@ -0,0 +1,33 @@
|
||||||
|
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { CoreContentLinksModuleIndexHandler } from '@features/contentlinks/classes/module-index-handler';
|
||||||
|
import { makeSingleton } from '@singletons';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler to treat links to Big Blue Button activity.
|
||||||
|
*/
|
||||||
|
@Injectable({ providedIn: 'root' })
|
||||||
|
export class AddonModBBBIndexLinkHandlerService extends CoreContentLinksModuleIndexHandler {
|
||||||
|
|
||||||
|
name = 'AddonModBBBIndexLinkHandlerService';
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super('AddonModBBB', 'bigbluebuttonbn', 'bn');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AddonModBBBIndexLinkHandler = makeSingleton(AddonModBBBIndexLinkHandlerService);
|
|
@ -0,0 +1,33 @@
|
||||||
|
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { CoreContentLinksModuleListHandler } from '@features/contentlinks/classes/module-list-handler';
|
||||||
|
import { makeSingleton } from '@singletons';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler to treat links to Big Blue Button list page.
|
||||||
|
*/
|
||||||
|
@Injectable({ providedIn: 'root' })
|
||||||
|
export class AddonModBBBListLinkHandlerService extends CoreContentLinksModuleListHandler {
|
||||||
|
|
||||||
|
name = 'AddonModBBBListLinkHandler';
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super('AddonModBBB', 'bigbluebuttonbn');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AddonModBBBListLinkHandler = makeSingleton(AddonModBBBListLinkHandlerService);
|
|
@ -0,0 +1,79 @@
|
||||||
|
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { CoreConstants } from '@/core/constants';
|
||||||
|
import { Injectable, Type } from '@angular/core';
|
||||||
|
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
|
||||||
|
import { CoreCourseAnyModuleData } from '@features/course/services/course';
|
||||||
|
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
|
||||||
|
import { makeSingleton } from '@singletons';
|
||||||
|
import { AddonModBBBIndexComponent } from '../../components/index';
|
||||||
|
import { AddonModBBB } from '../bigbluebuttonbn';
|
||||||
|
|
||||||
|
export const ADDON_MOD_BBB_MAIN_MENU_PAGE_NAME = 'mod_bigbluebuttonbn';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler to support Big Blue Button activities.
|
||||||
|
*/
|
||||||
|
@Injectable({ providedIn: 'root' })
|
||||||
|
export class AddonModBBBModuleHandlerService extends CoreModuleHandlerBase implements CoreCourseModuleHandler {
|
||||||
|
|
||||||
|
name = 'AddonModBBB';
|
||||||
|
modName = 'bigbluebuttonbn';
|
||||||
|
protected pageName = ADDON_MOD_BBB_MAIN_MENU_PAGE_NAME;
|
||||||
|
|
||||||
|
supportedFeatures = {
|
||||||
|
[CoreConstants.FEATURE_GROUPS]: true,
|
||||||
|
[CoreConstants.FEATURE_GROUPINGS]: true,
|
||||||
|
[CoreConstants.FEATURE_MOD_INTRO]: true,
|
||||||
|
[CoreConstants.FEATURE_COMPLETION_TRACKS_VIEWS]: true,
|
||||||
|
[CoreConstants.FEATURE_GRADE_HAS_GRADE]: false,
|
||||||
|
[CoreConstants.FEATURE_GRADE_OUTCOMES]: true,
|
||||||
|
[CoreConstants.FEATURE_BACKUP_MOODLE2]: true,
|
||||||
|
[CoreConstants.FEATURE_SHOW_DESCRIPTION]: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
async isEnabled(): Promise<boolean> {
|
||||||
|
return AddonModBBB.isPluginEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
getData(
|
||||||
|
module: CoreCourseAnyModuleData,
|
||||||
|
courseId: number,
|
||||||
|
sectionId?: number,
|
||||||
|
forCoursePage?: boolean,
|
||||||
|
): CoreCourseModuleHandlerData {
|
||||||
|
const data = super.getData(module, courseId, sectionId, forCoursePage);
|
||||||
|
|
||||||
|
data.showDownloadButton = false;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
async getMainComponent(): Promise<Type<unknown>> {
|
||||||
|
return AddonModBBBIndexComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AddonModBBBModuleHandler = makeSingleton(AddonModBBBModuleHandlerService);
|
|
@ -15,6 +15,7 @@
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
|
|
||||||
import { AddonModAssignModule } from './assign/assign.module';
|
import { AddonModAssignModule } from './assign/assign.module';
|
||||||
|
import { AddonModBBBModule } from './bigbluebuttonbn/bigbluebuttonbn.module';
|
||||||
import { AddonModBookModule } from './book/book.module';
|
import { AddonModBookModule } from './book/book.module';
|
||||||
import { AddonModChatModule } from './chat/chat.module';
|
import { AddonModChatModule } from './chat/chat.module';
|
||||||
import { AddonModChoiceModule } from './choice/choice.module';
|
import { AddonModChoiceModule } from './choice/choice.module';
|
||||||
|
@ -40,6 +41,7 @@ import { AddonModWorkshopModule } from './workshop/workshop.module';
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
AddonModAssignModule,
|
AddonModAssignModule,
|
||||||
|
AddonModBBBModule,
|
||||||
AddonModBookModule,
|
AddonModBookModule,
|
||||||
AddonModChatModule,
|
AddonModChatModule,
|
||||||
AddonModChoiceModule,
|
AddonModChoiceModule,
|
||||||
|
|
Loading…
Reference in New Issue