Add BigBlueButton widget to integration manager

This adds the widget and the configuration for it to the integration
manager, so that the user can add a BBB widget. The code that will
actually run inside of the widget is not yet here.

A few CSS things are updated as well to make them more generic, as
we reused a few things that were previously jitsi only.
This commit is contained in:
Andrew Morgan 2020-07-23 22:59:48 +02:00
parent db2298172f
commit 401812931a
13 changed files with 109 additions and 5 deletions

View File

@ -0,0 +1,23 @@
import { QueryInterface } from "sequelize";
export default {
up: (queryInterface: QueryInterface) => {
return Promise.resolve()
.then(() => queryInterface.bulkInsert("dimension_widgets", [
{
type: "bigbluebutton",
name: "BigBlueButton",
avatarUrl: "/img/avatars/bigbluebutton.png",
isEnabled: true,
isPublic: true,
description: "Embed a BigBlueButton conference",
}
]));
},
down: (queryInterface: QueryInterface) => {
return Promise.resolve()
.then(() => queryInterface.bulkDelete("dimension_widgets", {
type: "bigbluebutton",
}));
}
}

View File

@ -118,6 +118,7 @@ import { CKEditorModule } from "@ckeditor/ckeditor5-angular";
import { AdminNewEditTermsComponent } from "./admin/terms/new-edit/new-edit.component";
import { AdminTermsNewEditPublishDialogComponent } from "./admin/terms/new-edit/publish/publish.component";
import { TermsWidgetWrapperComponent } from "./widget-wrappers/terms/terms.component";
import { BigBlueButtonConfigComponent } from "./configs/widget/bigbluebutton/bigbluebutton.widget.component";
@NgModule({
imports: [
@ -148,6 +149,7 @@ import { TermsWidgetWrapperComponent } from "./widget-wrappers/terms/terms.compo
VideoWidgetWrapperComponent,
JitsiWidgetWrapperComponent,
GCalWidgetWrapperComponent,
BigBlueButtonConfigComponent,
RiotHomeComponent,
IboxComponent,
ConfigScreenWidgetComponent,

View File

@ -2,6 +2,7 @@ import { RouterModule, Routes } from "@angular/router";
import { HomeComponent } from "./home/home.component";
import { RiotComponent } from "./riot/riot.component";
import { GenericWidgetWrapperComponent } from "./widget-wrappers/generic/generic.component";
import { BigBlueButtonConfigComponent } from "./configs/widget/bigbluebutton/bigbluebutton.widget.component";
import { VideoWidgetWrapperComponent } from "./widget-wrappers/video/video.component";
import { JitsiWidgetWrapperComponent } from "./widget-wrappers/jitsi/jitsi.component";
import { GCalWidgetWrapperComponent } from "./widget-wrappers/gcal/gcal.component";
@ -180,6 +181,11 @@ const routes: Routes = [
component: CustomWidgetConfigComponent,
data: {breadcrumb: "Custom Widgets", name: "Custom Widgets"},
},
{
path: "bigbluebutton",
component: BigBlueButtonConfigComponent,
data: {breadcrumb: "BigBlueButton Widgets", name: "BigBlueButton Widgets"},
},
{
path: "etherpad",
component: EtherpadWidgetConfigComponent,

View File

@ -0,0 +1,11 @@
<my-widget-config [widgetComponent]="this">
<ng-template #widgetParamsTemplate let-widget="widget">
<label class="label-block">
BigBlueButton Meeting URL
<input type="text" class="form-control"
placeholder="https://bbb.example.com/abc-def-ghi"
[(ngModel)]="widget.dimension.newData.conferenceUrl" name="widget-url-{{widget.id}}"
[disabled]="isUpdating"/>
</label>
</ng-template>
</my-widget-config>

View File

@ -0,0 +1,53 @@
import { WidgetComponent, DISABLE_AUTOMATIC_WRAPPING } from "../widget.component";
import { WIDGET_BIGBLUEBUTTON, EditableWidget } from "../../../shared/models/widget";
import { Component } from "@angular/core";
import { FE_BigBlueButtonWidget } from "../../../shared/models/integration";
import { SessionStorage } from "../../../shared/SessionStorage";
import * as url from "url";
@Component({
templateUrl: "bigbluebutton.widget.component.html",
styleUrls: ["bigbluebutton.widget.component.scss"],
})
// Configuration of BigBlueButton widgets
export class BigBlueButtonConfigComponent extends WidgetComponent {
private bigBlueButtonWidget: FE_BigBlueButtonWidget = <FE_BigBlueButtonWidget>SessionStorage.editIntegration;
constructor() {
super(WIDGET_BIGBLUEBUTTON, "BigBlueButton Conference", DISABLE_AUTOMATIC_WRAPPING);
}
protected OnWidgetsDiscovered(widgets: EditableWidget[]) {
for (const widget of widgets) {
widget.data.conferenceUrl = this.templateUrl(widget.url, widget.data);
}
}
protected OnNewWidgetPrepared(widget: EditableWidget): void {
widget.dimension.newData["conferenceUrl"] = this.bigBlueButtonWidget.options.conferenceUrl;
}
protected OnWidgetBeforeAdd(widget: EditableWidget) {
this.setWidgetOptions(widget);
}
protected OnWidgetBeforeEdit(widget: EditableWidget) {
this.setWidgetOptions(widget);
}
private setWidgetOptions(widget: EditableWidget) {
widget.dimension.newData.url = widget.dimension.newData.conferenceUrl;
let widgetQueryString = url.format({
query: {
"conferenceUrl": "$conferenceUrl",
"displayName": "$matrix_display_name",
"avatarUrl": "$matrix_avatar_url",
"userId": "$matrix_user_id",
},
});
widgetQueryString = this.decodeParams(widgetQueryString, Object.keys(widget.dimension.newData).map(k => "$" + k));
widget.dimension.newUrl = window.location.origin + "/widgets/bigbluebutton" + widgetQueryString;
}
}

View File

@ -69,6 +69,10 @@
<img src="/img/avatars/googlecalendar.png">
<span>Google Calendar</span>
</div>
<div class="integration">
<img src="/img/avatars/bigbluebutton.png">
<span>BigBlueButton</span>
</div>
<div class="integration">
<img src="/img/avatars/customwidget.png">
<span>Custom Widget</span>

View File

@ -1,6 +1,7 @@
import { WidgetsResponse } from "./server-client-responses";
export const WIDGET_CUSTOM = ["m.custom", "customwidget", "dimension-customwidget"];
export const WIDGET_BIGBLUEBUTTON = ["m.bigbluebutton", "bigbluebutton", "dimension-bigbluebutton"];
export const WIDGET_ETHERPAD = ["m.etherpad", "etherpad", "dimension-etherpad"];
export const WIDGET_GOOGLE_DOCS = ["m.googledoc", "googledocs", "dimension-googledocs"];
export const WIDGET_GOOGLE_CALENDAR = ["m.googlecalendar", "googlecalendar", "dimension-googlecalendar"];

View File

@ -1,6 +1,7 @@
import { Injectable } from "@angular/core";
import {
WIDGET_CUSTOM,
WIDGET_BIGBLUEBUTTON,
WIDGET_ETHERPAD,
WIDGET_GOOGLE_CALENDAR,
WIDGET_GOOGLE_DOCS,
@ -35,6 +36,9 @@ export class IntegrationsRegistry {
"custom": {
types: WIDGET_CUSTOM,
},
"bigbluebutton": {
types: WIDGET_BIGBLUEBUTTON,
},
"youtube": {
types: WIDGET_YOUTUBE
},

View File

@ -16,7 +16,7 @@
position: absolute;
height: 100%;
width: 100%;
background-color: themed(jitsiWelcomeBgColor);
background-color: themed(widgetWelcomeBgColor);
}
.join-conference-boat {
@ -30,4 +30,4 @@
width: 90%;
text-align: center;
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -48,7 +48,7 @@ $theme_dark: (
stickerPickerStickerBgColor: #fff,
stickerPickerShadowColor: hsla(0, 0%, 0%, 0.2),
jitsiWelcomeBgColor: #fff,
widgetWelcomeBgColor: #fff,
troubleshooterBgColor: #2d2d2d,
troubleshooterNeutralColor: rgb(205, 215, 222),

View File

@ -48,7 +48,7 @@ $theme_light: (
stickerPickerStickerBgColor: #fff,
stickerPickerShadowColor: hsla(0, 0%, 0%, 0.2),
jitsiWelcomeBgColor: #fff,
widgetWelcomeBgColor: #fff,
troubleshooterBgColor: #fff,
troubleshooterNeutralColor: rgb(205, 215, 222),
@ -86,4 +86,4 @@ $theme_light: (
appserviceConfigPreFgColor: rgb(41, 43, 44),
appserviceConfigPreBorderColor: #ccc,
appserviceConfigPreBgColor: #eee,
);
);