From 6140301d9ecd2f1b5b1df7777823ea1089308cc1 Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Wed, 24 Nov 2021 15:12:38 +0000 Subject: [PATCH] Implement lazy-loading from placeholder to room In placeholder-rooms.html --- .../session/leftpanel/BaseTileViewModel.js | 4 ++ .../session/leftpanel/LeftPanelViewModel.js | 7 +- .../leftpanel/PlaceholderRoomTileViewModel.js | 10 ++- .../session/leftpanel/RoomTileViewModel.js | 6 ++ src/matrix/Session.js | 2 - src/placeholder-rooms.html | 70 +++++++++++++++++++ src/platform/web/ui/general/LazyListView.ts | 27 ++++--- .../web/ui/session/leftpanel/LeftPanelView.js | 2 +- 8 files changed, 114 insertions(+), 14 deletions(-) create mode 100644 src/placeholder-rooms.html diff --git a/src/domain/session/leftpanel/BaseTileViewModel.js b/src/domain/session/leftpanel/BaseTileViewModel.js index 95e91458..e8955c3b 100644 --- a/src/domain/session/leftpanel/BaseTileViewModel.js +++ b/src/domain/session/leftpanel/BaseTileViewModel.js @@ -57,6 +57,10 @@ export class BaseTileViewModel extends ViewModel { } compare(other) { + // don't use KIND_ORDER for placeholder|room kinds as they are comparable + if (this.kind !== "invite" && other.kind !== "invite") { + return 0; + } if (other.kind !== this.kind) { return KIND_ORDER.indexOf(this.kind) - KIND_ORDER.indexOf(other.kind); } diff --git a/src/domain/session/leftpanel/LeftPanelViewModel.js b/src/domain/session/leftpanel/LeftPanelViewModel.js index ff27ad9b..f38471ac 100644 --- a/src/domain/session/leftpanel/LeftPanelViewModel.js +++ b/src/domain/session/leftpanel/LeftPanelViewModel.js @@ -43,7 +43,7 @@ export class LeftPanelViewModel extends ViewModel { if (roomOrInvite.isInvite) { vm = new InviteTileViewModel(this.childOptions({invite: roomOrInvite, emitChange})); } else if (roomOrInvite.isPlaceholder) { - vm = new PlaceholderRoomTileViewModel(this.childOptions({emitChange})); + vm = new PlaceholderRoomTileViewModel(this.childOptions({room: roomOrInvite, emitChange})); } else { vm = new RoomTileViewModel(this.childOptions({room: roomOrInvite, emitChange})); } @@ -140,4 +140,9 @@ export class LeftPanelViewModel extends ViewModel { return startFiltering; } } + + // TODO: used in sync v3 + loadRoomRange(range) { + + } } diff --git a/src/domain/session/leftpanel/PlaceholderRoomTileViewModel.js b/src/domain/session/leftpanel/PlaceholderRoomTileViewModel.js index 0acad483..5a6db640 100644 --- a/src/domain/session/leftpanel/PlaceholderRoomTileViewModel.js +++ b/src/domain/session/leftpanel/PlaceholderRoomTileViewModel.js @@ -20,6 +20,11 @@ import {BaseTileViewModel} from "./BaseTileViewModel.js"; export class PlaceholderRoomTileViewModel extends BaseTileViewModel { constructor(options) { super(options); + // Placeholder tiles can be sorted with Room tiles, so we need to ensure we have the same + // fields else the comparison needs to take into account the kind(). + // We need a fake room so we can do compare(other) with RoomTileViewModels + const {room} = options; + this._room = room; } get busy() { @@ -31,11 +36,14 @@ export class PlaceholderRoomTileViewModel extends BaseTileViewModel { } compare(other) { + if (other._room.index !== undefined) { + return this._room.index > other._room.index ? 1 : -1; + } return super.compare(other); } get name() { - return "Placeholder"; + return "Placeholder " + this._room.index; } get avatarLetter() { diff --git a/src/domain/session/leftpanel/RoomTileViewModel.js b/src/domain/session/leftpanel/RoomTileViewModel.js index eebea618..51b3fdf0 100644 --- a/src/domain/session/leftpanel/RoomTileViewModel.js +++ b/src/domain/session/leftpanel/RoomTileViewModel.js @@ -38,6 +38,12 @@ export class RoomTileViewModel extends BaseTileViewModel { if (parentComparison !== 0) { return parentComparison; } + + // sync v3 has its own ordering, use it if we have an index + if (this._room.index !== undefined && other._room.index !== undefined) { + return this._room.index > other._room.index ? 1 : -1;; + } + /* put unread rooms first then put rooms with a timestamp first, and sort by name diff --git a/src/matrix/Session.js b/src/matrix/Session.js index 50b83f23..217de25e 100644 --- a/src/matrix/Session.js +++ b/src/matrix/Session.js @@ -401,8 +401,6 @@ export class Session { room.setInvite(invite); } } - const room = this.createRoom("!temp:localhost"); - room.isPlaceholder = true; this._rooms.add(room.id, room); } diff --git a/src/placeholder-rooms.html b/src/placeholder-rooms.html new file mode 100644 index 00000000..5f0f305e --- /dev/null +++ b/src/placeholder-rooms.html @@ -0,0 +1,70 @@ + + + + + + + + + +
+ + + diff --git a/src/platform/web/ui/general/LazyListView.ts b/src/platform/web/ui/general/LazyListView.ts index 1696f044..c1e42bbe 100644 --- a/src/platform/web/ui/general/LazyListView.ts +++ b/src/platform/web/ui/general/LazyListView.ts @@ -14,15 +14,16 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {tag} from "./html"; -import {removeChildren, mountView} from "./utils"; -import {ListRange, ResultType, AddRemoveResult} from "./ListRange"; -import {ListView, IOptions as IParentOptions} from "./ListView"; -import {IView} from "./types"; +import { tag } from "./html"; +import { removeChildren, mountView } from "./utils"; +import { ListRange, ResultType, AddRemoveResult } from "./ListRange"; +import { ListView, IOptions as IParentOptions } from "./ListView"; +import { IView } from "./types"; export interface IOptions extends IParentOptions { itemHeight: number; overflowItems?: number; + onRangeVisible?: (range: ListRange) => void; } export class LazyListView extends ListView { @@ -31,14 +32,16 @@ export class LazyListView extends ListView { private itemHeight: number; private overflowItems: number; private scrollContainer?: HTMLElement; + private onRangeVisible?: (range: ListRange) => void; constructor( - {itemHeight, overflowItems = 20, ...options}: IOptions, + { itemHeight, onRangeVisible, overflowItems = 20, ...options }: IOptions, childCreator: (value: T) => V ) { super(options, childCreator); this.itemHeight = itemHeight; this.overflowItems = overflowItems; + this.onRangeVisible = onRangeVisible; // function(ItemRange) } handleEvent(e: Event) { @@ -60,7 +63,7 @@ export class LazyListView extends ListView { this.renderUpdate(prevRenderRange, this.renderRange); } } - + // override async loadList() { /* @@ -82,7 +85,7 @@ export class LazyListView extends ListView { } private _getVisibleRange() { - const {clientHeight, scrollTop} = this.root()!; + const { clientHeight, scrollTop } = this.root()!; if (clientHeight === 0) { throw new Error("LazyListView height is 0"); } @@ -101,6 +104,9 @@ export class LazyListView extends ListView { }); this._listElement!.appendChild(fragment); this.adjustPadding(range); + if (this.onRangeVisible) { + this.onRangeVisible(range); + } } private renderUpdate(prevRange: ListRange, newRange: ListRange) { @@ -121,6 +127,9 @@ export class LazyListView extends ListView { } }); this.adjustPadding(newRange); + if (this.onRangeVisible) { + this.onRangeVisible(newRange); + } } else { this.reRenderFullRange(newRange); } @@ -136,7 +145,7 @@ export class LazyListView extends ListView { mount() { const listElement = super.mount(); - this.scrollContainer = tag.div({className: "LazyListParent"}, listElement) as HTMLElement; + this.scrollContainer = tag.div({ className: "LazyListParent" }, listElement) as HTMLElement; this.scrollContainer.addEventListener("scroll", this); return this.scrollContainer; } diff --git a/src/platform/web/ui/session/leftpanel/LeftPanelView.js b/src/platform/web/ui/session/leftpanel/LeftPanelView.js index a75207ee..fcf5c5e8 100644 --- a/src/platform/web/ui/session/leftpanel/LeftPanelView.js +++ b/src/platform/web/ui/session/leftpanel/LeftPanelView.js @@ -65,7 +65,7 @@ export class LeftPanelView extends TemplateView { itemHeight: 44, list: vm.tileViewModels, onRangeVisible: (range) => { - console.log(range); + vm.loadRoomRange(range); }, }, tileVM => {