Skip to content

Commit

Permalink
Merge branch 'adding_timezone' into 'master'
Browse files Browse the repository at this point in the history
add timezone parameter

See merge request kchat/webapp!851
  • Loading branch information
antonbuks committed Sep 16, 2024
2 parents 5f51061 + 3fa5d6b commit 597cbb4
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {autoUpdateTimezone} from 'mattermost-redux/actions/timezone';
import {updateMe} from 'mattermost-redux/actions/users';
import {getConfig, getLicense} from 'mattermost-redux/selectors/entities/general';
import {get, isCollapsedThreadsAllowed, getCollapsedThreadsPreference} from 'mattermost-redux/selectors/entities/preferences';
import {getCurrentTimezone, getCurrentTimezoneLabel} from 'mattermost-redux/selectors/entities/timezone';
import {getCurrentTimezone, getCurrentTimezoneFull, getCurrentTimezoneLabel} from 'mattermost-redux/selectors/entities/timezone';
import {getCurrentUserId, getUser} from 'mattermost-redux/selectors/entities/users';
import {getUserCurrentTimezone} from 'mattermost-redux/utils/timezone_utils';

Expand All @@ -28,6 +28,7 @@ export function makeMapStateToProps() {
const config = getConfig(state);
const currentUserId = getCurrentUserId(state);
const userTimezone = getCurrentTimezone(state);
const timezone = getCurrentTimezoneFull(state);
const timezoneLabel = getCurrentTimezoneLabel(state);
const allowCustomThemes = config.AllowCustomThemes === 'true';
const enableLinkPreviews = config.EnableLinkPreviews === 'true';
Expand All @@ -50,6 +51,7 @@ export function makeMapStateToProps() {
timezones,
timezoneLabel,
userTimezone,
timezone,
currentUserTimezone: getCurrentTimezone(state),
availabilityStatusOnPosts: get(state, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.AVAILABILITY_STATUS_ON_POSTS, Preferences.AVAILABILITY_STATUS_ON_POSTS_DEFAULT),
teammateNameDisplay: get(state, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.NAME_NAME_FORMAT, configTeammateNameDisplay),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@
// See LICENSE.txt for license information.

import type {PrimitiveType, FormatXMLElementFn} from 'intl-messageformat';
import isEqual from 'lodash/isEqual';
import type {ComponentProps} from 'react';
import React from 'react';
import {FormattedMessage} from 'react-intl';
import ReactSelect from 'react-select';
import type {Timezone} from 'timezones.json';

import type {PreferenceType} from '@mattermost/types/preferences';
import type {UserProfile, UserTimezone} from '@mattermost/types/users';
Expand All @@ -17,6 +20,7 @@ import RhsLimitVisibleGMsDMs from 'components/rhs_settings/rhs_settings_display/
import RhsSettingsItem from 'components/rhs_settings/rhs_settings_item/rhs_settings_item';
import RhsThemeSetting from 'components/rhs_settings/rhs_settings_theme';
import Toggle from 'components/toggle';
import ManageTimezones from 'components/user_settings/display/manage_timezones';

import Constants from 'utils/constants';
import {t} from 'utils/i18n';
Expand Down Expand Up @@ -110,6 +114,8 @@ type Props = {
setRequireConfirm?: () => void;
setEnforceFocus?: () => void;
userTimezone: UserTimezone;
timezones: Timezone[];
timezone: UserTimezone;
allowCustomThemes: boolean;
enableLinkPreviews: boolean;
defaultClientLocale: string;
Expand Down Expand Up @@ -158,6 +164,7 @@ type State = {
serverError?: string;
militaryTime: string;
lastActiveDisplay: string;
timezone: UserTimezone;
}

export default class RhsSettingsDisplay extends React.PureComponent<Props, State> {
Expand All @@ -175,6 +182,7 @@ export default class RhsSettingsDisplay extends React.PureComponent<Props, State
oneClickReactionsOnPosts: props.oneClickReactionsOnPosts ? props.oneClickReactionsOnPosts : 'true',
showUnreadsCategory: props.showUnreadsCategory ? props.showUnreadsCategory : 'true',
unreadScrollPosition: props.unreadScrollPosition ? props.unreadScrollPosition : Preferences.UNREAD_SCROLL_POSITION,
timezone: props.timezone,
};
}

Expand Down Expand Up @@ -204,6 +212,7 @@ export default class RhsSettingsDisplay extends React.PureComponent<Props, State
showUnreadsCategory: props.showUnreadsCategory ? props.showUnreadsCategory : 'true',
unreadScrollPosition: props.unreadScrollPosition ? props.unreadScrollPosition : Preferences.UNREAD_SCROLL_POSITION,
isSaving: false,
timezone: props.timezone,
};

this.prevSections = {
Expand Down Expand Up @@ -236,9 +245,11 @@ export default class RhsSettingsDisplay extends React.PureComponent<Props, State
const userId = user.id;

// User preferences patch user and don't need to update preferences
if (newSettingsState.lastActiveDisplay !== this.props.lastActiveDisplay) {
if (newSettingsState.lastActiveDisplay !== this.props.lastActiveDisplay ||
!isEqual(newSettingsState.timezone, this.props.timezone)) {
const updatedUser = {
...user,
timezone: newSettingsState.timezone,
props: {
...user.props,
show_last_active: newSettingsState.lastActiveDisplay,
Expand Down Expand Up @@ -336,7 +347,6 @@ export default class RhsSettingsDisplay extends React.PureComponent<Props, State
name: Preferences.USE_MILITARY_TIME,
value: newSettingsState.militaryTime,
};

this.setState({isSaving: true});

const preferences = [
Expand All @@ -363,6 +373,16 @@ export default class RhsSettingsDisplay extends React.PureComponent<Props, State
handleOnChange(display: {[key: string]: any}) {
this.handleSubmit({...this.state, ...display});
}
handleOnTimezoneChange: ComponentProps<typeof ManageTimezones>['onChange'] = (timezone, xd) => {
console.log(timezone);
console.log(xd);
this.handleOnChange({timezone: {
useAutomaticTimezone: timezone.useAutomaticTimezone.toString(),

// manualTimezone: timezone.useAutomaticTimezone ? timezone.automaticTimezone : timezone.manualTimezone,
// automaticTimezone: timezone.useAutomaticTimezone ? timezone.automaticTimezone : timezone.manualTimezone,
}});
};

updateSection = (section: string) => {
this.props.updateSection(section);
Expand Down Expand Up @@ -873,6 +893,27 @@ export default class RhsSettingsDisplay extends React.PureComponent<Props, State
});
}

let timezoneSelection;
if (this.props.enableTimezone && !this.props.shouldAutoUpdateTimezone) {
timezoneSelection = (
<>
<label htmlFor='user.settings.display.timezone'>
<FormattedMessage
id='user.settings.display.timezone2'
defaultMessage='Automatic timezone'
/>
</label>
<ManageTimezones
user={this.props.user}
updateSection={this.updateSection}
onChange={this.handleOnTimezoneChange}
compact={true}
{...this.props.timezone}
/>
</>
);
}

return (
<div id='displaySettings'>
<div className='user-settings user-rhs-container container'>
Expand All @@ -886,6 +927,7 @@ export default class RhsSettingsDisplay extends React.PureComponent<Props, State
{lastActiveSection}
{channelDisplayModeSection}
{UnreadScrollPositionSection}
{timezoneSelection}
{clockSection}
{teammateNameDisplaySection}
<RhsLimitVisibleGMsDMs/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,38 @@ import type {UserProfile} from '@mattermost/types/users';
import type {ActionResult} from 'mattermost-redux/types/actions';
import {getTimezoneLabel} from 'mattermost-redux/utils/timezone_utils';

import ExternalLink from 'components/external_link';
import SettingItemMax from 'components/setting_item_max';
import Toggle from 'components/toggle';

import {getBrowserTimezone} from 'utils/timezone';

type Actions = {
updateMe: (user: UserProfile) => Promise<ActionResult>;
}

type OnChangeActions = {
selectedOption: {
label: string;
value: string;
};
} & ({
useAutomaticTimezone: boolean;
automaticTimezone: string;
manualTimezone: string;
});

type Props = {
user: UserProfile;
updateSection: (section: string) => void;
useAutomaticTimezone: boolean;
useAutomaticTimezone: boolean | string;
automaticTimezone: string;
manualTimezone: string;
timezones: Timezone[];
timezoneLabel: string;
actions: Actions;
compact?: boolean;
onChange?: (values: OnChangeActions) => void;
}
type SelectedOption = {
value: string;
Expand All @@ -48,21 +63,36 @@ type State = {
export default class ManageTimezones extends React.PureComponent<Props, State> {
constructor(props: Props) {
super(props);
const useAutomaticTimezone = (
props.useAutomaticTimezone === 'true' ||
props.useAutomaticTimezone === true
);
this.state = {
useAutomaticTimezone: props.useAutomaticTimezone,
useAutomaticTimezone,
automaticTimezone: props.automaticTimezone,
manualTimezone: props.manualTimezone,
isSaving: false,
openMenu: false,
selectedOption: {label: props.timezoneLabel, value: props.useAutomaticTimezone ? props.automaticTimezone : props.manualTimezone},
selectedOption: {
label: props.timezoneLabel,
value: useAutomaticTimezone ? props.automaticTimezone : props.manualTimezone,
},
};
}

onChange = (selectedOption: ValueType<SelectedOption>) => {
if (selectedOption && 'value' in selectedOption) {
this.setState({
manualTimezone: selectedOption.value,
automaticTimezone: selectedOption.value,
selectedOption,
useAutomaticTimezone: false,
});
this.props.onChange?.({
manualTimezone: selectedOption.value,
automaticTimezone: selectedOption.value,
selectedOption,
useAutomaticTimezone: false,
});
}
};
Expand Down Expand Up @@ -128,8 +158,9 @@ export default class ManageTimezones extends React.PureComponent<Props, State> {
});
};

handleAutomaticTimezone = (e: React.ChangeEvent<HTMLInputElement>) => {
const useAutomaticTimezone = e.target.checked;
handleAutomaticTimezone = () => {
const useAutomaticTimezone = !this.state.automaticTimezone;
const manualTimezone = '';
let automaticTimezone = '';
let timezoneLabel: string;
let selectedOptionValue: string;
Expand All @@ -151,13 +182,19 @@ export default class ManageTimezones extends React.PureComponent<Props, State> {
automaticTimezone,
selectedOption: {label: timezoneLabel, value: selectedOptionValue},
});
this.props.onChange?.({
useAutomaticTimezone,
manualTimezone,
automaticTimezone,
selectedOption: {label: timezoneLabel, value: selectedOptionValue},
});
};

handleManualTimezone = (e: React.ChangeEvent<HTMLSelectElement>) => {
this.setState({manualTimezone: e.target.value});
};
render() {
const {timezones} = this.props;
const {timezones, compact} = this.props;
const {useAutomaticTimezone} = this.state;

const timeOptions = this.props.timezones.map((timeObject) => {
Expand All @@ -183,65 +220,69 @@ export default class ManageTimezones extends React.PureComponent<Props, State> {

const noTimezonesFromServer = timezones.length === 0;
const automaticTimezoneInput = (
<div className='checkbox'>
<label>
<input
id='automaticTimezoneInput'
type='checkbox'
checked={useAutomaticTimezone}
onChange={this.handleAutomaticTimezone}
disabled={noTimezonesFromServer}
/>
<FormattedMessage
id='user.settings.timezones.automatic'
defaultMessage='Automatic'
/>

</label>
</div>
// <div className='checkbox'>
// <label>
// <input
// id='automaticTimezoneInput'
// type='checkbox'
// checked={useAutomaticTimezone}
// onChange={this.handleAutomaticTimezone}
// disabled={noTimezonesFromServer}
// />
// <FormattedMessage
// id='user.settings.timezones.automatic'
// defaultMessage='Automatic'
// />

// </label>
// </div>
<Toggle
id={'automaticTimezoneInput childOption'}
onToggle={this.handleAutomaticTimezone}
toggled={useAutomaticTimezone}
/>
);

const manualTimezoneInput = (
<div
className='pt-2'
className='pt-2 pb-4'
>
<ReactSelect
className='react-select react-select-top'
classNamePrefix='react-select'
id='displayTimezone'
menuPortalTarget={document.body}
styles={reactStyles}
options={timeOptions}
clearable={false}
onChange={this.onChange}
value={this.state.selectedOption}
aria-labelledby='changeInterfaceTimezoneLabel'
isDisabled={useAutomaticTimezone}
/>
{serverError}
{!useAutomaticTimezone &&
<ExternalLink
href='https://manager.infomaniak.com/v3/ng/profile/user/dashboard'
target='_blank'
>
<FormattedMessage
id='user.settings.timezones.modify'
defaultMessage='Change your time zone'
/>
</ExternalLink>}
</div>
);

inputs.push(automaticTimezoneInput);

inputs.push(manualTimezoneInput);

inputs.push(
<div>
<br/>
<FormattedMessage
id='user.settings.timezones.promote'
defaultMessage='Select the time zone used for timestamps in the user interface and email notifications.'
/>
</div>,
);

// inputs.push(
// <div>
// <br/>
// <FormattedMessage
// id='user.settings.timezones.promote'
// defaultMessage='Select the time zone used for timestamps in the user interface and email notifications.'
// />
// </div>,
// );
if (compact) {
return inputs;
}
return (
<SettingItemMax
title={
<FormattedMessage
id='user.settings.display.timezone'
defaultMessage='Timezone'
id='user.settings.display.timezone2'
defaultMessage='Automatic timezone'
/>
}
containerStyle='timezone-container'
Expand Down
2 changes: 2 additions & 0 deletions webapp/channels/src/i18n/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -5719,6 +5719,7 @@
"user.settings.display.theme.themeDark": "Thema Dunkel",
"user.settings.display.theme.themeAuto": "Automatisches Thema",
"user.settings.display.timezone": "Zeitzone",
"user.settings.display.timezone2": "automatische Zeitzone",
"user.settings.display.title": "Anzeigeeinstellungen",
"user.settings.general.close": "Schließen",
"user.settings.general.confirmEmail": "E-Mail-Adresse bestätigen",
Expand Down Expand Up @@ -5975,6 +5976,7 @@
"user.settings.sidebar.title": "Seitenleisteneinstellungen",
"user.settings.timezones.automatic": "Automatisch",
"user.settings.timezones.promote": "Wähle die Zeitzone, die für Zeitstempel in der Benutzeroberfläche und E-Mail-Benachrichtigungen verwendet wird.",
"user.settings.timezones.modify" : "Seine Zeitzone ändern",
"user.settings.tokens.activate": "Aktivieren",
"user.settings.tokens.cancel": "Abbrechen",
"user.settings.tokens.clickToEdit": "Klicke 'Bearbeiten', um deine persönlichen Zugriffs-Token zu verwalten",
Expand Down
Loading

0 comments on commit 597cbb4

Please sign in to comment.