From d993157cfae9dced77e8f5ac772b5b14bc46a6aa Mon Sep 17 00:00:00 2001 From: Mira Nord Date: Sun, 16 Mar 2025 21:20:06 +0100 Subject: [PATCH] Add form to configure custom web instance --- src/Preferences.js | 24 +++++++++++----------- src/open/ClientView.js | 40 ++++++++++++++++++++++++++----------- src/open/ClientViewModel.js | 23 ++++++++++++++++++--- 3 files changed, 60 insertions(+), 27 deletions(-) diff --git a/src/Preferences.js b/src/Preferences.js index cdd1446..d365230 100644 --- a/src/Preferences.js +++ b/src/Preferences.js @@ -25,7 +25,7 @@ export class Preferences extends EventEmitter { // used to differentiate web from native if a client supports both this.platform = null; this.homeservers = null; - this.preferredWebInstances = {}; + this.customWebInstances = {}; const prefsStr = localStorage.getItem("preferred_client"); if (prefsStr) { @@ -37,9 +37,9 @@ export class Preferences extends EventEmitter { if (serversStr) { this.homeservers = JSON.parse(serversStr); } - const preferredWebInstancesStr = localStorage.getItem("preferred_web_instances"); - if (preferredWebInstancesStr) { - this.preferredWebInstances = JSON.parse(preferredWebInstancesStr); + const customWebInstancesStr = localStorage.getItem("custom_web_instances"); + if (customWebInstancesStr) { + this.customWebInstances = JSON.parse(customWebInstancesStr); } } @@ -59,27 +59,27 @@ export class Preferences extends EventEmitter { } } - setPreferredWebInstance(client_id, instance_url) { - this.preferredWebInstances[client_id] = instance_url; - this._localStorage.setItem("preferred_web_instances", JSON.stringify(this.preferredWebInstances)); + setCustomWebInstance(client_id, instance_url) { + this.customWebInstances[client_id] = instance_url; + this._localStorage.setItem("custom_web_instances", JSON.stringify(this.customWebInstances)); this.emit("canClear"); } - getPreferredWebInstance(client_id) { - return this.preferredWebInstances[client_id]; + getCustomWebInstance(client_id) { + return this.customWebInstances[client_id]; } clear() { this._localStorage.removeItem("preferred_client"); this._localStorage.removeItem("consented_servers"); - this._localStorage.removeItem("preferred_web_instances"); + this._localStorage.removeItem("custom_web_instances"); this.clientId = null; this.platform = null; this.homeservers = null; - this.preferredWebInstances = {}; + this.customWebInstances = {}; } get canClear() { - return !!this.clientId || !!this.platform || !!this.homeservers; + return !!this.clientId || !!this.platform || !!this.homeservers || !!this.customWebInstances; } } diff --git a/src/open/ClientView.js b/src/open/ClientView.js index b42eb16..37c2b9e 100644 --- a/src/open/ClientView.js +++ b/src/open/ClientView.js @@ -39,6 +39,14 @@ function renderInstructions(parts) { export class ClientView extends TemplateView { render(t, vm) { + return t.mapView(vm => vm.customWebInstanceFormOpen, open => { + switch (open) { + case true: return new SetCustomWebInstanceView(vm); + case false: return new TemplateView(vm, t => this.renderContent(t, vm)); + } + }); + } + renderContent(t, vm) { return t.div({className: {"ClientView": true, "isPreferred": vm => vm.hasPreferredWebInstance}}, [ ... vm.hasPreferredWebInstance ? [t.div({className: "hostedBanner"}, vm.hostedByBannerLabel)] : [], t.div({className: "header"}, [ @@ -119,22 +127,30 @@ export class SetCustomWebInstanceView extends TemplateView { "Use a custom web instance for the ", t.strong(vm.name), " client:", ]), t.form({action: "#", id: "setCustomWebInstanceForm", onSubmit: evt => this._onSubmit(evt)}, [ - t.label([ - "Host name:", - t.input({ - type: "text", - className: "line", - placeholder: "chat.example.org", - name: "instanceHostname", - }) - ]) + t.input({ + type: "text", + className: "fullwidth large", + placeholder: "chat.example.org", + name: "instanceHostname", + value: vm.preferredWebInstance || "", + }), + t.input({type: "submit", value: "Save", className: "primary fullwidth"}), + t.input({type: "button", value: "Use Default Instance", className: "secondary fullwidth", onClick: evt => this._onReset(evt)}), ]) ]); } _onSubmit(evt) { evt.preventDefault(); - this.value.continueWithSelection(this._askEveryTimeChecked); + const form = evt.target; + const {instanceHostname} = form.elements; + this.value.setCustomWebInstance(instanceHostname.value || undefined); + this.value.closeCustomWebInstanceForm(); + } + + _onReset(evt) { + this.value.setCustomWebInstance(undefined); + this.value.closeCustomWebInstanceForm(); } } @@ -142,9 +158,9 @@ function showBack(t, vm) { return t.p({className: {caption: true, "back": true, hidden: vm => !vm.showBack}}, [ `Continue with ${vm.name} · `, t.button({className: "text", onClick: () => vm.back()}, "Change"), - t.span({hidden: vm => !vm.showSetWebInstance}, [ + t.span({hidden: vm => !vm.supportsCustomWebInstances}, [ ' · ', - t.button({className: "text", onClick: () => vm.setCustomWebInstance()}, "Use Custom Web Instance"), + t.button({className: "text", onClick: () => vm.configureCustomWebInstance()}, "Use Custom Web Instance"), ]) ]); diff --git a/src/open/ClientViewModel.js b/src/open/ClientViewModel.js index 380512f..b2e5f87 100644 --- a/src/open/ClientViewModel.js +++ b/src/open/ClientViewModel.js @@ -35,6 +35,7 @@ export class ClientViewModel extends ViewModel { this._pickClient = pickClient; // to provide "choose other client" button after calling pick() this._clientListViewModel = null; + this.customWebInstanceFormOpen = false; this._update(); } @@ -132,7 +133,7 @@ export class ClientViewModel extends ViewModel { // also check there is a web platform that matches the platforms the user is on (mobile or desktop web) if (!this._webPlatform) return undefined; return ( - this.preferences.getPreferredWebInstance(this._client.id) + this.preferences.getCustomWebInstance(this._client.id) || this._client.getPreferredWebInstance(this._link) ); } @@ -231,7 +232,7 @@ export class ClientViewModel extends ViewModel { return !!this._clientListViewModel; } - get showSetWebInstance() { + get supportsCustomWebInstances() { return !!this._client.supportsCustomInstances; } @@ -243,10 +244,26 @@ export class ClientViewModel extends ViewModel { // in the list with all clients, and also if we refresh, we get the list with // all clients rather than having our "change client" click reverted. this.preferences.setClient(undefined, undefined); - this.preferences.setPreferredWebInstance(this._client.id, undefined); + this.preferences.setCustomWebInstance(this._client.id, undefined); this._update(); this.emitChange(); vm.showAll(); } } + + configureCustomWebInstance() { + this.customWebInstanceFormOpen = true; + this.emitChange(); + } + + closeCustomWebInstanceForm() { + this.customWebInstanceFormOpen = false; + this.emitChange(); + } + + setCustomWebInstance(hostname) { + this.preferences.setClient(this._client.id, hostname ? this._webPlatform : (this._nativePlatform || this._webPlatform)); + this.preferences.setCustomWebInstance(this._client.id, hostname); + this._update(); + } }