diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..7a73a41 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/config/bot.json b/config/bot.json new file mode 100644 index 0000000..88a688e --- /dev/null +++ b/config/bot.json @@ -0,0 +1,6 @@ +{ + "syncToken": "s22_2648_0_1_29_1_25_19_1", + "filter": null, + "appserviceUsers": {}, + "appserviceTransactions": {} +} \ No newline at end of file diff --git a/config/bot.json.bak b/config/bot.json.bak new file mode 100644 index 0000000..5735938 --- /dev/null +++ b/config/bot.json.bak @@ -0,0 +1,6 @@ +{ + "syncToken": "s3510138_39116385_25484_5602626_218935_269_119102_8310593_32", + "filter": null, + "appserviceUsers": {}, + "appserviceTransactions": {} +} \ No newline at end of file diff --git a/config/dimension.db.bak b/config/dimension.db.bak new file mode 100644 index 0000000..112c0d7 Binary files /dev/null and b/config/dimension.db.bak differ diff --git a/package-lock.json b/package-lock.json index 36b4494..95644d4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11648,15 +11648,6 @@ "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==" }, - "ngx-modialog": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ngx-modialog/-/ngx-modialog-5.0.1.tgz", - "integrity": "sha512-m6o7V01j97C/6GGQjNfxF96k6713G11Fs/S6RF7NbxRV3EUZsG0MqkDn2Q1fR0UEoaNqyKMDVDTya7N3hAnfPA==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, "ngx-ui-switch": { "version": "12.0.1", "resolved": "https://registry.npmjs.org/ngx-ui-switch/-/ngx-ui-switch-12.0.1.tgz", diff --git a/package.json b/package.json index 7a9808c..6f3b624 100644 --- a/package.json +++ b/package.json @@ -117,7 +117,6 @@ "jquery": "^3.6.0", "json-loader": "^0.5.7", "mini-css-extract-plugin": "^2.1.0", - "ngx-modialog": "^5.0.1", "postcss-cssnext": "^3.1.0", "postcss-import": "^14.0.2", "postcss-loader": "^6.1.1", diff --git a/web/app/admin/bridges/irc/add-selfhosted/add-selfhosted.component.html b/web/app/admin/bridges/irc/add-selfhosted/add-selfhosted.component.html index 690f61d..aa9ef0b 100644 --- a/web/app/admin/bridges/irc/add-selfhosted/add-selfhosted.component.html +++ b/web/app/admin/bridges/irc/add-selfhosted/add-selfhosted.component.html @@ -1,24 +1,23 @@ -
-
-

{{'Add a new self-hosted IRC Bridge' | translate}}

-
-
-

{{'Self-hosted IRC bridges must have' | translate}}{{'provisioning' | translate}} {{'enabled in the configuration.' | translate}}

- - -
- + + + diff --git a/web/app/admin/bridges/irc/add-selfhosted/add-selfhosted.component.ts b/web/app/admin/bridges/irc/add-selfhosted/add-selfhosted.component.ts index 7e3c09f..c502ac5 100644 --- a/web/app/admin/bridges/irc/add-selfhosted/add-selfhosted.component.ts +++ b/web/app/admin/bridges/irc/add-selfhosted/add-selfhosted.component.ts @@ -1,23 +1,24 @@ import { Component } from "@angular/core"; +import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap"; import { ToasterService } from "angular2-toaster"; -import { DialogRef, ModalComponent } from "ngx-modialog"; -import { BSModalContext } from "ngx-modialog/plugins/bootstrap"; import { AdminIrcApiService } from "../../../../shared/services/admin/admin-irc-api.service"; import { TranslateService } from "@ngx-translate/core"; -export class AddSelfhostedIrcBridgeDialogContext extends BSModalContext { +export interface AddSelfhostedIrcBridgeDialogContextt { + isSaving: boolean; + provisionUrl: string; } @Component({ templateUrl: "./add-selfhosted.component.html", styleUrls: ["./add-selfhosted.component.scss"], }) -export class AdminIrcBridgeAddSelfhostedComponent implements ModalComponent { +export class AdminIrcBridgeAddSelfhostedComponent { public isSaving = false; public provisionUrl: string; - constructor(public dialog: DialogRef, + constructor(public modal: NgbActiveModal, private ircApi: AdminIrcApiService, private toaster: ToasterService, public translate: TranslateService) { @@ -28,7 +29,7 @@ export class AdminIrcBridgeAddSelfhostedComponent implements ModalComponent { this.translate.get('IRC Bridge added').subscribe((res: string) => {this.toaster.pop("success", res); }); - this.dialog.close(); + this.modal.close(); }).catch(err => { console.error(err); this.isSaving = false; diff --git a/web/app/admin/bridges/irc/irc.component.ts b/web/app/admin/bridges/irc/irc.component.ts index 7dbf699..a424fe5 100644 --- a/web/app/admin/bridges/irc/irc.component.ts +++ b/web/app/admin/bridges/irc/irc.component.ts @@ -4,13 +4,12 @@ import { AdminIrcApiService } from "../../../shared/services/admin/admin-irc-api import { FE_Upstream } from "../../../shared/models/admin-responses"; import { AdminUpstreamApiService } from "../../../shared/services/admin/admin-upstream-api.service"; import { FE_IrcBridge } from "../../../shared/models/irc"; -import { Modal, overlayConfigFactory } from "ngx-modialog"; import { AdminIrcBridgeNetworksComponent, IrcNetworksDialogContext } from "./networks/networks.component"; import { - AddSelfhostedIrcBridgeDialogContext, AdminIrcBridgeAddSelfhostedComponent } from "./add-selfhosted/add-selfhosted.component"; import { TranslateService } from "@ngx-translate/core"; +import { NgbModal } from "@ng-bootstrap/ng-bootstrap"; @Component({ templateUrl: "./irc.component.html", @@ -28,7 +27,7 @@ export class AdminIrcBridgeComponent implements OnInit { constructor(private upstreamApi: AdminUpstreamApiService, private ircApi: AdminIrcApiService, private toaster: ToasterService, - private modal: Modal, + private modal: NgbModal, public translate: TranslateService) { this.translate = translate; } @@ -94,23 +93,34 @@ export class AdminIrcBridgeComponent implements OnInit { } public addSelfHostedBridge() { - this.modal.open(AdminIrcBridgeAddSelfhostedComponent, overlayConfigFactory({ - isBlocking: true, + const selfhostedRef = this.modal.open(AdminIrcBridgeAddSelfhostedComponent, { + backdrop: 'static', size: 'lg', - }, AddSelfhostedIrcBridgeDialogContext)).result.then(() => { - this.reload().catch(err => { + }); + selfhostedRef.result.then(() => { + try { + this.reload() + } catch (err) { console.error(err); this.translate.get('Failed to get an update IRC bridge list').subscribe((res: string) => {this.toaster.pop("error", res); }); - }); - }); + } + }) } public editNetworks(bridge: FE_IrcBridge) { - this.modal.open(AdminIrcBridgeNetworksComponent, overlayConfigFactory({ - bridge: bridge, - - isBlocking: true, + const selfhostedRef = this.modal.open(AdminIrcBridgeNetworksComponent, { + backdrop: 'static', size: 'lg', - }, IrcNetworksDialogContext)); + }); + selfhostedRef.result.then(() => { + try { + this.reload() + } catch (err) { + console.error(err); + this.translate.get('Failed to get an update IRC bridge list').subscribe((res: string) => {this.toaster.pop("error", res); }); + } + }) + const selfhostedInstance = selfhostedRef.componentInstance as IrcNetworksDialogContext; + selfhostedInstance.bridge = bridge; } } diff --git a/web/app/admin/bridges/irc/networks/networks.component.html b/web/app/admin/bridges/irc/networks/networks.component.html index ffa9068..00046ca 100644 --- a/web/app/admin/bridges/irc/networks/networks.component.html +++ b/web/app/admin/bridges/irc/networks/networks.component.html @@ -1,29 +1,28 @@ -
-
-

{{ bridge.upstreamId ? "matrix.org's" : "Self-hosted" }} IRC Bridge Networks

-
-
- - - - - - - - - - - - - -
{{'Network' | translate}}{{'Enabled' | translate}}
{{ network.name }} - -
-
- + + + diff --git a/web/app/admin/bridges/irc/networks/networks.component.ts b/web/app/admin/bridges/irc/networks/networks.component.ts index 6e06cde..80f77be 100644 --- a/web/app/admin/bridges/irc/networks/networks.component.ts +++ b/web/app/admin/bridges/irc/networks/networks.component.ts @@ -1,13 +1,12 @@ import { Component } from "@angular/core"; +import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap"; import { ToasterService } from "angular2-toaster"; -import { DialogRef, ModalComponent } from "ngx-modialog"; -import { BSModalContext } from "ngx-modialog/plugins/bootstrap"; import { FE_IrcBridge } from "../../../../shared/models/irc"; import { AdminIrcApiService } from "../../../../shared/services/admin/admin-irc-api.service"; import { TranslateService } from "@ngx-translate/core"; -export class IrcNetworksDialogContext extends BSModalContext { - public bridge: FE_IrcBridge; +export interface IrcNetworksDialogContext { + bridge: FE_IrcBridge; } interface LocalNetwork { @@ -22,19 +21,17 @@ interface LocalNetwork { templateUrl: "./networks.component.html", styleUrls: ["./networks.component.scss"], }) -export class AdminIrcBridgeNetworksComponent implements ModalComponent { +export class AdminIrcBridgeNetworksComponent { public isUpdating = false; public bridge: FE_IrcBridge; public networks: LocalNetwork[]; - constructor(public dialog: DialogRef, + constructor(public modal: NgbActiveModal, private ircApi: AdminIrcApiService, private toaster: ToasterService, public translate: TranslateService) { this.translate = translate; - this.bridge = dialog.context.bridge; - const networkIds = Object.keys(this.bridge.availableNetworks); this.networks = networkIds.map(i => { return { diff --git a/web/app/admin/bridges/slack/manage-selfhosted/manage-selfhosted.component.html b/web/app/admin/bridges/slack/manage-selfhosted/manage-selfhosted.component.html index a545584..718496f 100644 --- a/web/app/admin/bridges/slack/manage-selfhosted/manage-selfhosted.component.html +++ b/web/app/admin/bridges/slack/manage-selfhosted/manage-selfhosted.component.html @@ -1,26 +1,25 @@ -
-
-

{{'self-hosted Slack bridge' | translate}} ({{ isAdding ? "Add a new" : "Edit" }})

-
-
-

- {{'Self-hosted Slack bridges already have provisioning enabled. Be careful not to expose the API to the public internet.' | translate}} -

- - -
- + + + diff --git a/web/app/admin/bridges/slack/manage-selfhosted/manage-selfhosted.component.ts b/web/app/admin/bridges/slack/manage-selfhosted/manage-selfhosted.component.ts index d0df4e7..afab78e 100644 --- a/web/app/admin/bridges/slack/manage-selfhosted/manage-selfhosted.component.ts +++ b/web/app/admin/bridges/slack/manage-selfhosted/manage-selfhosted.component.ts @@ -1,34 +1,31 @@ import { Component } from "@angular/core"; +import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap"; import { ToasterService } from "angular2-toaster"; -import { DialogRef, ModalComponent } from "ngx-modialog"; -import { BSModalContext } from "ngx-modialog/plugins/bootstrap"; import { AdminSlackApiService } from "../../../../shared/services/admin/admin-slack-api.service"; import { TranslateService } from "@ngx-translate/core"; -export class ManageSelfhostedSlackBridgeDialogContext extends BSModalContext { - public provisionUrl: string; - public bridgeId: number; +export interface ManageSelfhostedSlackBridgeDialogContext { + provisionUrl: string; + bridgeId: number; + isAdding: boolean; } @Component({ templateUrl: "./manage-selfhosted.component.html", styleUrls: ["./manage-selfhosted.component.scss"], }) -export class AdminSlackBridgeManageSelfhostedComponent implements ModalComponent { +export class AdminSlackBridgeManageSelfhostedComponent { public isSaving = false; public provisionUrl: string; public bridgeId: number; - public isAdding = false; + public isAdding = true; - constructor(public dialog: DialogRef, + constructor(public modal: NgbActiveModal, private slackApi: AdminSlackApiService, private toaster: ToasterService, public translate: TranslateService) { this.translate = translate; - this.provisionUrl = dialog.context.provisionUrl; - this.bridgeId = dialog.context.bridgeId; - this.isAdding = !this.bridgeId; } public add() { @@ -36,7 +33,7 @@ export class AdminSlackBridgeManageSelfhostedComponent implements ModalComponent if (this.isAdding) { this.slackApi.newSelfhosted(this.provisionUrl).then(() => { this.translate.get('Slack bridge added').subscribe((res: string) => {this.toaster.pop("success", res); }); - this.dialog.close(); + this.modal.close(); }).catch(err => { console.error(err); this.isSaving = false; @@ -45,7 +42,7 @@ export class AdminSlackBridgeManageSelfhostedComponent implements ModalComponent } else { this.slackApi.updateSelfhosted(this.bridgeId, this.provisionUrl).then(() => { this.translate.get('Slack bridge updated').subscribe((res: string) => this.toaster.pop("success", res)); - this.dialog.close(); + this.modal.close(); }).catch(err => { console.error(err); this.isSaving = false; diff --git a/web/app/admin/bridges/slack/slack.component.ts b/web/app/admin/bridges/slack/slack.component.ts index 34eb109..18972bd 100644 --- a/web/app/admin/bridges/slack/slack.component.ts +++ b/web/app/admin/bridges/slack/slack.component.ts @@ -1,6 +1,5 @@ import { Component, OnInit } from "@angular/core"; import { ToasterService } from "angular2-toaster"; -import { Modal, overlayConfigFactory } from "ngx-modialog"; import { FE_Upstream } from "../../../shared/models/admin-responses"; import { AdminUpstreamApiService } from "../../../shared/services/admin/admin-upstream-api.service"; import { @@ -10,6 +9,7 @@ import { import { FE_SlackBridge } from "../../../shared/models/slack"; import { AdminSlackApiService } from "../../../shared/services/admin/admin-slack-api.service"; import { TranslateService } from "@ngx-translate/core"; +import { NgbModal } from "@ng-bootstrap/ng-bootstrap"; @Component({ templateUrl: "./slack.component.html", @@ -26,7 +26,7 @@ export class AdminSlackBridgeComponent implements OnInit { constructor(private slackApi: AdminSlackApiService, private upstreamApi: AdminUpstreamApiService, private toaster: ToasterService, - private modal: Modal, + private modal: NgbModal, public translate: TranslateService) { this.translate = translate; } @@ -75,31 +75,38 @@ export class AdminSlackBridgeComponent implements OnInit { } public addSelfHostedBridge() { - this.modal.open(AdminSlackBridgeManageSelfhostedComponent, overlayConfigFactory({ - isBlocking: true, + const selfhostedRef = this.modal.open(AdminSlackBridgeManageSelfhostedComponent, { + backdrop: 'static', size: 'lg', - - provisionUrl: '', - }, ManageSelfhostedSlackBridgeDialogContext)).result.then(() => { - this.reload().catch(err => { + }); + selfhostedRef.result.then(() => { + try { + this.reload() + } catch (err) { console.error(err); this.translate.get('Failed to get an update Slack bridge list').subscribe((res: string) => {this.toaster.pop("error", res); }); - }); + } }); + const selfhostedInstance = selfhostedRef.componentInstance as ManageSelfhostedSlackBridgeDialogContext; + selfhostedInstance.provisionUrl = ''; } public editBridge(bridge: FE_SlackBridge) { - this.modal.open(AdminSlackBridgeManageSelfhostedComponent, overlayConfigFactory({ - isBlocking: true, + const selfhostedRef = this.modal.open(AdminSlackBridgeManageSelfhostedComponent, { + backdrop: 'static', size: 'lg', - - provisionUrl: bridge.provisionUrl, - bridgeId: bridge.id, - }, ManageSelfhostedSlackBridgeDialogContext)).result.then(() => { - this.reload().catch(err => { + }); + selfhostedRef.result.then(() => { + try { + this.reload() + } catch (err) { console.error(err); this.translate.get('Failed to get an update Slack bridge list').subscribe((res: string) => {this.toaster.pop("error", res); }); - }); + } }); + const selfhostedInstance = selfhostedRef.componentInstance as ManageSelfhostedSlackBridgeDialogContext; + selfhostedInstance.provisionUrl = ''; + selfhostedInstance.bridgeId = bridge.id; + selfhostedInstance.isAdding = !bridge.id; } } diff --git a/web/app/admin/bridges/telegram/manage-selfhosted/manage-selfhosted.component.html b/web/app/admin/bridges/telegram/manage-selfhosted/manage-selfhosted.component.html index b1a2248..e8b9f54 100644 --- a/web/app/admin/bridges/telegram/manage-selfhosted/manage-selfhosted.component.html +++ b/web/app/admin/bridges/telegram/manage-selfhosted/manage-selfhosted.component.html @@ -1,46 +1,45 @@ -
-
-

{{'self-hosted Telegram bridge' | translate}} ({{ isAdding ? "Add a new" : "Edit" }})

-
-
-

{{'Self-hosted Telegram bridges must have' | translate}} {{'provisioning' | translate}} {{'enabled in the configuration.' | translate}}

- - - - - - - - -
- + + + diff --git a/web/app/admin/bridges/telegram/manage-selfhosted/manage-selfhosted.component.ts b/web/app/admin/bridges/telegram/manage-selfhosted/manage-selfhosted.component.ts index a2b268d..9579f7d 100644 --- a/web/app/admin/bridges/telegram/manage-selfhosted/manage-selfhosted.component.ts +++ b/web/app/admin/bridges/telegram/manage-selfhosted/manage-selfhosted.component.ts @@ -1,43 +1,37 @@ import { Component } from "@angular/core"; +import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap"; import { ToasterService } from "angular2-toaster"; -import { DialogRef, ModalComponent } from "ngx-modialog"; -import { BSModalContext } from "ngx-modialog/plugins/bootstrap"; import { AdminTelegramApiService } from "../../../../shared/services/admin/admin-telegram-api.service"; import { TranslateService } from "@ngx-translate/core"; -export class ManageSelfhostedTelegramBridgeDialogContext extends BSModalContext { - public provisionUrl: string; - public sharedSecret: string; - public allowTgPuppets = false; - public allowMxPuppets = false; - public bridgeId: number; +export interface ManageSelfhostedTelegramBridgeDialogContext { + provisionUrl: string; + sharedSecret: string; + allowTgPuppets: boolean; + allowMxPuppets: boolean; + bridgeId: number; + isAdding: boolean; } @Component({ templateUrl: "./manage-selfhosted.component.html", styleUrls: ["./manage-selfhosted.component.scss"], }) -export class AdminTelegramBridgeManageSelfhostedComponent implements ModalComponent { +export class AdminTelegramBridgeManageSelfhostedComponent { - public isSaving = false; - public provisionUrl: string; - public sharedSecret: string; - public allowTgPuppets = false; - public allowMxPuppets = false; - public bridgeId: number; - public isAdding = false; + isSaving = false; + provisionUrl: string; + sharedSecret: string; + allowTgPuppets = false; + allowMxPuppets = false; + bridgeId: number; + isAdding = true; - constructor(public dialog: DialogRef, + constructor(public modal: NgbActiveModal, private telegramApi: AdminTelegramApiService, private toaster: ToasterService, public translate: TranslateService) { this.translate = translate; - this.provisionUrl = dialog.context.provisionUrl; - this.sharedSecret = dialog.context.sharedSecret; - this.allowTgPuppets = dialog.context.allowTgPuppets; - this.allowMxPuppets = dialog.context.allowMxPuppets; - this.bridgeId = dialog.context.bridgeId; - this.isAdding = !this.bridgeId; } public add() { @@ -49,7 +43,7 @@ export class AdminTelegramBridgeManageSelfhostedComponent implements ModalCompon if (this.isAdding) { this.telegramApi.newSelfhosted(this.provisionUrl, this.sharedSecret, options).then(() => { this.translate.get('Telegram bridge added').subscribe((res: string) => {this.toaster.pop("success", res); }); - this.dialog.close(); + this.modal.close(); }).catch(err => { console.error(err); this.isSaving = false; @@ -58,7 +52,7 @@ export class AdminTelegramBridgeManageSelfhostedComponent implements ModalCompon } else { this.telegramApi.updateSelfhosted(this.bridgeId, this.provisionUrl, this.sharedSecret, options).then(() => { this.translate.get('Telegram bridge updated').subscribe((res: string) => {this.toaster.pop("success", res); }); - this.dialog.close(); + this.modal.close(); }).catch(err => { console.error(err); this.isSaving = false; diff --git a/web/app/admin/bridges/telegram/telegram.component.ts b/web/app/admin/bridges/telegram/telegram.component.ts index 1e29c07..50cbe48 100644 --- a/web/app/admin/bridges/telegram/telegram.component.ts +++ b/web/app/admin/bridges/telegram/telegram.component.ts @@ -1,6 +1,5 @@ import { Component, OnInit } from "@angular/core"; import { ToasterService } from "angular2-toaster"; -import { Modal, overlayConfigFactory } from "ngx-modialog"; import { AdminTelegramBridgeManageSelfhostedComponent, ManageSelfhostedTelegramBridgeDialogContext @@ -8,6 +7,7 @@ import { import { FE_TelegramBridge } from "../../../shared/models/telegram"; import { AdminTelegramApiService } from "../../../shared/services/admin/admin-telegram-api.service"; import { TranslateService } from "@ngx-translate/core"; +import { NgbModal } from "@ng-bootstrap/ng-bootstrap"; @Component({ templateUrl: "./telegram.component.html", @@ -21,7 +21,7 @@ export class AdminTelegramBridgeComponent implements OnInit { constructor(private telegramApi: AdminTelegramApiService, private toaster: ToasterService, - private modal: Modal, + private modal: NgbModal, public translate: TranslateService) { this.translate = translate; } @@ -40,19 +40,23 @@ export class AdminTelegramBridgeComponent implements OnInit { } public addSelfHostedBridge() { - this.modal.open(AdminTelegramBridgeManageSelfhostedComponent, overlayConfigFactory({ - isBlocking: true, + const selfhostedRef = this.modal.open(AdminTelegramBridgeManageSelfhostedComponent, { + backdrop: 'static', size: 'lg', - - provisionUrl: '', - sharedSecret: '', - allowPuppets: false, - }, ManageSelfhostedTelegramBridgeDialogContext)).result.then(() => { - this.reload().catch(err => { + }); + selfhostedRef.result.then(() => { + try { + this.reload() + } catch (err) { console.error(err); this.translate.get('Failed to get an update Telegram bridge list').subscribe((res: string) => {this.toaster.pop("error", res); }); - }); - }); + } + }) + const selfhostedInstance = selfhostedRef.componentInstance as ManageSelfhostedTelegramBridgeDialogContext; + selfhostedInstance.provisionUrl = ''; + selfhostedInstance.sharedSecret = ''; + selfhostedInstance.allowMxPuppets = false; + selfhostedInstance.allowTgPuppets = false; } public getEnabledFeaturesString(bridge: FE_TelegramBridge): string { @@ -63,20 +67,24 @@ export class AdminTelegramBridgeComponent implements OnInit { } public editBridge(bridge: FE_TelegramBridge) { - this.modal.open(AdminTelegramBridgeManageSelfhostedComponent, overlayConfigFactory({ - isBlocking: true, + const selfhostedRef = this.modal.open(AdminTelegramBridgeManageSelfhostedComponent, { + backdrop: 'static', size: 'lg', - - provisionUrl: bridge.provisionUrl, - sharedSecret: bridge.sharedSecret, - allowTgPuppets: bridge.options ? bridge.options.allowTgPuppets : false, - allowMxPuppets: bridge.options ? bridge.options.allowMxPuppets : false, - bridgeId: bridge.id, - }, ManageSelfhostedTelegramBridgeDialogContext)).result.then(() => { - this.reload().catch(err => { + }); + selfhostedRef.result.then(() => { + try { + this.reload() + } catch (err) { console.error(err); this.translate.get('Failed to get an update Telegram bridge list').subscribe((res: string) => {this.toaster.pop("error", res); }); - }); - }); + } + }) + const selfhostedInstance = selfhostedRef.componentInstance as ManageSelfhostedTelegramBridgeDialogContext; + selfhostedInstance.provisionUrl = bridge.provisionUrl; + selfhostedInstance.sharedSecret = bridge.sharedSecret; + selfhostedInstance.allowMxPuppets = bridge.options?.allowTgPuppets || false; + selfhostedInstance.allowTgPuppets = bridge.options?.allowMxPuppets || false; + selfhostedInstance.bridgeId = bridge.id; + selfhostedInstance.isAdding = !bridge.id; } } diff --git a/web/app/admin/bridges/webhooks/manage-selfhosted/manage-selfhosted.component.html b/web/app/admin/bridges/webhooks/manage-selfhosted/manage-selfhosted.component.html index 2a80119..deda693 100644 --- a/web/app/admin/bridges/webhooks/manage-selfhosted/manage-selfhosted.component.html +++ b/web/app/admin/bridges/webhooks/manage-selfhosted/manage-selfhosted.component.html @@ -1,32 +1,31 @@ -
-
-

{{'self-hosted webhook bridge' | translate}} ({{ isAdding ? "Add a new" : "Edit" }})

-
-
-

{{'Self-hosted webhook bridges must have' | translate}} {{'provisioning' | translate}} {{'enabled in the configuration.' | translate}}

- - - - -
- + + + diff --git a/web/app/admin/bridges/webhooks/manage-selfhosted/manage-selfhosted.component.ts b/web/app/admin/bridges/webhooks/manage-selfhosted/manage-selfhosted.component.ts index 80798a7..29c9444 100644 --- a/web/app/admin/bridges/webhooks/manage-selfhosted/manage-selfhosted.component.ts +++ b/web/app/admin/bridges/webhooks/manage-selfhosted/manage-selfhosted.component.ts @@ -1,39 +1,37 @@ import { Component } from "@angular/core"; +import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap"; import { ToasterService } from "angular2-toaster"; -import { DialogRef, ModalComponent } from "ngx-modialog"; -import { BSModalContext } from "ngx-modialog/plugins/bootstrap"; import { AdminWebhooksApiService } from "../../../../shared/services/admin/admin-webhooks-api.service"; import { TranslateService } from "@ngx-translate/core"; -export class ManageSelfhostedWebhooksBridgeDialogContext extends BSModalContext { - public provisionUrl: string; - public sharedSecret: string; - public allowTgPuppets = false; - public allowMxPuppets = false; - public bridgeId: number; +export interface ManageSelfhostedWebhooksBridgeDialogContext { + provisionUrl: string; + sharedSecret: string; + allowTgPuppets: boolean; + allowMxPuppets: boolean; + bridgeId: number; + isAdding: boolean; } @Component({ templateUrl: "./manage-selfhosted.component.html", styleUrls: ["./manage-selfhosted.component.scss"], }) -export class AdminWebhooksBridgeManageSelfhostedComponent implements ModalComponent { +export class AdminWebhooksBridgeManageSelfhostedComponent { public isSaving = false; - public provisionUrl: string; - public sharedSecret: string; + public provisionUrl: ''; + public sharedSecret: ''; + public allowTgPuppets = false; + public allowMxPuppets = false; public bridgeId: number; - public isAdding = false; + public isAdding = true; - constructor(public dialog: DialogRef, + constructor(public modal: NgbActiveModal, private webhooksApi: AdminWebhooksApiService, private toaster: ToasterService, public translate: TranslateService) { this.translate = translate; - this.provisionUrl = dialog.context.provisionUrl; - this.sharedSecret = dialog.context.sharedSecret; - this.bridgeId = dialog.context.bridgeId; - this.isAdding = !this.bridgeId; } public add() { @@ -41,7 +39,7 @@ export class AdminWebhooksBridgeManageSelfhostedComponent implements ModalCompon if (this.isAdding) { this.webhooksApi.newSelfhosted(this.provisionUrl, this.sharedSecret).then(() => { this.translate.get('Webhook bridge added').subscribe((res: string) => {this.toaster.pop("success", res); }); - this.dialog.close(); + this.modal.close(); }).catch(err => { console.error(err); this.isSaving = false; @@ -50,7 +48,7 @@ export class AdminWebhooksBridgeManageSelfhostedComponent implements ModalCompon } else { this.webhooksApi.updateSelfhosted(this.bridgeId, this.provisionUrl, this.sharedSecret).then(() => { this.translate.get('Webhook bridge updated').subscribe((res: string) => {this.toaster.pop("success", res); }); - this.dialog.close(); + this.modal.close(); }).catch(err => { console.error(err); this.isSaving = false; diff --git a/web/app/admin/bridges/webhooks/webhooks.component.ts b/web/app/admin/bridges/webhooks/webhooks.component.ts index 1d53c94..1fab46e 100644 --- a/web/app/admin/bridges/webhooks/webhooks.component.ts +++ b/web/app/admin/bridges/webhooks/webhooks.component.ts @@ -1,6 +1,5 @@ import { Component, OnInit } from "@angular/core"; import { ToasterService } from "angular2-toaster"; -import { Modal, overlayConfigFactory } from "ngx-modialog"; import { AdminWebhooksBridgeManageSelfhostedComponent, ManageSelfhostedWebhooksBridgeDialogContext @@ -8,6 +7,7 @@ import { import { FE_WebhooksBridge } from "../../../shared/models/webhooks"; import { AdminWebhooksApiService } from "../../../shared/services/admin/admin-webhooks-api.service"; import { TranslateService } from "@ngx-translate/core"; +import { NgbModal } from "@ng-bootstrap/ng-bootstrap"; @Component({ templateUrl: "./webhooks.component.html", @@ -21,7 +21,7 @@ export class AdminWebhooksBridgeComponent implements OnInit { constructor(private webhooksApi: AdminWebhooksApiService, private toaster: ToasterService, - private modal: Modal, + private modal: NgbModal, public translate: TranslateService) { this.translate = translate; } @@ -40,34 +40,42 @@ export class AdminWebhooksBridgeComponent implements OnInit { } public addSelfHostedBridge() { - this.modal.open(AdminWebhooksBridgeManageSelfhostedComponent, overlayConfigFactory({ - isBlocking: true, + const selfhostedRef = this.modal.open(AdminWebhooksBridgeManageSelfhostedComponent, { + backdrop: 'static', size: 'lg', - - provisionUrl: '', - sharedSecret: '', - allowPuppets: false, - }, ManageSelfhostedWebhooksBridgeDialogContext)).result.then(() => { - this.reload().catch(err => { + }); + selfhostedRef.result.then(() => { + try { + this.reload() + } catch (err) { console.error(err); this.translate.get('Failed to get an update Webhooks bridge list').subscribe((res: string) => {this.toaster.pop("error", res); }); - }); + } }); + const selfhostedInstance = selfhostedRef.componentInstance as ManageSelfhostedWebhooksBridgeDialogContext; + selfhostedInstance.provisionUrl = ''; + selfhostedInstance.sharedSecret = ''; + selfhostedInstance.allowMxPuppets = false; + selfhostedInstance.allowTgPuppets = false; } public editBridge(bridge: FE_WebhooksBridge) { - this.modal.open(AdminWebhooksBridgeManageSelfhostedComponent, overlayConfigFactory({ - isBlocking: true, + const selfhostedRef = this.modal.open(AdminWebhooksBridgeManageSelfhostedComponent, { + backdrop: 'static', size: 'lg', - - provisionUrl: bridge.provisionUrl, - sharedSecret: bridge.sharedSecret, - bridgeId: bridge.id, - }, ManageSelfhostedWebhooksBridgeDialogContext)).result.then(() => { - this.reload().catch(err => { + }); + selfhostedRef.result.then(() => { + try { + this.reload() + } catch (err) { console.error(err); this.translate.get('Failed to get an update Webhooks bridge list').subscribe((res: string) => {this.toaster.pop("error", res); }); - }); + } }); + const selfhostedInstance = selfhostedRef.componentInstance as ManageSelfhostedWebhooksBridgeDialogContext; + selfhostedInstance.provisionUrl = bridge.provisionUrl; + selfhostedInstance.sharedSecret = bridge.sharedSecret + selfhostedInstance.bridgeId = bridge.id; + selfhostedInstance.isAdding = !bridge.id; } } diff --git a/web/app/admin/custom-bots/add/add.component.html b/web/app/admin/custom-bots/add/add.component.html index fdf8447..19cca09 100644 --- a/web/app/admin/custom-bots/add/add.component.html +++ b/web/app/admin/custom-bots/add/add.component.html @@ -1,56 +1,55 @@ -
-
-

{{ isAdding ? "Add a new" : "Edit" }} {{ 'custom bot' | translate}}

-
-
- - - - - - - - - -
- + + + diff --git a/web/app/admin/custom-bots/add/add.component.ts b/web/app/admin/custom-bots/add/add.component.ts index c67eee4..9797e16 100644 --- a/web/app/admin/custom-bots/add/add.component.ts +++ b/web/app/admin/custom-bots/add/add.component.ts @@ -1,34 +1,32 @@ import { Component } from "@angular/core"; +import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap"; import { ToasterService } from "angular2-toaster"; -import { DialogRef, ModalComponent } from "ngx-modialog"; -import { BSModalContext } from "ngx-modialog/plugins/bootstrap"; import { FE_CustomSimpleBot, FE_UserProfile } from "../../../shared/models/admin-responses"; import { AdminCustomSimpleBotsApiService } from "../../../shared/services/admin/admin-custom-simple-bots-api.service"; import { TranslateService } from "@ngx-translate/core"; -export class AddCustomBotDialogContext extends BSModalContext { +export interface AddCustomBotDialogContext { bot: FE_CustomSimpleBot; + isAdding: boolean; } @Component({ templateUrl: "./add.component.html", styleUrls: ["./add.component.scss"], }) -export class AdminAddCustomBotComponent implements ModalComponent { +export class AdminAddCustomBotComponent { - public bot: FE_CustomSimpleBot; - public isAdding = false; + public bot = {}; + public isAdding = true; public isSaving = false; private lastProfile: FE_UserProfile; - constructor(public dialog: DialogRef, + constructor(public modal: NgbActiveModal, private botApi: AdminCustomSimpleBotsApiService, private toaster: ToasterService, public translate: TranslateService) { this.translate = translate; - this.bot = this.dialog.context.bot || {}; - this.isAdding = !this.dialog.context.bot; } public loadProfile() { @@ -89,7 +87,7 @@ export class AdminAddCustomBotComponent implements ModalComponent { this.translate.get('Bot updated').subscribe((res: string) => {this.toaster.pop("success", res); }); - this.dialog.close(); + this.modal.close(); }).catch(error => { this.isSaving = false; console.error(error); diff --git a/web/app/admin/custom-bots/custom-bots.component.ts b/web/app/admin/custom-bots/custom-bots.component.ts index 52fcbc2..cb7549e 100644 --- a/web/app/admin/custom-bots/custom-bots.component.ts +++ b/web/app/admin/custom-bots/custom-bots.component.ts @@ -2,9 +2,9 @@ import { Component } from "@angular/core"; import { ToasterService } from "angular2-toaster"; import { FE_CustomSimpleBot } from "../../shared/models/admin-responses"; import { AdminCustomSimpleBotsApiService } from "../../shared/services/admin/admin-custom-simple-bots-api.service"; -import { Modal, overlayConfigFactory } from "ngx-modialog"; import { AddCustomBotDialogContext, AdminAddCustomBotComponent } from "./add/add.component"; import { TranslateService } from "@ngx-translate/core"; +import { NgbModal } from "@ng-bootstrap/ng-bootstrap"; @Component({ templateUrl: "./custom-bots.component.html", @@ -18,7 +18,7 @@ export class AdminCustomBotsComponent { constructor(private botApi: AdminCustomSimpleBotsApiService, private toaster: ToasterService, - private modal: Modal, + private modal: NgbModal, public translate: TranslateService) { this.translate = translate; @@ -36,29 +36,36 @@ export class AdminCustomBotsComponent { } public addBot() { - this.modal.open(AdminAddCustomBotComponent, overlayConfigFactory({ - isBlocking: true, + const selfhostedRef = this.modal.open(AdminAddCustomBotComponent, { + backdrop: 'static', size: 'lg', - }, AddCustomBotDialogContext)).result.then(() => { - this.reload().catch(err => { + }); + selfhostedRef.result.then(() => { + try { + this.reload() + } catch (err) { console.error(err); this.translate.get('Failed to get an updated bot list').subscribe((res: string) => {this.toaster.pop("error", res); }); - }); + } }); } public editBot(bot: FE_CustomSimpleBot) { - this.modal.open(AdminAddCustomBotComponent, overlayConfigFactory({ - isBlocking: true, + const selfhostedRef = this.modal.open(AdminAddCustomBotComponent, { + backdrop: 'static', size: 'lg', - - bot: bot, - }, AddCustomBotDialogContext)).result.then(() => { - this.reload().catch(err => { + }); + selfhostedRef.result.then(() => { + try { + this.reload() + } catch (err) { console.error(err); this.translate.get('Failed to get an updated bot list').subscribe((res: string) => {this.toaster.pop("error", res); }); - }); + } }); + const selfhostedInstance = selfhostedRef.componentInstance as AddCustomBotDialogContext; + selfhostedInstance.bot = bot; + selfhostedInstance.isAdding = !bot; } public toggleBot(bot: FE_CustomSimpleBot) { diff --git a/web/app/admin/home/home.component.ts b/web/app/admin/home/home.component.ts index 57457dc..05d357f 100644 --- a/web/app/admin/home/home.component.ts +++ b/web/app/admin/home/home.component.ts @@ -2,12 +2,11 @@ import { Component } from "@angular/core"; import { AdminApiService } from "../../shared/services/admin/admin-api.service"; import { FE_DimensionConfig } from "../../shared/models/admin-responses"; import { ToasterService } from "angular2-toaster"; -import { Modal, overlayConfigFactory } from "ngx-modialog"; import { AdminLogoutConfirmationDialogComponent, - LogoutConfirmationDialogContext } from "./logout-confirmation/logout-confirmation.component"; import { TranslateService } from "@ngx-translate/core"; +import { NgbModal } from "@ng-bootstrap/ng-bootstrap"; @Component({ templateUrl: "./home.component.html", @@ -20,7 +19,7 @@ export class AdminHomeComponent { constructor(private adminApi: AdminApiService, private toaster: ToasterService, - private modal: Modal, + private modal: NgbModal, public translate: TranslateService) { this.translate = translate; adminApi.getConfig().then(config => { @@ -30,16 +29,18 @@ export class AdminHomeComponent { } public logoutAll(): void { - this.modal.open(AdminLogoutConfirmationDialogComponent, overlayConfigFactory({ - isBlocking: true, - }, LogoutConfirmationDialogContext)).result.then(() => { - this.adminApi.logoutAll().then(() => { + const selfhostedRef = this.modal.open(AdminLogoutConfirmationDialogComponent, { + backdrop: 'static' + }); + selfhostedRef.result.then(async () => { + try { + await this.adminApi.logoutAll(); this.translate.get('Everyone has been logged out').subscribe((res: string) => {this.toaster.pop("success", res); }); this.config.sessionInfo.numTokens = 0; - }).catch(err => { + } catch (err) { console.error(err); this.translate.get('Error logging everyone out').subscribe((res: string) => {this.toaster.pop("error", res); }); - }); + } }); } } diff --git a/web/app/admin/home/logout-confirmation/logout-confirmation.component.html b/web/app/admin/home/logout-confirmation/logout-confirmation.component.html index 956b74e..7459841 100644 --- a/web/app/admin/home/logout-confirmation/logout-confirmation.component.html +++ b/web/app/admin/home/logout-confirmation/logout-confirmation.component.html @@ -1,18 +1,17 @@ -
-
-

{{'Logout confirmation' | translate}}

-
-
-

- {{'Logging everyone out will disable all known login tokens for Dimension and upstream integration managers. Most clients will automatically re-register for a login token behind the scenes, similar to how a login token was first acquired.' | translate}} -

-
- + + + diff --git a/web/app/admin/home/logout-confirmation/logout-confirmation.component.ts b/web/app/admin/home/logout-confirmation/logout-confirmation.component.ts index 471ad27..8287c35 100644 --- a/web/app/admin/home/logout-confirmation/logout-confirmation.component.ts +++ b/web/app/admin/home/logout-confirmation/logout-confirmation.component.ts @@ -1,16 +1,15 @@ import { Component } from "@angular/core"; -import { DialogRef, ModalComponent } from "ngx-modialog"; -import { BSModalContext } from "ngx-modialog/plugins/bootstrap"; +import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap"; -export class LogoutConfirmationDialogContext extends BSModalContext { +export interface LogoutConfirmationDialogContext { } @Component({ templateUrl: "./logout-confirmation.component.html", styleUrls: ["./logout-confirmation.component.scss"], }) -export class AdminLogoutConfirmationDialogComponent implements ModalComponent { +export class AdminLogoutConfirmationDialogComponent { - constructor(public dialog: DialogRef) { + constructor(public modal: NgbActiveModal) { } } diff --git a/web/app/admin/neb/add-selfhosted/add-selfhosted.component.ts b/web/app/admin/neb/add-selfhosted/add-selfhosted.component.ts index 5f35d91..93d1730 100644 --- a/web/app/admin/neb/add-selfhosted/add-selfhosted.component.ts +++ b/web/app/admin/neb/add-selfhosted/add-selfhosted.component.ts @@ -3,12 +3,12 @@ import { AdminAppserviceApiService } from "../../../shared/services/admin/admin- import { AdminNebApiService } from "../../../shared/services/admin/admin-neb-api.service"; import { ToasterService } from "angular2-toaster"; import { ActivatedRoute, Router } from "@angular/router"; -import { Modal, overlayConfigFactory } from "ngx-modialog"; import { AdminNebAppserviceConfigComponent, AppserviceConfigDialogContext } from "../appservice-config/appservice-config.component"; import { TranslateService } from "@ngx-translate/core"; +import { NgbModal } from "@ng-bootstrap/ng-bootstrap"; @Component({ @@ -26,9 +26,9 @@ export class AdminAddSelfhostedNebComponent { private toaster: ToasterService, private router: Router, private activatedRoute: ActivatedRoute, - private modal: Modal, + private modal: NgbModal, public translate: TranslateService) { - this.translate = translate; + this.translate = translate;{ } public save(): void { @@ -37,12 +37,14 @@ export class AdminAddSelfhostedNebComponent { return this.nebApi.newAppserviceConfiguration(this.adminUrl, appservice); }).then(neb => { this.translate.get('New go-neb created').subscribe((res: string) => {this.toaster.pop("success", res); }); - this.modal.open(AdminNebAppserviceConfigComponent, overlayConfigFactory({ - neb: neb, - isBlocking: true, + const selfhostedRef = this.modal.open(AdminNebAppserviceConfigComponent, { + backdrop: 'static', size: 'lg', - }, AppserviceConfigDialogContext)).result.then(() => this.router.navigate(["../.."], {relativeTo: this.activatedRoute})); + }); + selfhostedRef.result.then(() => this.router.navigate(["../.."], {relativeTo: this.activatedRoute})); + const selfhostedInstance = selfhostedRef.componentInstance as AppserviceConfigDialogContext; + selfhostedInstance.neb = neb; }).catch(err => { console.error(err); this.isSaving = false; diff --git a/web/app/admin/neb/appservice-config/appservice-config.component.html b/web/app/admin/neb/appservice-config/appservice-config.component.html index 833e80f..5f07280 100644 --- a/web/app/admin/neb/appservice-config/appservice-config.component.html +++ b/web/app/admin/neb/appservice-config/appservice-config.component.html @@ -1,22 +1,21 @@ -
-
-

{{'go-neb appservice configuration' | translate}}

-
-
- -
-
- {{'Copy and paste this configuration to' | translate}} appservice-{{appservice.id}}.yaml - {{'on your homeserver and register it as an application service.' | translate}} -
-
{{appserviceConfig}}
-
- + + + + diff --git a/web/app/admin/neb/appservice-config/appservice-config.component.ts b/web/app/admin/neb/appservice-config/appservice-config.component.ts index 9532d13..22e0b68 100644 --- a/web/app/admin/neb/appservice-config/appservice-config.component.ts +++ b/web/app/admin/neb/appservice-config/appservice-config.component.ts @@ -1,32 +1,29 @@ import { Component } from "@angular/core"; import { ToasterService } from "angular2-toaster"; -import { DialogRef, ModalComponent } from "ngx-modialog"; import { FE_Appservice, FE_NebConfiguration } from "../../../shared/models/admin-responses"; import { AdminAppserviceApiService } from "../../../shared/services/admin/admin-appservice-api.service"; -import { BSModalContext } from "ngx-modialog/plugins/bootstrap"; import { TranslateService } from "@ngx-translate/core"; +import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap"; -export class AppserviceConfigDialogContext extends BSModalContext { - public neb: FE_NebConfiguration; +export interface AppserviceConfigDialogContext { + neb: FE_NebConfiguration; } @Component({ templateUrl: "./appservice-config.component.html", styleUrls: ["./appservice-config.component.scss"], }) -export class AdminNebAppserviceConfigComponent implements ModalComponent { +export class AdminNebAppserviceConfigComponent { public isLoading = true; public neb: FE_NebConfiguration; public appservice: FE_Appservice; - constructor(public dialog: DialogRef, + constructor(public modal: NgbActiveModal, private adminAppserviceApi: AdminAppserviceApiService, private toaster: ToasterService, public translate: TranslateService) { this.translate = translate; - this.neb = dialog.context.neb; - this.adminAppserviceApi.getAppservice(this.neb.appserviceId).then(appservice => { this.appservice = appservice; this.isLoading = false; diff --git a/web/app/admin/neb/config/config-context.ts b/web/app/admin/neb/config/config-context.ts index cc3299e..1eb9ddc 100644 --- a/web/app/admin/neb/config/config-context.ts +++ b/web/app/admin/neb/config/config-context.ts @@ -1,8 +1,7 @@ -import { BSModalContext } from "ngx-modialog/plugins/bootstrap"; import { FE_NebConfiguration } from "../../../shared/models/admin-responses"; import { FE_Integration } from "../../../shared/models/integration"; -export class NebBotConfigurationDialogContext extends BSModalContext { - public integration: FE_Integration; - public neb: FE_NebConfiguration; +export interface NebBotConfigurationDialogContext { + integration: FE_Integration; + neb: FE_NebConfiguration; } \ No newline at end of file diff --git a/web/app/admin/neb/config/giphy/giphy.component.html b/web/app/admin/neb/config/giphy/giphy.component.html index 47412fb..53357b8 100644 --- a/web/app/admin/neb/config/giphy/giphy.component.html +++ b/web/app/admin/neb/config/giphy/giphy.component.html @@ -1,33 +1,32 @@ -
-
-

{{'Giphy Configuration' | translate}}

-
-
- -
-
- - -
- + + + + diff --git a/web/app/admin/neb/config/giphy/giphy.component.ts b/web/app/admin/neb/config/giphy/giphy.component.ts index b814908..6bd963b 100644 --- a/web/app/admin/neb/config/giphy/giphy.component.ts +++ b/web/app/admin/neb/config/giphy/giphy.component.ts @@ -1,11 +1,10 @@ import { Component, OnInit } from "@angular/core"; import { ToasterService } from "angular2-toaster"; -import { DialogRef, ModalComponent } from "ngx-modialog"; -import { NebBotConfigurationDialogContext } from "../config-context"; import { AdminNebApiService } from "../../../../shared/services/admin/admin-neb-api.service"; import { FE_NebConfiguration } from "../../../../shared/models/admin-responses"; import { FE_Integration } from "../../../../shared/models/integration"; import { TranslateService } from "@ngx-translate/core"; +import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap"; interface GiphyConfig { api_key: string; @@ -16,7 +15,7 @@ interface GiphyConfig { templateUrl: "./giphy.component.html", styleUrls: ["./giphy.component.scss", "../config-dialog.scss"], }) -export class AdminNebGiphyConfigComponent implements ModalComponent, OnInit { +export class AdminNebGiphyConfigComponent implements OnInit { public isLoading = true; public isUpdating = false; @@ -24,13 +23,11 @@ export class AdminNebGiphyConfigComponent implements ModalComponent, + constructor(public modal: NgbActiveModal, private adminNebApi: AdminNebApiService, private toaster: ToasterService, public translate: TranslateService) { this.translate = translate; - this.neb = dialog.context.neb; - this.integration = dialog.context.integration; } public ngOnInit() { @@ -47,7 +44,7 @@ export class AdminNebGiphyConfigComponent implements ModalComponent { this.translate.get('Configuration updated').subscribe((res: string) => {this.toaster.pop("success", res); }); - this.dialog.close(); + this.modal.close(); }).catch(err => { this.isUpdating = false; console.error(err); diff --git a/web/app/admin/neb/config/google/google.component.html b/web/app/admin/neb/config/google/google.component.html index 1f9fd4b..b0355a6 100644 --- a/web/app/admin/neb/config/google/google.component.html +++ b/web/app/admin/neb/config/google/google.component.html @@ -1,32 +1,31 @@ -
-
-

{{'Google Configuration' | translate}}

-
-
- -
-
- - -
- + + + + diff --git a/web/app/admin/neb/config/google/google.component.ts b/web/app/admin/neb/config/google/google.component.ts index aa6e71e..8f3d005 100644 --- a/web/app/admin/neb/config/google/google.component.ts +++ b/web/app/admin/neb/config/google/google.component.ts @@ -1,11 +1,10 @@ import { Component, OnInit } from "@angular/core"; import { ToasterService } from "angular2-toaster"; -import { DialogRef, ModalComponent } from "ngx-modialog"; -import { NebBotConfigurationDialogContext } from "../config-context"; import { AdminNebApiService } from "../../../../shared/services/admin/admin-neb-api.service"; import { FE_NebConfiguration } from "../../../../shared/models/admin-responses"; import { FE_Integration } from "../../../../shared/models/integration"; import { TranslateService } from "@ngx-translate/core"; +import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap"; interface GoogleConfig { api_key: string; @@ -16,7 +15,7 @@ interface GoogleConfig { templateUrl: "./google.component.html", styleUrls: ["./google.component.scss", "../config-dialog.scss"], }) -export class AdminNebGoogleConfigComponent implements ModalComponent, OnInit { +export class AdminNebGoogleConfigComponent implements OnInit { public isLoading = true; public isUpdating = false; @@ -24,13 +23,11 @@ export class AdminNebGoogleConfigComponent implements ModalComponent, + constructor(public modal: NgbActiveModal, private adminNebApi: AdminNebApiService, private toaster: ToasterService, public translate: TranslateService) { this.translate = translate; - this.neb = dialog.context.neb; - this.integration = dialog.context.integration; } public ngOnInit() { @@ -47,7 +44,7 @@ export class AdminNebGoogleConfigComponent implements ModalComponent { this.translate.get('Configuration updated').subscribe((res: string) => {this.toaster.pop("success", res); }); - this.dialog.close(); + this.modal.close(); }).catch(err => { this.isUpdating = false; console.error(err); diff --git a/web/app/admin/neb/config/guggy/guggy.component.html b/web/app/admin/neb/config/guggy/guggy.component.html index cb39e55..47423f2 100644 --- a/web/app/admin/neb/config/guggy/guggy.component.html +++ b/web/app/admin/neb/config/guggy/guggy.component.html @@ -1,25 +1,24 @@ -
-
-

{{'Guggy Configuration' | translate}}

-
-
- -
-
- -
- + + + + diff --git a/web/app/admin/neb/config/guggy/guggy.component.ts b/web/app/admin/neb/config/guggy/guggy.component.ts index 0d827c3..cc60730 100644 --- a/web/app/admin/neb/config/guggy/guggy.component.ts +++ b/web/app/admin/neb/config/guggy/guggy.component.ts @@ -1,11 +1,10 @@ import { Component, OnInit } from "@angular/core"; import { ToasterService } from "angular2-toaster"; -import { DialogRef, ModalComponent } from "ngx-modialog"; -import { NebBotConfigurationDialogContext } from "../config-context"; import { AdminNebApiService } from "../../../../shared/services/admin/admin-neb-api.service"; import { FE_NebConfiguration } from "../../../../shared/models/admin-responses"; import { FE_Integration } from "../../../../shared/models/integration"; import { TranslateService } from "@ngx-translate/core"; +import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap"; interface GuggyConfig { api_key: string; @@ -15,7 +14,7 @@ interface GuggyConfig { templateUrl: "./guggy.component.html", styleUrls: ["./guggy.component.scss", "../config-dialog.scss"], }) -export class AdminNebGuggyConfigComponent implements ModalComponent, OnInit { +export class AdminNebGuggyConfigComponent implements OnInit { public isLoading = true; public isUpdating = false; @@ -23,13 +22,11 @@ export class AdminNebGuggyConfigComponent implements ModalComponent, + constructor(public modal: NgbActiveModal, private adminNebApi: AdminNebApiService, private toaster: ToasterService, public translate: TranslateService) { this.translate = translate; - this.neb = dialog.context.neb; - this.integration = dialog.context.integration; } public ngOnInit() { @@ -46,7 +43,7 @@ export class AdminNebGuggyConfigComponent implements ModalComponent { this.translate.get('Configuration updated').subscribe((res: string) => {this.toaster.pop("success", res); }); - this.dialog.close(); + this.modal.close(); }).catch(err => { this.isUpdating = false; console.error(err); diff --git a/web/app/admin/neb/config/imgur/imgur.component.html b/web/app/admin/neb/config/imgur/imgur.component.html index 0b3d700..8566133 100644 --- a/web/app/admin/neb/config/imgur/imgur.component.html +++ b/web/app/admin/neb/config/imgur/imgur.component.html @@ -1,32 +1,31 @@ -
-
-

{{'Imgur Configuration' | translate}}

-
-
- -
-
- - -
- + + + + diff --git a/web/app/admin/neb/config/imgur/imgur.component.ts b/web/app/admin/neb/config/imgur/imgur.component.ts index 39d0ed0..c932d02 100644 --- a/web/app/admin/neb/config/imgur/imgur.component.ts +++ b/web/app/admin/neb/config/imgur/imgur.component.ts @@ -1,11 +1,10 @@ import { Component, OnInit } from "@angular/core"; import { ToasterService } from "angular2-toaster"; -import { DialogRef, ModalComponent } from "ngx-modialog"; -import { NebBotConfigurationDialogContext } from "../config-context"; import { AdminNebApiService } from "../../../../shared/services/admin/admin-neb-api.service"; import { FE_NebConfiguration } from "../../../../shared/models/admin-responses"; import { FE_Integration } from "../../../../shared/models/integration"; import { TranslateService } from "@ngx-translate/core"; +import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap"; interface ImgurConfig { client_id: string; @@ -16,7 +15,7 @@ interface ImgurConfig { templateUrl: "./imgur.component.html", styleUrls: ["./imgur.component.scss", "../config-dialog.scss"], }) -export class AdminNebImgurConfigComponent implements ModalComponent, OnInit { +export class AdminNebImgurConfigComponent implements OnInit { public isLoading = true; public isUpdating = false; @@ -24,13 +23,11 @@ export class AdminNebImgurConfigComponent implements ModalComponent, + constructor(public modal: NgbActiveModal, private adminNebApi: AdminNebApiService, private toaster: ToasterService, public translate: TranslateService) { this.translate = translate; - this.neb = dialog.context.neb; - this.integration = dialog.context.integration; } public ngOnInit() { @@ -47,7 +44,7 @@ export class AdminNebImgurConfigComponent implements ModalComponent { this.translate.get('Configuration updated').subscribe((res: string) => {this.toaster.pop("success", res); }); - this.dialog.close(); + this.modal.close(); }).catch(err => { this.isUpdating = false; console.error(err); diff --git a/web/app/admin/neb/edit/edit.component.ts b/web/app/admin/neb/edit/edit.component.ts index 4bd46bb..5ec312e 100644 --- a/web/app/admin/neb/edit/edit.component.ts +++ b/web/app/admin/neb/edit/edit.component.ts @@ -5,14 +5,13 @@ import { ActivatedRoute } from "@angular/router"; import { ToasterService } from "angular2-toaster"; import { FE_Integration } from "../../../shared/models/integration"; import { NEB_HAS_CONFIG, NEB_IS_COMPLEX } from "../../../shared/models/neb"; -import { ContainerContent, Modal, overlayConfigFactory } from "ngx-modialog"; import { AdminNebGiphyConfigComponent } from "../config/giphy/giphy.component"; import { NebBotConfigurationDialogContext } from "../config/config-context"; import { AdminNebGuggyConfigComponent } from "../config/guggy/guggy.component"; import { AdminNebGoogleConfigComponent } from "../config/google/google.component"; import { AdminNebImgurConfigComponent } from "../config/imgur/imgur.component"; import { TranslateService } from "@ngx-translate/core"; - +import { NgbModal } from "@ng-bootstrap/ng-bootstrap"; @Component({ templateUrl: "./edit.component.html", @@ -30,7 +29,7 @@ export class AdminEditNebComponent implements OnInit, OnDestroy { constructor(private nebApi: AdminNebApiService, private route: ActivatedRoute, - private modal: Modal, + private modal: NgbModal, private toaster: ToasterService, public translate: TranslateService) { this.translate = translate; @@ -87,7 +86,7 @@ export class AdminEditNebComponent implements OnInit, OnDestroy { } public editBot(bot: FE_Integration) { - let component: ContainerContent; + let component; if (bot.type === "giphy") component = AdminNebGiphyConfigComponent; if (bot.type === "guggy") component = AdminNebGuggyConfigComponent; @@ -95,13 +94,13 @@ export class AdminEditNebComponent implements OnInit, OnDestroy { if (bot.type === "imgur") component = AdminNebImgurConfigComponent; if (!component) throw new Error("No config component for " + bot.type); - this.modal.open(component, overlayConfigFactory({ - neb: this.nebConfig, - integration: bot, - - isBlocking: true, + const nebBotRef = this.modal.open(component, { + backdrop: 'static', size: 'lg', - }, NebBotConfigurationDialogContext)); + }); + const nebBotInstance = nebBotRef.componentInstance as NebBotConfigurationDialogContext; + nebBotInstance.neb = this.nebConfig; + nebBotInstance.integration = bot; } private loadNeb(nebId: number) { diff --git a/web/app/admin/neb/neb.component.ts b/web/app/admin/neb/neb.component.ts index 86ad0f2..045ad41 100644 --- a/web/app/admin/neb/neb.component.ts +++ b/web/app/admin/neb/neb.component.ts @@ -9,8 +9,8 @@ import { AdminNebAppserviceConfigComponent, AppserviceConfigDialogContext } from "./appservice-config/appservice-config.component"; -import { Modal, overlayConfigFactory } from "ngx-modialog"; import { TranslateService } from "@ngx-translate/core"; +import { NgbModal } from "@ng-bootstrap/ng-bootstrap"; @Component({ templateUrl: "./neb.component.html", @@ -31,7 +31,7 @@ export class AdminNebComponent { private toaster: ToasterService, private router: Router, private activatedRoute: ActivatedRoute, - private modal: Modal, + private modal: NgbModal, public translate: TranslateService) { this.translate = translate; @@ -77,12 +77,12 @@ export class AdminNebComponent { } public showAppserviceConfig(neb: FE_NebConfiguration) { - this.modal.open(AdminNebAppserviceConfigComponent, overlayConfigFactory({ - neb: neb, - - isBlocking: true, + const selfhostedRef = this.modal.open(AdminNebAppserviceConfigComponent, { + backdrop: 'static', size: 'lg', - }, AppserviceConfigDialogContext)); + }); + const selfhostedInstance = selfhostedRef.componentInstance as AppserviceConfigDialogContext; + selfhostedInstance.neb = neb; } public getEnabledBotsString(neb: FE_NebConfiguration): string { diff --git a/web/app/admin/sticker-packs/preview/preview.component.html b/web/app/admin/sticker-packs/preview/preview.component.html index 0a5e04f..9561b06 100644 --- a/web/app/admin/sticker-packs/preview/preview.component.html +++ b/web/app/admin/sticker-packs/preview/preview.component.html @@ -1,19 +1,16 @@ -
-
-

Sticker Pack: {{ pack.displayName }}

-
-
-
- -
- {{ sticker.name }} - {{ sticker.description }} -
+ + + diff --git a/web/app/admin/sticker-packs/preview/preview.component.ts b/web/app/admin/sticker-packs/preview/preview.component.ts index ffd9d72..f4956ea 100644 --- a/web/app/admin/sticker-packs/preview/preview.component.ts +++ b/web/app/admin/sticker-packs/preview/preview.component.ts @@ -1,10 +1,9 @@ import { Component } from "@angular/core"; import { FE_StickerPack } from "../../../shared/models/integration"; -import { DialogRef, ModalComponent } from "ngx-modialog"; -import { BSModalContext } from "ngx-modialog/plugins/bootstrap"; import { MediaService } from "../../../shared/services/media.service"; +import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap"; -export class StickerPackPreviewDialogContext extends BSModalContext { +export class StickerPackPreviewMoadlInstance { public pack: FE_StickerPack; } @@ -12,12 +11,12 @@ export class StickerPackPreviewDialogContext extends BSModalContext { templateUrl: "./preview.component.html", styleUrls: ["./preview.component.scss"], }) -export class AdminStickerPackPreviewComponent implements ModalComponent { +export class AdminStickerPackPreviewComponent { - public pack: FE_StickerPack; + pack: FE_StickerPack; + + constructor(public modal: NgbActiveModal, private media: MediaService) { - constructor(public dialog: DialogRef, private media: MediaService) { - this.pack = dialog.context.pack; } public getThumbnailUrl(mxc: string, width: number, height: number, method: "crop" | "scale" = "scale"): string { diff --git a/web/app/admin/sticker-packs/sticker-packs.component.ts b/web/app/admin/sticker-packs/sticker-packs.component.ts index c4c5ef7..421d4d1 100644 --- a/web/app/admin/sticker-packs/sticker-packs.component.ts +++ b/web/app/admin/sticker-packs/sticker-packs.component.ts @@ -2,8 +2,8 @@ import { Component, OnInit } from "@angular/core"; import { ToasterService } from "angular2-toaster"; import { FE_StickerPack } from "../../shared/models/integration"; import { AdminStickersApiService } from "../../shared/services/admin/admin-stickers-api-service"; -import { Modal, overlayConfigFactory } from "ngx-modialog"; -import { AdminStickerPackPreviewComponent, StickerPackPreviewDialogContext } from "./preview/preview.component"; +import { AdminStickerPackPreviewComponent, StickerPackPreviewMoadlInstance } from "./preview/preview.component"; +import { NgbModal } from "@ng-bootstrap/ng-bootstrap"; import { TranslateService } from "@ngx-translate/core"; @Component({ @@ -20,7 +20,7 @@ export class AdminStickerPacksComponent implements OnInit { constructor(private adminStickers: AdminStickersApiService, private toaster: ToasterService, - private modal: Modal, + private modal: NgbModal, public translate: TranslateService) { this.translate = translate; } @@ -50,12 +50,10 @@ export class AdminStickerPacksComponent implements OnInit { } public previewStickers(pack: FE_StickerPack) { - this.modal.open(AdminStickerPackPreviewComponent, overlayConfigFactory({ - pack: pack, + const modalRef = this.modal.open(AdminStickerPackPreviewComponent, { size: 'lg' }); + const previewInstance = modalRef.componentInstance as StickerPackPreviewMoadlInstance; - isBlocking: false, - size: 'lg', - }, StickerPackPreviewDialogContext)); + previewInstance.pack = pack; } public startTelegramImport() { diff --git a/web/app/admin/terms/new-edit/new-edit.component.ts b/web/app/admin/terms/new-edit/new-edit.component.ts index ce682ae..830ac45 100644 --- a/web/app/admin/terms/new-edit/new-edit.component.ts +++ b/web/app/admin/terms/new-edit/new-edit.component.ts @@ -4,12 +4,11 @@ import { AdminTermsApiService } from "../../../shared/services/admin/admin-terms import { ActivatedRoute, Router } from "@angular/router"; import * as ClassicEditor from '@ckeditor/ckeditor5-build-classic'; import ISO6391 from "iso-639-1"; -import { Modal, overlayConfigFactory } from "ngx-modialog"; import { AdminTermsNewEditPublishDialogComponent, - AdminTermsNewEditPublishDialogContext } from "./publish/publish.component"; import { TranslateService } from "@ngx-translate/core"; +import { NgbModal } from "@ng-bootstrap/ng-bootstrap"; interface ILanguage { name: string, @@ -67,7 +66,7 @@ export class AdminNewEditTermsComponent implements OnInit { private toaster: ToasterService, private router: Router, private activatedRoute: ActivatedRoute, - private modal: Modal, + private modal: NgbModal, public translate: TranslateService) { this.translate = translate; } @@ -119,11 +118,11 @@ export class AdminNewEditTermsComponent implements OnInit { url: `${window.location.origin}/widgets/terms/${this.shortcode}/en/draft`, }); - - this.modal.open(AdminTermsNewEditPublishDialogComponent, overlayConfigFactory({ - isBlocking: true, + const termsEditRef = this.modal.open(AdminTermsNewEditPublishDialogComponent, { + backdrop: 'static', size: 'sm', - }, AdminTermsNewEditPublishDialogContext)).result.then(async (val) => { + }); + termsEditRef.result.then(async (val) => { if (!val) return; // closed without publish try { diff --git a/web/app/admin/terms/new-edit/publish/publish.component.html b/web/app/admin/terms/new-edit/publish/publish.component.html index 5dc07f4..e4cfde7 100644 --- a/web/app/admin/terms/new-edit/publish/publish.component.html +++ b/web/app/admin/terms/new-edit/publish/publish.component.html @@ -1,20 +1,19 @@ -
-
-

{{'Publish policy' | translate}}

-
-
- -
- + + + diff --git a/web/app/admin/terms/new-edit/publish/publish.component.ts b/web/app/admin/terms/new-edit/publish/publish.component.ts index b3c1bbb..9f7be40 100644 --- a/web/app/admin/terms/new-edit/publish/publish.component.ts +++ b/web/app/admin/terms/new-edit/publish/publish.component.ts @@ -1,21 +1,20 @@ import { Component } from "@angular/core"; -import { DialogRef, ModalComponent } from "ngx-modialog"; -import { BSModalContext } from "ngx-modialog/plugins/bootstrap"; import { ToasterService } from "angular2-toaster"; import { TranslateService } from "@ngx-translate/core"; +import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap"; -export class AdminTermsNewEditPublishDialogContext extends BSModalContext { +export interface AdminTermsNewEditPublishDialogContext { } @Component({ templateUrl: "./publish.component.html", styleUrls: ["./publish.component.scss"], }) -export class AdminTermsNewEditPublishDialogComponent implements ModalComponent { +export class AdminTermsNewEditPublishDialogComponent { public version: string; - constructor(public dialog: DialogRef, private toaster: ToasterService, public translate: TranslateService) { + constructor(public modal: NgbActiveModal, private toaster: ToasterService, public translate: TranslateService) { } public publish() { @@ -23,6 +22,6 @@ export class AdminTermsNewEditPublishDialogComponent implements ModalComponent {this.toaster.pop("warning", res); }); return; } - this.dialog.close(this.version); + this.modal.close(this.version); } } diff --git a/web/app/admin/widgets/etherpad/etherpad.component.html b/web/app/admin/widgets/etherpad/etherpad.component.html index 30763dd..d0b775f 100644 --- a/web/app/admin/widgets/etherpad/etherpad.component.html +++ b/web/app/admin/widgets/etherpad/etherpad.component.html @@ -1,22 +1,21 @@ -
-
-

{{'Etherpad Widget Configuration' | translate}}

-
-
- -
- + + + diff --git a/web/app/admin/widgets/etherpad/etherpad.component.ts b/web/app/admin/widgets/etherpad/etherpad.component.ts index 25b97c4..c2eb69b 100644 --- a/web/app/admin/widgets/etherpad/etherpad.component.ts +++ b/web/app/admin/widgets/etherpad/etherpad.component.ts @@ -1,27 +1,29 @@ -import { Component } from "@angular/core"; +import { Component, OnInit } from "@angular/core"; import { FE_EtherpadWidget } from "../../../shared/models/integration"; import { ToasterService } from "angular2-toaster"; -import { DialogRef, ModalComponent } from "ngx-modialog"; -import { WidgetConfigDialogContext } from "../widgets.component"; import { AdminIntegrationsApiService } from "../../../shared/services/admin/admin-integrations-api.service"; import { TranslateService } from "@ngx-translate/core"; +import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap"; @Component({ templateUrl: "./etherpad.component.html", styleUrls: ["./etherpad.component.scss", "../config-dialog.scss"], }) -export class AdminWidgetEtherpadConfigComponent implements ModalComponent { +export class AdminWidgetEtherpadConfigComponent implements OnInit { public isUpdating = false; public widget: FE_EtherpadWidget; - private originalWidget: FE_EtherpadWidget; + private originalWidget = {}; - constructor(public dialog: DialogRef, + constructor(public modal: NgbActiveModal, private adminIntegrationsApi: AdminIntegrationsApiService, private toaster: ToasterService, public translate: TranslateService) { this.translate = translate; - this.originalWidget = dialog.context.widget; + } + + ngOnInit() { + this.originalWidget = this.widget; this.widget = JSON.parse(JSON.stringify(this.originalWidget)); } @@ -30,7 +32,7 @@ export class AdminWidgetEtherpadConfigComponent implements ModalComponent { this.originalWidget.options = this.widget.options; this.translate.get('Widget updated').subscribe((res: string) => {this.toaster.pop("success", res); }); - this.dialog.close(); + this.modal.close(); }).catch(err => { this.isUpdating = false; console.error(err); diff --git a/web/app/admin/widgets/jitsi/jitsi.component.html b/web/app/admin/widgets/jitsi/jitsi.component.html index df74150..b3d1ae8 100644 --- a/web/app/admin/widgets/jitsi/jitsi.component.html +++ b/web/app/admin/widgets/jitsi/jitsi.component.html @@ -1,35 +1,34 @@ -
-
-

{{'Jitsi Widget Configuration' | translate}}

-
-
- - - -
- + + + diff --git a/web/app/admin/widgets/jitsi/jitsi.component.ts b/web/app/admin/widgets/jitsi/jitsi.component.ts index 309581d..8a3c09e 100644 --- a/web/app/admin/widgets/jitsi/jitsi.component.ts +++ b/web/app/admin/widgets/jitsi/jitsi.component.ts @@ -1,24 +1,29 @@ -import { Component } from "@angular/core"; +import { Component, OnInit } from "@angular/core"; import { FE_JitsiWidget } from "../../../shared/models/integration"; import { ToasterService } from "angular2-toaster"; -import { DialogRef, ModalComponent } from "ngx-modialog"; -import { WidgetConfigDialogContext } from "../widgets.component"; import { AdminIntegrationsApiService } from "../../../shared/services/admin/admin-integrations-api.service"; import { TranslateService } from "@ngx-translate/core"; +import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap"; @Component({ templateUrl: "./jitsi.component.html", styleUrls: ["./jitsi.component.scss", "../config-dialog.scss"], }) -export class AdminWidgetJitsiConfigComponent implements ModalComponent { +export class AdminWidgetJitsiConfigComponent implements OnInit { public isUpdating = false; public widget: FE_JitsiWidget; - private originalWidget: FE_JitsiWidget; + private originalWidget = {}; - constructor(public dialog: DialogRef, private adminIntegrationsApi: AdminIntegrationsApiService, private toaster: ToasterService, public translate: TranslateService) { - this.translate = translate; - this.originalWidget = dialog.context.widget; + constructor(public modal: NgbActiveModal, + private adminIntegrationsApi: AdminIntegrationsApiService, + private toaster: ToasterService, + public translate: TranslateService) { + this.translate = translate; + } + + ngOnInit() { + this.originalWidget = this.widget; this.widget = JSON.parse(JSON.stringify(this.originalWidget)); // Fix the ui-switch not picking up a boolean value @@ -30,7 +35,7 @@ export class AdminWidgetJitsiConfigComponent implements ModalComponent { this.originalWidget.options = this.widget.options; this.translate.get('Widget updated').subscribe((res: string) => {this.toaster.pop("success", res); }); - this.dialog.close(); + this.modal.close(); }).catch(err => { this.isUpdating = false; console.error(err); diff --git a/web/app/admin/widgets/whiteboard/whiteboard.component.html b/web/app/admin/widgets/whiteboard/whiteboard.component.html index 68fc80c..93822ae 100644 --- a/web/app/admin/widgets/whiteboard/whiteboard.component.html +++ b/web/app/admin/widgets/whiteboard/whiteboard.component.html @@ -1,22 +1,20 @@ -
-
-

Whiteboard Widget Configuration

-
-
- -
- + + + \ No newline at end of file diff --git a/web/app/admin/widgets/whiteboard/whiteboard.component.ts b/web/app/admin/widgets/whiteboard/whiteboard.component.ts index 6b9c01b..73071e8 100644 --- a/web/app/admin/widgets/whiteboard/whiteboard.component.ts +++ b/web/app/admin/widgets/whiteboard/whiteboard.component.ts @@ -1,22 +1,29 @@ -import { Component } from "@angular/core"; +import { Component, OnInit } from "@angular/core"; import { FE_WhiteBoardWidget } from "../../../shared/models/integration"; import { ToasterService } from "angular2-toaster"; -import { DialogRef, ModalComponent } from "ngx-modialog"; -import { WidgetConfigDialogContext } from "../widgets.component"; +import { TranslateService } from "@ngx-translate/core"; +import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap"; import { AdminIntegrationsApiService } from "../../../shared/services/admin/admin-integrations-api.service"; @Component({ templateUrl: "./whiteboard.component.html", styleUrls: ["./whiteboard.component.scss", "../config-dialog.scss"], }) -export class AdminWidgetWhiteboardConfigComponent implements ModalComponent { +export class AdminWidgetWhiteboardConfigComponent implements OnInit { public isUpdating = false; public widget: FE_WhiteBoardWidget; private originalWidget: FE_WhiteBoardWidget; - constructor(public dialog: DialogRef, private adminIntegrationsApi: AdminIntegrationsApiService, private toaster: ToasterService) { - this.originalWidget = dialog.context.widget; + constructor(public modal: NgbActiveModal, + private adminIntegrationsApi: AdminIntegrationsApiService, + private toaster: ToasterService, + public translate: TranslateService) { + this.translate = translate; + } + + ngOnInit() { + this.originalWidget = this.widget; this.widget = JSON.parse(JSON.stringify(this.originalWidget)); } @@ -25,7 +32,7 @@ export class AdminWidgetWhiteboardConfigComponent implements ModalComponent { this.originalWidget.options = this.widget.options; this.toaster.pop("success", "Widget updated"); - this.dialog.close(); + this.modal.close(); }).catch(err => { this.isUpdating = false; console.error(err); diff --git a/web/app/admin/widgets/widgets.component.ts b/web/app/admin/widgets/widgets.component.ts index eccad8e..4cda925 100644 --- a/web/app/admin/widgets/widgets.component.ts +++ b/web/app/admin/widgets/widgets.component.ts @@ -2,15 +2,14 @@ import { Component } from "@angular/core"; import { FE_Widget } from "../../shared/models/integration"; import { ToasterService } from "angular2-toaster"; import { AdminWidgetEtherpadConfigComponent } from "./etherpad/etherpad.component"; -import { Modal, overlayConfigFactory } from "ngx-modialog"; -import { BSModalContext } from "ngx-modialog/plugins/bootstrap"; import { AdminWidgetJitsiConfigComponent } from "./jitsi/jitsi.component"; import { AdminIntegrationsApiService } from "../../shared/services/admin/admin-integrations-api.service"; import { AdminWidgetWhiteboardConfigComponent } from "./whiteboard/whiteboard.component"; import { TranslateService } from "@ngx-translate/core"; +import { NgbModal } from "@ng-bootstrap/ng-bootstrap"; -export class WidgetConfigDialogContext extends BSModalContext { - public widget: FE_Widget; +export interface WidgetConfigDialogContext { + widget: FE_Widget; } @Component({ @@ -23,7 +22,7 @@ export class AdminWidgetsComponent { public isUpdating = false; public widgets: FE_Widget[]; - constructor(private adminIntegrationsApi: AdminIntegrationsApiService, private toaster: ToasterService, private modal: Modal, public translate: TranslateService) { + constructor(private adminIntegrationsApi: AdminIntegrationsApiService, private toaster: ToasterService, private modal: NgbModal, public translate: TranslateService) { this.translate = translate; this.adminIntegrationsApi.getAllWidgets().then(widgets => { this.isLoading = false; @@ -61,12 +60,11 @@ export class AdminWidgetsComponent { return; } - this.modal.open(component, overlayConfigFactory({ - widget: widget, - - isBlocking: true, - size: 'lg', - }, WidgetConfigDialogContext)); + const widgetConfigRef = this.modal.open(component, { + backdrop: 'static' + }); + const widgetConfigInterface = widgetConfigRef.componentInstance as WidgetConfigDialogContext; + widgetConfigInterface.widget = widget; } public hasConfiguration(widget: FE_Widget) { diff --git a/web/app/app.module.ts b/web/app/app.module.ts index 0408557..6daf9c2 100644 --- a/web/app/app.module.ts +++ b/web/app/app.module.ts @@ -1,6 +1,4 @@ import { ApplicationRef, Injector, NgModule } from "@angular/core"; -import { ModalModule } from "ngx-modialog"; -import { BootstrapModalModule } from "ngx-modialog/plugins/bootstrap"; import { BreadcrumbModule } from "xng-breadcrumb"; import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; import { UiSwitchModule } from "ngx-ui-switch"; @@ -137,9 +135,7 @@ export function HttpLoaderFactory(http: HttpClient) { UiSwitchModule, ToasterModule, BrowserAnimationsModule, - ModalModule.forRoot(), - BootstrapModalModule, - BreadcrumbsModule, + BreadcrumbModule, CKEditorModule, FontAwesomeModule, TranslateModule.forRoot({ diff --git a/web/app/configs/bridge/telegram/ask-unbridge/ask-unbridge.component.html b/web/app/configs/bridge/telegram/ask-unbridge/ask-unbridge.component.html index 55f1a1a..45d7b93 100644 --- a/web/app/configs/bridge/telegram/ask-unbridge/ask-unbridge.component.html +++ b/web/app/configs/bridge/telegram/ask-unbridge/ask-unbridge.component.html @@ -1,17 +1,15 @@ -
-
-

{{'Telegram chat is already bridged' | translate}}

-
-
- {{'You have the appropriate permissions to be able to unbridge the chat, however. Would you like to unbridge the other room and instead bridge it here?' | translate}} -
- + + + diff --git a/web/app/configs/bridge/telegram/ask-unbridge/ask-unbridge.component.ts b/web/app/configs/bridge/telegram/ask-unbridge/ask-unbridge.component.ts index fee4d9b..6f44a4d 100644 --- a/web/app/configs/bridge/telegram/ask-unbridge/ask-unbridge.component.ts +++ b/web/app/configs/bridge/telegram/ask-unbridge/ask-unbridge.component.ts @@ -1,24 +1,23 @@ import { Component } from "@angular/core"; -import { DialogRef, ModalComponent } from "ngx-modialog"; -import { BSModalContext } from "ngx-modialog/plugins/bootstrap"; +import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap"; -export class AskUnbridgeDialogContext extends BSModalContext { +export interface AskUnbridgeDialogContext { } @Component({ templateUrl: "./ask-unbridge.component.html", styleUrls: ["./ask-unbridge.component.scss"], }) -export class TelegramAskUnbridgeComponent implements ModalComponent { +export class TelegramAskUnbridgeComponent { - constructor(public dialog: DialogRef) { + constructor(public modal: NgbActiveModal) { } public unbridgeAndContinue(): void { - this.dialog.close({unbridge: true}); + this.modal.close({unbridge: true}); } public cancel(): void { - this.dialog.close({unbridge: false}); + this.modal.close({unbridge: false}); } } diff --git a/web/app/configs/bridge/telegram/cannot-unbridge/cannot-unbridge.component.html b/web/app/configs/bridge/telegram/cannot-unbridge/cannot-unbridge.component.html index 7514937..3a500bf 100644 --- a/web/app/configs/bridge/telegram/cannot-unbridge/cannot-unbridge.component.html +++ b/web/app/configs/bridge/telegram/cannot-unbridge/cannot-unbridge.component.html @@ -1,13 +1,12 @@ -
-
-

{{'Telegram chat is already bridged' | translate}}

-
-
- {{'That Telegram chat is bridged to another Matrix room and cannot be bridged here. Unfortunately, you do not have the required permissions to be able to unbridge the other room.' | translate}} -
- + + + diff --git a/web/app/configs/bridge/telegram/cannot-unbridge/cannot-unbridge.component.ts b/web/app/configs/bridge/telegram/cannot-unbridge/cannot-unbridge.component.ts index 7496884..c32969d 100644 --- a/web/app/configs/bridge/telegram/cannot-unbridge/cannot-unbridge.component.ts +++ b/web/app/configs/bridge/telegram/cannot-unbridge/cannot-unbridge.component.ts @@ -1,16 +1,15 @@ import { Component } from "@angular/core"; -import { DialogRef, ModalComponent } from "ngx-modialog"; -import { BSModalContext } from "ngx-modialog/plugins/bootstrap"; +import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap"; -export class CannotUnbridgeDialogContext extends BSModalContext { +export interface CannotUnbridgeDialogContext { } @Component({ templateUrl: "./cannot-unbridge.component.html", styleUrls: ["./cannot-unbridge.component.scss"], }) -export class TelegramCannotUnbridgeComponent implements ModalComponent { +export class TelegramCannotUnbridgeComponent { - constructor(public dialog: DialogRef) { + constructor(public modal: NgbActiveModal) { } } diff --git a/web/app/configs/bridge/telegram/telegram.bridge.component.ts b/web/app/configs/bridge/telegram/telegram.bridge.component.ts index 0695a46..73cb405 100644 --- a/web/app/configs/bridge/telegram/telegram.bridge.component.ts +++ b/web/app/configs/bridge/telegram/telegram.bridge.component.ts @@ -2,13 +2,12 @@ import { Component } from "@angular/core"; import { BridgeComponent } from "../bridge.component"; import { TelegramApiService } from "../../../shared/services/integrations/telegram-api.service"; import { FE_PortalInfo } from "../../../shared/models/telegram"; -import { Modal, overlayConfigFactory } from "ngx-modialog"; -import { AskUnbridgeDialogContext, TelegramAskUnbridgeComponent } from "./ask-unbridge/ask-unbridge.component"; +import { TelegramAskUnbridgeComponent } from "./ask-unbridge/ask-unbridge.component"; import { - CannotUnbridgeDialogContext, TelegramCannotUnbridgeComponent } from "./cannot-unbridge/cannot-unbridge.component"; import { TranslateService } from "@ngx-translate/core"; +import { NgbModal } from "@ng-bootstrap/ng-bootstrap"; interface TelegramConfig { puppet: { @@ -40,7 +39,7 @@ export class TelegramBridgeConfigComponent extends BridgeComponent { let forceUnbridge = false; if (chatInfo.bridged && chatInfo.canUnbridge) { - const response = await this.modal.open(TelegramAskUnbridgeComponent, overlayConfigFactory({ - isBlocking: true, + const askUnbridgeRef = this.modal.open(TelegramAskUnbridgeComponent, { + backdrop: 'static', size: 'lg', - }, AskUnbridgeDialogContext)).result; - - if (response.unbridge) { - forceUnbridge = true; - } else { - return {aborted: true}; - } + }); + askUnbridgeRef.result.then((response) => { + if (response.unbridge) { + forceUnbridge = true; + } else { + return {aborted: true}; + } + }); } else if (chatInfo.bridged) { - this.modal.open(TelegramCannotUnbridgeComponent, overlayConfigFactory({ - isBlocking: true, + this.modal.open(TelegramCannotUnbridgeComponent, { + backdrop: 'static', size: 'lg', - }, CannotUnbridgeDialogContext)); + }); return {aborted: true}; } diff --git a/web/app/configs/simple-bot/simple-bot.component.html b/web/app/configs/simple-bot/simple-bot.component.html index 17da6c8..c83dde2 100644 --- a/web/app/configs/simple-bot/simple-bot.component.html +++ b/web/app/configs/simple-bot/simple-bot.component.html @@ -1,14 +1,13 @@ -
-
-

{{ bot.displayName }}

-
-
-

{{ bot.description }}

- -
- + + + diff --git a/web/app/configs/simple-bot/simple-bot.component.ts b/web/app/configs/simple-bot/simple-bot.component.ts index c8cb89d..cc4e8e4 100644 --- a/web/app/configs/simple-bot/simple-bot.component.ts +++ b/web/app/configs/simple-bot/simple-bot.component.ts @@ -1,36 +1,35 @@ -import { Component } from "@angular/core"; +import { Component, OnInit } from "@angular/core"; import { FE_SimpleBot } from "../../shared/models/integration"; import { ToasterService } from "angular2-toaster"; import { ScalarClientApiService } from "../../shared/services/scalar/scalar-client-api.service"; import { IntegrationsApiService } from "../../shared/services/integrations/integrations-api.service"; -import { BSModalContext } from "ngx-modialog/plugins/bootstrap"; -import { DialogRef } from "ngx-modialog"; import { TranslateService } from "@ngx-translate/core"; +import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap"; -export class SimpleBotConfigDialogContext extends BSModalContext { - public bot: FE_SimpleBot; - public roomId: string; +export interface SimpleBotConfigDialogContext { + bot: FE_SimpleBot; + roomId: string; } @Component({ templateUrl: "simple-bot.component.html", styleUrls: ["simple-bot.component.scss"], }) -export class ConfigSimpleBotComponent { +export class ConfigSimpleBotComponent implements OnInit { public bot: FE_SimpleBot; private roomId: string; - constructor(public dialog: DialogRef, + constructor(public modal: NgbActiveModal, private toaster: ToasterService, private scalar: ScalarClientApiService, private integrationsApi: IntegrationsApiService, public translate: TranslateService) { this.translate = translate; - this.bot = dialog.context.bot; - this.roomId = dialog.context.roomId; + } + ngOnInit() { this.bot._isUpdating = false; } diff --git a/web/app/riot/riot-home/home.component.ts b/web/app/riot/riot-home/home.component.ts index 93aba02..a90c946 100644 --- a/web/app/riot/riot-home/home.component.ts +++ b/web/app/riot/riot-home/home.component.ts @@ -3,322 +3,481 @@ import { ActivatedRoute, Router } from "@angular/router"; import { ScalarClientApiService } from "../../shared/services/scalar/scalar-client-api.service"; import * as _ from "lodash"; import { ScalarServerApiService } from "../../shared/services/scalar/scalar-server-api.service"; -import { FE_Integration, FE_IntegrationRequirement, FE_SimpleBot } from "../../shared/models/integration"; +import { + FE_Integration, + FE_IntegrationRequirement, + FE_SimpleBot, +} from "../../shared/models/integration"; import { IntegrationsRegistry } from "../../shared/registry/integrations.registry"; import { SessionStorage } from "../../shared/SessionStorage"; import { AdminApiService } from "../../shared/services/admin/admin-api.service"; import { IntegrationsApiService } from "../../shared/services/integrations/integrations-api.service"; -import { Modal, overlayConfigFactory } from "ngx-modialog"; -import { ConfigSimpleBotComponent, SimpleBotConfigDialogContext } from "../../configs/simple-bot/simple-bot.component"; +import { + ConfigSimpleBotComponent, + SimpleBotConfigDialogContext, +} from "../../configs/simple-bot/simple-bot.component"; import { ToasterService } from "angular2-toaster"; import { StickerApiService } from "../../shared/services/integrations/sticker-api.service"; import { TranslateService } from "@ngx-translate/core"; +import { NgbModal } from "@ng-bootstrap/ng-bootstrap"; const CATEGORY_MAP = { - "Widgets": ["widget"], - "Bots": ["complex-bot", "bot"], - "Bridges": ["bridge"], + Widgets: ["widget"], + Bots: ["complex-bot", "bot"], + Bridges: ["bridge"], }; @Component({ - selector: "my-riot-home", - templateUrl: "./home.component.html", - styleUrls: ["./home.component.scss"], + selector: "my-riot-home", + templateUrl: "./home.component.html", + styleUrls: ["./home.component.scss"], }) export class RiotHomeComponent { - public isLoading = true; - public isError = false; - public errorMessage: string; - public isRoomEncrypted: boolean; - public hasStickerPacks = false; + public isLoading = true; + public isError = false; + public errorMessage: string; + public isRoomEncrypted: boolean; + public hasStickerPacks = false; - private roomId: string; - private userId: string; - private requestedScreen: string = null; - private requestedIntegrationId: string = null; - public integrationsForCategory: { [category: string]: FE_Integration[] } = {}; - private categoryMap: { [categoryName: string]: string[] } = CATEGORY_MAP; + private roomId: string; + private userId: string; + private requestedScreen: string = null; + private requestedIntegrationId: string = null; + public integrationsForCategory: { [category: string]: FE_Integration[] } = {}; + private categoryMap: { [categoryName: string]: string[] } = CATEGORY_MAP; - constructor(private activatedRoute: ActivatedRoute, - private scalarApi: ScalarServerApiService, - private scalar: ScalarClientApiService, - private integrationsApi: IntegrationsApiService, - private stickerApi: StickerApiService, - private adminApi: AdminApiService, - private router: Router, - private modal: Modal, - private toaster: ToasterService, - public translate: TranslateService) { - this.translate = translate; - let params: any = this.activatedRoute.snapshot.queryParams; + constructor( + private activatedRoute: ActivatedRoute, + private scalarApi: ScalarServerApiService, + private scalar: ScalarClientApiService, + private integrationsApi: IntegrationsApiService, + private stickerApi: StickerApiService, + private adminApi: AdminApiService, + private router: Router, + private modal: NgbModal, + private toaster: ToasterService, + public translate: TranslateService + ) { + this.translate = translate; + let params: any = this.activatedRoute.snapshot.queryParams; - this.requestedScreen = params.screen; - this.requestedIntegrationId = params.integ_id; + this.requestedScreen = params.screen; + this.requestedIntegrationId = params.integ_id; - if (SessionStorage.roomId && SessionStorage.userId) { - this.roomId = SessionStorage.roomId; - this.userId = SessionStorage.userId; - console.log("Already checked scalar token and other params - continuing startup"); + if (SessionStorage.roomId && SessionStorage.userId) { + this.roomId = SessionStorage.roomId; + this.userId = SessionStorage.userId; + console.log( + "Already checked scalar token and other params - continuing startup" + ); + this.prepareIntegrations(); + return; + } + + if (!params.scalar_token || !params.room_id) { + console.error( + "Unable to load Dimension. Missing room ID or scalar token." + ); + this.isError = true; + this.isLoading = false; + this.translate + .get("Unable to load Dimension - missing room ID or token.") + .subscribe((res: string) => { + this.errorMessage = res; + }); + } else { + this.roomId = params.room_id; + SessionStorage.scalarToken = params.scalar_token; + SessionStorage.roomId = this.roomId; + + this.scalarApi + .getAccount() + .then((response) => { + const userId = response.user_id; + SessionStorage.userId = userId; + if (!userId) { + console.error( + "No user returned for token. Is the token registered in Dimension?" + ); + this.isError = true; + this.isLoading = false; + this.translate + .get( + "Could not verify your token. Please try logging out of Element and back in. Be sure to back up your encryption keys!" + ) + .subscribe((res: string) => { + this.errorMessage = res; + }); + } else { + this.userId = userId; + console.log("Scalar token belongs to " + userId); + this.checkAdmin(); this.prepareIntegrations(); - return; - } - - if (!params.scalar_token || !params.room_id) { - console.error("Unable to load Dimension. Missing room ID or scalar token."); - this.isError = true; - this.isLoading = false; - this.translate.get('Unable to load Dimension - missing room ID or token.').subscribe((res: string) => {this.errorMessage = res}); - } else { - this.roomId = params.room_id; - SessionStorage.scalarToken = params.scalar_token; - SessionStorage.roomId = this.roomId; - - this.scalarApi.getAccount().then(response => { - const userId = response.user_id; - SessionStorage.userId = userId; - if (!userId) { - console.error("No user returned for token. Is the token registered in Dimension?"); - this.isError = true; - this.isLoading = false; - this.translate.get('Could not verify your token. Please try logging out of Element and back in. Be sure to back up your encryption keys!').subscribe((res: string) => {this.errorMessage = res}); - } else { - this.userId = userId; - console.log("Scalar token belongs to " + userId); - this.checkAdmin(); - this.prepareIntegrations(); - } - }).catch(err => { - console.error(err); - this.isError = true; - this.isLoading = false; - this.translate.get('Unable to communicate with Dimension due to an unknown error.').subscribe((res: string) => {this.errorMessage = res}); + } + }) + .catch((err) => { + console.error(err); + this.isError = true; + this.isLoading = false; + this.translate + .get( + "Unable to communicate with Dimension due to an unknown error." + ) + .subscribe((res: string) => { + this.errorMessage = res; }); - } + }); + } + } + + private checkAdmin() { + this.adminApi + .isAdmin() + .then(() => { + console.log( + SessionStorage.userId + " is an admin for this Dimension instance" + ); + SessionStorage.isAdmin = true; + }) + .catch(() => (SessionStorage.isAdmin = false)); + } + + public hasIntegrations(): boolean { + for (const category of this.getCategories()) { + if (this.getIntegrationsIn(category).length > 0) return true; } - private checkAdmin() { - this.adminApi.isAdmin().then(() => { - console.log(SessionStorage.userId + " is an admin for this Dimension instance"); - SessionStorage.isAdmin = true; - }).catch(() => SessionStorage.isAdmin = false); + return false; + } + + public getCategories(): string[] { + return Object.keys(this.categoryMap); + } + + public getIntegrationsIn(category: string): FE_Integration[] { + return this.integrationsForCategory[category]; + } + + private getIntegrations(): FE_Integration[] { + const result: FE_Integration[] = []; + + for (const category of this.getCategories()) { + for (const integration of this.getIntegrationsIn(category)) { + result.push(integration); + } } - public hasIntegrations(): boolean { - for (const category of this.getCategories()) { - if (this.getIntegrationsIn(category).length > 0) return true; - } + return result; + } - return false; + public modifyIntegration(integration: FE_Integration) { + if (!integration._isSupported) { + console.log( + this.userId + + " tried to modify " + + integration.displayName + + " with error: " + + integration._notSupportedReason + ); + this.translate + .get( + "You do not appear to have permission to modify widgets in this room" + ) + .subscribe((res: string) => { + const reason = + integration.category === "widget" + ? res + : integration._notSupportedReason; + this.toaster.pop("error", reason); + }); + return; } - public getCategories(): string[] { - return Object.keys(this.categoryMap); + SessionStorage.editIntegration = integration; + SessionStorage.editsRequested++; + console.log( + this.userId + " is trying to modify " + integration.displayName + ); + + if (integration.category === "bot") { + const widgetConfigRef = this.modal.open(ConfigSimpleBotComponent, { + backdrop: "static", + size: "lg", + }); + const widgetConfigInterface = + widgetConfigRef.componentInstance as SimpleBotConfigDialogContext; + widgetConfigInterface.bot = integration; + widgetConfigInterface.roomId = this.roomId; + } else { + console.log( + "Navigating to edit screen for " + + integration.category + + " " + + integration.type + ); + this.router.navigate( + ["riot-app", integration.category, integration.type], + { queryParams: { roomId: this.roomId } } + ); } + } - public getIntegrationsIn(category: string): FE_Integration[] { - return this.integrationsForCategory[category]; - } + private prepareIntegrations() { + this.scalar + .isRoomEncrypted(this.roomId) + .then((payload) => { + this.isRoomEncrypted = payload.response; + return this.integrationsApi.getIntegrations(this.roomId); + }) + .then((response) => { + const integrations: FE_Integration[] = _.flatten( + Object.keys(response).map((k) => response[k]) + ); + const supportedIntegrations: FE_Integration[] = _.filter( + integrations, + (i) => IntegrationsRegistry.isSupported(i) + ); - private getIntegrations(): FE_Integration[] { - const result: FE_Integration[] = []; - - for (const category of this.getCategories()) { - for (const integration of this.getIntegrationsIn(category)) { - result.push(integration); + // Flag integrations that aren't supported in encrypted rooms + if (this.isRoomEncrypted) { + for (const integration of supportedIntegrations) { + if (!integration.isEncryptionSupported) { + integration._isSupported = false; + integration._notSupportedReason = + "This integration is not supported in encrypted rooms"; } + } } - return result; + // Set up the categories + for (const category of Object.keys(this.categoryMap)) { + const supportedTypes = this.categoryMap[category]; + this.integrationsForCategory[category] = _.filter( + supportedIntegrations, + (i) => supportedTypes.indexOf(i.category) !== -1 + ); + } + + let promises = supportedIntegrations.map((i) => + this.updateIntegrationState(i) + ); + return Promise.all(promises); + }) + .then(() => { + this.isLoading = false; + + // HACK: We wait for the digest cycle so we actually have components to look at + setTimeout(() => this.tryOpenConfigScreen(), 20); + }) + .catch((err) => { + console.error(err); + this.isError = true; + this.isLoading = false; + this.translate + .get( + "Unable to set up Dimension. This version of Element may not supported or there may be a problem with the server." + ) + .subscribe((res: string) => { + this.errorMessage = res; + }); + }); + + this.stickerApi + .getPacks() + .then((packs) => { + this.hasStickerPacks = packs.length > 0; + }) + .catch((err) => { + console.error(err); + }); + } + + private tryOpenConfigScreen() { + let category = null; + let type = null; + if (!this.requestedScreen) return; + + if (this.requestedScreen === "type_m.stickerpicker") { + console.log( + "Intercepting config screen handling to open sticker picker config" + ); + this.router.navigate(["riot-app", "stickerpicker"]); + return; } - public modifyIntegration(integration: FE_Integration) { - if (!integration._isSupported) { - console.log(this.userId + " tried to modify " + integration.displayName + " with error: " + integration._notSupportedReason); - this.translate.get('You do not appear to have permission to modify widgets in this room').subscribe((res: string) => { - const reason = integration.category === "widget" ? res : integration._notSupportedReason; - this.toaster.pop("error", reason); - }); - return; - } + const targetIntegration = IntegrationsRegistry.getIntegrationForScreen( + this.requestedScreen + ); + if (targetIntegration) { + category = targetIntegration.category; + type = targetIntegration.type; + } else { + console.log("Unknown screen requested: " + this.requestedScreen); + } + console.log("Searching for integration for requested screen"); + for (const integration of this.getIntegrations()) { + if (integration.category === category && integration.type === type) { + console.log( + "Configuring integration " + + this.requestedIntegrationId + + " category=" + + category + + " type=" + + type + ); SessionStorage.editIntegration = integration; - SessionStorage.editsRequested++; - console.log(this.userId + " is trying to modify " + integration.displayName); - - if (integration.category === "bot") { - this.modal.open(ConfigSimpleBotComponent, overlayConfigFactory({ - bot: integration, - roomId: this.roomId, - - isBlocking: true, - size: 'lg', - }, SimpleBotConfigDialogContext)); - } else { - console.log("Navigating to edit screen for " + integration.category + " " + integration.type); - this.router.navigate(['riot-app', integration.category, integration.type], {queryParams: {roomId: this.roomId}}); - } + SessionStorage.editIntegrationId = this.requestedIntegrationId; + this.modifyIntegration(integration); + return; + } } - private prepareIntegrations() { - this.scalar.isRoomEncrypted(this.roomId).then(payload => { - this.isRoomEncrypted = payload.response; - return this.integrationsApi.getIntegrations(this.roomId); - }).then(response => { - const integrations: FE_Integration[] = _.flatten(Object.keys(response).map(k => response[k])); - const supportedIntegrations: FE_Integration[] = _.filter(integrations, i => IntegrationsRegistry.isSupported(i)); + console.log( + "Failed to find integration component for category=" + + category + + " type=" + + type + ); + } - // Flag integrations that aren't supported in encrypted rooms - if (this.isRoomEncrypted) { - for (const integration of supportedIntegrations) { - if (!integration.isEncryptionSupported) { - integration._isSupported = false; - integration._notSupportedReason = "This integration is not supported in encrypted rooms"; - } - } - } - - // Set up the categories - for (const category of Object.keys(this.categoryMap)) { - const supportedTypes = this.categoryMap[category]; - this.integrationsForCategory[category] = _.filter(supportedIntegrations, i => supportedTypes.indexOf(i.category) !== -1); - } - - let promises = supportedIntegrations.map(i => this.updateIntegrationState(i)); - return Promise.all(promises); - }).then(() => { - this.isLoading = false; - - // HACK: We wait for the digest cycle so we actually have components to look at - setTimeout(() => this.tryOpenConfigScreen(), 20); - }).catch(err => { - console.error(err); - this.isError = true; - this.isLoading = false; - this.translate.get('Unable to set up Dimension. This version of Element may not supported or there may be a problem with the server.').subscribe((res: string) => {this.errorMessage = res}); + private async updateIntegrationState(integration: FE_Integration) { + if (!integration.isOnline) { + integration._isSupported = false; + this.translate + .get("This integration is offline or unavailable") + .subscribe((res: string) => { + integration._notSupportedReason = res; }); + return; + } - this.stickerApi.getPacks().then(packs => { - this.hasStickerPacks = packs.length > 0; - }).catch(err => { - console.error(err); + if (!integration.requirements) return; + + let promises = integration.requirements.map((r) => + this.checkRequirement(r) + ); + + if (integration.category === "bot") { + const state = await this.scalar.getMembershipState( + this.roomId, + (integration).userId + ); + if (state && state.response && state.response.membership) { + integration._inRoom = + ["join", "invite"].indexOf(state.response.membership) !== -1; + } else integration._inRoom = false; + } + + return Promise.all(promises).then( + () => { + integration._isSupported = true; + integration._notSupportedReason = null; + }, + (error) => { + console.error(error); + integration._isSupported = false; + integration._notSupportedReason = error; + } + ); + } + + private checkRequirement(requirement: FE_IntegrationRequirement) { + switch (requirement.condition) { + case "publicRoom": + return this.scalar.getJoinRule(this.roomId).then((payload) => { + if (!payload.response) { + let message: string; + this.translate + .get("Could not communicate with Element") + .subscribe((res: string) => { + message = res; + }); + return Promise.reject(message); + } + const isPublic = payload.response.join_rule === "public"; + if (isPublic !== requirement.expectedValue) { + let message: string; + let message1: string; + this.translate + .get(["The room must be", "to use this integration"]) + .subscribe((res: string) => { + message = res[0]; + message1 = res[1]; + }); + return Promise.reject( + message + (isPublic ? "non-public" : "public") + message1 + ); + } else return Promise.resolve(); }); - } + case "canSendEventTypes": + const processPayload = (payload) => { + const response = payload.response; + if (response === true) return Promise.resolve(); + if (response.error || response.error.message) { + let message: string; + this.translate + .get("You cannot modify widgets in this room") + .subscribe((res: string) => { + message = res; + }); + return Promise.reject(message); + } + let message: string; + this.translate + .get("Error communicating with Element") + .subscribe((res: string) => { + message = res; + }); + return Promise.reject(message); + }; - private tryOpenConfigScreen() { - let category = null; - let type = null; - if (!this.requestedScreen) return; - - if (this.requestedScreen === "type_m.stickerpicker") { - console.log("Intercepting config screen handling to open sticker picker config"); - this.router.navigate(['riot-app', 'stickerpicker']); - return; - } - - const targetIntegration = IntegrationsRegistry.getIntegrationForScreen(this.requestedScreen); - if (targetIntegration) { - category = targetIntegration.category; - type = targetIntegration.type; - } else { - console.log("Unknown screen requested: " + this.requestedScreen); - } - - console.log("Searching for integration for requested screen"); - for (const integration of this.getIntegrations()) { - if (integration.category === category && integration.type === type) { - console.log("Configuring integration " + this.requestedIntegrationId + " category=" + category + " type=" + type); - SessionStorage.editIntegration = integration; - SessionStorage.editIntegrationId = this.requestedIntegrationId; - this.modifyIntegration(integration); - return; - } - } - - console.log("Failed to find integration component for category=" + category + " type=" + type); - } - - private async updateIntegrationState(integration: FE_Integration) { - if (!integration.isOnline) { - integration._isSupported = false; - this.translate.get('This integration is offline or unavailable').subscribe((res: string) => {integration._notSupportedReason = res}); - return; - } - - if (!integration.requirements) return; - - let promises = integration.requirements.map(r => this.checkRequirement(r)); - - if (integration.category === "bot") { - const state = await this.scalar.getMembershipState(this.roomId, (integration).userId); - if (state && state.response && state.response.membership) { - integration._inRoom = ["join", "invite"].indexOf(state.response.membership) !== -1; - } else integration._inRoom = false; - } - - return Promise.all(promises).then(() => { - integration._isSupported = true; - integration._notSupportedReason = null; - }, error => { - console.error(error); - integration._isSupported = false; - integration._notSupportedReason = error; - }); - } - - private checkRequirement(requirement: FE_IntegrationRequirement) { - switch (requirement.condition) { - case "publicRoom": - return this.scalar.getJoinRule(this.roomId).then(payload => { - if (!payload.response) { - let message: string; - this.translate.get('Could not communicate with Element').subscribe((res: string) => {message = res}); - return Promise.reject(message); - } - const isPublic = payload.response.join_rule === "public"; - if (isPublic !== requirement.expectedValue) { - let message: string; - let message1: string; - this.translate.get(['The room must be', 'to use this integration']).subscribe((res: string) => {message = res[0]; message1 = res[1]}); - return Promise.reject(message + (isPublic ? "non-public" : "public") + message1); - } else return Promise.resolve(); + let promiseChain = Promise.resolve(); + requirement.argument.forEach( + (e) => + (promiseChain = promiseChain.then(() => + this.scalar + .canSendEvent(this.roomId, e.type, e.isState) + .then(processPayload) + .catch(processPayload) + )) + ); + return promiseChain + .then(() => { + if (!requirement.expectedValue) { + let message: string; + this.translate + .get("Expected to not be able to send specific event types") + .subscribe((res: string) => { + message = res; }); - case "canSendEventTypes": - const processPayload = payload => { - const response = payload.response; - if (response === true) return Promise.resolve(); - if (response.error || response.error.message) { - let message: string; - this.translate.get('You cannot modify widgets in this room').subscribe((res: string) => {message = res}); - return Promise.reject(message); - } - let message: string; - this.translate.get('Error communicating with Element').subscribe((res: string) => {message = res}); - return Promise.reject(message); - }; - - let promiseChain = Promise.resolve(); - requirement.argument.forEach(e => promiseChain = promiseChain.then(() => this.scalar.canSendEvent(this.roomId, e.type, e.isState).then(processPayload).catch(processPayload))); - return promiseChain.then(() => { - if (!requirement.expectedValue) { - let message: string; - this.translate.get('Expected to not be able to send specific event types').subscribe((res: string) => {message = res}); - return Promise.reject(message); - } - }).catch(err => { - console.error(err); - if (requirement.expectedValue) { - let message: string; - this.translate.get('Expected to be able to send specific event types').subscribe((res: string) => {message = res}); - return Promise.reject(message); - } + return Promise.reject(message); + } + }) + .catch((err) => { + console.error(err); + if (requirement.expectedValue) { + let message: string; + this.translate + .get("Expected to be able to send specific event types") + .subscribe((res: string) => { + message = res; }); - case "userInRoom": - // TODO: Implement - default: - let message: string; - let message1: string; - this.translate.get(['Requirement', 'not found']).subscribe((res: string) => {message = res[0]; message1 = res[1]}); - return Promise.reject(message + requirement.condition + message1); - } + return Promise.reject(message); + } + }); + case "userInRoom": + // TODO: Implement + default: + let message: string; + let message1: string; + this.translate + .get(["Requirement", "not found"]) + .subscribe((res: string) => { + message = res[0]; + message1 = res[1]; + }); + return Promise.reject(message + requirement.condition + message1); } + } } diff --git a/web/style/app.scss b/web/style/app.scss index bb240b2..38bc1b2 100644 --- a/web/style/app.scss +++ b/web/style/app.scss @@ -1,7 +1,7 @@ // styles in src/style directory are applied to the whole page @import "../assets//fonts/opensans100-roboto300"; @import "../../node_modules/angular2-toaster/toaster"; -@import "../../node_modules/bootstrap/dist/css/bootstrap.min.css"; +@import "~bootstrap/scss/bootstrap"; @import "~ngx-ui-switch/ui-switch.component.scss"; @import "themes/themes"; @import "components/ibox";