MM-51359 Replace makeGetUserTimezone selector with getCurrentTimezone and similar selectors (#22832)

Этот коммит содержится в:
Harrison Healey
2023-04-05 14:57:19 -04:00
коммит произвёл GitHub
родитель 7029d88443
Коммит 54af9a7c7d
23 изменённых файлов: 219 добавлений и 227 удалений

Просмотреть файл

@@ -14,13 +14,12 @@ import {
searchFilesWithParams,
} from 'mattermost-redux/actions/search';
import * as PostActions from 'mattermost-redux/actions/posts';
import {getCurrentUserId, getCurrentUserMentionKeys} from 'mattermost-redux/selectors/entities/users';
import {getCurrentUserMentionKeys} from 'mattermost-redux/selectors/entities/users';
import {getCurrentTeamId} from 'mattermost-redux/selectors/entities/teams';
import {getConfig} from 'mattermost-redux/selectors/entities/general';
import {getCurrentChannelId, getCurrentChannelNameForSearchShortcut, getChannel as getChannelSelector} from 'mattermost-redux/selectors/entities/channels';
import {getPost} from 'mattermost-redux/selectors/entities/posts';
import {makeGetUserTimezone} from 'mattermost-redux/selectors/entities/timezone';
import {getUserCurrentTimezone} from 'mattermost-redux/utils/timezone_utils';
import {getCurrentTimezone} from 'mattermost-redux/selectors/entities/timezone';
import {Action, ActionResult, DispatchFunc, GenericAction, GetStateFunc} from 'mattermost-redux/types/actions';
import {Post} from '@mattermost/types/posts';
@@ -174,9 +173,7 @@ export function performSearch(terms: string, isMentionSearch?: boolean) {
}
// timezone offset in seconds
const userId = getCurrentUserId(getState());
const userTimezone = makeGetUserTimezone()(getState(), userId);
const userCurrentTimezone = getUserCurrentTimezone(userTimezone);
const userCurrentTimezone = getCurrentTimezone(getState());
const timezoneOffset = ((userCurrentTimezone && (userCurrentTimezone.length > 0)) ? getUtcOffsetForTimeZone(userCurrentTimezone) : getBrowserUtcOffset()) * 60;
const messagesPromise = dispatch(searchPostsWithParams(isMentionSearch ? '' : teamId, {terms, is_or_search: Boolean(isMentionSearch), include_deleted_channels: viewArchivedChannels, time_zone_offset: timezoneOffset, page: 0, per_page: 20}));
const filesPromise = dispatch(searchFilesWithParams(teamId, {terms: termsWithExtensionsFilters, is_or_search: Boolean(isMentionSearch), include_deleted_channels: viewArchivedChannels, time_zone_offset: timezoneOffset, page: 0, per_page: 20}));

Просмотреть файл

@@ -11,14 +11,13 @@ import {TopChannel, TopChannelGraphData} from '@mattermost/types/insights';
import {CircleSkeletonLoader, RectangleSkeletonLoader} from '@mattermost/components';
import {getCurrentRelativeTeamUrl, getCurrentTeamId} from 'mattermost-redux/selectors/entities/teams';
import {getCurrentTimezone} from 'mattermost-redux/selectors/entities/timezone';
import {getMyTopChannels, getTopChannelsForTeam} from 'mattermost-redux/actions/insights';
import Constants, {InsightsScopes} from 'utils/constants';
import {trackEvent} from 'actions/telemetry_actions';
import {getCurrentUserTimezone} from 'selectors/general';
import OverlayTrigger from 'components/overlay_trigger';
import Tooltip from 'components/tooltip';
@@ -38,7 +37,7 @@ const TopChannels = (props: WidgetHocProps) => {
const currentTeamId = useSelector(getCurrentTeamId);
const currentTeamUrl = useSelector(getCurrentRelativeTeamUrl);
const timeZone = useSelector(getCurrentUserTimezone);
const timeZone = useSelector(getCurrentTimezone);
const getTopTeamChannels = useCallback(async () => {
if (props.filterType === InsightsScopes.TEAM) {

Просмотреть файл

@@ -12,8 +12,8 @@ import mockStore from 'tests/test_store';
import CustomStatusEmoji from './custom_status_emoji';
jest.mock('mattermost-redux/selectors/entities/timezone');
jest.mock('selectors/views/custom_status');
jest.mock('selectors/general');
describe('components/custom_status/custom_status_emoji', () => {
const store = mockStore({});

Просмотреть файл

@@ -6,8 +6,9 @@ import {useSelector} from 'react-redux';
import {CustomStatusDuration} from '@mattermost/types/users';
import {getCurrentTimezone} from 'mattermost-redux/selectors/entities/timezone';
import {GlobalState} from 'types/store';
import {getCurrentUserTimezone} from 'selectors/general';
import {makeGetCustomStatus, isCustomStatusEnabled, isCustomStatusExpired} from 'selectors/views/custom_status';
import Constants from 'utils/constants';
@@ -41,7 +42,7 @@ function CustomStatusEmoji({
const getCustomStatus = useMemo(makeGetCustomStatus, []);
const customStatus = useSelector((state: GlobalState) => getCustomStatus(state, userID));
const timezone = useSelector(getCurrentUserTimezone);
const timezone = useSelector(getCurrentTimezone);
const customStatusExpired = useSelector((state: GlobalState) => isCustomStatusExpired(state, customStatus));
const customStatusEnabled = useSelector(isCustomStatusEnabled);

Просмотреть файл

@@ -11,6 +11,7 @@ import {useRouteMatch} from 'react-router-dom';
import {setCustomStatus, unsetCustomStatus, removeRecentCustomStatus} from 'mattermost-redux/actions/users';
import {setCustomStatusInitialisationState} from 'mattermost-redux/actions/preferences';
import {Preferences} from 'mattermost-redux/constants';
import {getCurrentTimezone} from 'mattermost-redux/selectors/entities/timezone';
import {loadCustomEmojisIfNeeded} from 'actions/emoji_actions';
import {closeModal} from 'actions/views/modals';
@@ -20,7 +21,6 @@ import EmojiPickerOverlay from 'components/emoji_picker/emoji_picker_overlay';
import RenderEmoji from 'components/emoji/render_emoji';
import QuickInput, {MaxLengthInput} from 'components/quick_input';
import {makeGetCustomStatus, getRecentCustomStatuses, showStatusDropdownPulsatingDot, isCustomStatusExpired} from 'selectors/views/custom_status';
import {getCurrentUserTimezone} from 'selectors/general';
import {GlobalState} from 'types/store';
import {getCurrentMomentForTimezone} from 'utils/timezone';
import {A11yCustomEventTypes, A11yFocusEventDetail, Constants, ModalIdentifiers} from 'utils/constants';
@@ -115,7 +115,7 @@ const CustomStatusModal: React.FC<Props> = (props: Props) => {
const [duration, setDuration] = useState<CustomStatusDuration>(initialDuration === undefined ? defaultDuration : initialDuration);
const isStatusSet = Boolean(emoji || text);
const firstTimeModalOpened = useSelector(showStatusDropdownPulsatingDot);
const timezone = useSelector(getCurrentUserTimezone);
const timezone = useSelector(getCurrentTimezone);
const inCustomEmojiPath = useRouteMatch('/:team/emoji');
const currentTime = getCurrentMomentForTimezone(timezone);

Просмотреть файл

@@ -12,7 +12,7 @@ import {getCurrentTeamId, getCurrentTeam, getTeam} from 'mattermost-redux/select
import {makeGetThreadOrSynthetic} from 'mattermost-redux/selectors/entities/threads';
import {getPost} from 'mattermost-redux/selectors/entities/posts';
import {getBool, isCollapsedThreadsEnabled} from 'mattermost-redux/selectors/entities/preferences';
import {getCurrentUserTimezone} from 'selectors/general';
import {getCurrentTimezone} from 'mattermost-redux/selectors/entities/timezone';
import {isSystemMessage} from 'mattermost-redux/utils/post_utils';
import {GenericAction} from 'mattermost-redux/types/actions';
import {setThreadFollow} from 'mattermost-redux/actions/threads';
@@ -126,7 +126,7 @@ function makeMapStateToProps() {
isCollapsedThreadsEnabled: collapsedThreads,
threadReplyCount,
isMobileView: getIsMobileView(state),
timezone: getCurrentUserTimezone(state),
timezone: getCurrentTimezone(state),
isMilitaryTime,
};
};

Просмотреть файл

@@ -19,12 +19,11 @@ import {getBool} from 'mattermost-redux/selectors/entities/preferences';
import {Preferences} from 'utils/constants';
import {getCurrentTeam} from 'mattermost-redux/selectors/entities/teams';
import {getCurrentTimezone} from 'mattermost-redux/selectors/entities/timezone';
import {Channel} from '@mattermost/types/channels';
import {Post} from '@mattermost/types/posts';
import {getCurrentUserTimezone} from '../../selectors/general';
import PostMarkdown from './post_markdown';
export function makeGetMentionKeysForPost(): (
@@ -75,7 +74,7 @@ function makeMapStateToProps() {
isUserCanManageMembers: channel && canManageMembers(state, channel),
mentionKeys: getMentionKeysForPost(state, ownProps.post, channel),
isMilitaryTime: getBool(state, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.USE_MILITARY_TIME, false),
timezone: getCurrentUserTimezone(state),
timezone: getCurrentTimezone(state),
};
};
}

Просмотреть файл

@@ -10,17 +10,16 @@ import {Preferences} from 'mattermost-redux/constants';
import {addPostReminder} from 'mattermost-redux/actions/posts';
import {getBool} from 'mattermost-redux/selectors/entities/preferences';
import {getCurrentTimezone} from 'mattermost-redux/selectors/entities/timezone';
import {getCurrentUserId} from 'mattermost-redux/selectors/entities/users';
import {GlobalState} from 'types/store';
import {makeAsyncComponent} from 'components/async_load';
import {getCurrentUserTimezone} from 'selectors/general';
const PostReminderCustomTimePicker = makeAsyncComponent('PostReminderCustomTimePicker', React.lazy(() => import('./post_reminder_custom_time_picker_modal')));
function mapStateToProps(state: GlobalState) {
const timezone = getCurrentUserTimezone(state);
const timezone = getCurrentTimezone(state);
const userId = getCurrentUserId(state);
const isMilitaryTime = getBool(state, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.USE_MILITARY_TIME, false);

Просмотреть файл

@@ -6,18 +6,16 @@ import {connect} from 'react-redux';
import {bindActionCreators, Dispatch} from 'redux';
import {getCurrentUserId} from 'mattermost-redux/selectors/entities/common';
import {makeGetUserTimezone} from 'mattermost-redux/selectors/entities/timezone';
import {getUserCurrentTimezone} from 'mattermost-redux/utils/timezone_utils';
import {getBool} from 'mattermost-redux/selectors/entities/preferences';
import {getPost} from 'mattermost-redux/selectors/entities/posts';
import {getPostEditHistory} from 'mattermost-redux/actions/posts';
import {getConfig, getLicense} from 'mattermost-redux/selectors/entities/general';
import {getChannel} from 'mattermost-redux/selectors/entities/channels';
import {getCurrentTimezone, isTimezoneEnabled} from 'mattermost-redux/selectors/entities/timezone';
import {Preferences} from 'utils/constants';
import {isPostOwner, canEditPost} from 'utils/post_utils';
import {areTimezonesEnabledAndSupported} from '../../../selectors/general';
import {GlobalState} from '../../../types/store';
import {Props as TimestampProps} from '../../timestamp/timestamp';
@@ -49,27 +47,23 @@ type DispatchProps = {
export type Props = OwnProps & StateProps & DispatchProps;
function makeMapStateToProps() {
const getUserTimezone = makeGetUserTimezone();
function mapStateToProps(state: GlobalState, ownProps: OwnProps): StateProps {
const currentUserId = getCurrentUserId(state);
const post = ownProps.postId ? getPost(state, ownProps.postId) : undefined;
const license = getLicense(state);
const config = getConfig(state);
const channel = getChannel(state, post?.channel_id || '');
return (state: GlobalState, ownProps: OwnProps): StateProps => {
const currentUserId = getCurrentUserId(state);
const post = ownProps.postId ? getPost(state, ownProps.postId) : undefined;
const license = getLicense(state);
const config = getConfig(state);
const channel = getChannel(state, post?.channel_id || '');
let timeZone: TimestampProps['timeZone'];
let timeZone: TimestampProps['timeZone'];
if (isTimezoneEnabled(state)) {
timeZone = getCurrentTimezone(state);
}
const postOwner = post ? isPostOwner(state, post) : undefined;
if (areTimezonesEnabledAndSupported(state)) {
timeZone = getUserCurrentTimezone(getUserTimezone(state, currentUserId)) ?? undefined;
}
const postOwner = post ? isPostOwner(state, post) : undefined;
const isMilitaryTime = getBool(state, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.USE_MILITARY_TIME, false);
const canEdit = post ? canEditPost(state, post, license, config, channel, currentUserId) : false;
return {isMilitaryTime, timeZone, postOwner, post, canEdit};
};
const isMilitaryTime = getBool(state, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.USE_MILITARY_TIME, false);
const canEdit = post ? canEditPost(state, post, license, config, channel, currentUserId) : false;
return {isMilitaryTime, timeZone, postOwner, post, canEdit};
}
function mapDispatchToProps(dispatch: Dispatch) {
@@ -81,4 +75,4 @@ function mapDispatchToProps(dispatch: Dispatch) {
};
}
export default connect<StateProps, DispatchProps, OwnProps, GlobalState>(makeMapStateToProps, mapDispatchToProps)(PostEditedIndicator);
export default connect<StateProps, DispatchProps, OwnProps, GlobalState>(mapStateToProps, mapDispatchToProps)(PostEditedIndicator);

Просмотреть файл

@@ -19,12 +19,12 @@ import {
import {getCallsConfig, getCalls} from 'mattermost-redux/selectors/entities/common';
import {Action} from 'mattermost-redux/types/actions';
import {getTeammateNameDisplaySetting} from 'mattermost-redux/selectors/entities/preferences';
import {getCurrentTimezone, isTimezoneEnabled} from 'mattermost-redux/selectors/entities/timezone';
import {openDirectChannelToUserId} from 'actions/channel_actions';
import {getMembershipForEntities} from 'actions/views/profile_popover';
import {closeModal, openModal} from 'actions/views/modals';
import {areTimezonesEnabledAndSupported, getCurrentUserTimezone} from 'selectors/general';
import {getRhsState, getSelectedPost} from 'selectors/rhs';
import {getIsMobileView} from 'selectors/views/browser';
import {isAnyModalOpen} from 'selectors/views/modals';
@@ -98,7 +98,7 @@ function makeMapStateToProps() {
return {
currentTeamId: team.id,
currentUserId,
enableTimezone: areTimezonesEnabledAndSupported(state),
enableTimezone: isTimezoneEnabled(state),
isTeamAdmin,
isChannelAdmin,
isInCurrentTeam: Boolean(teamMember) && teamMember?.delete_at === 0,
@@ -111,7 +111,7 @@ function makeMapStateToProps() {
isCustomStatusEnabled: isCustomStatusEnabled(state),
isCustomStatusExpired: isCustomStatusExpired(state, customStatus),
channelId,
currentUserTimezone: getCurrentUserTimezone(state),
currentUserTimezone: getCurrentTimezone(state),
lastActivityTimestamp,
enableLastActiveTime,
timestampUnits,

Просмотреть файл

@@ -40,7 +40,7 @@ import Tooltip from 'components/tooltip';
import ProfilePopoverCallButton from 'components/profile_popover_call_button';
import {ServerError} from '@mattermost/types/errors';
import {UserCustomStatus, UserProfile, UserTimezone, CustomStatusDuration} from '@mattermost/types/users';
import {UserCustomStatus, UserProfile, CustomStatusDuration} from '@mattermost/types/users';
import './profile_popover.scss';
import BotTag from '../widgets/tag/bot_tag';
@@ -587,7 +587,7 @@ class ProfilePopover extends React.PureComponent<ProfilePopoverProps, ProfilePop
<Timestamp
useRelative={false}
useDate={false}
userTimezone={this.props.user?.timezone as UserTimezone | undefined}
userTimezone={this.props.user?.timezone}
useTime={{
hour: 'numeric',
minute: 'numeric',

Просмотреть файл

@@ -4,10 +4,7 @@
import {Settings} from 'luxon';
import {getCurrentLocale} from 'selectors/i18n';
import {areTimezonesEnabledAndSupported} from 'selectors/general';
import {getUserCurrentTimezone} from 'mattermost-redux/utils/timezone_utils';
import {getCurrentUserId} from 'mattermost-redux/selectors/entities/users';
import {makeGetUserTimezone} from 'mattermost-redux/selectors/entities/timezone';
import {getCurrentTimezone, isTimezoneEnabled} from 'mattermost-redux/selectors/entities/timezone';
import {GlobalState} from 'types/store';
let prevTimezone: string | undefined;
@@ -19,8 +16,8 @@ export function applyLuxonDefaults(state: GlobalState) {
Settings.defaultLocale = locale;
}
if (areTimezonesEnabledAndSupported(state)) {
const tz = getUserCurrentTimezone(makeGetUserTimezone()(state, getCurrentUserId(state))) ?? undefined;
if (isTimezoneEnabled(state)) {
const tz = getCurrentTimezone(state);
if (tz !== prevTimezone) {
prevTimezone = tz;
Settings.defaultZone = tz ?? 'system';

Просмотреть файл

@@ -11,12 +11,12 @@ import {Client4} from 'mattermost-redux/client';
import {Preferences} from 'mattermost-redux/constants';
import {get, getBool, getInt} from 'mattermost-redux/selectors/entities/preferences';
import {getCurrentTimezone} from 'mattermost-redux/selectors/entities/timezone';
import {getCurrentUser, getStatusForUserId} from 'mattermost-redux/selectors/entities/users';
import {openModal} from 'actions/views/modals';
import {setStatusDropdown} from 'actions/views/status_dropdown';
import {getCurrentUserTimezone} from 'selectors/general';
import {makeGetCustomStatus, isCustomStatusEnabled, showStatusDropdownPulsatingDot, isCustomStatusExpired} from 'selectors/views/custom_status';
import {isStatusDropdownOpen} from 'selectors/views/status_dropdown';
import {GenericAction} from 'mattermost-redux/types/actions';
@@ -53,7 +53,7 @@ function makeMapStateToProps() {
isStatusDropdownOpen: isStatusDropdownOpen(state),
showCustomStatusPulsatingDot: showStatusDropdownPulsatingDot(state),
showCompleteYourProfileTour,
timezone: getCurrentUserTimezone(state),
timezone: getCurrentTimezone(state),
};
};
}

Просмотреть файл

@@ -3,41 +3,30 @@
import {connect} from 'react-redux';
import {getCurrentUserId} from 'mattermost-redux/selectors/entities/users';
import {makeGetUserTimezone} from 'mattermost-redux/selectors/entities/timezone';
import {getCurrentTimezone, isTimezoneEnabled} from 'mattermost-redux/selectors/entities/timezone';
import {getCurrentDateForTimezone} from 'utils/timezone';
import {areTimezonesEnabledAndSupported} from 'selectors/general';
import {getCurrentLocale} from 'selectors/i18n';
import {GlobalState} from 'types/store';
import SearchDateSuggestion from './search_date_suggestion';
function makeMapStateToProps() {
const getUserTimezone = makeGetUserTimezone();
function mapStateToProps(state: GlobalState) {
const timezone = getCurrentTimezone(state);
const locale = getCurrentLocale(state);
return (state: GlobalState) => {
const currentUserId = getCurrentUserId(state);
const userTimezone = getUserTimezone(state, currentUserId);
const locale = getCurrentLocale(state);
const enableTimezone = isTimezoneEnabled(state);
const enableTimezone = areTimezonesEnabledAndSupported(state);
let currentDate;
if (enableTimezone) {
currentDate = getCurrentDateForTimezone(timezone);
}
let currentDate;
if (enableTimezone) {
if (userTimezone.useAutomaticTimezone) {
currentDate = getCurrentDateForTimezone(userTimezone.automaticTimezone);
} else {
currentDate = getCurrentDateForTimezone(userTimezone.manualTimezone);
}
}
return {
currentDate,
locale,
};
return {
currentDate,
locale,
};
}
export default connect(makeMapStateToProps)(SearchDateSuggestion);
export default connect(mapStateToProps)(SearchDateSuggestion);

Просмотреть файл

@@ -1,13 +1,13 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import mergeObjects from 'packages/mattermost-redux/test/merge_objects';
import {GlobalState} from 'types/store';
import {UserTimezone} from '@mattermost/types/users';
import {PreferenceType} from '@mattermost/types/preferences';
import * as Timestamp from './timestamp';
import {makeMapStateToProps} from './index';
import {mapStateToProps} from './index';
const supportsHourCycleOg = Timestamp.supportsHourCycle;
Object.defineProperty(Timestamp, 'supportsHourCycle', {get: () => supportsHourCycleOg});
@@ -39,57 +39,89 @@ describe('mapStateToProps', () => {
describe('hourCycle', () => {
test('hourCycle should be h12 when military time is false and the prop was not set', () => {
const props = makeMapStateToProps()(initialState, {});
const props = mapStateToProps(initialState, {});
expect(props.hourCycle).toBe('h12');
});
test('hourCycle should be h23 when military time is true and the prop was not set', () => {
const testState = {...initialState};
testState.entities.preferences.myPreferences['display_settings--use_military_time'] = {
category: 'display_settings',
name: 'use_military_time',
user_id: currentUserId,
value: 'true',
} as PreferenceType;
const testState = mergeObjects(initialState, {
entities: {
preferences: {
myPreferences: {
'display_settings--use_military_time': {
category: 'display_settings',
name: 'use_military_time',
user_id: currentUserId,
value: 'true',
},
},
},
},
});
const props = makeMapStateToProps()(testState, {});
const props = mapStateToProps(testState, {});
expect(props.hourCycle).toBe('h23');
});
test('hourCycle should have the value of prop.hourCycle when given', () => {
const testState = {...initialState};
testState.entities.preferences.myPreferences['display_settings--use_military_time'] = {
category: 'display_settings',
name: 'use_military_time',
user_id: currentUserId,
value: 'true',
} as PreferenceType;
const testState = mergeObjects(initialState, {
entities: {
preferences: {
myPreferences: {
'display_settings--use_military_time': {
category: 'display_settings',
name: 'use_military_time',
user_id: currentUserId,
value: 'true',
},
},
},
},
});
const props = makeMapStateToProps()(testState, {hourCycle: 'h24'});
const props = mapStateToProps(testState, {hourCycle: 'h24'});
expect(props.hourCycle).toBe('h24');
});
});
describe('timeZone', () => {
test('timeZone should be the user TZ when the prop was not set', () => {
const testState = {...initialState};
testState.entities.users.profiles[currentUserId].timezone = {
useAutomaticTimezone: false,
manualTimezone: 'Europe/Paris',
} as UserTimezone;
const testState = mergeObjects(initialState, {
entities: {
users: {
profiles: {
[currentUserId]: {
timezone: {
useAutomaticTimezone: false,
manualTimezone: 'Europe/Paris',
},
},
},
},
},
});
const props = makeMapStateToProps()(testState, {});
const props = mapStateToProps(testState, {});
expect(props.timeZone).toBe('Europe/Paris');
});
test('timeZone should be the value of prop.timeZone when given', () => {
const testState = {...initialState};
testState.entities.users.profiles[currentUserId].timezone = {
useAutomaticTimezone: false,
manualTimezone: 'Europe/Paris',
} as UserTimezone;
const testState = mergeObjects(initialState, {
entities: {
users: {
profiles: {
[currentUserId]: {
timezone: {
useAutomaticTimezone: false,
manualTimezone: 'Europe/Paris',
},
},
},
},
},
});
const props = makeMapStateToProps()(testState, {timeZone: 'America/Phoenix'});
const props = mapStateToProps(testState, {timeZone: 'America/Phoenix'});
expect(props.timeZone).toBe('America/Phoenix');
});
@@ -97,51 +129,72 @@ describe('mapStateToProps', () => {
const testState = {...initialState};
testState.entities.general.config.ExperimentalTimezone = 'false';
const props = makeMapStateToProps()(testState, {timeZone: 'America/Chicago'});
const props = mapStateToProps(testState, {timeZone: 'America/Chicago'});
expect(props.timeZone).toBe('America/Chicago');
});
});
describe('hour12, hourCycle unsupported', () => {
test('hour12 should be false when using military time', () => {
const testState = {...initialState};
testState.entities.preferences.myPreferences['display_settings--use_military_time'] = {
category: 'display_settings',
name: 'use_military_time',
user_id: currentUserId,
value: 'true',
} as PreferenceType;
const testState = mergeObjects(initialState, {
entities: {
preferences: {
myPreferences: {
'display_settings--use_military_time': {
category: 'display_settings',
name: 'use_military_time',
user_id: currentUserId,
value: 'true',
},
},
},
},
});
supportsHourCycleSpy.mockReturnValueOnce(false);
const props = makeMapStateToProps()(testState, {});
const props = mapStateToProps(testState, {});
expect(props.hour12).toBe(false);
});
test('hour12 should be true when not using military time', () => {
const testState = {...initialState};
testState.entities.preferences.myPreferences['display_settings--use_military_time'] = {
category: 'display_settings',
name: 'use_military_time',
user_id: currentUserId,
value: 'false',
} as PreferenceType;
const testState = mergeObjects(initialState, {
entities: {
preferences: {
myPreferences: {
'display_settings--use_military_time': {
category: 'display_settings',
name: 'use_military_time',
user_id: currentUserId,
value: 'false',
},
},
},
},
});
supportsHourCycleSpy.mockReturnValueOnce(false);
const props = makeMapStateToProps()(testState, {});
const props = mapStateToProps(testState, {});
expect(props.hour12).toBe(true);
});
test('hour12 should equal props.hour12 when defined', () => {
const testState = {...initialState};
testState.entities.preferences.myPreferences['display_settings--use_military_time'] = {
category: 'display_settings',
name: 'use_military_time',
user_id: currentUserId,
value: 'false',
} as PreferenceType;
const testState = mergeObjects(initialState, {
entities: {
preferences: {
myPreferences: {
'display_settings--use_military_time': {
category: 'display_settings',
name: 'use_military_time',
user_id: currentUserId,
value: 'false8',
},
},
},
},
});
supportsHourCycleSpy.mockReturnValueOnce(false);
const props = makeMapStateToProps()(testState, {hour12: false});
const props = mapStateToProps(testState, {hour12: false});
expect(props.hour12).toBe(false);
});
});

Просмотреть файл

@@ -3,14 +3,11 @@
import {connect} from 'react-redux';
import {getCurrentUserId} from 'mattermost-redux/selectors/entities/users';
import {makeGetUserTimezone} from 'mattermost-redux/selectors/entities/timezone';
import {getCurrentTimezoneFull, isTimezoneEnabled} from 'mattermost-redux/selectors/entities/timezone';
import {getUserCurrentTimezone} from 'mattermost-redux/utils/timezone_utils';
import {getBool} from 'mattermost-redux/selectors/entities/preferences';
import {UserTimezone} from '@mattermost/types/users';
import {areTimezonesEnabledAndSupported} from 'selectors/general';
import {GlobalState} from 'types/store';
import {Preferences} from 'utils/constants';
@@ -24,33 +21,27 @@ type Props = {
hourCycle?: TimestampProps['hourCycle'];
}
export function makeMapStateToProps() {
const getUserTimezone = makeGetUserTimezone();
export function mapStateToProps(state: GlobalState, ownProps: Props) {
let timeZone: TimestampProps['timeZone'];
let hourCycle: TimestampProps['hourCycle'];
let hour12: TimestampProps['hour12'];
return (state: GlobalState, ownProps: Props) => {
const currentUserId = getCurrentUserId(state);
if (isTimezoneEnabled(state)) {
timeZone = getUserCurrentTimezone(ownProps.userTimezone ?? getCurrentTimezoneFull(state)) ?? undefined;
}
let timeZone: TimestampProps['timeZone'];
let hourCycle: TimestampProps['hourCycle'];
let hour12: TimestampProps['hour12'];
const useMilitaryTime = getBool(state, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.USE_MILITARY_TIME, false);
if (areTimezonesEnabledAndSupported(state)) {
timeZone = getUserCurrentTimezone(ownProps.userTimezone ?? getUserTimezone(state, currentUserId)) ?? undefined;
}
if (supportsHourCycle) {
hourCycle = ownProps.hourCycle || (useMilitaryTime ? 'h23' : 'h12');
} else {
hour12 = ownProps.hour12 ?? (!useMilitaryTime);
}
const useMilitaryTime = getBool(state, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.USE_MILITARY_TIME, false);
if (supportsHourCycle) {
hourCycle = ownProps.hourCycle || (useMilitaryTime ? 'h23' : 'h12');
} else {
hour12 = ownProps.hour12 ?? (!useMilitaryTime);
}
return {timeZone: ownProps.timeZone || timeZone, hourCycle, hour12};
};
return {timeZone: ownProps.timeZone || timeZone, hourCycle, hour12};
}
export default connect(makeMapStateToProps)(Timestamp);
export default connect(mapStateToProps)(Timestamp);
export {default as SemanticTime} from './semantic_time';
import * as RelativeRanges from './relative_ranges';

Просмотреть файл

@@ -15,7 +15,7 @@ import {autoUpdateTimezone} from 'mattermost-redux/actions/timezone';
import {getConfig, getLicense} from 'mattermost-redux/selectors/entities/general';
import {getCurrentUserId, getUser} from 'mattermost-redux/selectors/entities/users';
import {get, isCollapsedThreadsAllowed, getCollapsedThreadsPreference} from 'mattermost-redux/selectors/entities/preferences';
import {getTimezoneLabel, makeGetUserTimezone} from 'mattermost-redux/selectors/entities/timezone';
import {getCurrentTimezoneFull, getCurrentTimezoneLabel} from 'mattermost-redux/selectors/entities/timezone';
import {getUserCurrentTimezone} from 'mattermost-redux/utils/timezone_utils';
import {CollapsedThreads} from '@mattermost/types/config';
@@ -34,15 +34,13 @@ type Actions = {
}
export function makeMapStateToProps() {
const getUserTimezone = makeGetUserTimezone();
return (state: GlobalState) => {
const config = getConfig(state);
const currentUserId = getCurrentUserId(state);
const userTimezone = getUserTimezone(state, currentUserId);
const userTimezone = getCurrentTimezoneFull(state);
const automaticTimezoneNotSet = userTimezone && userTimezone.useAutomaticTimezone && !userTimezone.automaticTimezone;
const shouldAutoUpdateTimezone = !userTimezone || automaticTimezoneNotSet;
const timezoneLabel = getTimezoneLabel(state, currentUserId);
const timezoneLabel = getCurrentTimezoneLabel(state);
const allowCustomThemes = config.AllowCustomThemes === 'true';
const enableLinkPreviews = config.EnableLinkPreviews === 'true';
const defaultClientLocale = config.DefaultClientLocale as string;

Просмотреть файл

@@ -10,9 +10,7 @@ import {updateMe} from 'mattermost-redux/actions/users';
import {ActionFunc, ActionResult} from 'mattermost-redux/types/actions';
import {UserProfile} from '@mattermost/types/users';
import {GlobalState} from '@mattermost/types/store';
import {getTimezoneLabel} from 'mattermost-redux/selectors/entities/timezone';
import {getCurrentUserId} from 'mattermost-redux/selectors/entities/users';
import {getCurrentTimezoneLabel} from 'mattermost-redux/selectors/entities/timezone';
import ManageTimezones from './manage_timezones';
@@ -27,8 +25,7 @@ function mapDispatchToProps(dispatch: Dispatch) {
}, dispatch)};
}
function mapStateToProps(state: GlobalState) {
const currentUserId = getCurrentUserId(state);
const timezoneLabel = getTimezoneLabel(state, currentUserId);
const timezoneLabel = getCurrentTimezoneLabel(state);
return {
timezones,
timezoneLabel,

Просмотреть файл

@@ -2,15 +2,16 @@
// See LICENSE.txt for license information.
import {getCurrentUser} from 'mattermost-redux/selectors/entities/users';
import {makeGetUserTimezone} from 'mattermost-redux/selectors/entities/timezone';
import {getCurrentTimezoneFull} from 'mattermost-redux/selectors/entities/timezone';
import {DispatchFunc, GetStateFunc} from 'mattermost-redux/types/actions';
import {updateMe} from './users';
export function autoUpdateTimezone(deviceTimezone: string) {
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
const currentUser = getCurrentUser(getState());
const currentTimezone = makeGetUserTimezone()(getState(), currentUser.id);
const currentTimezone = getCurrentTimezoneFull(getState());
const newTimezoneExists = currentTimezone.automaticTimezone !== deviceTimezone;
if (currentTimezone.useAutomaticTimezone && newTimezoneExists) {

Просмотреть файл

@@ -1,17 +1,17 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import timezones, {Timezone} from 'timezones.json';
import {getUser} from 'mattermost-redux/selectors/entities/users';
import timezones from 'timezones.json';
import {GlobalState} from '@mattermost/types/store';
import {UserProfile, UserTimezone} from '@mattermost/types/users';
import {UserProfile} from '@mattermost/types/users';
import {createSelector} from 'reselect';
import {getUserCurrentTimezone, getTimezoneLabel as getTimezoneLabelUtil} from 'mattermost-redux/utils/timezone_utils';
import {getTimezoneLabel, getUserCurrentTimezone} from 'mattermost-redux/utils/timezone_utils';
export function getTimezoneForUserProfile(profile: UserProfile) {
import {getCurrentUser} from './common';
function getTimezoneForUserProfile(profile: UserProfile) {
if (profile && profile.timezone) {
return {
...profile.timezone,
@@ -31,23 +31,30 @@ export function isTimezoneEnabled(state: GlobalState) {
return config.ExperimentalTimezone === 'true';
}
export const makeGetUserTimezone = () => createSelector(
'makeGetUserTimezone',
(state: GlobalState, userId: string) => getUser(state, userId),
(user: UserProfile) => {
return getTimezoneForUserProfile(user);
export const getCurrentTimezoneFull = createSelector(
'getCurrentTimezoneFull',
getCurrentUser,
(currentUser) => {
return getTimezoneForUserProfile(currentUser);
},
);
export const getTimezoneLabel: (state: GlobalState, userId: UserProfile['id']) => string = createSelector(
'getTimezoneLabel',
() => timezones,
makeGetUserTimezone(),
(timezones: Timezone[], timezoneObject: UserTimezone) => {
const timezone = getUserCurrentTimezone(timezoneObject);
export const getCurrentTimezone = createSelector(
'getCurrentTimezone',
getCurrentTimezoneFull,
(timezoneFull) => {
return getUserCurrentTimezone(timezoneFull);
},
);
export const getCurrentTimezoneLabel = createSelector(
'getCurrentTimezoneLabel',
getCurrentTimezone,
(timezone) => {
if (!timezone) {
return '';
}
return getTimezoneLabelUtil(timezones, timezone);
return getTimezoneLabel(timezones, timezone);
},
);

Просмотреть файл

@@ -5,9 +5,9 @@ import {Timezone} from 'timezones.json';
import {UserTimezone} from '@mattermost/types/users';
export function getUserCurrentTimezone(userTimezone?: UserTimezone): string | undefined | null {
export function getUserCurrentTimezone(userTimezone?: UserTimezone): string {
if (!userTimezone) {
return null;
return 'UTC';
}
const {
useAutomaticTimezone,

Просмотреть файл

@@ -1,13 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {createSelector} from 'reselect';
import {getCurrentUser} from 'mattermost-redux/selectors/entities/common';
import {getConfig} from 'mattermost-redux/selectors/entities/general';
import {getTimezoneForUserProfile} from 'mattermost-redux/selectors/entities/timezone';
import * as UserAgent from 'utils/user_agent';
import type {GlobalState} from 'types/store';
@@ -17,15 +11,6 @@ declare global {
}
}
export function areTimezonesEnabledAndSupported(state: GlobalState) {
if (UserAgent.isInternetExplorer()) {
return false;
}
const config = getConfig(state);
return config.ExperimentalTimezone === 'true';
}
export function getBasePath(state: GlobalState) {
const config = getConfig(state) || {};
@@ -36,21 +21,6 @@ export function getBasePath(state: GlobalState) {
return window.basename || '/';
}
export const getCurrentUserTimezone = createSelector(
'getCurrentUserTimezone',
getCurrentUser,
areTimezonesEnabledAndSupported,
(user, enabledTimezone) => {
let timezone;
if (enabledTimezone) {
const userTimezone = getTimezoneForUserProfile(user);
timezone = userTimezone.useAutomaticTimezone ? userTimezone.automaticTimezone : userTimezone.manualTimezone;
}
return timezone;
},
);
export function getConnectionId(state: GlobalState) {
return state.websocket.connectionId;
}

Просмотреть файл

@@ -5,6 +5,7 @@ import moment from 'moment-timezone';
import {createSelector} from 'reselect';
import {getCurrentTimezone} from 'mattermost-redux/selectors/entities/timezone';
import {getCurrentUser, getUser} from 'mattermost-redux/selectors/entities/users';
import {getConfig} from 'mattermost-redux/selectors/entities/general';
@@ -15,7 +16,6 @@ import {CustomStatusDuration, UserCustomStatus} from '@mattermost/types/users';
import {isDateWithinDaysRange, TimeInformation} from 'utils/utils';
import {GlobalState} from 'types/store';
import {getCurrentUserTimezone} from 'selectors/general';
import {getCurrentMomentForTimezone} from 'utils/timezone';
export function makeGetCustomStatus(): (state: GlobalState, userID?: string) => UserCustomStatus {
@@ -39,7 +39,7 @@ export function isCustomStatusExpired(state: GlobalState, customStatus?: UserCus
}
const expiryTime = moment(customStatus.expires_at);
const timezone = getCurrentUserTimezone(state);
const timezone = getCurrentTimezone(state);
const currentTime = getCurrentMomentForTimezone(timezone);
return currentTime.isSameOrAfter(expiryTime);
}