diff --git a/public/config.json b/public/config.json index c6e0925f58f00099ca2d2adbd2758b250f429030..6bf7142ecbc58c5c71751a8ed0943c803dc04303 100644 --- a/public/config.json +++ b/public/config.json @@ -6,5 +6,6 @@ "title": "Chatterbox Test Room", "avatar": "https://i.picsum.photos/id/907/200/200.jpg?hmac=SdeLZNONJ3CX-OB15hSXsCheWDC6yYac5N5VUJM7FIQ" }, - "token": "k9SL1R~GcdbjiFjC" + "token": "k9SL1R~GcdbjiFjC", + "invite_user": "@midhun:matrix.midhun.dev" } diff --git a/src/types/IChatterboxConfig.ts b/src/types/IChatterboxConfig.ts index 789fcc58cdd0676a79d56539a13e3f5c8bcb3caa..8e0720216f1b0618386a9f49f3d779b90f7a2b38 100644 --- a/src/types/IChatterboxConfig.ts +++ b/src/types/IChatterboxConfig.ts @@ -1,9 +1,12 @@ export interface IChatterboxConfig { homeserver: string; - // internal room-id of the room to which chatterbox should join + // Internal room-id of the room to which chatterbox should join auto_join_room: string; - // string that is to be prepended to the generated random usernames + // String that is to be prepended to the generated random usernames username_prefix: string; + // If specified, chatterbox will create a dm with this user + // This option takes precedence over 'auto_join_room' + invite_user: string; // Configurations for header on chatterbox (containing title, avatar, minimize button) header: IHeader; // Token needed for token-authenticated registration diff --git a/src/viewmodels/ChatterboxViewModel.ts b/src/viewmodels/ChatterboxViewModel.ts index afb36fea89d57864954dda75d612548503677b5c..caefff1c392b0850f35572a3b283bb0a7c469037 100644 --- a/src/viewmodels/ChatterboxViewModel.ts +++ b/src/viewmodels/ChatterboxViewModel.ts @@ -11,11 +11,18 @@ export class ChatterboxViewModel extends ViewModel { this._loginPromise = options.loginPromise; } - async loadRoom() { + async load() { // wait until login is completed await this._loginPromise; - const roomId = this._options.config["auto_join_room"]; - const room = this._session.rooms.get(roomId) ?? await this._joinRoom(roomId); + let room; + if (this._options.config["invite_user"]) { + room = await this.createRoomWithUserSpecifiedInConfig(); + } else if(this._options.config["auto_join_room"]) { + room = await this.joinRoomSpecifiedInConfig(); + } + else { + throw new Error("ConfigError: You must either specify 'invite_user' or 'auto_join_room'"); + } this._roomViewModel = new RoomViewModel({ room, ownUserId: this._session.userId, @@ -28,12 +35,38 @@ export class ChatterboxViewModel extends ViewModel { this.emitChange("timelineViewModel"); } - private async _joinRoom(roomId: string): Promise<any> { - await this._session.joinRoom(roomId); - // even though we've joined the room, we need to wait till the next sync to get the room - await this._waitForRoomFromSync(roomId); - return this._session.rooms.get(roomId); + private async createRoomWithUserSpecifiedInConfig() { + const roomBeingCreated = this._session.createRoom({ + type: 1, + name: this._name ?? undefined, + topic: this._topic ?? undefined, + isEncrypted: false, + isFederationDisabled: false, + alias: undefined, + avatar: undefined, + invites: [this._options.config["invite_user"]], + }); + await this._waitForRoomCreation(roomBeingCreated); + const roomId = roomBeingCreated.roomId; + let room = this._session.rooms.get(roomId); + if (!room) { + await this._waitForRoomFromSync(roomId); + room = this._session.rooms.get(roomId); + } + return room; + } + private async joinRoomSpecifiedInConfig() { + const roomId = this._options.config["auto_join_room"]; + let room = this._session.rooms.get(roomId); + if (!room) { + // user is not in specified room, so join it + await this._session.joinRoom(roomId); + // even though we've joined the room, we need to wait till the next sync to get the room + await this._waitForRoomFromSync(roomId); + room = this._session.rooms.get(roomId); + } + return room; } private _waitForRoomFromSync(roomId: string): Promise<void> { @@ -46,11 +79,24 @@ export class ChatterboxViewModel extends ViewModel { resolve(); } }, + onUpdate: () => undefined, + onRemove: () => undefined, }; this._session.rooms.subscribe(subscription); return promise; } + private _waitForRoomCreation(roomBeingCreated): Promise<void> { + let resolve: () => void; + const promise: Promise<void> = new Promise(r => { resolve = r; }) + roomBeingCreated.on("change", () => { + if (roomBeingCreated.roomId) { + resolve(); + } + }); + return promise; + } + get timelineViewModel() { return this._roomViewModel?.timelineViewModel; } diff --git a/src/viewmodels/RootViewModel.ts b/src/viewmodels/RootViewModel.ts index 120714830478aee8eeb1541591c4a88ae208f906..b4f5484c6fd5058fcbc1622dade8ad366c3f5412 100644 --- a/src/viewmodels/RootViewModel.ts +++ b/src/viewmodels/RootViewModel.ts @@ -45,7 +45,7 @@ export class RootViewModel extends ViewModel { loginPromise, }) )); - this._chatterBoxViewModel.loadRoom(); + this._chatterBoxViewModel.load(); } this.emitChange("activeSection"); }