MOBILE-4100 bbb: Display recordings
parent
ffb247c9ac
commit
6e1677a757
|
@ -458,10 +458,14 @@
|
||||||
"addon.mod_bigbluebuttonbn.view_message_conference_room_ready": "bigbluebuttonbn",
|
"addon.mod_bigbluebuttonbn.view_message_conference_room_ready": "bigbluebuttonbn",
|
||||||
"addon.mod_bigbluebuttonbn.view_message_moderator": "bigbluebuttonbn",
|
"addon.mod_bigbluebuttonbn.view_message_moderator": "bigbluebuttonbn",
|
||||||
"addon.mod_bigbluebuttonbn.view_message_moderators": "bigbluebuttonbn",
|
"addon.mod_bigbluebuttonbn.view_message_moderators": "bigbluebuttonbn",
|
||||||
|
"addon.mod_bigbluebuttonbn.view_message_norecordings": "bigbluebuttonbn",
|
||||||
"addon.mod_bigbluebuttonbn.view_message_session_started_at": "bigbluebuttonbn",
|
"addon.mod_bigbluebuttonbn.view_message_session_started_at": "bigbluebuttonbn",
|
||||||
"addon.mod_bigbluebuttonbn.view_message_viewer": "bigbluebuttonbn",
|
"addon.mod_bigbluebuttonbn.view_message_viewer": "bigbluebuttonbn",
|
||||||
"addon.mod_bigbluebuttonbn.view_message_viewers": "bigbluebuttonbn",
|
"addon.mod_bigbluebuttonbn.view_message_viewers": "bigbluebuttonbn",
|
||||||
"addon.mod_bigbluebuttonbn.view_nojoin": "bigbluebuttonbn",
|
"addon.mod_bigbluebuttonbn.view_nojoin": "bigbluebuttonbn",
|
||||||
|
"addon.mod_bigbluebuttonbn.view_recording_format_presentation": "bigbluebuttonbn",
|
||||||
|
"addon.mod_bigbluebuttonbn.view_recording_list_action_play": "bigbluebuttonbn",
|
||||||
|
"addon.mod_bigbluebuttonbn.view_section_title_recordings": "bigbluebuttonbn",
|
||||||
"addon.mod_book.errorchapter": "book",
|
"addon.mod_book.errorchapter": "book",
|
||||||
"addon.mod_book.modulenameplural": "book",
|
"addon.mod_book.modulenameplural": "book",
|
||||||
"addon.mod_book.navnexttitle": "book",
|
"addon.mod_book.navnexttitle": "book",
|
||||||
|
|
|
@ -83,6 +83,46 @@
|
||||||
</ion-card>
|
</ion-card>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container *ngIf="showRecordings && recordings">
|
||||||
|
<ion-item class="ion-text-wrap">
|
||||||
|
<ion-label>
|
||||||
|
<h2>{{ 'addon.mod_bigbluebuttonbn.view_section_title_recordings' | translate }}</h2>
|
||||||
|
</ion-label>
|
||||||
|
</ion-item>
|
||||||
|
<ng-container *ngFor="let recording of recordings">
|
||||||
|
<ion-item *ngIf="recording.url" button class="addon-mod_bbb-recording-title" [attr.aria-expanded]="recording.expanded"
|
||||||
|
(click)="toggle(recording)" [attr.aria-label]="(recording.expanded ? 'core.collapse' : 'core.expand') | translate">
|
||||||
|
<ion-icon name="fas-chevron-right" flip-rtl slot="start" aria-hidden="true" class="expandable-status-icon"
|
||||||
|
[class.expandable-status-icon-expanded]="recording.expanded">
|
||||||
|
</ion-icon>
|
||||||
|
<ion-label>
|
||||||
|
<p>{{ recording.type }}</p>
|
||||||
|
<p>{{ recording.name }}</p>
|
||||||
|
</ion-label>
|
||||||
|
<ion-button slot="end" fill="clear" (click)="playRecording($event, recording)"
|
||||||
|
[attr.aria-label]="'addon.mod_bigbluebuttonbn.view_recording_list_action_play' | translate">
|
||||||
|
<ion-icon name="fas-play-circle" slot="icon-only" aria-hidden="true"></ion-icon>
|
||||||
|
</ion-button>
|
||||||
|
</ion-item>
|
||||||
|
<div [hidden]="!recording.expanded" class="addon-mod_bbb-recording-details">
|
||||||
|
<ion-item *ngFor="let data of recording.details" class="ion-text-wrap">
|
||||||
|
<ion-label>
|
||||||
|
<h2>{{ data.label }}</h2>
|
||||||
|
<p *ngIf="data.allowHTML">
|
||||||
|
<core-format-text [text]="data.value" [component]="component" [componentId]="module.id" contextLevel="module"
|
||||||
|
[contextInstanceId]="module.id" [courseId]="module.course"></core-format-text>
|
||||||
|
</p>
|
||||||
|
<p *ngIf="!data.allowHTML">{{ data.value }}</p>
|
||||||
|
</ion-label>
|
||||||
|
</ion-item>
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<core-empty-box *ngIf="recordings && !recordings.length" icon="far-file-video"
|
||||||
|
[message]="'addon.mod_bigbluebuttonbn.view_message_norecordings' | translate">
|
||||||
|
</core-empty-box>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<div collapsible-footer *ngIf="!showLoading" slot="fixed">
|
<div collapsible-footer *ngIf="!showLoading" slot="fixed">
|
||||||
<div class="list-item-limited-width adaptable-buttons-row"
|
<div class="list-item-limited-width adaptable-buttons-row"
|
||||||
*ngIf="meetingInfo && showRoom && (meetingInfo.canjoin || (meetingInfo.statusrunning && meetingInfo.ismoderator))">
|
*ngIf="meetingInfo && showRoom && (meetingInfo.canjoin || (meetingInfo.statusrunning && meetingInfo.ismoderator))">
|
||||||
|
|
|
@ -1,3 +1,26 @@
|
||||||
|
:host {
|
||||||
|
--recording-details-background: var(--gray-100);
|
||||||
|
--recording-details-border: var(--gray-500);
|
||||||
|
|
||||||
ion-item > p[slot="end"] {
|
ion-item > p[slot="end"] {
|
||||||
font-size: var(--text-size);
|
font-size: var(--text-size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
core-empty-box ::ng-deep p {
|
||||||
|
font-size: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.addon-mod_bbb-recording-details {
|
||||||
|
border-top: 2px solid var(--recording-details-border);
|
||||||
|
border-bottom: 2px solid var(--recording-details-border);
|
||||||
|
|
||||||
|
ion-item {
|
||||||
|
--background: var(--recording-details-background);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:host-context(html.dark) {
|
||||||
|
--recording-details-background: var(--gray-800);
|
||||||
|
--recording-details-border: var(--gray-500);
|
||||||
|
}
|
||||||
|
|
|
@ -19,7 +19,10 @@ import { CoreCourseContentsPage } from '@features/course/pages/contents/contents
|
||||||
import { IonContent } from '@ionic/angular';
|
import { IonContent } from '@ionic/angular';
|
||||||
import { CoreApp } from '@services/app';
|
import { CoreApp } from '@services/app';
|
||||||
import { CoreGroupInfo, CoreGroups } from '@services/groups';
|
import { CoreGroupInfo, CoreGroups } from '@services/groups';
|
||||||
|
import { CoreSites } from '@services/sites';
|
||||||
import { CoreDomUtils } from '@services/utils/dom';
|
import { CoreDomUtils } from '@services/utils/dom';
|
||||||
|
import { CoreTextUtils } from '@services/utils/text';
|
||||||
|
import { CoreTimeUtils } from '@services/utils/time';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
import { CoreUtils } from '@services/utils/utils';
|
||||||
import { Translate } from '@singletons';
|
import { Translate } from '@singletons';
|
||||||
import { AddonModBBB, AddonModBBBData, AddonModBBBMeetingInfo, AddonModBBBService } from '../../services/bigbluebuttonbn';
|
import { AddonModBBB, AddonModBBBData, AddonModBBBMeetingInfo, AddonModBBBService } from '../../services/bigbluebuttonbn';
|
||||||
|
@ -40,6 +43,7 @@ export class AddonModBBBIndexComponent extends CoreCourseModuleMainActivityCompo
|
||||||
groupInfo?: CoreGroupInfo;
|
groupInfo?: CoreGroupInfo;
|
||||||
groupId = 0;
|
groupId = 0;
|
||||||
meetingInfo?: AddonModBBBMeetingInfo;
|
meetingInfo?: AddonModBBBMeetingInfo;
|
||||||
|
recordings?: RecordingData[];
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
protected content?: IonContent,
|
protected content?: IonContent,
|
||||||
|
@ -61,6 +65,10 @@ export class AddonModBBBIndexComponent extends CoreCourseModuleMainActivityCompo
|
||||||
return !!this.meetingInfo && (!this.meetingInfo.features || this.meetingInfo.features.showroom);
|
return !!this.meetingInfo && (!this.meetingInfo.features || this.meetingInfo.features.showroom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get showRecordings(): boolean {
|
||||||
|
return !!this.meetingInfo && (!this.meetingInfo.features || this.meetingInfo.features.showrecordings);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
|
@ -79,6 +87,8 @@ export class AddonModBBBIndexComponent extends CoreCourseModuleMainActivityCompo
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.fetchMeetingInfo();
|
await this.fetchMeetingInfo();
|
||||||
|
|
||||||
|
await this.fetchRecordings();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -113,6 +123,72 @@ export class AddonModBBBIndexComponent extends CoreCourseModuleMainActivityCompo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get recordings.
|
||||||
|
*
|
||||||
|
* @return Promise resolved when done.
|
||||||
|
*/
|
||||||
|
async fetchRecordings(): Promise<void> {
|
||||||
|
if (!this.bbb || !this.showRecordings) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const recordingsTable = await AddonModBBB.getRecordings(this.bbb.id, this.groupId, {
|
||||||
|
cmId: this.module.id,
|
||||||
|
});
|
||||||
|
const columns = CoreUtils.arrayToObject(recordingsTable.columns, 'key');
|
||||||
|
|
||||||
|
this.recordings = recordingsTable.parsedData.map(recordingData => {
|
||||||
|
const playbackEl = CoreDomUtils.convertToElement(String(recordingData.playback));
|
||||||
|
const playbackAnchor = playbackEl.querySelector('a');
|
||||||
|
const details: RecordingDetailData[] = [];
|
||||||
|
|
||||||
|
Object.entries(recordingData).forEach(([key, value]) => {
|
||||||
|
const columnData = columns[key];
|
||||||
|
if (!columnData || value === '' || key === 'actionbar') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (columnData.formatter === 'customDate' && !isNaN(Number(value))) {
|
||||||
|
value = CoreTimeUtils.userDate(Number(value), 'core.strftimedaydate');
|
||||||
|
} else if (columnData.allowHTML && typeof value === 'string') {
|
||||||
|
// If the HTML is empty, don't display it.
|
||||||
|
const valueElement = CoreDomUtils.convertToElement(value);
|
||||||
|
if (!valueElement.querySelector('img') && (valueElement.textContent ?? '').trim() === '') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key === 'playback') {
|
||||||
|
// Remove HTML, we're only interested in the text.
|
||||||
|
value = (valueElement.textContent ?? '').trim();
|
||||||
|
} else {
|
||||||
|
// Treat "quick edit" buttons, they aren't supported in the app.
|
||||||
|
const quickEditLink = valueElement.querySelector('.quickeditlink');
|
||||||
|
if (quickEditLink) {
|
||||||
|
// The first span in quick edit link contains the actual HTML, use it.
|
||||||
|
value = (quickEditLink.querySelector('span')?.innerHTML ?? '').trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
details.push({
|
||||||
|
label: columnData.label,
|
||||||
|
value: String(value),
|
||||||
|
allowHTML: !!columnData.allowHTML,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: playbackAnchor?.innerText ??
|
||||||
|
Translate.instant('addon.mod_bigbluebuttonbn.view_recording_format_presentation'),
|
||||||
|
name: CoreTextUtils.cleanTags(String(recordingData.recording), true),
|
||||||
|
url: playbackAnchor?.href ?? '',
|
||||||
|
details,
|
||||||
|
expanded: false,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
|
@ -157,6 +233,7 @@ export class AddonModBBBIndexComponent extends CoreCourseModuleMainActivityCompo
|
||||||
|
|
||||||
if (this.bbb) {
|
if (this.bbb) {
|
||||||
promises.push(AddonModBBB.invalidateAllGroupsMeetingInfo(this.bbb.id));
|
promises.push(AddonModBBB.invalidateAllGroupsMeetingInfo(this.bbb.id));
|
||||||
|
promises.push(AddonModBBB.invalidateAllGroupsRecordings(this.bbb.id));
|
||||||
}
|
}
|
||||||
|
|
||||||
await Promise.all(promises);
|
await Promise.all(promises);
|
||||||
|
@ -172,6 +249,8 @@ export class AddonModBBBIndexComponent extends CoreCourseModuleMainActivityCompo
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.fetchMeetingInfo();
|
await this.fetchMeetingInfo();
|
||||||
|
|
||||||
|
await this.fetchRecordings();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
CoreDomUtils.showErrorModal(error);
|
CoreDomUtils.showErrorModal(error);
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -239,4 +318,46 @@ export class AddonModBBBIndexComponent extends CoreCourseModuleMainActivityCompo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toogle the visibility of a recording (expand/collapse).
|
||||||
|
*
|
||||||
|
* @param recording Recording.
|
||||||
|
*/
|
||||||
|
toggle(recording: RecordingData): void {
|
||||||
|
recording.expanded = !recording.expanded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Play a recording.
|
||||||
|
*
|
||||||
|
* @param event Click event.
|
||||||
|
* @param recording Recording.
|
||||||
|
*/
|
||||||
|
playRecording(event: MouseEvent, recording: RecordingData): void {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
|
CoreSites.getCurrentSite()?.openInBrowserWithAutoLogin(recording.url);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recording data.
|
||||||
|
*/
|
||||||
|
type RecordingData = {
|
||||||
|
type: string;
|
||||||
|
name: string;
|
||||||
|
url: string;
|
||||||
|
expanded: boolean;
|
||||||
|
details: RecordingDetailData[];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recording detail data.
|
||||||
|
*/
|
||||||
|
type RecordingDetailData = {
|
||||||
|
label: string;
|
||||||
|
value: string;
|
||||||
|
allowHTML: boolean;
|
||||||
|
};
|
||||||
|
|
|
@ -12,8 +12,12 @@
|
||||||
"view_message_conference_room_ready": "This room is ready. You can join the session now.",
|
"view_message_conference_room_ready": "This room is ready. You can join the session now.",
|
||||||
"view_message_moderator": "moderator",
|
"view_message_moderator": "moderator",
|
||||||
"view_message_moderators": "moderators",
|
"view_message_moderators": "moderators",
|
||||||
|
"view_message_norecordings": "There are no recordings available.",
|
||||||
"view_message_session_started_at": "This session started at",
|
"view_message_session_started_at": "This session started at",
|
||||||
"view_message_viewer": "viewer",
|
"view_message_viewer": "viewer",
|
||||||
"view_message_viewers": "viewers",
|
"view_message_viewers": "viewers",
|
||||||
"view_nojoin": "You do not have a role that is allowed to join this session."
|
"view_nojoin": "You do not have a role that is allowed to join this session.",
|
||||||
|
"view_recording_format_presentation": "Presentation",
|
||||||
|
"view_recording_list_action_play": "Play",
|
||||||
|
"view_section_title_recordings": "Recordings"
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ import { CoreSite, CoreSiteWSPreSets } from '@classes/site';
|
||||||
import { CoreCourseCommonModWSOptions } from '@features/course/services/course';
|
import { CoreCourseCommonModWSOptions } from '@features/course/services/course';
|
||||||
import { CoreCourseLogHelper } from '@features/course/services/log-helper';
|
import { CoreCourseLogHelper } from '@features/course/services/log-helper';
|
||||||
import { CoreSites, CoreSitesCommonWSOptions } from '@services/sites';
|
import { CoreSites, CoreSitesCommonWSOptions } from '@services/sites';
|
||||||
|
import { CoreTextUtils } from '@services/utils/text';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
import { CoreUtils } from '@services/utils/utils';
|
||||||
import { CoreWSExternalFile, CoreWSExternalWarning } from '@services/ws';
|
import { CoreWSExternalFile, CoreWSExternalWarning } from '@services/ws';
|
||||||
import { makeSingleton, Translate } from '@singletons';
|
import { makeSingleton, Translate } from '@singletons';
|
||||||
|
@ -206,6 +207,71 @@ export class AddonModBBBService {
|
||||||
return ROOT_CACHE_KEY + 'meetingInfo:' + id + ':';
|
return ROOT_CACHE_KEY + 'meetingInfo:' + id + ':';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 getRecordings(
|
||||||
|
id: number,
|
||||||
|
groupId: number = 0,
|
||||||
|
options: AddonModBBBGetMeetingInfoOptions = {},
|
||||||
|
): Promise<AddonModBBBRecordingsTableData> {
|
||||||
|
const site = await CoreSites.getSite(options.siteId);
|
||||||
|
|
||||||
|
const params: AddonModBBBGetRecordingsWSParams = {
|
||||||
|
bigbluebuttonbnid: id,
|
||||||
|
groupid: groupId,
|
||||||
|
};
|
||||||
|
const preSets: CoreSiteWSPreSets = {
|
||||||
|
cacheKey: this.getRecordingsCacheKey(id, groupId),
|
||||||
|
component: AddonModBBBService.COMPONENT,
|
||||||
|
componentId: options.cmId,
|
||||||
|
...CoreSites.getReadingStrategyPreSets(options.readingStrategy), // Include reading strategy preSets.
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = await site.read<AddonModBBBGetRecordingsWSResponse>(
|
||||||
|
'mod_bigbluebuttonbn_get_recordings',
|
||||||
|
params,
|
||||||
|
preSets,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result.warnings?.length) {
|
||||||
|
throw new CoreWSError(result.warnings[0]);
|
||||||
|
} else if (!result.tabledata) {
|
||||||
|
throw new CoreError('Cannot retrieve recordings.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...result.tabledata,
|
||||||
|
parsedData: CoreTextUtils.parseJSON(result.tabledata?.data, []),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get cache key for get recordings WS call.
|
||||||
|
*
|
||||||
|
* @param id BBB ID.
|
||||||
|
* @param groupId Group ID, 0 means that the function will determine the user group.
|
||||||
|
* @return Cache key.
|
||||||
|
*/
|
||||||
|
protected getRecordingsCacheKey(id: number, groupId: number = 0): string {
|
||||||
|
return this.getRecordingsCacheKeyPrefix(id) + groupId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get cache key prefix for get recordings WS call.
|
||||||
|
*
|
||||||
|
* @param id BBB ID.
|
||||||
|
* @return Cache key prefix.
|
||||||
|
*/
|
||||||
|
protected getRecordingsCacheKeyPrefix(id: number): string {
|
||||||
|
return ROOT_CACHE_KEY + 'recordings:' + id + ':';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Report a BBB as being viewed.
|
* Report a BBB as being viewed.
|
||||||
*
|
*
|
||||||
|
@ -271,6 +337,33 @@ export class AddonModBBBService {
|
||||||
await site.invalidateWsCacheForKeyStartingWith(this.getMeetingInfoCacheKeyPrefix(id));
|
await site.invalidateWsCacheForKeyStartingWith(this.getMeetingInfoCacheKeyPrefix(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidate recordings 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 invalidateRecordings(id: number, groupId: number = 0, siteId?: string): Promise<void> {
|
||||||
|
const site = await CoreSites.getSite(siteId);
|
||||||
|
|
||||||
|
await site.invalidateWsCacheForKey(this.getRecordingsCacheKey(id, groupId));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidate recordings 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 invalidateAllGroupsRecordings(id: number, siteId?: string): Promise<void> {
|
||||||
|
const site = await CoreSites.getSite(siteId);
|
||||||
|
|
||||||
|
await site.invalidateWsCacheForKeyStartingWith(this.getRecordingsCacheKeyPrefix(id));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether or not the BBB plugin is enabled for a certain site.
|
* Returns whether or not the BBB plugin is enabled for a certain site.
|
||||||
*
|
*
|
||||||
|
@ -410,3 +503,48 @@ export type AddonModBBBEndMeetingWSParams = {
|
||||||
export type AddonModBBBGetMeetingInfoOptions = CoreCourseCommonModWSOptions & {
|
export type AddonModBBBGetMeetingInfoOptions = CoreCourseCommonModWSOptions & {
|
||||||
updateCache?: boolean;
|
updateCache?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Params of mod_bigbluebuttonbn_get_recordings WS.
|
||||||
|
*/
|
||||||
|
export type AddonModBBBGetRecordingsWSParams = {
|
||||||
|
bigbluebuttonbnid: number; // Bigbluebuttonbn instance id.
|
||||||
|
tools?: string; // A set of enabled tools.
|
||||||
|
groupid?: number; // Group ID.
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data returned by mod_bigbluebuttonbn_get_recordings WS.
|
||||||
|
*/
|
||||||
|
export type AddonModBBBGetRecordingsWSResponse = {
|
||||||
|
status: boolean; // Whether the fetch was successful.
|
||||||
|
tabledata?: AddonModBBBRecordingsWSTableData;
|
||||||
|
warnings?: CoreWSExternalWarning[];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Table data returned by mod_bigbluebuttonbn_get_recordings WS.
|
||||||
|
*/
|
||||||
|
export type AddonModBBBRecordingsWSTableData = {
|
||||||
|
activity: string;
|
||||||
|
ping_interval: number; // eslint-disable-line @typescript-eslint/naming-convention
|
||||||
|
locale: string;
|
||||||
|
profile_features: string[]; // eslint-disable-line @typescript-eslint/naming-convention
|
||||||
|
columns: {
|
||||||
|
key: string;
|
||||||
|
label: string;
|
||||||
|
width: string;
|
||||||
|
type?: string; // Column type.
|
||||||
|
sortable?: boolean; // Whether this column is sortable.
|
||||||
|
allowHTML?: boolean; // Whether this column contains HTML.
|
||||||
|
formatter?: string; // Formatter name.
|
||||||
|
}[];
|
||||||
|
data: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recordings table data with some calculated data.
|
||||||
|
*/
|
||||||
|
export type AddonModBBBRecordingsTableData = AddonModBBBRecordingsWSTableData & {
|
||||||
|
parsedData: Record<string, string|number|boolean>[];
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in New Issue