Skip to content
Snippets Groups Projects
ChatterboxViewModel.ts 4.46 KiB
Newer Older
  • Learn to ignore specific revisions
  • import { RoomViewModel, ViewModel, RoomStatus, tileClassForEntry} from "hydrogen-view-sdk";
    
    function createCustomTileClassForEntry(ownUserId: string) {
        return function customTileClassForEntry(entry) {
    
    RMidhunSuresh's avatar
    RMidhunSuresh committed
            if (entry.content?.membership === "join" && entry.sender !== ownUserId ||
                entry.eventType !== "m.room.member") {
    
                return tileClassForEntry(entry);
            }
            return undefined;
        }
    }
    
    Midhun Suresh's avatar
    Midhun Suresh committed
    
    export class ChatterboxViewModel extends ViewModel {
    
    Midhun Suresh's avatar
    Midhun Suresh committed
        private _roomViewModel?: typeof RoomViewModel;
    
        private _loginPromise: Promise<void>;
    
    RMidhunSuresh's avatar
    RMidhunSuresh committed
        private _minimize: () => void;
    
    Midhun Suresh's avatar
    Midhun Suresh committed
    
        constructor(options) {
            super(options);
    
            this._client = options.client;
            this._loginPromise = options.loginPromise;
    
    RMidhunSuresh's avatar
    RMidhunSuresh committed
            this._minimize = options.minimize;
    
    Midhun Suresh's avatar
    Midhun Suresh committed
        }
    
    
            // wait until login is completed
            await this._loginPromise;
    
            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'");
            }
    
    RMidhunSuresh's avatar
    RMidhunSuresh committed
            this._roomViewModel = this.track(new RoomViewModel({
    
    Midhun Suresh's avatar
    Midhun Suresh committed
                room,
                ownUserId: this._session.userId,
                platform: this.platform,
                urlCreator: this.urlCreator,
                navigation: this.navigation,
    
                tileClassForEntry: createCustomTileClassForEntry(this._session.userId),
    
    RMidhunSuresh's avatar
    RMidhunSuresh committed
            }));
    
    Midhun Suresh's avatar
    Midhun Suresh committed
            await this._roomViewModel.load();
    
            this.emitChange("roomViewModel");
    
    Midhun Suresh's avatar
    Midhun Suresh committed
        }
    
    
        private async createRoomWithUserSpecifiedInConfig() {
    
            const userId = this._options.config["invite_user"];
            let room = this._session.findDirectMessageForUserId(userId);
            if (room) {
                // we already have a DM with this user
                return room;
            }
    
            const roomBeingCreated = this._session.createRoom({
    
    RMidhunSuresh's avatar
    RMidhunSuresh committed
                type: 1, //todo: use enum from hydrogen-sdk here
                name: undefined,
                topic: undefined,
    
                isEncrypted: false,
                isFederationDisabled: false,
                alias: undefined,
                avatar: undefined,
    
                invites: [userId],
    
    RMidhunSuresh's avatar
    RMidhunSuresh committed
            const roomStatusObservable = await this._session.observeRoomStatus(roomBeingCreated.id);
            await roomStatusObservable.waitFor(status => status === (RoomStatus.BeingCreated | RoomStatus.Replaced)).promise;
    
            const roomId = roomBeingCreated.roomId;
    
            room = this._session.rooms.get(roomId);
    
    Midhun Suresh's avatar
    Midhun Suresh committed
    
    
        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;
    
    Midhun Suresh's avatar
    Midhun Suresh committed
        }
    
        private _waitForRoomFromSync(roomId: string): Promise<void> {
            let resolve: () => void;
            const promise: Promise<void> = new Promise(r => { resolve = r; })
            const subscription = {
                onAdd: (_: string, value: {id: string}) => {
                    if (value.id === roomId) {
                        this._session.rooms.unsubscribe(subscription);
                        resolve();
                    }
                },
    
                onUpdate: () => undefined,
                onRemove: () => undefined,
    
    Midhun Suresh's avatar
    Midhun Suresh committed
            };
            this._session.rooms.subscribe(subscription);
            return promise;
        }
    
    
    RMidhunSuresh's avatar
    RMidhunSuresh committed
        minimize() {
            (window as any).sendMinimizeToParent();
            this._minimize();
        }
    
    
    Midhun Suresh's avatar
    Midhun Suresh committed
        get timelineViewModel() {
    
    Midhun Suresh's avatar
    Midhun Suresh committed
            return this._roomViewModel?.timelineViewModel;
    
    Midhun Suresh's avatar
    Midhun Suresh committed
        }
    
        get messageComposerViewModel() {
    
            return this._roomViewModel?.composerViewModel;
    
    Midhun Suresh's avatar
    Midhun Suresh committed
        }
    
    Midhun Suresh's avatar
    Midhun Suresh committed
        
        get roomViewModel() {
            return this._roomViewModel;
        }
    
        get roomName() {
            return this._options.config["header"]?.["title"] ?? this._roomViewModel.name;
        }
    
        get customAvatarURL() {
            // has user specified specific avatar to use in config?
            return this._options.config["header"]?.["avatar"];
        }
    
    
        private get _session() {
            return this._client.session;
        }
    
    Midhun Suresh's avatar
    Midhun Suresh committed
    }