mirror of
https://github.com/vector-im/hydrogen-web.git
synced 2024-12-23 03:25:12 +01:00
UI in settings for toggling features
This commit is contained in:
parent
bb477b6aad
commit
da1b7d4108
70
src/domain/session/settings/FeaturesViewModel.ts
Normal file
70
src/domain/session/settings/FeaturesViewModel.ts
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
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 "../../ViewModel";
|
||||||
|
import type {Options as BaseOptions} from "../../ViewModel";
|
||||||
|
import {FeatureFlag, FeatureSet} from "../../../features";
|
||||||
|
import type {SegmentType} from "../../navigation/index";
|
||||||
|
|
||||||
|
export class FeaturesViewModel extends ViewModel {
|
||||||
|
public readonly featureViewModels: ReadonlyArray<FeatureViewModel>;
|
||||||
|
|
||||||
|
constructor(options) {
|
||||||
|
super(options);
|
||||||
|
this.featureViewModels = [
|
||||||
|
new FeatureViewModel(this.childOptions({
|
||||||
|
name: this.i18n`Audio/video calls (experimental)`,
|
||||||
|
description: this.i18n`Allows starting and participating in A/V calls compatible with Element Call (MSC3401). Look for the start call option in the room menu ((...) in the right corner) to start a call.`,
|
||||||
|
feature: FeatureFlag.Calls
|
||||||
|
})),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type FeatureOptions = BaseOptions & {
|
||||||
|
feature: FeatureFlag,
|
||||||
|
description: string,
|
||||||
|
name: string
|
||||||
|
};
|
||||||
|
|
||||||
|
export class FeatureViewModel extends ViewModel<SegmentType, FeatureOptions> {
|
||||||
|
get enabled(): boolean {
|
||||||
|
return this.features.isFeatureEnabled(this.getOption("feature"));
|
||||||
|
}
|
||||||
|
|
||||||
|
async enableFeature(enabled: boolean): Promise<void> {
|
||||||
|
let newFeatures;
|
||||||
|
if (enabled) {
|
||||||
|
newFeatures = this.features.withFeature(this.getOption("feature"));
|
||||||
|
} else {
|
||||||
|
newFeatures = this.features.withoutFeature(this.getOption("feature"));
|
||||||
|
}
|
||||||
|
await newFeatures.store(this.platform.settingsStorage);
|
||||||
|
this.platform.restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
get id(): string {
|
||||||
|
return `${this.getOption("feature")}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
get name(): string {
|
||||||
|
return this.getOption("name");
|
||||||
|
}
|
||||||
|
|
||||||
|
get description(): string {
|
||||||
|
return this.getOption("description");
|
||||||
|
}
|
||||||
|
}
|
@ -16,6 +16,7 @@ limitations under the License.
|
|||||||
|
|
||||||
import {ViewModel} from "../../ViewModel";
|
import {ViewModel} from "../../ViewModel";
|
||||||
import {KeyBackupViewModel} from "./KeyBackupViewModel.js";
|
import {KeyBackupViewModel} from "./KeyBackupViewModel.js";
|
||||||
|
import {FeaturesViewModel} from "./FeaturesViewModel";
|
||||||
import {submitLogsFromSessionToDefaultServer} from "../../../domain/rageshake";
|
import {submitLogsFromSessionToDefaultServer} from "../../../domain/rageshake";
|
||||||
|
|
||||||
class PushNotificationStatus {
|
class PushNotificationStatus {
|
||||||
@ -53,6 +54,7 @@ export class SettingsViewModel extends ViewModel {
|
|||||||
this.pushNotifications = new PushNotificationStatus();
|
this.pushNotifications = new PushNotificationStatus();
|
||||||
this._activeTheme = undefined;
|
this._activeTheme = undefined;
|
||||||
this._logsFeedbackMessage = undefined;
|
this._logsFeedbackMessage = undefined;
|
||||||
|
this._featuresViewModel = new FeaturesViewModel(this.childOptions());
|
||||||
}
|
}
|
||||||
|
|
||||||
get _session() {
|
get _session() {
|
||||||
@ -125,6 +127,10 @@ export class SettingsViewModel extends ViewModel {
|
|||||||
return this._keyBackupViewModel;
|
return this._keyBackupViewModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get featuresViewModel() {
|
||||||
|
return this._featuresViewModel;
|
||||||
|
}
|
||||||
|
|
||||||
get storageQuota() {
|
get storageQuota() {
|
||||||
return this._formatBytes(this._estimate?.quota);
|
return this._formatBytes(this._estimate?.quota);
|
||||||
}
|
}
|
||||||
|
@ -283,6 +283,10 @@ export class Platform {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
restart() {
|
||||||
|
document.location.reload();
|
||||||
|
}
|
||||||
|
|
||||||
openFile(mimeType = null) {
|
openFile(mimeType = null) {
|
||||||
const input = document.createElement("input");
|
const input = document.createElement("input");
|
||||||
input.setAttribute("type", "file");
|
input.setAttribute("type", "file");
|
||||||
|
@ -751,6 +751,24 @@ a {
|
|||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.FeatureView {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.FeaturesView ul {
|
||||||
|
list-style: none;
|
||||||
|
padding: 8px 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.FeaturesView input[type="checkbox"] {
|
||||||
|
align-self: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.FeatureView h4 {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.error {
|
.error {
|
||||||
color: var(--error-color);
|
color: var(--error-color);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
52
src/platform/web/ui/session/settings/FeaturesView.ts
Normal file
52
src/platform/web/ui/session/settings/FeaturesView.ts
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2023 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, TemplateBuilder} from "../../general/TemplateView";
|
||||||
|
import {ViewNode} from "../../general/types";
|
||||||
|
import {disableTargetCallback} from "../../general/utils";
|
||||||
|
import type {FeaturesViewModel, FeatureViewModel} from "../../../../../domain/session/settings/FeaturesViewModel";
|
||||||
|
|
||||||
|
export class FeaturesView extends TemplateView<FeaturesViewModel> {
|
||||||
|
render(t, vm: FeaturesViewModel): ViewNode {
|
||||||
|
return t.div({
|
||||||
|
className: "FeaturesView",
|
||||||
|
}, [
|
||||||
|
t.p("Enable experimental features here that are still in development. These are not yet ready for primetime, so expect bugs."),
|
||||||
|
// we don't use a binding/ListView because this is a static list
|
||||||
|
t.ul(vm.featureViewModels.map(vm => {
|
||||||
|
return t.li(t.view(new FeatureView(vm)));
|
||||||
|
}))
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FeatureView extends TemplateView<FeatureViewModel> {
|
||||||
|
render(t, vm): ViewNode {
|
||||||
|
let id = `feature_${vm.id}`;
|
||||||
|
return t.div({className: "FeatureView"}, [
|
||||||
|
t.input({
|
||||||
|
type: "checkbox",
|
||||||
|
id,
|
||||||
|
checked: vm => vm.enabled,
|
||||||
|
onChange: evt => vm.enableFeature(evt.target.checked)
|
||||||
|
}),
|
||||||
|
t.div({class: "FeatureView_container"}, [
|
||||||
|
t.h4(t.label({for: id}, vm.name)),
|
||||||
|
t.p(vm.description)
|
||||||
|
])
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||||||
import {TemplateView} from "../../general/TemplateView";
|
import {TemplateView} from "../../general/TemplateView";
|
||||||
import {disableTargetCallback} from "../../general/utils";
|
import {disableTargetCallback} from "../../general/utils";
|
||||||
import {KeyBackupSettingsView} from "./KeyBackupSettingsView.js"
|
import {KeyBackupSettingsView} from "./KeyBackupSettingsView.js"
|
||||||
|
import {FeaturesView} from "./FeaturesView"
|
||||||
|
|
||||||
export class SettingsView extends TemplateView {
|
export class SettingsView extends TemplateView {
|
||||||
render(t, vm) {
|
render(t, vm) {
|
||||||
@ -110,6 +111,12 @@ export class SettingsView extends TemplateView {
|
|||||||
logButtons.push(t.button({onClick: disableTargetCallback(() => vm.sendLogsToServer())}, `Submit logs to ${vm.logsServer}`));
|
logButtons.push(t.button({onClick: disableTargetCallback(() => vm.sendLogsToServer())}, `Submit logs to ${vm.logsServer}`));
|
||||||
}
|
}
|
||||||
logButtons.push(t.button({onClick: () => vm.exportLogs()}, "Download logs"));
|
logButtons.push(t.button({onClick: () => vm.exportLogs()}, "Download logs"));
|
||||||
|
|
||||||
|
settingNodes.push(
|
||||||
|
t.h3("Experimental features"),
|
||||||
|
t.view(new FeaturesView(vm.featuresViewModel))
|
||||||
|
);
|
||||||
|
|
||||||
settingNodes.push(
|
settingNodes.push(
|
||||||
t.h3("Application"),
|
t.h3("Application"),
|
||||||
row(t, vm.i18n`Version`, version),
|
row(t, vm.i18n`Version`, version),
|
||||||
|
Loading…
Reference in New Issue
Block a user