diff --git a/src/domain/session/leftpanel/LeftPanelViewModel.js b/src/domain/session/leftpanel/LeftPanelViewModel.js index 59b68ca1..ff27ad9b 100644 --- a/src/domain/session/leftpanel/LeftPanelViewModel.js +++ b/src/domain/session/leftpanel/LeftPanelViewModel.js @@ -21,6 +21,7 @@ import {InviteTileViewModel} from "./InviteTileViewModel.js"; import {RoomFilter} from "./RoomFilter.js"; import {ApplyMap} from "../../../observable/map/ApplyMap.js"; import {addPanelIfNeeded} from "../../navigation/index.js"; +import { PlaceholderRoomTileViewModel } from "./PlaceholderRoomTileViewModel.js"; export class LeftPanelViewModel extends ViewModel { constructor(options) { @@ -41,6 +42,8 @@ export class LeftPanelViewModel extends ViewModel { let vm; if (roomOrInvite.isInvite) { vm = new InviteTileViewModel(this.childOptions({invite: roomOrInvite, emitChange})); + } else if (roomOrInvite.isPlaceholder) { + vm = new PlaceholderRoomTileViewModel(this.childOptions({emitChange})); } else { vm = new RoomTileViewModel(this.childOptions({room: roomOrInvite, emitChange})); } diff --git a/src/domain/session/leftpanel/PlaceholderRoomTileViewModel.js b/src/domain/session/leftpanel/PlaceholderRoomTileViewModel.js new file mode 100644 index 00000000..0acad483 --- /dev/null +++ b/src/domain/session/leftpanel/PlaceholderRoomTileViewModel.js @@ -0,0 +1,56 @@ +/* +Copyright 2021 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import {getIdentifierColorNumber} from "../../avatar.js"; +import {BaseTileViewModel} from "./BaseTileViewModel.js"; + +export class PlaceholderRoomTileViewModel extends BaseTileViewModel { + constructor(options) { + super(options); + } + + get busy() { + return false; + } + + get kind() { + return "placeholder"; + } + + compare(other) { + return super.compare(other); + } + + get name() { + return "Placeholder"; + } + + get avatarLetter() { + return " "; + } + + get avatarColorNumber() { + return getIdentifierColorNumber("placeholder"); // TODO: randomise + } + + avatarUrl(size) { + return null; + } + + get avatarTitle() { + return "Placeholder"; + } +} diff --git a/src/matrix/Session.js b/src/matrix/Session.js index 37fd90ad..50b83f23 100644 --- a/src/matrix/Session.js +++ b/src/matrix/Session.js @@ -401,6 +401,9 @@ export class Session { room.setInvite(invite); } } + const room = this.createRoom("!temp:localhost"); + room.isPlaceholder = true; + this._rooms.add(room.id, room); } dispose() { diff --git a/src/platform/web/ui/css/left-panel.css b/src/platform/web/ui/css/left-panel.css index f00c1572..8e900ea5 100644 --- a/src/platform/web/ui/css/left-panel.css +++ b/src/platform/web/ui/css/left-panel.css @@ -45,6 +45,19 @@ limitations under the License. align-items: center; } +.RoomList > .placeholder { + display: flex; + align-items: center; +} + +.RoomList > .placeholder > .phdescription { + /* the avatar icon doesn't pad right because the placeholder lacks an tag, so pad left to get the equiv layout */ + margin-left: 8px; + /* make grey rectangles where the description should be */ + background: rgb(236,237,238); + color: rgb(236,237,238); +} + .RoomList .description { margin: 0; flex: 1 1 0; diff --git a/src/platform/web/ui/session/leftpanel/LeftPanelView.js b/src/platform/web/ui/session/leftpanel/LeftPanelView.js index 481c5362..b6f7a8db 100644 --- a/src/platform/web/ui/session/leftpanel/LeftPanelView.js +++ b/src/platform/web/ui/session/leftpanel/LeftPanelView.js @@ -14,10 +14,11 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {ListView} from "../../general/ListView"; +import {LazyListView} from "../../general/LazyListView"; import {TemplateView} from "../../general/TemplateView"; import {RoomTileView} from "./RoomTileView.js"; import {InviteTileView} from "./InviteTileView.js"; +import { PlaceholderRoomTileView } from "./PlaceholderRoomTileView"; class FilterField extends TemplateView { render(t, options) { @@ -58,14 +59,17 @@ export class LeftPanelView extends TemplateView { vm.i18n`Show single room` : vm.i18n`Enable grid layout`; }; - const roomList = t.view(new ListView( + const roomList = t.view(new LazyListView( { className: "RoomList", + itemHeight: 44, list: vm.tileViewModels, }, tileVM => { if (tileVM.kind === "invite") { return new InviteTileView(tileVM); + } if (tileVM.kind === "placeholder") { + return new PlaceholderRoomTileView(tileVM); } else { return new RoomTileView(tileVM); } diff --git a/src/platform/web/ui/session/leftpanel/PlaceholderRoomTileView.js b/src/platform/web/ui/session/leftpanel/PlaceholderRoomTileView.js new file mode 100644 index 00000000..344b7006 --- /dev/null +++ b/src/platform/web/ui/session/leftpanel/PlaceholderRoomTileView.js @@ -0,0 +1,34 @@ +/* +Copyright 2021 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import {TemplateView} from "../../general/TemplateView"; +import {renderStaticAvatar} from "../../avatar.js"; + +export class PlaceholderRoomTileView extends TemplateView { + render(t, vm) { + const classes = { + "active": vm => vm.isOpen, + "hidden": vm => vm.hidden, + "placeholder": true, + }; + return t.li({"className": classes}, [ + renderStaticAvatar(vm, 32), + t.div({className: "phdescription"}, [ + t.div({className: "name"}, vm.name), + ]) + ]); + } +}