@@ -51,7 +51,7 @@
|
|||||||
"localforage": "1.10.0",
|
"localforage": "1.10.0",
|
||||||
"localforage-observable": "2.1.1",
|
"localforage-observable": "2.1.1",
|
||||||
"lodash": "4.17.21",
|
"lodash": "4.17.21",
|
||||||
"luxon": "3.0.4",
|
"luxon": "3.3.0",
|
||||||
"mark.js": "8.11.1",
|
"mark.js": "8.11.1",
|
||||||
"marked": "github:mattermost/marked#2ef7f28cc7718e3f551c4ce9ea75fdd7580c2008",
|
"marked": "github:mattermost/marked#2ef7f28cc7718e3f551c4ce9ea75fdd7580c2008",
|
||||||
"memoize-one": "6.0.0",
|
"memoize-one": "6.0.0",
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import {DateTime, Duration} from 'luxon';
|
||||||
|
|
||||||
|
import {FormattedMessage} from 'react-intl';
|
||||||
|
|
||||||
|
import {UserTimezone} from '@mattermost/types/users';
|
||||||
|
import Timestamp from 'components/timestamp';
|
||||||
|
import {getUserCurrentTimezone} from 'mattermost-redux/utils/timezone_utils';
|
||||||
|
|
||||||
|
type ProfileTimezoneProps = {
|
||||||
|
profileUserTimezone?: UserTimezone;
|
||||||
|
currentUserTimezone: string | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const returnTimeDiff = (
|
||||||
|
currentUserTimezone: string | undefined | null,
|
||||||
|
profileUserTimezone: string,
|
||||||
|
) => {
|
||||||
|
if (!currentUserTimezone) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const currentUserDate = DateTime.local().setZone(currentUserTimezone);
|
||||||
|
const profileUserDate = DateTime.local().setZone(profileUserTimezone);
|
||||||
|
|
||||||
|
const offset = Duration.fromObject({
|
||||||
|
hours: (profileUserDate.offset - currentUserDate.offset) / 60,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!offset.valueOf()) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const timeOffset = offset.toHuman({unitDisplay: 'short', signDisplay: 'never'});
|
||||||
|
|
||||||
|
return offset.valueOf() > 0 ? (
|
||||||
|
<FormattedMessage
|
||||||
|
id='user_profile.account.hoursAhead'
|
||||||
|
defaultMessage='({timeOffset} ahead)'
|
||||||
|
values={{timeOffset}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<FormattedMessage
|
||||||
|
id='user_profile.account.hoursBehind'
|
||||||
|
defaultMessage='({timeOffset} behind)'
|
||||||
|
values={{timeOffset}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ProfileTimezone = (
|
||||||
|
{
|
||||||
|
currentUserTimezone,
|
||||||
|
profileUserTimezone,
|
||||||
|
}: ProfileTimezoneProps,
|
||||||
|
) => {
|
||||||
|
const profileTimezone = getUserCurrentTimezone(profileUserTimezone) || 'UTC';
|
||||||
|
const profileTimezoneShort = profileTimezone ? DateTime.now().setZone(profileTimezone).offsetNameShort : undefined;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className='user-popover__time-status-container'
|
||||||
|
>
|
||||||
|
<span className='user-popover__subtitle'>
|
||||||
|
{profileTimezoneShort ? (
|
||||||
|
<FormattedMessage
|
||||||
|
id='user_profile.account.localTimeWithTimezone'
|
||||||
|
defaultMessage='Local Time ({timezone})'
|
||||||
|
values={{
|
||||||
|
timezone: profileTimezoneShort,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<FormattedMessage
|
||||||
|
id='user_profile.account.localTime'
|
||||||
|
defaultMessage='Local Time'
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
<Timestamp
|
||||||
|
useRelative={false}
|
||||||
|
useDate={false}
|
||||||
|
userTimezone={profileUserTimezone}
|
||||||
|
useTime={{
|
||||||
|
hour: 'numeric',
|
||||||
|
minute: 'numeric',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{' '}
|
||||||
|
{returnTimeDiff(currentUserTimezone, profileTimezone)}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -23,6 +23,8 @@ import {t} from 'utils/i18n';
|
|||||||
import * as Utils from 'utils/utils';
|
import * as Utils from 'utils/utils';
|
||||||
import {shouldFocusMainTextbox} from 'utils/post_utils';
|
import {shouldFocusMainTextbox} from 'utils/post_utils';
|
||||||
|
|
||||||
|
import {ProfileTimezone} from './profile_localtime';
|
||||||
|
|
||||||
import StatusIcon from 'components/status_icon';
|
import StatusIcon from 'components/status_icon';
|
||||||
import Timestamp from 'components/timestamp';
|
import Timestamp from 'components/timestamp';
|
||||||
import UserSettingsModal from 'components/user_settings/modal';
|
import UserSettingsModal from 'components/user_settings/modal';
|
||||||
@@ -574,27 +576,11 @@ class ProfilePopover extends React.PureComponent<ProfilePopoverProps, ProfilePop
|
|||||||
!haveOverrideProp
|
!haveOverrideProp
|
||||||
) {
|
) {
|
||||||
dataContent.push(
|
dataContent.push(
|
||||||
<div
|
<ProfileTimezone
|
||||||
|
currentUserTimezone={this.props.currentUserTimezone}
|
||||||
|
profileUserTimezone={this.props.user.timezone}
|
||||||
key='user-popover-local-time'
|
key='user-popover-local-time'
|
||||||
className='user-popover__time-status-container'
|
/>,
|
||||||
>
|
|
||||||
<span className='user-popover__subtitle' >
|
|
||||||
<FormattedMessage
|
|
||||||
id='user_profile.account.localTime'
|
|
||||||
defaultMessage='Local Time'
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
<Timestamp
|
|
||||||
useRelative={false}
|
|
||||||
useDate={false}
|
|
||||||
userTimezone={this.props.user?.timezone}
|
|
||||||
useTime={{
|
|
||||||
hour: 'numeric',
|
|
||||||
minute: 'numeric',
|
|
||||||
timeZoneName: 'short',
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5255,7 +5255,10 @@
|
|||||||
"user_groups_modal.viewGroup": "View Group",
|
"user_groups_modal.viewGroup": "View Group",
|
||||||
"user_list.notFound": "No users found",
|
"user_list.notFound": "No users found",
|
||||||
"user_profile.account.editProfile": "Edit Profile",
|
"user_profile.account.editProfile": "Edit Profile",
|
||||||
|
"user_profile.account.hoursAhead": "({timeOffset} ahead)",
|
||||||
|
"user_profile.account.hoursBehind": "({timeOffset} behind)",
|
||||||
"user_profile.account.localTime": "Local Time",
|
"user_profile.account.localTime": "Local Time",
|
||||||
|
"user_profile.account.localTimeWithTimezone": "Local Time ({timezone})",
|
||||||
"user_profile.account.post_was_created": "This post was created by an integration from",
|
"user_profile.account.post_was_created": "This post was created by an integration from",
|
||||||
"user_profile.add_user_to_channel": "Add to a Channel",
|
"user_profile.add_user_to_channel": "Add to a Channel",
|
||||||
"user_profile.add_user_to_channel.icon": "Add User to Channel Icon",
|
"user_profile.add_user_to_channel.icon": "Add User to Channel Icon",
|
||||||
|
|||||||
16
webapp/package-lock.json
сгенерированный
16
webapp/package-lock.json
сгенерированный
@@ -3598,7 +3598,7 @@
|
|||||||
"localforage": "1.10.0",
|
"localforage": "1.10.0",
|
||||||
"localforage-observable": "2.1.1",
|
"localforage-observable": "2.1.1",
|
||||||
"lodash": "4.17.21",
|
"lodash": "4.17.21",
|
||||||
"luxon": "3.0.4",
|
"luxon": "3.3.0",
|
||||||
"mark.js": "8.11.1",
|
"mark.js": "8.11.1",
|
||||||
"marked": "github:mattermost/marked#2ef7f28cc7718e3f551c4ce9ea75fdd7580c2008",
|
"marked": "github:mattermost/marked#2ef7f28cc7718e3f551c4ce9ea75fdd7580c2008",
|
||||||
"memoize-one": "6.0.0",
|
"memoize-one": "6.0.0",
|
||||||
@@ -24101,9 +24101,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/luxon": {
|
"node_modules/luxon": {
|
||||||
"version": "3.0.4",
|
"version": "3.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/luxon/-/luxon-3.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/luxon/-/luxon-3.3.0.tgz",
|
||||||
"integrity": "sha512-aV48rGUwP/Vydn8HT+5cdr26YYQiUZ42NM6ToMoaGKwYfWbfLeRkEu1wXWMHBZT6+KyLfcbbtVcoQFCbbPjKlw==",
|
"integrity": "sha512-An0UCfG/rSiqtAIiBPO0Y9/zAnHUZxAMiCpTd5h2smgsj7GGmcenvrvww2cqNA8/4A5ZrD1gJpHN2mIHZQF+Mg==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
@@ -54303,9 +54303,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"luxon": {
|
"luxon": {
|
||||||
"version": "3.0.4",
|
"version": "3.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/luxon/-/luxon-3.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/luxon/-/luxon-3.3.0.tgz",
|
||||||
"integrity": "sha512-aV48rGUwP/Vydn8HT+5cdr26YYQiUZ42NM6ToMoaGKwYfWbfLeRkEu1wXWMHBZT6+KyLfcbbtVcoQFCbbPjKlw=="
|
"integrity": "sha512-An0UCfG/rSiqtAIiBPO0Y9/zAnHUZxAMiCpTd5h2smgsj7GGmcenvrvww2cqNA8/4A5ZrD1gJpHN2mIHZQF+Mg=="
|
||||||
},
|
},
|
||||||
"lz-string": {
|
"lz-string": {
|
||||||
"version": "1.5.0",
|
"version": "1.5.0",
|
||||||
@@ -54521,7 +54521,7 @@
|
|||||||
"localforage": "1.10.0",
|
"localforage": "1.10.0",
|
||||||
"localforage-observable": "2.1.1",
|
"localforage-observable": "2.1.1",
|
||||||
"lodash": "4.17.21",
|
"lodash": "4.17.21",
|
||||||
"luxon": "3.0.4",
|
"luxon": "3.3.0",
|
||||||
"mark.js": "8.11.1",
|
"mark.js": "8.11.1",
|
||||||
"marked": "github:mattermost/marked#2ef7f28cc7718e3f551c4ce9ea75fdd7580c2008",
|
"marked": "github:mattermost/marked#2ef7f28cc7718e3f551c4ce9ea75fdd7580c2008",
|
||||||
"memoize-one": "6.0.0",
|
"memoize-one": "6.0.0",
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user