From 67af9dcbe8cc5e60d9b8046319621c490baea8b2 Mon Sep 17 00:00:00 2001
From: Midhun Suresh <midhunr@element.io>
Date: Tue, 18 Jan 2022 13:29:21 +0530
Subject: [PATCH] Add loading view in timeline

---
 src/style.css                           |  5 +++++
 src/ui/views/ChatterboxView.ts          |  6 +++---
 src/viewmodels/AccountSetupViewModel.ts |  6 ++----
 src/viewmodels/ChatterboxViewModel.ts   | 12 ++++++++++--
 src/viewmodels/RootViewModel.ts         |  9 +++++----
 5 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/src/style.css b/src/style.css
index a079c50..ffaf7aa 100644
--- a/src/style.css
+++ b/src/style.css
@@ -65,6 +65,11 @@ todo: this style should actually be in hydrogen-web
     width: 100%;
 }
 
+.ChatterboxView {
+    width: 375px;
+    height: 570px;
+}
+
 .hydrogen {
     background-color: transparent !important;
 }
diff --git a/src/ui/views/ChatterboxView.ts b/src/ui/views/ChatterboxView.ts
index c8be32f..632bd0b 100644
--- a/src/ui/views/ChatterboxView.ts
+++ b/src/ui/views/ChatterboxView.ts
@@ -1,12 +1,12 @@
-import { TemplateView, TimelineView } from "hydrogen-view-sdk";
+import { TemplateView, TimelineView, LoadingView } from "hydrogen-view-sdk";
 import { Builder } from "hydrogen-view-sdk/types/platform/web/ui/general/TemplateView";
 import { MessageComposer } from "hydrogen-view-sdk";
 import { ChatterboxViewModel } from "../../viewmodels/ChatterboxViewModel";
 
 export class ChatterboxView extends TemplateView<ChatterboxViewModel> {
     render(t: Builder<ChatterboxViewModel>) {
-        return t.div([
-            t.mapView(vm => vm.timelineViewModel, vm => vm ? new TimelineView(vm) : null),
+        return t.div({className: "ChatterboxView"}, [
+            t.mapView(vm => vm.timelineViewModel, vm => vm ? new TimelineView(vm) : new LoadingView()),
             t.mapView(vm => vm.messageComposerViewModel, vm => vm ? new MessageComposer(vm) : null)
         ]);
     }
diff --git a/src/viewmodels/AccountSetupViewModel.ts b/src/viewmodels/AccountSetupViewModel.ts
index 39a750b..448b79a 100644
--- a/src/viewmodels/AccountSetupViewModel.ts
+++ b/src/viewmodels/AccountSetupViewModel.ts
@@ -34,13 +34,13 @@ export class AccountSetupViewModel extends ViewModel {
             stage = await stage.complete();
         }
         // stage is username when registration is completed
-        await this.login(stage, this._password);
+        const loginPromise = this.login(stage, this._password);
+        this._applySegment("timeline", loginPromise);
     }
 
     async login(username: string, password: string): Promise<void> {
         const loginOptions = await this._client.queryLogin(this._homeserver).result;
         this._client.startWithLogin(loginOptions.password(username, password));
-
         await this._client.loadStatus.waitFor((status: string) => {
             return status === LoadStatus.Ready ||
                 status === LoadStatus.Error ||
@@ -52,8 +52,6 @@ export class AccountSetupViewModel extends ViewModel {
         } else if (this._client.loadError) {
             throw new Error("load failed: " + this._client.loadError.message);
         }
-
-        this._applySegment("timeline");
     }
 
     dismiss() {
diff --git a/src/viewmodels/ChatterboxViewModel.ts b/src/viewmodels/ChatterboxViewModel.ts
index c62f6fe..b3c3d36 100644
--- a/src/viewmodels/ChatterboxViewModel.ts
+++ b/src/viewmodels/ChatterboxViewModel.ts
@@ -1,16 +1,19 @@
 import { RoomViewModel, ViewModel, TimelineViewModel, ComposerViewModel} from "hydrogen-view-sdk";
 
 export class ChatterboxViewModel extends ViewModel {
-    private readonly _session: any;
     private _timelineViewModel?: TimelineViewModel;
     private _messageComposerViewModel?: ComposerViewModel;
+    private _loginPromise: Promise<void>;
 
     constructor(options) {
         super(options);
-        this._session = options.session; 
+        this._client = options.client;
+        this._loginPromise = options.loginPromise;
     }
 
     async loadRoom() {
+        // 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);
         const roomVm = new RoomViewModel({
@@ -23,6 +26,7 @@ export class ChatterboxViewModel extends ViewModel {
         await roomVm.load();
         this._timelineViewModel = roomVm.timelineViewModel;
         this._messageComposerViewModel = new ComposerViewModel(roomVm);
+        this.emitChange("timelineViewModel");
     }
 
     private async _joinRoom(roomId: string): Promise<any> {
@@ -55,4 +59,8 @@ export class ChatterboxViewModel extends ViewModel {
     get messageComposerViewModel() {
         return this._messageComposerViewModel;
     }
+
+    private get _session() {
+        return this._client.session;
+    }
 }
diff --git a/src/viewmodels/RootViewModel.ts b/src/viewmodels/RootViewModel.ts
index 4ec090b..7957949 100644
--- a/src/viewmodels/RootViewModel.ts
+++ b/src/viewmodels/RootViewModel.ts
@@ -24,7 +24,7 @@ export class RootViewModel extends ViewModel {
 
     private _setupNavigation() {
         this.navigation.observe("account-setup").subscribe(() => this._showAccountSetup());
-        this.navigation.observe("timeline").subscribe(() => this._showTimeline());
+        this.navigation.observe("timeline").subscribe((loginPromise) => this._showTimeline(loginPromise));
         this.navigation.observe("start").subscribe(() => this._showStartButton());
     }
 
@@ -37,17 +37,18 @@ export class RootViewModel extends ViewModel {
         this._applySegment("account-setup");
     }
 
-    private async _showTimeline() {
+    private async _showTimeline(loginPromise: Promise<void>) {
         this._activeSection = "timeline";
         this._chatterBoxViewModel = new ChatterboxViewModel(
             this.childOptions({
-                session: this._client.session,
+                client: this._client,
                 config: this._config,
                 state: this._state,
                 applySegment: this._applySegment,
+                loginPromise,
             })
         );
-        await this._chatterBoxViewModel.loadRoom();
+        this._chatterBoxViewModel.loadRoom();
         this.emitChange("activeSection");
     }
 
-- 
GitLab