make preview useable without client list, to reuse in create link view
This commit is contained in:
parent
60b280bbf9
commit
5d40d01360
17 changed files with 165 additions and 66 deletions
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import {createEnum} from "../utils/enum.js";
|
||||
import {createEnum} from "./utils/enum.js";
|
||||
|
||||
export const Platform = createEnum(
|
||||
"DesktopWeb",
|
||||
|
@ -29,7 +29,7 @@ export const Platform = createEnum(
|
|||
export function guessApplicablePlatforms(userAgent) {
|
||||
// use https://github.com/faisalman/ua-parser-js to guess, and pass as RootVM options
|
||||
return [Platform.DesktopWeb, Platform.Linux];
|
||||
//return [Platform.MobileWeb, Platform.iOS];
|
||||
// return [Platform.MobileWeb, Platform.Android];
|
||||
}
|
||||
|
||||
export function isWebPlatform(p) {
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import {Platform} from "./client/Platform.js";
|
||||
import {Platform} from "./Platform.js";
|
||||
|
||||
export class Preferences {
|
||||
constructor(localStorage) {
|
||||
|
|
|
@ -15,12 +15,14 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import {TemplateView} from "./utils/TemplateView.js";
|
||||
import {PreviewView} from "./preview/PreviewView.js";
|
||||
import {OpenLinkView} from "./open/OpenLinkView.js";
|
||||
import {CreateLinkView} from "./create/CreateLinkView.js";
|
||||
|
||||
export class RootView extends TemplateView {
|
||||
render(t, vm) {
|
||||
return t.div({className: "RootView"}, [
|
||||
t.mapView(vm => vm.previewViewModel, vm => vm ? new PreviewView(vm) : null),
|
||||
t.mapView(vm => vm.openLinkViewModel, vm => vm ? new OpenLinkView(vm) : null),
|
||||
t.mapView(vm => vm.createLinkViewModel, vm => vm ? new CreateLinkView(vm) : null),
|
||||
t.div({className: "footer"}, [
|
||||
t.p(t.img({src: "images/matrix-logo.svg"})),
|
||||
t.p(["This invite uses ", externalLink(t, "https://matrix.org", "Matrix"), ", an open network for secure, decentralized communication."]),
|
||||
|
|
|
@ -16,27 +16,29 @@ limitations under the License.
|
|||
|
||||
import {Link} from "./Link.js";
|
||||
import {ViewModel} from "./utils/ViewModel.js";
|
||||
import {PreviewViewModel} from "./preview/PreviewViewModel.js";
|
||||
import {Element} from "./client/clients/Element.js";
|
||||
import {Weechat} from "./client/clients/Weechat.js";
|
||||
import {Platform} from "./client/Platform.js";
|
||||
import {OpenLinkViewModel} from "./open/OpenLinkViewModel.js";
|
||||
import {createClients} from "./open/clients/index.js";
|
||||
import {CreateLinkViewModel} from "./create/CreateLinkViewModel.js";
|
||||
import {Platform} from "./Platform.js";
|
||||
|
||||
export class RootViewModel extends ViewModel {
|
||||
constructor(options) {
|
||||
super(options);
|
||||
this.link = null;
|
||||
this.previewViewModel = null;
|
||||
this.openLinkViewModel = null;
|
||||
this.createLinkViewModel = null;
|
||||
}
|
||||
|
||||
_updateChildVMs(oldLink) {
|
||||
if (this.link) {
|
||||
this.createLinkViewModel = null;
|
||||
if (!oldLink || !oldLink.equals(this.link)) {
|
||||
this.previewViewModel = new PreviewViewModel(this.childOptions({
|
||||
this.openLinkViewModel = new OpenLinkViewModel(this.childOptions({
|
||||
link: this.link,
|
||||
consentedServers: this.link.servers,
|
||||
clients: [new Element(), new Weechat()]
|
||||
clients: createClients()
|
||||
}));
|
||||
this.previewViewModel.load();
|
||||
this.openLinkViewModel.load();
|
||||
}
|
||||
} else {
|
||||
this.previewViewModel = null;
|
||||
|
@ -50,13 +52,6 @@ export class RootViewModel extends ViewModel {
|
|||
this._updateChildVMs(oldLink);
|
||||
}
|
||||
|
||||
get activeSection() {
|
||||
if (this.previewViewModel) {
|
||||
return "preview";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
clearPreferences() {
|
||||
this.preferences.clear();
|
||||
this._updateChildVMs();
|
||||
|
|
|
@ -2,7 +2,7 @@ import {xhrRequest} from "./utils/xhr.js";
|
|||
import {RootViewModel} from "./RootViewModel.js";
|
||||
import {RootView} from "./RootView.js";
|
||||
import {Preferences} from "./Preferences.js";
|
||||
import {guessApplicablePlatforms} from "./client/Platform.js";
|
||||
import {guessApplicablePlatforms} from "./Platform.js";
|
||||
|
||||
export async function main(container) {
|
||||
const vm = new RootViewModel({
|
||||
|
@ -10,6 +10,7 @@ export async function main(container) {
|
|||
openLink: url => location.href = url,
|
||||
platforms: guessApplicablePlatforms(navigator.userAgent),
|
||||
preferences: new Preferences(window.localStorage),
|
||||
origin: location.origin,
|
||||
});
|
||||
vm.updateHash(location.hash);
|
||||
window.__rootvm = vm;
|
||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import {isWebPlatform, Platform} from "./Platform.js";
|
||||
import {isWebPlatform, Platform} from "../Platform.js";
|
||||
import {Maturity} from "./types.js";
|
||||
import {ClientViewModel} from "./ClientViewModel.js";
|
||||
import {ViewModel} from "../utils/ViewModel.js";
|
|
@ -99,6 +99,7 @@ class InstallClientView extends TemplateView {
|
|||
const deepLink = t.a({
|
||||
rel: "noopener noreferrer",
|
||||
href: vm.deepLink,
|
||||
onClick: () => vm.deepLinkActivated(),
|
||||
}, "open it here");
|
||||
children.push(t.p([`If you already have ${vm.name} installed, you can `, deepLink, "."]))
|
||||
}
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import {isWebPlatform, isDesktopPlatform, Platform} from "./Platform.js";
|
||||
import {isWebPlatform, isDesktopPlatform, Platform} from "../Platform.js";
|
||||
import {ViewModel} from "../utils/ViewModel.js";
|
||||
|
||||
export class ClientViewModel extends ViewModel {
|
||||
|
@ -44,7 +44,7 @@ export class ClientViewModel extends ViewModel {
|
|||
_createActions(client, link, nativePlatform, webPlatform) {
|
||||
let actions = [];
|
||||
if (nativePlatform) {
|
||||
const nativeActions = client.getInstallLinks(nativePlatform).map(installLink => {
|
||||
const nativeActions = (client.getInstallLinks(nativePlatform) || []).map(installLink => {
|
||||
return {
|
||||
label: installLink.description,
|
||||
url: installLink.createInstallURL(link),
|
||||
|
@ -56,13 +56,16 @@ export class ClientViewModel extends ViewModel {
|
|||
actions.push(...nativeActions);
|
||||
}
|
||||
if (webPlatform) {
|
||||
const webDeepLink = client.getDeepLink(webPlatform, link);
|
||||
if (webDeepLink) {
|
||||
actions.push({
|
||||
label: `Or open in ${client.getName(webPlatform)}`,
|
||||
url: client.getDeepLink(webPlatform, link),
|
||||
url: webDeepLink,
|
||||
kind: "open-in-web",
|
||||
activated: () => this.preferences.setClient(client.id, webPlatform),
|
||||
});
|
||||
}
|
||||
}
|
||||
if (actions.length === 0) {
|
||||
actions.push({
|
||||
label: `Visit app homepage`,
|
35
src/open/OpenLinkView.js
Normal file
35
src/open/OpenLinkView.js
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
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 {ClientListView} from "./ClientListView.js";
|
||||
import {PreviewView} from "../preview/PreviewView.js";
|
||||
|
||||
export class OpenLinkView extends TemplateView {
|
||||
render(t, vm) {
|
||||
return t.div({className: "OpenLinkView card"}, [
|
||||
t.view(new PreviewView(vm.previewViewModel)),
|
||||
t.div({className: {hidden: vm => vm.previewLoading}}, [
|
||||
t.p({className: {hidden: vm => vm.clientsViewModel}}, t.button({
|
||||
className: "primary fullwidth",
|
||||
onClick: () => vm.showClients()
|
||||
}, vm => vm.showClientsLabel)),
|
||||
t.mapView(vm => vm.clientsViewModel, childVM => childVM ? new ClientListView(childVM) : null),
|
||||
t.p(["Preview provided by ", vm => vm.previewDomain]),
|
||||
])
|
||||
]);
|
||||
}
|
||||
}
|
64
src/open/OpenLinkViewModel.js
Normal file
64
src/open/OpenLinkViewModel.js
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
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 "../utils/ViewModel.js";
|
||||
import {ClientListViewModel} from "./ClientListViewModel.js";
|
||||
import {ClientViewModel} from "./ClientViewModel.js";
|
||||
import {PreviewViewModel} from "../preview/PreviewViewModel.js";
|
||||
import {getLabelForLinkKind} from "../Link.js";
|
||||
|
||||
export class OpenLinkViewModel extends ViewModel {
|
||||
constructor(options) {
|
||||
super(options);
|
||||
const {clients, link, consentedServers} = options;
|
||||
this._link = link;
|
||||
this._clients = clients;
|
||||
this.previewViewModel = new PreviewViewModel(this.childOptions({link, consentedServers}));
|
||||
this.previewLoading = false;
|
||||
const preferredClient = this.preferences.clientId ? clients.find(c => c.id === this.preferences.clientId) : null;
|
||||
this.clientsViewModel = preferredClient ? new ClientListViewModel(this.childOptions({
|
||||
clients,
|
||||
link,
|
||||
client: preferredClient,
|
||||
})) : null;
|
||||
}
|
||||
|
||||
async load() {
|
||||
this.previewLoading = true;
|
||||
this.emitChange();
|
||||
await this.previewViewModel.load();
|
||||
this.previewLoading = false;
|
||||
this.emitChange();
|
||||
}
|
||||
|
||||
get previewDomain() {
|
||||
return this.previewViewModel.previewDomain;
|
||||
}
|
||||
|
||||
get showClientsLabel() {
|
||||
return getLabelForLinkKind(this._link.kind);
|
||||
}
|
||||
|
||||
showClients() {
|
||||
if (!this.clientsViewModel) {
|
||||
this.clientsViewModel = new ClientListViewModel(this.childOptions({
|
||||
clients: this._clients,
|
||||
link: this._link
|
||||
}));
|
||||
this.emitChange();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -28,7 +28,7 @@ export class Element {
|
|||
return [
|
||||
Platform.Android, Platform.iOS,
|
||||
Platform.Windows, Platform.macOS, Platform.Linux,
|
||||
Platform.DesktopWeb, Platform.MobileWeb
|
||||
Platform.DesktopWeb
|
||||
];
|
||||
}
|
||||
|
25
src/open/clients/index.js
Normal file
25
src/open/clients/index.js
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
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 {Element} from "./Element.js";
|
||||
import {Weechat} from "./Weechat.js";
|
||||
|
||||
export function createClients() {
|
||||
return [
|
||||
new Element(),
|
||||
new Weechat(),
|
||||
];
|
||||
}
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
|||
import {createEnum} from "../utils/enum.js";
|
||||
export const Maturity = createEnum("Alpha", "Beta", "Stable");
|
||||
export {LinkKind} from "../Link.js";
|
||||
export {Platform} from "./Platform.js";
|
||||
export {Platform} from "../Platform.js";
|
||||
|
||||
export class AppleStoreLink {
|
||||
constructor(org, appId) {
|
|
@ -15,12 +15,12 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import {TemplateView} from "../utils/TemplateView.js";
|
||||
import {ClientListView} from "../client/ClientListView.js";
|
||||
import {ClientView} from "../client/ClientView.js";
|
||||
import {ClientListView} from "../open/ClientListView.js";
|
||||
import {ClientView} from "../open/ClientView.js";
|
||||
|
||||
export class PreviewView extends TemplateView {
|
||||
render(t, vm) {
|
||||
return t.div({className: "PreviewView card"}, [
|
||||
return t.div({className: "PreviewView"}, [
|
||||
t.h1({className: {hidden: vm => !vm.loading}}, "Loading preview…"),
|
||||
t.div({className: {hidden: vm => vm.loading}}, [
|
||||
t.div({className: "preview"}, [
|
||||
|
@ -30,12 +30,6 @@ export class PreviewView extends TemplateView {
|
|||
t.p({className: {memberCount: true, hidden: vm => !vm.memberCount}}, [vm => vm.memberCount, " members"]),
|
||||
t.p({className: {topic: true, hidden: vm => !vm.topic}}, [vm => vm.topic]),
|
||||
]),
|
||||
t.p({className: {hidden: vm => vm.clientsViewModel}}, t.button({
|
||||
className: "primary fullwidth",
|
||||
onClick: () => vm.showClients()
|
||||
}, vm => vm.showClientsLabel)),
|
||||
t.mapView(vm => vm.clientsViewModel, childVM => childVM ? new ClientListView(childVM) : null),
|
||||
t.p(["Preview provided by ", vm => vm.previewDomain]),
|
||||
])
|
||||
]);
|
||||
}
|
||||
|
|
|
@ -14,21 +14,18 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import {LinkKind, IdentifierKind, getLabelForLinkKind} from "../Link.js";
|
||||
import {LinkKind, IdentifierKind} from "../Link.js";
|
||||
import {ViewModel} from "../utils/ViewModel.js";
|
||||
import {resolveServer} from "./HomeServer.js";
|
||||
import {ClientListViewModel} from "../client/ClientListViewModel.js";
|
||||
import {ClientViewModel} from "../client/ClientViewModel.js";
|
||||
import {ClientListViewModel} from "../open/ClientListViewModel.js";
|
||||
import {ClientViewModel} from "../open/ClientViewModel.js";
|
||||
|
||||
export class PreviewViewModel extends ViewModel {
|
||||
constructor(options) {
|
||||
super(options);
|
||||
const { link, consentedServers, clients } = options;
|
||||
const { link, consentedServers } = options;
|
||||
this._link = link;
|
||||
this._consentedServers = consentedServers;
|
||||
this._clients = clients;
|
||||
this._preferredClient = this.preferences.clientId ? clients.find(c => c.id === this.preferences.clientId) : null;
|
||||
|
||||
this.loading = false;
|
||||
this.name = null;
|
||||
this.avatarUrl = null;
|
||||
|
@ -36,13 +33,6 @@ export class PreviewViewModel extends ViewModel {
|
|||
this.memberCount = null;
|
||||
this.topic = null;
|
||||
this.previewDomain = null;
|
||||
this.clientsViewModel = null;
|
||||
this.acceptInstructions = null;
|
||||
this.clientsViewModel = this._preferredClient ? new ClientListViewModel(this.childOptions({
|
||||
clients: this._clients,
|
||||
client: this._preferredClient,
|
||||
link: this._link,
|
||||
})) : null;
|
||||
}
|
||||
|
||||
async load() {
|
||||
|
@ -97,15 +87,4 @@ export class PreviewViewModel extends ViewModel {
|
|||
this.topic = publicRoom?.topic;
|
||||
this.identifier = publicRoom?.canonical_alias || link.identifier;
|
||||
}
|
||||
|
||||
get showClientsLabel() {
|
||||
return getLabelForLinkKind(this._link.kind);
|
||||
}
|
||||
|
||||
showClients() {
|
||||
if (!this.clientsViewModel) {
|
||||
this.clientsViewModel = new ClientListViewModel(this.childOptions({clients: this._clients, link: this._link}));
|
||||
this.emitChange();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue