Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Abstract electron settings properly to avoid boilerplate-hell #8798

Merged
merged 7 commits into from
Jun 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 15 additions & 62 deletions src/BasePlatform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,17 @@ export enum UpdateCheckStatus {
Ready = "READY",
}

export interface UpdateStatus {
/**
* The current phase of the manual update check.
*/
status: UpdateCheckStatus;
/**
* Detail string relating to the current status, typically for error details.
*/
detail?: string;
}

const UPDATE_DEFER_KEY = "mx_defer_update";

/**
Expand Down Expand Up @@ -225,79 +236,21 @@ export default abstract class BasePlatform {
*/
public abstract getAppVersion(): Promise<string>;

/*
* If it's not expected that capturing the screen will work
* with getUserMedia, return a string explaining why not.
* Otherwise, return null.
*/
public screenCaptureErrorString(): string {
return "Not implemented";
}

/**
* Restarts the application, without necessarily reloading
* any application code
*/
public abstract reload(): void;

public supportsAutoLaunch(): boolean {
return false;
}

// XXX: Surely this should be a setting like any other?
public async getAutoLaunchEnabled(): Promise<boolean> {
return false;
}

public async setAutoLaunchEnabled(enabled: boolean): Promise<void> {
throw new Error("Unimplemented");
}

public supportsWarnBeforeExit(): boolean {
return false;
}

public async shouldWarnBeforeExit(): Promise<boolean> {
return false;
}

public async setWarnBeforeExit(enabled: boolean): Promise<void> {
throw new Error("Unimplemented");
}

public supportsAutoHideMenuBar(): boolean {
return false;
}

public async getAutoHideMenuBarEnabled(): Promise<boolean> {
return false;
}

public async setAutoHideMenuBarEnabled(enabled: boolean): Promise<void> {
throw new Error("Unimplemented");
}

public supportsMinimizeToTray(): boolean {
return false;
}

public async getMinimizeToTrayEnabled(): Promise<boolean> {
return false;
}

public async setMinimizeToTrayEnabled(enabled: boolean): Promise<void> {
throw new Error("Unimplemented");
}

public supportsTogglingHardwareAcceleration(): boolean {
public supportsSetting(settingName?: string): boolean {
return false;
}

public async getHardwareAccelerationEnabled(): Promise<boolean> {
return true;
public getSettingValue(settingName: string): Promise<any> {
return undefined;
}

public async setHardwareAccelerationEnabled(enabled: boolean): Promise<void> {
public setSettingValue(settingName: string, value: any): Promise<void> {
throw new Error("Unimplemented");
}

Expand Down
3 changes: 3 additions & 0 deletions src/components/views/elements/SettingsFlag.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ interface IProps {
// XXX: once design replaces all toggles make this the default
useCheckbox?: boolean;
disabled?: boolean;
hideIfCannotSet?: boolean;
onChange?(checked: boolean): void;
}

Expand Down Expand Up @@ -76,6 +77,8 @@ export default class SettingsFlag extends React.Component<IProps, IState> {
public render() {
const canChange = SettingsStore.canSetValue(this.props.name, this.props.roomId, this.props.level);

if (!canChange && this.props.hideIfCannotSet) return null;

const label = this.props.label
? _t(this.props.label)
: SettingsStore.getDisplayName(this.props.name, this.props.level);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,8 @@ limitations under the License.
import React from 'react';

import { _t } from "../../../../../languageHandler";
import LabelledToggleSwitch from "../../../elements/LabelledToggleSwitch";
import SettingsStore from "../../../../../settings/SettingsStore";
import Field from "../../../elements/Field";
import PlatformPeg from "../../../../../PlatformPeg";
import { SettingLevel } from "../../../../../settings/SettingLevel";
import SettingsFlag from '../../../elements/SettingsFlag';
import AccessibleButton from "../../../elements/AccessibleButton";
Expand All @@ -36,16 +34,6 @@ interface IProps {
}

interface IState {
autoLaunch: boolean;
autoLaunchSupported: boolean;
warnBeforeExit: boolean;
warnBeforeExitSupported: boolean;
alwaysShowMenuBarSupported: boolean;
alwaysShowMenuBar: boolean;
minimizeToTraySupported: boolean;
minimizeToTray: boolean;
togglingHardwareAccelerationSupported: boolean;
enableHardwareAcceleration: boolean;
autocompleteDelay: string;
readMarkerInViewThresholdMs: string;
readMarkerOutOfViewThresholdMs: string;
Expand Down Expand Up @@ -112,16 +100,6 @@ export default class PreferencesUserSettingsTab extends React.Component<IProps,
super(props);

this.state = {
autoLaunch: false,
autoLaunchSupported: false,
warnBeforeExit: true,
warnBeforeExitSupported: false,
alwaysShowMenuBar: true,
alwaysShowMenuBarSupported: false,
minimizeToTray: true,
minimizeToTraySupported: false,
enableHardwareAcceleration: true,
togglingHardwareAccelerationSupported: false,
autocompleteDelay:
SettingsStore.getValueAt(SettingLevel.DEVICE, 'autocompleteDelay').toString(10),
readMarkerInViewThresholdMs:
Expand All @@ -131,74 +109,6 @@ export default class PreferencesUserSettingsTab extends React.Component<IProps,
};
}

async componentDidMount() {
const platform = PlatformPeg.get();

const autoLaunchSupported = await platform.supportsAutoLaunch();
let autoLaunch = false;
if (autoLaunchSupported) {
autoLaunch = await platform.getAutoLaunchEnabled();
}

const warnBeforeExitSupported = await platform.supportsWarnBeforeExit();
let warnBeforeExit = false;
if (warnBeforeExitSupported) {
warnBeforeExit = await platform.shouldWarnBeforeExit();
}

const alwaysShowMenuBarSupported = await platform.supportsAutoHideMenuBar();
let alwaysShowMenuBar = true;
if (alwaysShowMenuBarSupported) {
alwaysShowMenuBar = !(await platform.getAutoHideMenuBarEnabled());
}

const minimizeToTraySupported = await platform.supportsMinimizeToTray();
let minimizeToTray = true;
if (minimizeToTraySupported) {
minimizeToTray = await platform.getMinimizeToTrayEnabled();
}

const togglingHardwareAccelerationSupported = platform.supportsTogglingHardwareAcceleration();
let enableHardwareAcceleration = true;
if (togglingHardwareAccelerationSupported) {
enableHardwareAcceleration = await platform.getHardwareAccelerationEnabled();
}

this.setState({
autoLaunch,
autoLaunchSupported,
warnBeforeExit,
warnBeforeExitSupported,
alwaysShowMenuBarSupported,
alwaysShowMenuBar,
minimizeToTraySupported,
minimizeToTray,
togglingHardwareAccelerationSupported,
enableHardwareAcceleration,
});
}

private onAutoLaunchChange = (checked: boolean) => {
PlatformPeg.get().setAutoLaunchEnabled(checked).then(() => this.setState({ autoLaunch: checked }));
};

private onWarnBeforeExitChange = (checked: boolean) => {
PlatformPeg.get().setWarnBeforeExit(checked).then(() => this.setState({ warnBeforeExit: checked }));
};

private onAlwaysShowMenuBarChange = (checked: boolean) => {
PlatformPeg.get().setAutoHideMenuBarEnabled(!checked).then(() => this.setState({ alwaysShowMenuBar: checked }));
};

private onMinimizeToTrayChange = (checked: boolean) => {
PlatformPeg.get().setMinimizeToTrayEnabled(checked).then(() => this.setState({ minimizeToTray: checked }));
};

private onHardwareAccelerationChange = (checked: boolean) => {
PlatformPeg.get().setHardwareAccelerationEnabled(checked).then(
() => this.setState({ enableHardwareAcceleration: checked }));
};

private onAutocompleteDelayChange = (e: React.ChangeEvent<HTMLInputElement>) => {
this.setState({ autocompleteDelay: e.target.value });
SettingsStore.setValue("autocompleteDelay", null, SettingLevel.DEVICE, e.target.value);
Expand Down Expand Up @@ -232,49 +142,6 @@ export default class PreferencesUserSettingsTab extends React.Component<IProps,
};

render() {
let autoLaunchOption = null;
if (this.state.autoLaunchSupported) {
autoLaunchOption = <LabelledToggleSwitch
value={this.state.autoLaunch}
onChange={this.onAutoLaunchChange}
label={_t('Start automatically after system login')} />;
}

let warnBeforeExitOption = null;
if (this.state.warnBeforeExitSupported) {
warnBeforeExitOption = <LabelledToggleSwitch
value={this.state.warnBeforeExit}
onChange={this.onWarnBeforeExitChange}
label={_t('Warn before quitting')} />;
}

let autoHideMenuOption = null;
if (this.state.alwaysShowMenuBarSupported) {
autoHideMenuOption = <LabelledToggleSwitch
value={this.state.alwaysShowMenuBar}
onChange={this.onAlwaysShowMenuBarChange}
label={_t('Always show the window menu bar')} />;
}

let minimizeToTrayOption = null;
if (this.state.minimizeToTraySupported) {
minimizeToTrayOption = <LabelledToggleSwitch
value={this.state.minimizeToTray}
onChange={this.onMinimizeToTrayChange}
label={_t('Show tray icon and minimise window to it on close')} />;
}

let hardwareAccelerationOption = null;
if (this.state.togglingHardwareAccelerationSupported) {
const appName = SdkConfig.get().brand;
hardwareAccelerationOption = <LabelledToggleSwitch
value={this.state.enableHardwareAcceleration}
onChange={this.onHardwareAccelerationChange}
label={_t('Enable hardware acceleration (restart %(appName)s to take effect)', {
appName,
})} />;
}

return (
<div className="mx_SettingsTab mx_PreferencesUserSettingsTab">
<div className="mx_SettingsTab_heading">{ _t("Preferences") }</div>
Expand Down Expand Up @@ -331,11 +198,20 @@ export default class PreferencesUserSettingsTab extends React.Component<IProps,
<div className="mx_SettingsTab_section">
<span className="mx_SettingsTab_subheading">{ _t("General") }</span>
{ this.renderGroup(PreferencesUserSettingsTab.GENERAL_SETTINGS) }
{ minimizeToTrayOption }
{ hardwareAccelerationOption }
{ autoHideMenuOption }
{ autoLaunchOption }
{ warnBeforeExitOption }

<SettingsFlag name="Electron.showTrayIcon" level={SettingLevel.PLATFORM} hideIfCannotSet />
<SettingsFlag
name="Electron.enableHardwareAcceleration"
level={SettingLevel.PLATFORM}
hideIfCannotSet
label={_t('Enable hardware acceleration (restart %(appName)s to take effect)', {
appName: SdkConfig.get().brand,
})}
/>
<SettingsFlag name="Electron.alwaysShowMenuBar" level={SettingLevel.PLATFORM} hideIfCannotSet />
<SettingsFlag name="Electron.autoLaunch" level={SettingLevel.PLATFORM} hideIfCannotSet />
<SettingsFlag name="Electron.warnBeforeExit" level={SettingLevel.PLATFORM} hideIfCannotSet />

<Field
label={_t('Autocomplete delay (ms)')}
type='number'
Expand Down
14 changes: 2 additions & 12 deletions src/dispatcher/payloads/CheckUpdatesPayload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,8 @@ limitations under the License.

import { ActionPayload } from "../payloads";
import { Action } from "../actions";
import { UpdateCheckStatus } from "../../BasePlatform";
import { UpdateStatus } from "../../BasePlatform";

export interface CheckUpdatesPayload extends ActionPayload {
export interface CheckUpdatesPayload extends ActionPayload, UpdateStatus {
action: Action.CheckUpdates;

/**
* The current phase of the manual update check.
*/
status: UpdateCheckStatus;

/**
* Detail string relating to the current status, typically for error details.
*/
detail?: string;
}
11 changes: 6 additions & 5 deletions src/i18n/strings/en_EN.json
Original file line number Diff line number Diff line change
Expand Up @@ -971,6 +971,11 @@
"Automatically send debug logs on any error": "Automatically send debug logs on any error",
"Automatically send debug logs on decryption errors": "Automatically send debug logs on decryption errors",
"Automatically send debug logs when key backup is not functioning": "Automatically send debug logs when key backup is not functioning",
"Start automatically after system login": "Start automatically after system login",
"Warn before quitting": "Warn before quitting",
"Always show the window menu bar": "Always show the window menu bar",
"Show tray icon and minimise window to it on close": "Show tray icon and minimise window to it on close",
"Enable hardware acceleration": "Enable hardware acceleration",
"Partial Support for Threads": "Partial Support for Threads",
"Your homeserver does not currently support threads, so this feature may be unreliable. Some threaded messages may not be reliably available. <a>Learn more</a>.": "Your homeserver does not currently support threads, so this feature may be unreliable. Some threaded messages may not be reliably available. <a>Learn more</a>.",
"Do you want to enable threads anyway?": "Do you want to enable threads anyway?",
Expand Down Expand Up @@ -1499,11 +1504,6 @@
"If this isn't what you want, please use a different tool to ignore users.": "If this isn't what you want, please use a different tool to ignore users.",
"Room ID or address of ban list": "Room ID or address of ban list",
"Subscribe": "Subscribe",
"Start automatically after system login": "Start automatically after system login",
"Warn before quitting": "Warn before quitting",
"Always show the window menu bar": "Always show the window menu bar",
"Show tray icon and minimise window to it on close": "Show tray icon and minimise window to it on close",
"Enable hardware acceleration (restart %(appName)s to take effect)": "Enable hardware acceleration (restart %(appName)s to take effect)",
"Preferences": "Preferences",
"Room list": "Room list",
"Keyboard shortcuts": "Keyboard shortcuts",
Expand All @@ -1513,6 +1513,7 @@
"Code blocks": "Code blocks",
"Images, GIFs and videos": "Images, GIFs and videos",
"Timeline": "Timeline",
"Enable hardware acceleration (restart %(appName)s to take effect)": "Enable hardware acceleration (restart %(appName)s to take effect)",
"Autocomplete delay (ms)": "Autocomplete delay (ms)",
"Read Marker lifetime (ms)": "Read Marker lifetime (ms)",
"Read Marker off-screen lifetime (ms)": "Read Marker off-screen lifetime (ms)",
Expand Down
1 change: 1 addition & 0 deletions src/settings/SettingLevel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export enum SettingLevel {
ROOM_ACCOUNT = "room-account",
ACCOUNT = "account",
ROOM = "room",
PLATFORM = "platform",
CONFIG = "config",
DEFAULT = "default",
}
Loading