Warn the user when they try to bridge chats that are already bridged

This commit is contained in:
Travis Ralston 2018-10-17 21:37:29 -06:00
parent c0936745c0
commit 83c06c8591
10 changed files with 118 additions and 14 deletions

View File

@ -11,6 +11,10 @@ interface PortalInfoResponse {
chatName: string; chatName: string;
} }
interface BridgeRoomRequest {
unbridgeOtherPortals: boolean;
}
/** /**
* API for interacting with the Telegram bridge * API for interacting with the Telegram bridge
*/ */
@ -49,12 +53,12 @@ export class DimensionTelegramService {
@POST @POST
@Path("chat/:chatId/room/:roomId") @Path("chat/:chatId/room/:roomId")
public async bridgeRoom(@QueryParam("scalar_token") scalarToken: string, @PathParam("chatId") chatId: number, @PathParam("roomId") roomId: string): Promise<PortalInfoResponse> { public async bridgeRoom(@QueryParam("scalar_token") scalarToken: string, @PathParam("chatId") chatId: number, @PathParam("roomId") roomId: string, request: BridgeRoomRequest): Promise<PortalInfoResponse> {
const userId = await ScalarService.getTokenOwner(scalarToken); const userId = await ScalarService.getTokenOwner(scalarToken);
try { try {
const telegram = new TelegramBridge(userId); const telegram = new TelegramBridge(userId);
const portal = await telegram.bridgeRoom(chatId, roomId); const portal = await telegram.bridgeRoom(chatId, roomId, request.unbridgeOtherPortals);
return { return {
bridged: true, bridged: true,
canUnbridge: portal.canUnbridge, canUnbridge: portal.canUnbridge,

View File

@ -97,9 +97,9 @@ export class TelegramBridge {
try { try {
const info = await this.doProvisionRequest<PortalInformationResponse>(bridge, "GET", `/portal/${inRoomId}`); const info = await this.doProvisionRequest<PortalInformationResponse>(bridge, "GET", `/portal/${inRoomId}`);
return { return {
bridged: !!info, bridged: !!info && info.mxid === inRoomId,
chatId: info ? info.chat_id : 0, chatId: info ? info.chat_id : 0,
roomId: inRoomId, roomId: info.mxid,
chatName: info ? info.title || info.username : null, chatName: info ? info.title || info.username : null,
canUnbridge: info ? info.can_unbridge : false, canUnbridge: info ? info.can_unbridge : false,
}; };
@ -150,11 +150,13 @@ export class TelegramBridge {
} }
} }
public async bridgeRoom(chatId: number, roomId: string): Promise<PortalInfo> { public async bridgeRoom(chatId: number, roomId: string, unbridgeOtherPortals = false): Promise<PortalInfo> {
const bridge = await this.getDefaultBridge(); const bridge = await this.getDefaultBridge();
try { try {
await this.doProvisionRequest(bridge, "POST", `/portal/${roomId}/connect/${chatId}`); const qs = {};
if (unbridgeOtherPortals) qs["force"] = "unbridge";
await this.doProvisionRequest(bridge, "POST", `/portal/${roomId}/connect/${chatId}`, qs);
return this.getChatConfiguration(chatId, roomId); return this.getChatConfiguration(chatId, roomId);
} catch (e) { } catch (e) {
if (!e.errBody) throw e.error || e; if (!e.errBody) throw e.error || e;

View File

@ -83,6 +83,8 @@ import { AdminTelegramBridgeComponent } from "./admin/bridges/telegram/telegram.
import { AdminTelegramBridgeManageSelfhostedComponent } from "./admin/bridges/telegram/manage-selfhosted/manage-selfhosted.component"; import { AdminTelegramBridgeManageSelfhostedComponent } from "./admin/bridges/telegram/manage-selfhosted/manage-selfhosted.component";
import { TelegramApiService } from "./shared/services/integrations/telegram-api.service"; import { TelegramApiService } from "./shared/services/integrations/telegram-api.service";
import { TelegramBridgeConfigComponent } from "./configs/bridge/telegram/telegram.bridge.component"; import { TelegramBridgeConfigComponent } from "./configs/bridge/telegram/telegram.bridge.component";
import { TelegramAskUnbridgeComponent } from "./configs/bridge/telegram/ask-unbridge/ask-unbridge.component";
import { TelegramCannotUnbridgeComponent } from "./configs/bridge/telegram/cannot-unbridge/cannot-unbridge.component";
@NgModule({ @NgModule({
imports: [ imports: [
@ -153,6 +155,8 @@ import { TelegramBridgeConfigComponent } from "./configs/bridge/telegram/telegra
AdminTelegramBridgeComponent, AdminTelegramBridgeComponent,
AdminTelegramBridgeManageSelfhostedComponent, AdminTelegramBridgeManageSelfhostedComponent,
TelegramBridgeConfigComponent, TelegramBridgeConfigComponent,
TelegramAskUnbridgeComponent,
TelegramCannotUnbridgeComponent,
// Vendor // Vendor
], ],
@ -192,6 +196,8 @@ import { TelegramBridgeConfigComponent } from "./configs/bridge/telegram/telegra
AdminIrcBridgeAddSelfhostedComponent, AdminIrcBridgeAddSelfhostedComponent,
AdminStickerPackPreviewComponent, AdminStickerPackPreviewComponent,
AdminTelegramBridgeManageSelfhostedComponent, AdminTelegramBridgeManageSelfhostedComponent,
TelegramAskUnbridgeComponent,
TelegramCannotUnbridgeComponent,
] ]
}) })
export class AppModule { export class AppModule {

View File

@ -0,0 +1,17 @@
<div class="dialog">
<div class="dialog-header">
<h4>Telegram chat is already bridged</h4>
</div>
<div class="dialog-content">
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?
</div>
<div class="dialog-footer">
<button type="button" (click)="unbridgeAndContinue()" title="unbridge and continue" class="btn btn-danger btn-sm">
Unbridge and continue
</button>
<button type="button" (click)="cancel()" title="cancel" class="btn btn-primary btn-sm">
<i class="far fa-times-circle"></i> No, don't bridge
</button>
</div>
</div>

View File

@ -0,0 +1,24 @@
import { Component } from "@angular/core";
import { DialogRef, ModalComponent } from "ngx-modialog";
import { BSModalContext } from "ngx-modialog/plugins/bootstrap";
export class AskUnbridgeDialogContext extends BSModalContext {
}
@Component({
templateUrl: "./ask-unbridge.component.html",
styleUrls: ["./ask-unbridge.component.scss"],
})
export class TelegramAskUnbridgeComponent implements ModalComponent<AskUnbridgeDialogContext> {
constructor(public dialog: DialogRef<AskUnbridgeDialogContext>) {
}
public unbridgeAndContinue(): void {
this.dialog.close({unbridge: true});
}
public cancel(): void {
this.dialog.close({unbridge: false});
}
}

View File

@ -0,0 +1,14 @@
<div class="dialog">
<div class="dialog-header">
<h4>Telegram chat is already bridged</h4>
</div>
<div class="dialog-content">
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.
</div>
<div class="dialog-footer">
<button type="button" (click)="dialog.close()" title="cancel" class="btn btn-primary btn-sm">
<i class="far fa-times-circle"></i> Close
</button>
</div>
</div>

View File

@ -0,0 +1,16 @@
import { Component } from "@angular/core";
import { DialogRef, ModalComponent } from "ngx-modialog";
import { BSModalContext } from "ngx-modialog/plugins/bootstrap";
export class CannotUnbridgeDialogContext extends BSModalContext {
}
@Component({
templateUrl: "./cannot-unbridge.component.html",
styleUrls: ["./cannot-unbridge.component.scss"],
})
export class TelegramCannotUnbridgeComponent implements ModalComponent<CannotUnbridgeDialogContext> {
constructor(public dialog: DialogRef<CannotUnbridgeDialogContext>) {
}
}

View File

@ -2,6 +2,12 @@ import { Component } from "@angular/core";
import { BridgeComponent } from "../bridge.component"; import { BridgeComponent } from "../bridge.component";
import { TelegramApiService } from "../../../shared/services/integrations/telegram-api.service"; import { TelegramApiService } from "../../../shared/services/integrations/telegram-api.service";
import { FE_PortalInfo } from "../../../shared/models/telegram"; import { FE_PortalInfo } from "../../../shared/models/telegram";
import { Modal, overlayConfigFactory } from "ngx-modialog";
import { AskUnbridgeDialogContext, TelegramAskUnbridgeComponent } from "./ask-unbridge/ask-unbridge.component";
import {
CannotUnbridgeDialogContext,
TelegramCannotUnbridgeComponent
} from "./cannot-unbridge/cannot-unbridge.component";
interface TelegramConfig { interface TelegramConfig {
puppet: { puppet: {
@ -33,7 +39,7 @@ export class TelegramBridgeConfigComponent extends BridgeComponent<TelegramConfi
public isUpdating: boolean; public isUpdating: boolean;
constructor(private telegram: TelegramApiService) { constructor(private telegram: TelegramApiService, private modal: Modal) {
super("telegram"); super("telegram");
} }
@ -69,16 +75,31 @@ export class TelegramBridgeConfigComponent extends BridgeComponent<TelegramConfi
} }
public bridgeRoom(): void { public bridgeRoom(): void {
this.telegram.getPortalInfo(this.bridge.config.portalInfo.chatId, this.roomId).then(chatInfo => { this.telegram.getPortalInfo(this.bridge.config.portalInfo.chatId, this.roomId).then(async (chatInfo) => {
let forceUnbridge = false;
if (chatInfo.bridged && chatInfo.canUnbridge) { if (chatInfo.bridged && chatInfo.canUnbridge) {
// TODO: Ask if the user would like to unbridge const response = await this.modal.open(TelegramAskUnbridgeComponent, overlayConfigFactory({
console.log("Ask for unbridge"); isBlocking: true,
size: 'lg',
}, AskUnbridgeDialogContext)).result;
if (response.unbridge) {
forceUnbridge = true;
} else {
return {aborted: true};
}
} else if (chatInfo.bridged) { } else if (chatInfo.bridged) {
// TODO: Dialog saying 'sorry' this.modal.open(TelegramCannotUnbridgeComponent, overlayConfigFactory({
console.log("Cannot bridge"); isBlocking: true,
size: 'lg',
}, CannotUnbridgeDialogContext));
return {aborted: true};
} }
return this.telegram.bridgeRoom(this.roomId, this.bridge.config.portalInfo.chatId);
}).then(portalInfo => { return this.telegram.bridgeRoom(this.roomId, this.bridge.config.portalInfo.chatId, forceUnbridge);
}).then((portalInfo: FE_PortalInfo) => {
if ((<any>portalInfo).aborted) return;
this.bridge.config.portalInfo = portalInfo; this.bridge.config.portalInfo = portalInfo;
this.bridge.config.linked = [portalInfo.chatId]; this.bridge.config.linked = [portalInfo.chatId];
this.isUpdating = false; this.isUpdating = false;