mirror of
https://github.com/turt2live/matrix-dimension.git
synced 2024-08-31 14:12:08 +00:00
Add etherpad widget configuration
This commit is contained in:
parent
7fd674a8ff
commit
fce6f2174a
@ -33,6 +33,8 @@ import { ServiceLocator } from "./shared/services/locator.service";
|
||||
import { IboxComponent } from "./elements/ibox/ibox.component";
|
||||
import { CustomWidgetConfigComponent } from "./configs/widget/custom/custom.widget.component";
|
||||
import { ConfigScreenWidgetComponent } from "./configs/widget/config_screen/config_screen.widget.component";
|
||||
import { EtherpadWidgetConfigComponent } from "./configs/widget/etherpad/etherpad.widget.component";
|
||||
import { NameService } from "./shared/services/name.service";
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@ -66,6 +68,7 @@ import { ConfigScreenWidgetComponent } from "./configs/widget/config_screen/conf
|
||||
IboxComponent,
|
||||
ConfigScreenWidgetComponent,
|
||||
CustomWidgetConfigComponent,
|
||||
EtherpadWidgetConfigComponent,
|
||||
|
||||
// Vendor
|
||||
],
|
||||
@ -74,6 +77,7 @@ import { ConfigScreenWidgetComponent } from "./configs/widget/config_screen/conf
|
||||
ScalarServerApiService,
|
||||
DimensionApiService,
|
||||
AdminApiService,
|
||||
NameService,
|
||||
{provide: Window, useValue: window},
|
||||
|
||||
// Vendor
|
||||
|
@ -7,6 +7,7 @@ import { JitsiWidgetWrapperComponent } from "./widget_wrappers/jitsi/jitsi.compo
|
||||
import { GCalWidgetWrapperComponent } from "./widget_wrappers/gcal/gcal.component";
|
||||
import { RiotHomeComponent } from "./riot/riot-home/home.component";
|
||||
import { CustomWidgetConfigComponent } from "./configs/widget/custom/custom.widget.component";
|
||||
import { EtherpadWidgetConfigComponent } from "./configs/widget/etherpad/etherpad.widget.component";
|
||||
|
||||
const routes: Routes = [
|
||||
{path: "", component: HomeComponent},
|
||||
@ -28,6 +29,11 @@ const routes: Routes = [
|
||||
component: CustomWidgetConfigComponent,
|
||||
data: {breadcrumb: "Custom Widgets", name: "Custom Widgets"}
|
||||
},
|
||||
{
|
||||
path: "etherpad",
|
||||
component: EtherpadWidgetConfigComponent,
|
||||
data: {breadcrumb: "Etherpad Widgets", name: "Etherpad Widgets"}
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
@ -0,0 +1,18 @@
|
||||
<my-widget-config [widgetComponent]="this">
|
||||
<ng-template #widgetParamsTemplate let-widget="widget">
|
||||
<label class="label-block">
|
||||
Pad Name
|
||||
<input type="text" class="form-control"
|
||||
placeholder="{{ defaultName }}"
|
||||
[(ngModel)]="widget.dimension.newName" name="widget-name-{{widget.id}}"
|
||||
[disabled]="isUpdating"/>
|
||||
</label>
|
||||
<label class="label-block">
|
||||
Pad URL
|
||||
<input type="text" class="form-control"
|
||||
placeholder="https://demo.riot.im/etherpad/p/MyCoolPadName"
|
||||
[(ngModel)]="widget.dimension.newUrl" name="widget-url-{{widget.id}}"
|
||||
[disabled]="isUpdating"/>
|
||||
</label>
|
||||
</ng-template>
|
||||
</my-widget-config>
|
34
web/app/configs/widget/etherpad/etherpad.widget.component.ts
Normal file
34
web/app/configs/widget/etherpad/etherpad.widget.component.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import { NewWidgetComponent } from "../widget.component";
|
||||
import { EditableWidget, WIDGET_ETHERPAD } from "../../../shared/models/widget";
|
||||
import { Component } from "@angular/core";
|
||||
import { EtherpadWidget } from "../../../shared/models/integration";
|
||||
import { SessionStorage } from "../../../shared/SessionStorage";
|
||||
import { NameService } from "../../../shared/services/name.service";
|
||||
|
||||
@Component({
|
||||
templateUrl: "etherpad.widget.component.html",
|
||||
styleUrls: ["etherpad.widget.component.scss"],
|
||||
})
|
||||
export class EtherpadWidgetConfigComponent extends NewWidgetComponent {
|
||||
|
||||
private etherpadWidget: EtherpadWidget = <EtherpadWidget>SessionStorage.editIntegration;
|
||||
|
||||
constructor(private nameService: NameService) {
|
||||
super(WIDGET_ETHERPAD, "Etherpad Widget", "generic", "etherpad");
|
||||
}
|
||||
|
||||
protected OnNewWidgetPrepared(widget: EditableWidget): void {
|
||||
const name = this.nameService.getHumanReadableName();
|
||||
|
||||
let template = "https://demo.riot.im/etherpad/p/$roomId_$padName";
|
||||
if (this.etherpadWidget.options && this.etherpadWidget.options.defaultUrl) {
|
||||
template = this.etherpadWidget.options.defaultUrl;
|
||||
}
|
||||
|
||||
template = template.replace("$roomId", encodeURIComponent(SessionStorage.roomId));
|
||||
template = template.replace("$padName", encodeURIComponent(name));
|
||||
|
||||
widget.dimension.newUrl = template;
|
||||
widget.dimension.newName = name;
|
||||
}
|
||||
}
|
@ -1,9 +1,9 @@
|
||||
import { EventEmitter } from "@angular/core";
|
||||
import { convertScalarWidgetsToDtos, EditableWidget } from "../../shared/models/widget";
|
||||
import { ToasterService } from "angular2-toaster";
|
||||
import { ScalarClientApiService } from "../../shared/services/scalar-client-api.service";
|
||||
import { ServiceLocator } from "../../shared/services/locator.service";
|
||||
import { SessionStorage } from "../../shared/SessionStorage";
|
||||
import { OnInit } from "@angular/core";
|
||||
|
||||
const SCALAR_WIDGET_LINKS = [
|
||||
"https://scalar-staging.riot.im/scalar/api/widgets/__TYPE__.html?url=",
|
||||
@ -12,7 +12,7 @@ const SCALAR_WIDGET_LINKS = [
|
||||
"https://demo.riot.im/scalar/api/widgets/__TYPE__.html?url=",
|
||||
];
|
||||
|
||||
export class NewWidgetComponent {
|
||||
export class NewWidgetComponent implements OnInit {
|
||||
|
||||
public isLoading = true;
|
||||
public isUpdating = false;
|
||||
@ -27,40 +27,32 @@ export class NewWidgetComponent {
|
||||
private window = ServiceLocator.injector.get(Window);
|
||||
private scalarApi = ServiceLocator.injector.get(ScalarClientApiService);
|
||||
|
||||
protected OnNewWidgetPrepared = new EventEmitter<EditableWidget>();
|
||||
protected OnWidgetsDiscovered = new EventEmitter<EditableWidget[]>();
|
||||
protected OnWidgetBeforeAdd = new EventEmitter<EditableWidget>();
|
||||
protected OnWidgetAfterAdd = new EventEmitter<EditableWidget>();
|
||||
protected OnWidgetPreparedForEdit = new EventEmitter<EditableWidget>();
|
||||
protected OnWidgetBeforeEdit = new EventEmitter<EditableWidget>();
|
||||
protected OnWidgetAfterEdit = new EventEmitter<EditableWidget>();
|
||||
protected OnWidgetBeforeDelete = new EventEmitter<EditableWidget>();
|
||||
protected OnWidgetAfterDelete = new EventEmitter<EditableWidget>();
|
||||
|
||||
constructor(private widgetTypes: string[],
|
||||
public defaultName: string,
|
||||
private wrapperId = "generic",
|
||||
private scalarWrapperId = null) {
|
||||
this.isLoading = true;
|
||||
this.isUpdating = false;
|
||||
}
|
||||
|
||||
if (wrapperId) {
|
||||
this.wrapperUrl = this.window.location.origin + "/widgets/" + wrapperId + "?url=";
|
||||
public ngOnInit(): void {
|
||||
if (this.wrapperId) {
|
||||
this.wrapperUrl = this.window.location.origin + "/widgets/" + this.wrapperId + "?url=";
|
||||
|
||||
if (!scalarWrapperId) scalarWrapperId = wrapperId;
|
||||
if (!this.scalarWrapperId) this.scalarWrapperId = this.wrapperId;
|
||||
for (let widgetLink of SCALAR_WIDGET_LINKS) {
|
||||
this.scalarWrapperUrls.push(widgetLink.replace("__TYPE__", scalarWrapperId));
|
||||
this.scalarWrapperUrls.push(widgetLink.replace("__TYPE__", this.scalarWrapperId));
|
||||
}
|
||||
}
|
||||
|
||||
this.prepareNewWidget();
|
||||
this.getWidgetsOfType(widgetTypes).then(widgets => {
|
||||
this.getWidgetsOfType(this.widgetTypes).then(widgets => {
|
||||
this.widgets = widgets;
|
||||
for (let widget of this.widgets) {
|
||||
this.unpackWidget(widget);
|
||||
}
|
||||
|
||||
this.OnWidgetsDiscovered.emit(this.widgets);
|
||||
this.OnWidgetsDiscovered(this.widgets);
|
||||
this.isLoading = false;
|
||||
this.isUpdating = false;
|
||||
|
||||
@ -155,7 +147,8 @@ export class NewWidgetComponent {
|
||||
newData: {},
|
||||
},
|
||||
};
|
||||
this.OnNewWidgetPrepared.emit(this.newWidget);
|
||||
console.log("Emitting new widget prepared event");
|
||||
this.OnNewWidgetPrepared(this.newWidget);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -238,12 +231,12 @@ export class NewWidgetComponent {
|
||||
this.packWidget(this.newWidget);
|
||||
|
||||
this.isUpdating = true;
|
||||
this.OnWidgetBeforeAdd.emit(this.newWidget);
|
||||
this.OnWidgetBeforeAdd(this.newWidget);
|
||||
return this.scalarApi.setWidget(SessionStorage.roomId, this.newWidget)
|
||||
.then(() => this.widgets.push(this.newWidget))
|
||||
.then(() => {
|
||||
this.isUpdating = false;
|
||||
this.OnWidgetAfterAdd.emit(this.newWidget);
|
||||
this.OnWidgetAfterAdd(this.newWidget);
|
||||
this.prepareNewWidget();
|
||||
this.toaster.pop("success", "Widget added!");
|
||||
})
|
||||
@ -268,11 +261,11 @@ export class NewWidgetComponent {
|
||||
this.packWidget(widget);
|
||||
|
||||
this.isUpdating = true;
|
||||
this.OnWidgetBeforeEdit.emit(widget);
|
||||
this.OnWidgetBeforeEdit(widget);
|
||||
return this.scalarApi.setWidget(SessionStorage.roomId, widget)
|
||||
.then(() => {
|
||||
this.isUpdating = false;
|
||||
this.OnWidgetAfterEdit.emit(widget);
|
||||
this.OnWidgetAfterEdit(widget);
|
||||
this.toaster.pop("success", "Widget updated!");
|
||||
})
|
||||
.catch(err => {
|
||||
@ -289,12 +282,12 @@ export class NewWidgetComponent {
|
||||
*/
|
||||
public removeWidget(widget: EditableWidget): Promise<any> {
|
||||
this.isUpdating = true;
|
||||
this.OnWidgetBeforeDelete.emit(widget);
|
||||
this.OnWidgetBeforeDelete(widget);
|
||||
return this.scalarApi.deleteWidget(SessionStorage.roomId, widget)
|
||||
.then(() => this.widgets.splice(this.widgets.indexOf(widget), 1))
|
||||
.then(() => {
|
||||
this.isUpdating = false;
|
||||
this.OnWidgetAfterDelete.emit(widget);
|
||||
this.OnWidgetAfterDelete(widget);
|
||||
this.toaster.pop("success", "Widget deleted!");
|
||||
})
|
||||
.catch(err => {
|
||||
@ -310,6 +303,90 @@ export class NewWidgetComponent {
|
||||
*/
|
||||
public resetWidget(widget: EditableWidget) {
|
||||
this.unpackWidget(widget);
|
||||
this.OnWidgetPreparedForEdit.emit(widget);
|
||||
this.OnWidgetPreparedForEdit(widget);
|
||||
}
|
||||
|
||||
// Component hooks below here
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Called when a new widget has been created in the newWidget field
|
||||
* @param {EditableWidget} _widget The widget that has been prepared
|
||||
*/
|
||||
protected OnNewWidgetPrepared(_widget: EditableWidget): void {
|
||||
// Component hook
|
||||
}
|
||||
|
||||
/**
|
||||
* Called after all the widgets have been discovered and unpacked for the room.
|
||||
* @param {EditableWidget[]} _widgets The widgets that were discovered
|
||||
*/
|
||||
protected OnWidgetsDiscovered(_widgets: EditableWidget[]): void {
|
||||
// Component hook
|
||||
}
|
||||
|
||||
/**
|
||||
* Called before the widget is added to the room, but after the Dimension-specific
|
||||
* settings have been copied over to the primary fields.
|
||||
* @param {EditableWidget} _widget The widget that is about to be added
|
||||
*/
|
||||
protected OnWidgetBeforeAdd(_widget: EditableWidget): void {
|
||||
// Component hook
|
||||
}
|
||||
|
||||
/**
|
||||
* Called after the widget has been added to the room, but before the newWidget field
|
||||
* has been set to a new widget.
|
||||
* @param {EditableWidget} _widget The widget that has been added.
|
||||
*/
|
||||
protected OnWidgetAfterAdd(_widget: EditableWidget): void {
|
||||
// Component hook
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the given widget has been asked to be prepared for editing. At this point
|
||||
* the widget is not being persisted to the room, it is just updating the EditingWidget's
|
||||
* properties for the user's ability to edit it.
|
||||
* @param {EditableWidget} _widget The widget that has been prepared for editing
|
||||
*/
|
||||
protected OnWidgetPreparedForEdit(_widget: EditableWidget): void {
|
||||
// Component hook
|
||||
}
|
||||
|
||||
/**
|
||||
* Called before the given widget has been updated in the room, but after the
|
||||
* Dimension-specific settings have been copied over to the primary fields.
|
||||
* This is not called for widgets being deleted.
|
||||
* @param {EditableWidget} _widget The widget about to be edited
|
||||
*/
|
||||
protected OnWidgetBeforeEdit(_widget: EditableWidget): void {
|
||||
// Component hook
|
||||
}
|
||||
|
||||
/**
|
||||
* Called after a given widget has been updated in the room. This is not called for
|
||||
* widgets being deleted.
|
||||
* @param {EditableWidget} _widget The widget that has been updated.
|
||||
*/
|
||||
protected OnWidgetAfterEdit(_widget: EditableWidget): void {
|
||||
// Component hook
|
||||
}
|
||||
|
||||
/**
|
||||
* Called before the given widget has been removed from the room. No changes to the
|
||||
* widget have been made at this point.
|
||||
* @param {EditableWidget} _widget The widget about to be deleted.
|
||||
*/
|
||||
protected OnWidgetBeforeDelete(_widget: EditableWidget): void {
|
||||
// Component hook
|
||||
}
|
||||
|
||||
/**
|
||||
* Called after a given widget has been deleted from the room. The widget will be in
|
||||
* the deleted state and will no longer be tracked anywhere on the component.
|
||||
* @param {EditableWidget} _widget The widget that has been deleted.
|
||||
*/
|
||||
protected OnWidgetAfterDelete(_widget: EditableWidget): void {
|
||||
// Component hook
|
||||
}
|
||||
}
|
18
web/app/shared/services/name.service.ts
Normal file
18
web/app/shared/services/name.service.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
import * as gobyInit from "goby";
|
||||
|
||||
const goby = gobyInit.init({
|
||||
// Converts words to a url-safe name
|
||||
// Ie: "hello world how-are you" becomes "HelloWorldHowAreYou"
|
||||
decorator: parts => parts.map(p => p ? p.split('-').map(p2 => p2 ? p2[0].toUpperCase() + p2.substring(1).toLowerCase() : '').join('') : '').join(''),
|
||||
});
|
||||
|
||||
@Injectable()
|
||||
export class NameService {
|
||||
constructor() {
|
||||
}
|
||||
|
||||
public getHumanReadableName(): string {
|
||||
return goby.generate(["adj", "pre", "suf"]);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user