From 68a0dd30ca17288db192f3738baeee1fb73fdadd Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 28 Oct 2020 17:42:18 +0100 Subject: [PATCH] add lightbox navigation and basic view & view model --- src/domain/navigation/index.js | 2 ++ src/domain/session/SessionViewModel.js | 21 ++++++++++++ src/domain/session/room/LightboxViewModel.js | 33 +++++++++++++++++++ .../session/room/timeline/tiles/ImageTile.js | 9 +++++ src/platform/web/ui/session/SessionView.js | 2 ++ .../web/ui/session/room/LightboxView.js | 23 +++++++++++++ .../web/ui/session/room/timeline/ImageView.js | 1 + 7 files changed, 91 insertions(+) create mode 100644 src/domain/session/room/LightboxViewModel.js create mode 100644 src/platform/web/ui/session/room/LightboxView.js diff --git a/src/domain/navigation/index.js b/src/domain/navigation/index.js index ec593122..44f81026 100644 --- a/src/domain/navigation/index.js +++ b/src/domain/navigation/index.js @@ -36,6 +36,8 @@ function allowsChild(parent, child) { case "rooms": // downside of the approach: both of these will control which tile is selected return type === "room" || type === "empty-grid-tile"; + case "room": + return type === "lightbox"; default: return false; } diff --git a/src/domain/session/SessionViewModel.js b/src/domain/session/SessionViewModel.js index 79d8d87c..5f327ef9 100644 --- a/src/domain/session/SessionViewModel.js +++ b/src/domain/session/SessionViewModel.js @@ -17,6 +17,7 @@ limitations under the License. import {LeftPanelViewModel} from "./leftpanel/LeftPanelViewModel.js"; import {RoomViewModel} from "./room/RoomViewModel.js"; +import {LightboxViewModel} from "./room/LightboxViewModel.js"; import {SessionStatusViewModel} from "./SessionStatusViewModel.js"; import {RoomGridViewModel} from "./RoomGridViewModel.js"; import {SettingsViewModel} from "./settings/SettingsViewModel.js"; @@ -67,6 +68,12 @@ export class SessionViewModel extends ViewModel { this._updateSettings(settingsOpen); })); this._updateSettings(settings.get()); + + const lightbox = this.navigation.observe("lightbox"); + this.track(lightbox.subscribe(eventId => { + this._updateLightbox(eventId); + })); + this._updateLightbox(lightbox.get()); } get id() { @@ -194,4 +201,18 @@ export class SessionViewModel extends ViewModel { } this.emitChange("activeSection"); } + + _updateLightbox(eventId) { + if (this._lightboxViewModel) { + this._lightboxViewModel = this.disposeTracked(this._lightboxViewModel); + } + if (eventId) { + this._lightboxViewModel = this.track(new LightboxViewModel(this.childOptions({eventId}))); + } + this.emitChange("lightboxViewModel"); + } + + get lightboxViewModel() { + return this._lightboxViewModel; + } } diff --git a/src/domain/session/room/LightboxViewModel.js b/src/domain/session/room/LightboxViewModel.js new file mode 100644 index 00000000..00599eca --- /dev/null +++ b/src/domain/session/room/LightboxViewModel.js @@ -0,0 +1,33 @@ +/* +Copyright 2020 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 {ViewModel} from "../../ViewModel.js"; + +export class LightboxViewModel extends ViewModel { + constructor(options) { + super(options); + this._eventId = options.eventId; + this._closeUrl = this.urlCreator.urlUntilSegment("room"); + } + + get eventId() { + return this._eventId; + } + + get closeUrl() { + return this._closeUrl; + } +} diff --git a/src/domain/session/room/timeline/tiles/ImageTile.js b/src/domain/session/room/timeline/tiles/ImageTile.js index 04cff3c9..f4212912 100644 --- a/src/domain/session/room/timeline/tiles/ImageTile.js +++ b/src/domain/session/room/timeline/tiles/ImageTile.js @@ -27,6 +27,11 @@ export class ImageTile extends MessageTile { this._decryptedImage = null; this._error = null; this.load(); + this._lightboxUrl = this.urlCreator.urlForSegments([ + // ensure the right room is active if in grid view + this.navigation.segment("room", this._room.id), + this.navigation.segment("lightbox", this._entry.id) + ]); } async _loadEncryptedFile(file) { @@ -54,6 +59,10 @@ export class ImageTile extends MessageTile { } } + get lightboxUrl() { + return this._lightboxUrl; + } + get thumbnailUrl() { if (this._decryptedThumbail) { return this._decryptedThumbail.url; diff --git a/src/platform/web/ui/session/SessionView.js b/src/platform/web/ui/session/SessionView.js index cc16b8d8..fa7a492a 100644 --- a/src/platform/web/ui/session/SessionView.js +++ b/src/platform/web/ui/session/SessionView.js @@ -17,6 +17,7 @@ limitations under the License. import {LeftPanelView} from "./leftpanel/LeftPanelView.js"; import {RoomView} from "./room/RoomView.js"; +import {LightboxView} from "./room/LightboxView.js"; import {TemplateView} from "../general/TemplateView.js"; import {StaticView} from "../general/StaticView.js"; import {SessionStatusView} from "./SessionStatusView.js"; @@ -45,6 +46,7 @@ export class SessionView extends TemplateView { return new RoomView(vm.currentRoomViewModel); } }), + t.mapView(vm => vm.lightboxViewModel, lightboxViewModel => lightboxViewModel ? new LightboxView(lightboxViewModel) : null) ]); } } diff --git a/src/platform/web/ui/session/room/LightboxView.js b/src/platform/web/ui/session/room/LightboxView.js new file mode 100644 index 00000000..4c4ef316 --- /dev/null +++ b/src/platform/web/ui/session/room/LightboxView.js @@ -0,0 +1,23 @@ +/* +Copyright 2020 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.js"; + +export class LightboxView extends TemplateView { + render(t, vm) { + return t.div({className: "lightbox"}, [vm.eventId, t.br(), t.a({href: vm.closeUrl}, "close")]); + } +} diff --git a/src/platform/web/ui/session/room/timeline/ImageView.js b/src/platform/web/ui/session/room/timeline/ImageView.js index 113fb1e4..90355fe6 100644 --- a/src/platform/web/ui/session/room/timeline/ImageView.js +++ b/src/platform/web/ui/session/room/timeline/ImageView.js @@ -31,6 +31,7 @@ export class ImageView extends TemplateView { title: vm => vm.label, }); const linkContainer = t.a({ + href: vm.lightboxUrl, style: `padding-top: ${heightRatioPercent}%; width: ${vm.thumbnailWidth}px;` }, [ image,