Add a view model for opening a client
This commit is contained in:
parent
820a090a71
commit
a781c527fd
3 changed files with 128 additions and 22 deletions
67
src/open/OpenDefaultViewModel.js
Normal file
67
src/open/OpenDefaultViewModel.js
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
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 {getMatchingPlatforms, selectPlatforms} from "./clients/index.js";
|
||||
|
||||
export class OpenDefaultViewModel extends ViewModel {
|
||||
constructor(options) {
|
||||
super(options);
|
||||
const {client, link, openLinkVM, proposedPlatform, webPlatform} = options;
|
||||
this._client = client;
|
||||
this._link = link;
|
||||
this._openLinkVM = openLinkVM;
|
||||
this._proposedPlatform = proposedPlatform;
|
||||
this._webPlatform = webPlatform;
|
||||
}
|
||||
|
||||
get name() {
|
||||
return this._client?.name;
|
||||
}
|
||||
|
||||
get openingDefault() {
|
||||
return !this._client;
|
||||
}
|
||||
|
||||
get autoRedirect() {
|
||||
// Only auto-redirect when a preferred client hasn't been set.
|
||||
return this.openingDefault;
|
||||
}
|
||||
|
||||
get webDeepLink() {
|
||||
return this._client && this._webPlatform && this._client.getDeepLink(this._webPlatform);
|
||||
}
|
||||
|
||||
close() {
|
||||
this._openLinkVM.closeDefault();
|
||||
}
|
||||
|
||||
tryOpenLink() {
|
||||
this._trying = true;
|
||||
// TODO actually try opening link
|
||||
this.setTimeout(() => {
|
||||
if (this.autoRedirect) {
|
||||
// We're about to be closed so don't
|
||||
// bother with visual updates.
|
||||
this.close();
|
||||
} else {
|
||||
this._trying = false;
|
||||
this.emitChange();
|
||||
}
|
||||
}, 1000);
|
||||
this.emitChange();
|
||||
}
|
||||
}
|
|
@ -22,17 +22,20 @@ import {ServerConsentView} from "./ServerConsentView.js";
|
|||
export class OpenLinkView extends TemplateView {
|
||||
render(t, vm) {
|
||||
return t.div({className: "OpenLinkView card"}, [
|
||||
t.map(vm => vm.tryingLink, tryingLink => tryingLink ?
|
||||
t.view(new TryingLinkView(vm)) :
|
||||
t.mapView(vm => vm.previewViewModel, previewVM => previewVM ?
|
||||
new ShowLinkView(vm) :
|
||||
new ServerConsentView(vm.serverConsentViewModel)
|
||||
),
|
||||
),
|
||||
t.mapView(vm => [ vm.openDefaultViewModel, vm.previewViewModel ], ([openDefaultVM, previewVM]) => {
|
||||
if (openDefaultVM) {
|
||||
return new TryingLinkView(openDefaultVM)
|
||||
} else if (previewVM) {
|
||||
return new ShowLinkView(vm);
|
||||
} else {
|
||||
return new ServerConsentView(vm.serverConsentViewModel);
|
||||
}
|
||||
}),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class TryingLinkView extends TemplateView {
|
||||
render (t, vm) {
|
||||
return t.div({ className: "OpeningClientView" }, [
|
||||
|
|
|
@ -18,9 +18,11 @@ import {ViewModel} from "../utils/ViewModel.js";
|
|||
import {ClientListViewModel} from "./ClientListViewModel.js";
|
||||
import {ClientViewModel} from "./ClientViewModel.js";
|
||||
import {PreviewViewModel} from "../preview/PreviewViewModel.js";
|
||||
import {OpenDefaultViewModel} from "./OpenDefaultViewModel.js";
|
||||
import {ServerConsentViewModel} from "./ServerConsentViewModel.js";
|
||||
import {getLabelForLinkKind} from "../Link.js";
|
||||
import {orderedUnique} from "../utils/unique.js";
|
||||
import {getMatchingPlatforms, selectPlatforms} from "./clients/index.js";
|
||||
|
||||
export class OpenLinkViewModel extends ViewModel {
|
||||
constructor(options) {
|
||||
|
@ -28,12 +30,53 @@ export class OpenLinkViewModel extends ViewModel {
|
|||
const {clients, link} = options;
|
||||
this._link = link;
|
||||
this._clients = clients;
|
||||
this.openDefaultViewModel = null;
|
||||
this.serverConsentViewModel = null;
|
||||
this.previewViewModel = null;
|
||||
this.clientsViewModel = null;
|
||||
this.previewLoading = false;
|
||||
this.tryingLink = false;
|
||||
this._tryLink();
|
||||
if (!this._tryOpenDefault()) {
|
||||
this._activeOpen();
|
||||
}
|
||||
}
|
||||
|
||||
_tryOpenDefault() {
|
||||
const client = this._getPreferredClient();
|
||||
let proposedPlatform = null;
|
||||
let webPlatform = null;
|
||||
if (client) {
|
||||
const matchingPlatforms = getMatchingPlatforms(client, this.platforms);
|
||||
const selectedPlatforms = selectPlatforms(matchingPlatforms, this.preferences.platform);
|
||||
if (selectedPlatforms.proposedPlatform !== selectedPlatforms.nativePlatform) {
|
||||
// Do not auto-open web applications
|
||||
return false;
|
||||
}
|
||||
proposedPlatform = selectedPlatforms.proposedPlatform;
|
||||
webPlatform = selectedPlatforms.webPlatform;
|
||||
|
||||
if (!client.getDeepLink(proposedPlatform, this._link)) {
|
||||
// Client doesn't support deep links. We can't open it.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
this.openDefaultViewModel = new OpenDefaultViewModel(this.childOptions({
|
||||
client,
|
||||
link: this._link,
|
||||
openLinkVM: this,
|
||||
proposedPlatform,
|
||||
webPlatform,
|
||||
}));
|
||||
this.openDefaultViewModel.tryOpenLink();
|
||||
return true;
|
||||
}
|
||||
|
||||
closeDefault() {
|
||||
this.openDefaultViewModel = null;
|
||||
this._activeOpen();
|
||||
}
|
||||
|
||||
_activeOpen() {
|
||||
if (this.preferences.homeservers === null) {
|
||||
this._showServerConsent();
|
||||
} else {
|
||||
|
@ -41,18 +84,6 @@ export class OpenLinkViewModel extends ViewModel {
|
|||
}
|
||||
}
|
||||
|
||||
_tryLink() {
|
||||
const matrixUrl = this._link.toMatrixUrl()
|
||||
if (matrixUrl) {
|
||||
this.tryingLink = true;
|
||||
this.setTimeout(() => {
|
||||
this.tryingLink = false;
|
||||
this.emitChange();
|
||||
}, 1000);
|
||||
this.openLink(matrixUrl);
|
||||
}
|
||||
}
|
||||
|
||||
_showServerConsent() {
|
||||
let servers = [];
|
||||
if (this.preferences.homeservers) {
|
||||
|
@ -67,11 +98,16 @@ export class OpenLinkViewModel extends ViewModel {
|
|||
this._showLink();
|
||||
}
|
||||
}));
|
||||
this.emitChange();
|
||||
}
|
||||
|
||||
_getPreferredClient() {
|
||||
const clientId = this.preferences.clientId || this._link.clientId;
|
||||
return clientId ? this._clients.find(c => c.id === clientId) : null;
|
||||
}
|
||||
|
||||
async _showLink() {
|
||||
const clientId = this.preferences.clientId || this._link.clientId;
|
||||
const preferredClient = clientId ? this._clients.find(c => c.id === clientId) : null;
|
||||
const preferredClient = this._getPreferredClient();
|
||||
this.clientsViewModel = new ClientListViewModel(this.childOptions({
|
||||
clients: this._clients,
|
||||
link: this._link,
|
||||
|
|
Loading…
Reference in a new issue