Fix platform settings race condition and make auto-launch tri-state (#30977)
* Fix race condition with platform settings not being read correctly Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Allow Desktop app to be auto-started minimised or focused Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * i18n Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Iterate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Use onChange prop Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Iterate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Iterate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Add tests Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Update res/css/views/elements/_SettingsDropdown.pcss Co-authored-by: Florian Duros <florianduros@element.io> --------- Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> Co-authored-by: Florian Duros <florianduros@element.io>
This commit is contained in:
committed by
GitHub
parent
3098eba4f2
commit
bc7b50f97c
81
src/components/views/elements/SettingsDropdown.tsx
Normal file
81
src/components/views/elements/SettingsDropdown.tsx
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
Copyright 2025 New Vector Ltd.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import React, { type JSX, useCallback, useId, useState } from "react";
|
||||
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import { type SettingLevel } from "../../../settings/SettingLevel";
|
||||
import { SETTINGS, type StringSettingKey } from "../../../settings/Settings";
|
||||
import { useSettingValueAt } from "../../../hooks/useSettings.ts";
|
||||
import Dropdown, { type DropdownProps } from "./Dropdown.tsx";
|
||||
import { _t } from "../../../shared-components/utils/i18n.tsx";
|
||||
|
||||
interface Props {
|
||||
settingKey: StringSettingKey;
|
||||
level: SettingLevel;
|
||||
roomId?: string; // for per-room settings
|
||||
label?: string;
|
||||
isExplicit?: boolean;
|
||||
hideIfCannotSet?: boolean;
|
||||
onChange?(option: string): void;
|
||||
}
|
||||
|
||||
const SettingsDropdown = ({
|
||||
settingKey,
|
||||
roomId,
|
||||
level,
|
||||
label: specificLabel,
|
||||
isExplicit,
|
||||
hideIfCannotSet,
|
||||
onChange,
|
||||
}: Props): JSX.Element => {
|
||||
const id = useId();
|
||||
const settingValue = useSettingValueAt(level, settingKey, roomId ?? null, isExplicit);
|
||||
const [value, setValue] = useState(settingValue);
|
||||
const setting = SETTINGS[settingKey];
|
||||
|
||||
const onOptionChange = useCallback(
|
||||
(value: string): void => {
|
||||
setValue(value); // local echo
|
||||
SettingsStore.setValue(settingKey, roomId ?? null, level, value);
|
||||
onChange?.(value);
|
||||
},
|
||||
[settingKey, roomId, level, onChange],
|
||||
);
|
||||
|
||||
const disabled = !SettingsStore.canSetValue(settingKey, roomId ?? null, level);
|
||||
if (disabled && hideIfCannotSet) return <></>;
|
||||
if (!setting.options) {
|
||||
console.error("SettingsDropdown used for a setting with no `options`");
|
||||
return <></>;
|
||||
}
|
||||
|
||||
const label = specificLabel ?? SettingsStore.getDisplayName(settingKey, level)!;
|
||||
const options = setting.options.map((option) => {
|
||||
return <div key={option.value}>{_t(option.label)}</div>;
|
||||
}) as DropdownProps["children"];
|
||||
|
||||
return (
|
||||
<div className="mx_SettingsDropdown">
|
||||
<label className="mx_SettingsDropdown_label" htmlFor={id}>
|
||||
<span className="mx_SettingsDropdown_labelText">{label}</span>
|
||||
</label>
|
||||
<Dropdown
|
||||
id={id}
|
||||
onOptionChange={onOptionChange}
|
||||
menuWidth={360} // matches CSS width
|
||||
value={value}
|
||||
disabled={disabled}
|
||||
label={label}
|
||||
>
|
||||
{options}
|
||||
</Dropdown>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SettingsDropdown;
|
||||
@@ -34,6 +34,7 @@ import * as TimezoneHandler from "../../../../../TimezoneHandler";
|
||||
import { type BooleanSettingKey } from "../../../../../settings/Settings.tsx";
|
||||
import { MediaPreviewAccountSettings } from "./MediaPreviewAccountSettings.tsx";
|
||||
import { InviteRulesAccountSetting } from "./InviteRulesAccountSettings.tsx";
|
||||
import SettingsDropdown from "../../../elements/SettingsDropdown.tsx";
|
||||
|
||||
interface IProps {
|
||||
closeSettingsFn(success: boolean): void;
|
||||
@@ -248,11 +249,12 @@ export default class PreferencesUserSettingsTab extends React.Component<IProps,
|
||||
});
|
||||
|
||||
const newRoomListEnabled = SettingsStore.getValue("feature_new_room_list");
|
||||
const brand = SdkConfig.get().brand;
|
||||
|
||||
// Always Preprend the default option
|
||||
const timezones = this.state.timezones.map((tz) => {
|
||||
return <div key={tz}>{tz}</div>;
|
||||
});
|
||||
// Always prepend the default option
|
||||
timezones.unshift(<div key="">{browserTimezoneLabel}</div>);
|
||||
|
||||
return (
|
||||
@@ -264,6 +266,17 @@ export default class PreferencesUserSettingsTab extends React.Component<IProps,
|
||||
<SpellCheckSection />
|
||||
</SettingsSubsection>
|
||||
|
||||
{SettingsStore.canSetValue("Electron.autoLaunch", null, SettingLevel.PLATFORM) && (
|
||||
<SettingsSubsection heading={_t("settings|preferences|startup_window_behaviour_label")}>
|
||||
<SettingsDropdown
|
||||
settingKey="Electron.autoLaunch"
|
||||
label={_t("settings|start_automatically|label", { brand })}
|
||||
level={SettingLevel.PLATFORM}
|
||||
hideIfCannotSet
|
||||
/>
|
||||
</SettingsSubsection>
|
||||
)}
|
||||
|
||||
<SettingsSubsection heading={_t("settings|preferences|room_list_heading")}>
|
||||
{!newRoomListEnabled && this.renderGroup(PreferencesUserSettingsTab.ROOM_LIST_SETTINGS)}
|
||||
{/* The settings is on device level where the other room list settings are on account level */}
|
||||
@@ -356,7 +369,7 @@ export default class PreferencesUserSettingsTab extends React.Component<IProps,
|
||||
level={SettingLevel.PLATFORM}
|
||||
hideIfCannotSet
|
||||
label={_t("settings|preferences|Electron.enableHardwareAcceleration", {
|
||||
appName: SdkConfig.get().brand,
|
||||
appName: brand,
|
||||
})}
|
||||
/>
|
||||
<SettingsFlag
|
||||
@@ -366,7 +379,6 @@ export default class PreferencesUserSettingsTab extends React.Component<IProps,
|
||||
label={_t("settings|preferences|Electron.enableContentProtection")}
|
||||
/>
|
||||
<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
|
||||
|
||||
Reference in New Issue
Block a user