diff --git a/index.html b/index.html index fc78de8..df58e7c 100644 --- a/index.html +++ b/index.html @@ -6,7 +6,7 @@ \ No newline at end of file diff --git a/src/Link.js b/src/Link.js index 5b60048..64827e2 100644 --- a/src/Link.js +++ b/src/Link.js @@ -14,7 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ - import {createEnum} from "./utils/enum.js"; const ROOMALIAS_PATTERN = /^#([^:]*):(.+)$/; diff --git a/src/RootView.js b/src/RootView.js new file mode 100644 index 0000000..2065d00 --- /dev/null +++ b/src/RootView.js @@ -0,0 +1,29 @@ +/* +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 "./utils/TemplateView.js"; +import {PreviewView} from "./preview/PreviewView.js"; + +export class RootView extends TemplateView { + render(t, vm) { + return t.div({className: "RootView"}, t.mapView(vm => vm.activeSection, activeSection => { + switch (activeSection) { + case "preview": return new PreviewView(vm.previewViewModel); + default: return null; + } + })); + } +} \ No newline at end of file diff --git a/src/RootViewModel.js b/src/RootViewModel.js index ea4a9bf..4cc2fed 100644 --- a/src/RootViewModel.js +++ b/src/RootViewModel.js @@ -20,17 +20,26 @@ import {PreviewViewModel} from "./preview/PreviewViewModel.js"; export class RootViewModel extends ViewModel { constructor(request, hash) { - super(); - this._request = request; + super({request}); this.link = Link.parseFragment(hash); this.previewViewModel = null; } load() { if (this.link) { - this.previewViewModel = new PreviewViewModel(this._request, this.link); + this.previewViewModel = new PreviewViewModel(this.childOptions({ + link: this.link, + consentedServers: this.link.servers + })); this.emitChange(); this.previewViewModel.load(); } } + + get activeSection() { + if (this.previewViewModel) { + return "preview"; + } + return ""; + } } \ No newline at end of file diff --git a/src/ViewModel.js b/src/ViewModel.js index 3d00dec..4cc14e1 100644 --- a/src/ViewModel.js +++ b/src/ViewModel.js @@ -31,7 +31,6 @@ class EventEmitter { on(name, callback) { let handlers = this._handlersByName[name]; if (!handlers) { - this.onFirstSubscriptionAdded(name); this._handlersByName[name] = handlers = new Set(); } handlers.add(callback); @@ -46,14 +45,26 @@ class EventEmitter { handlers.delete(callback); if (handlers.length === 0) { delete this._handlersByName[name]; - this.onLastSubscriptionRemoved(name); } } } } export class ViewModel extends EventEmitter { + constructor(options) { + super(); + this._options = options; + } + emitChange() { this.emit("change"); } + + get request() { + return this._options.request; + } + + childOptions(options = {}) { + return Object.assign({request: this.request}, options); + } } \ No newline at end of file diff --git a/src/main.js b/src/main.js index 901eb55..472fd6f 100644 --- a/src/main.js +++ b/src/main.js @@ -1,10 +1,11 @@ import {xhrRequest} from "./utils/xhr.js"; import {RootViewModel} from "./RootViewModel.js"; +import {RootView} from "./RootView.js"; export async function main(container) { const vm = new RootViewModel(xhrRequest, location.hash); vm.load(); window.__rootvm = vm; - // const view = new RootView(vm); - // container.appendChild(view.mount()); + const view = new RootView(vm); + container.appendChild(view.mount()); } \ No newline at end of file diff --git a/src/preview/PreviewView.js b/src/preview/PreviewView.js new file mode 100644 index 0000000..ed31ee2 --- /dev/null +++ b/src/preview/PreviewView.js @@ -0,0 +1,27 @@ +/* +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 "../utils/TemplateView.js"; + +export class PreviewView extends TemplateView { + render(t, vm) { + return t.div({className: "PreviewView"}, [ + t.p(t.img({src: vm => vm.avatarUrl})), + t.p(vm => vm.name), + t.p(["loading: ", vm => vm.loading]) + ]); + } +} \ No newline at end of file diff --git a/src/preview/PreviewViewModel.js b/src/preview/PreviewViewModel.js index e6fd7e8..109679f 100644 --- a/src/preview/PreviewViewModel.js +++ b/src/preview/PreviewViewModel.js @@ -19,21 +19,22 @@ import {ViewModel} from "../ViewModel.js"; import {resolveServer} from "./HomeServer.js"; export class PreviewViewModel extends ViewModel { - constructor(request, link) { - super(); + constructor(options) { + super(options); + const {link, consentedServers} = options; this._link = link; - this._request = request; + this._consentedServers = consentedServers; this.loading = false; this.name = null; - this.avatarURL = null; + this.avatarUrl = null; } async load() { this.loading = true; this.emitChange(); - for (const server of this._link.servers) { + for (const server of this._consentedServers) { try { - const homeserver = await resolveServer(this._request, server); + const homeserver = await resolveServer(this.request, server); switch (this._link.kind) { case LinkKind.User: await this._loadUserPreview(homeserver, this._link.identifier); @@ -51,7 +52,7 @@ export class PreviewViewModel extends ViewModel { async _loadUserPreview(homeserver, userId) { const profile = await homeserver.getUserProfile(userId); this.name = profile.displayname || userId; - this.avatarURL = profile.avatar_url ? + this.avatarUrl = profile.avatar_url ? homeserver.mxcUrlThumbnail(profile.avatar_url, 64, 64, "crop") : null; }