Custom web instances #1

Merged
Domoel merged 5 commits from custom-web-instances into main 2025-03-29 00:19:32 +01:00
3 changed files with 60 additions and 27 deletions
Showing only changes of commit d993157cfa - Show all commits
+12 -12
View File
@@ -25,7 +25,7 @@ export class Preferences extends EventEmitter {
// used to differentiate web from native if a client supports both // used to differentiate web from native if a client supports both
this.platform = null; this.platform = null;
this.homeservers = null; this.homeservers = null;
this.preferredWebInstances = {}; this.customWebInstances = {};
const prefsStr = localStorage.getItem("preferred_client"); const prefsStr = localStorage.getItem("preferred_client");
if (prefsStr) { if (prefsStr) {
@@ -37,9 +37,9 @@ export class Preferences extends EventEmitter {
if (serversStr) { if (serversStr) {
this.homeservers = JSON.parse(serversStr); this.homeservers = JSON.parse(serversStr);
} }
const preferredWebInstancesStr = localStorage.getItem("preferred_web_instances"); const customWebInstancesStr = localStorage.getItem("custom_web_instances");
if (preferredWebInstancesStr) { if (customWebInstancesStr) {
this.preferredWebInstances = JSON.parse(preferredWebInstancesStr); this.customWebInstances = JSON.parse(customWebInstancesStr);
} }
} }
@@ -59,27 +59,27 @@ export class Preferences extends EventEmitter {
} }
} }
setPreferredWebInstance(client_id, instance_url) { setCustomWebInstance(client_id, instance_url) {
this.preferredWebInstances[client_id] = instance_url; this.customWebInstances[client_id] = instance_url;
this._localStorage.setItem("preferred_web_instances", JSON.stringify(this.preferredWebInstances)); this._localStorage.setItem("custom_web_instances", JSON.stringify(this.customWebInstances));
this.emit("canClear"); this.emit("canClear");
} }
getPreferredWebInstance(client_id) { getCustomWebInstance(client_id) {
return this.preferredWebInstances[client_id]; return this.customWebInstances[client_id];
} }
clear() { clear() {
this._localStorage.removeItem("preferred_client"); this._localStorage.removeItem("preferred_client");
this._localStorage.removeItem("consented_servers"); this._localStorage.removeItem("consented_servers");
this._localStorage.removeItem("preferred_web_instances"); this._localStorage.removeItem("custom_web_instances");
this.clientId = null; this.clientId = null;
this.platform = null; this.platform = null;
this.homeservers = null; this.homeservers = null;
this.preferredWebInstances = {}; this.customWebInstances = {};
} }
get canClear() { get canClear() {
return !!this.clientId || !!this.platform || !!this.homeservers; return !!this.clientId || !!this.platform || !!this.homeservers || !!this.customWebInstances;
} }
} }
+28 -12
View File
@@ -39,6 +39,14 @@ function renderInstructions(parts) {
export class ClientView extends TemplateView { export class ClientView extends TemplateView {
render(t, vm) { 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}}, [ return t.div({className: {"ClientView": true, "isPreferred": vm => vm.hasPreferredWebInstance}}, [
... vm.hasPreferredWebInstance ? [t.div({className: "hostedBanner"}, vm.hostedByBannerLabel)] : [], ... vm.hasPreferredWebInstance ? [t.div({className: "hostedBanner"}, vm.hostedByBannerLabel)] : [],
t.div({className: "header"}, [ 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:", "Use a custom web instance for the ", t.strong(vm.name), " client:",
]), ]),
t.form({action: "#", id: "setCustomWebInstanceForm", onSubmit: evt => this._onSubmit(evt)}, [ t.form({action: "#", id: "setCustomWebInstanceForm", onSubmit: evt => this._onSubmit(evt)}, [
t.label([ t.input({
"Host name:", type: "text",
t.input({ className: "fullwidth large",
type: "text", placeholder: "chat.example.org",
className: "line", name: "instanceHostname",
placeholder: "chat.example.org", value: vm.preferredWebInstance || "",
name: "instanceHostname", }),
}) 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) { _onSubmit(evt) {
evt.preventDefault(); 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}}, [ return t.p({className: {caption: true, "back": true, hidden: vm => !vm.showBack}}, [
`Continue with ${vm.name} · `, `Continue with ${vm.name} · `,
t.button({className: "text", onClick: () => vm.back()}, "Change"), 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"),
]) ])
]); ]);
+20 -3
View File
@@ -35,6 +35,7 @@ export class ClientViewModel extends ViewModel {
this._pickClient = pickClient; this._pickClient = pickClient;
// to provide "choose other client" button after calling pick() // to provide "choose other client" button after calling pick()
this._clientListViewModel = null; this._clientListViewModel = null;
this.customWebInstanceFormOpen = false;
this._update(); 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) // also check there is a web platform that matches the platforms the user is on (mobile or desktop web)
if (!this._webPlatform) return undefined; if (!this._webPlatform) return undefined;
return ( return (
this.preferences.getPreferredWebInstance(this._client.id) this.preferences.getCustomWebInstance(this._client.id)
|| this._client.getPreferredWebInstance(this._link) || this._client.getPreferredWebInstance(this._link)
); );
} }
@@ -231,7 +232,7 @@ export class ClientViewModel extends ViewModel {
return !!this._clientListViewModel; return !!this._clientListViewModel;
} }
get showSetWebInstance() { get supportsCustomWebInstances() {
return !!this._client.supportsCustomInstances; 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 // 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. // all clients rather than having our "change client" click reverted.
this.preferences.setClient(undefined, undefined); this.preferences.setClient(undefined, undefined);
this.preferences.setPreferredWebInstance(this._client.id, undefined); this.preferences.setCustomWebInstance(this._client.id, undefined);
this._update(); this._update();
this.emitChange(); this.emitChange();
vm.showAll(); 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();
}
} }