Allow user to set timezone (#12775)
* Allow user to set timezone * Update test snapshots --------- Co-authored-by: Florian Duros <florianduros@element.io>
This commit is contained in:
parent
acc7342758
commit
ae15bbe6e0
15 changed files with 256 additions and 9 deletions
|
@ -47,6 +47,7 @@ import { ViewRoomOpts } from "@matrix-org/react-sdk-module-api/lib/lifecycles/Ro
|
|||
|
||||
import shouldHideEvent from "../../shouldHideEvent";
|
||||
import { _t } from "../../languageHandler";
|
||||
import * as TimezoneHandler from "../../TimezoneHandler";
|
||||
import { RoomPermalinkCreator } from "../../utils/permalinks/Permalinks";
|
||||
import ResizeNotifier from "../../utils/ResizeNotifier";
|
||||
import ContentMessages from "../../ContentMessages";
|
||||
|
@ -228,6 +229,7 @@ export interface IRoomState {
|
|||
lowBandwidth: boolean;
|
||||
alwaysShowTimestamps: boolean;
|
||||
showTwelveHourTimestamps: boolean;
|
||||
userTimezone: string | undefined;
|
||||
readMarkerInViewThresholdMs: number;
|
||||
readMarkerOutOfViewThresholdMs: number;
|
||||
showHiddenEvents: boolean;
|
||||
|
@ -455,6 +457,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
|||
lowBandwidth: SettingsStore.getValue("lowBandwidth"),
|
||||
alwaysShowTimestamps: SettingsStore.getValue("alwaysShowTimestamps"),
|
||||
showTwelveHourTimestamps: SettingsStore.getValue("showTwelveHourTimestamps"),
|
||||
userTimezone: TimezoneHandler.getUserTimezone(),
|
||||
readMarkerInViewThresholdMs: SettingsStore.getValue("readMarkerInViewThresholdMs"),
|
||||
readMarkerOutOfViewThresholdMs: SettingsStore.getValue("readMarkerOutOfViewThresholdMs"),
|
||||
showHiddenEvents: SettingsStore.getValue("showHiddenEventsInTimeline"),
|
||||
|
@ -512,6 +515,9 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
|||
SettingsStore.watchSetting("showTwelveHourTimestamps", null, (...[, , , value]) =>
|
||||
this.setState({ showTwelveHourTimestamps: value as boolean }),
|
||||
),
|
||||
SettingsStore.watchSetting(TimezoneHandler.USER_TIMEZONE_KEY, null, (...[, , , value]) =>
|
||||
this.setState({ userTimezone: value as string }),
|
||||
),
|
||||
SettingsStore.watchSetting("readMarkerInViewThresholdMs", null, (...[, , , value]) =>
|
||||
this.setState({ readMarkerInViewThresholdMs: value as number }),
|
||||
),
|
||||
|
|
|
@ -15,12 +15,14 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import React, { ReactElement, useCallback, useEffect, useState } from "react";
|
||||
|
||||
import { NonEmptyArray } from "../../../../../@types/common";
|
||||
import { _t, getCurrentLanguage } from "../../../../../languageHandler";
|
||||
import { UseCase } from "../../../../../settings/enums/UseCase";
|
||||
import SettingsStore from "../../../../../settings/SettingsStore";
|
||||
import Field from "../../../elements/Field";
|
||||
import Dropdown from "../../../elements/Dropdown";
|
||||
import { SettingLevel } from "../../../../../settings/SettingLevel";
|
||||
import SettingsFlag from "../../../elements/SettingsFlag";
|
||||
import AccessibleButton from "../../../elements/AccessibleButton";
|
||||
|
@ -38,12 +40,16 @@ import PlatformPeg from "../../../../../PlatformPeg";
|
|||
import { IS_MAC } from "../../../../../Keyboard";
|
||||
import SpellCheckSettings from "../../SpellCheckSettings";
|
||||
import LabelledToggleSwitch from "../../../elements/LabelledToggleSwitch";
|
||||
import * as TimezoneHandler from "../../../../../TimezoneHandler";
|
||||
|
||||
interface IProps {
|
||||
closeSettingsFn(success: boolean): void;
|
||||
}
|
||||
|
||||
interface IState {
|
||||
timezone: string | undefined;
|
||||
timezones: string[];
|
||||
timezoneSearch: string | undefined;
|
||||
autocompleteDelay: string;
|
||||
readMarkerInViewThresholdMs: string;
|
||||
readMarkerOutOfViewThresholdMs: string;
|
||||
|
@ -68,7 +74,7 @@ const LanguageSection: React.FC = () => {
|
|||
);
|
||||
|
||||
return (
|
||||
<div className="mx_SettingsSubsection_contentStretch">
|
||||
<div className="mx_SettingsSubsection_dropdown">
|
||||
{_t("settings|general|application_language")}
|
||||
<LanguageDropdown onOptionChange={onLanguageChange} value={language} />
|
||||
<div className="mx_PreferencesUserSettingsTab_section_hint">
|
||||
|
@ -173,6 +179,9 @@ export default class PreferencesUserSettingsTab extends React.Component<IProps,
|
|||
super(props);
|
||||
|
||||
this.state = {
|
||||
timezone: TimezoneHandler.getUserTimezone(),
|
||||
timezones: TimezoneHandler.getAllTimezones(),
|
||||
timezoneSearch: undefined,
|
||||
autocompleteDelay: SettingsStore.getValueAt(SettingLevel.DEVICE, "autocompleteDelay").toString(10),
|
||||
readMarkerInViewThresholdMs: SettingsStore.getValueAt(
|
||||
SettingLevel.DEVICE,
|
||||
|
@ -185,6 +194,25 @@ export default class PreferencesUserSettingsTab extends React.Component<IProps,
|
|||
};
|
||||
}
|
||||
|
||||
private onTimezoneChange = (tz: string): void => {
|
||||
this.setState({ timezone: tz });
|
||||
TimezoneHandler.setUserTimezone(tz);
|
||||
};
|
||||
|
||||
/**
|
||||
* If present filter the time zones matching the search term
|
||||
*/
|
||||
private onTimezoneSearchChange = (search: string): void => {
|
||||
const timezoneSearch = search.toLowerCase();
|
||||
const timezones = timezoneSearch
|
||||
? TimezoneHandler.getAllTimezones().filter((tz) => {
|
||||
return tz.toLowerCase().includes(timezoneSearch);
|
||||
})
|
||||
: TimezoneHandler.getAllTimezones();
|
||||
|
||||
this.setState({ timezones, timezoneSearch });
|
||||
};
|
||||
|
||||
private onAutocompleteDelayChange = (e: React.ChangeEvent<HTMLInputElement>): void => {
|
||||
this.setState({ autocompleteDelay: e.target.value });
|
||||
SettingsStore.setValue("autocompleteDelay", null, SettingLevel.DEVICE, e.target.value);
|
||||
|
@ -217,6 +245,16 @@ export default class PreferencesUserSettingsTab extends React.Component<IProps,
|
|||
// Only show the user onboarding setting if the user should see the user onboarding page
|
||||
.filter((it) => it !== "FTUE.userOnboardingButton" || showUserOnboardingPage(useCase));
|
||||
|
||||
const browserTimezoneLabel: string = _t("settings|preferences|default_timezone", {
|
||||
timezone: TimezoneHandler.shortBrowserTimezone(),
|
||||
});
|
||||
|
||||
// Always Preprend the default option
|
||||
const timezones = this.state.timezones.map((tz) => {
|
||||
return <div key={tz}>{tz}</div>;
|
||||
});
|
||||
timezones.unshift(<div key="">{browserTimezoneLabel}</div>);
|
||||
|
||||
return (
|
||||
<SettingsTab data-testid="mx_PreferencesUserSettingsTab">
|
||||
<SettingsSection>
|
||||
|
@ -254,6 +292,23 @@ export default class PreferencesUserSettingsTab extends React.Component<IProps,
|
|||
</SettingsSubsection>
|
||||
|
||||
<SettingsSubsection heading={_t("settings|preferences|time_heading")}>
|
||||
<div className="mx_SettingsSubsection_dropdown">
|
||||
{_t("settings|preferences|user_timezone")}
|
||||
<Dropdown
|
||||
id="mx_dropdownUserTimezone"
|
||||
className="mx_dropdownUserTimezone"
|
||||
data-testid="mx_dropdownUserTimezone"
|
||||
searchEnabled={true}
|
||||
value={this.state.timezone}
|
||||
label={_t("settings|preferences|user_timezone")}
|
||||
placeholder={browserTimezoneLabel}
|
||||
onOptionChange={this.onTimezoneChange}
|
||||
onSearchChange={this.onTimezoneSearchChange}
|
||||
>
|
||||
{timezones as NonEmptyArray<ReactElement & { key: string }>}
|
||||
</Dropdown>
|
||||
</div>
|
||||
|
||||
{this.renderGroup(PreferencesUserSettingsTab.TIME_SETTINGS)}
|
||||
</SettingsSubsection>
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue