Remove t from post and post textbox components (#27056)

* Remove t from components/post_view/combined_system_message

* Remove t from components/post_view

* Remove t from components/post_markdown

* Remove t from components/size_aware_image

* Remove t from components/advanced_text_editor

* Remove t from components/advanced_create_post

* Remove t from components/notify_confirm_modal
Этот коммит содержится в:
Harrison Healey
2024-05-24 12:00:14 -04:00
коммит произвёл GitHub
родитель 86aced1282
Коммит 497870a565
12 изменённых файлов: 280 добавлений и 215 удалений

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

@@ -2,7 +2,7 @@
// See LICENSE.txt for license information. // See LICENSE.txt for license information.
import React, {useMemo, memo} from 'react'; import React, {useMemo, memo} from 'react';
import {useIntl} from 'react-intl'; import {defineMessage, useIntl} from 'react-intl';
import styled from 'styled-components'; import styled from 'styled-components';
import type {Channel} from '@mattermost/types/channels'; import type {Channel} from '@mattermost/types/channels';
@@ -11,8 +11,6 @@ import {trackEvent} from 'actions/telemetry_actions';
import Chip from 'components/common/chip/chip'; import Chip from 'components/common/chip/chip';
import {t} from 'utils/i18n';
type Props = { type Props = {
prefillMessage: (msg: string, shouldFocus: boolean) => void; prefillMessage: (msg: string, shouldFocus: boolean) => void;
currentChannel: Channel; currentChannel: Channel;
@@ -36,10 +34,14 @@ const PrewrittenChips = ({currentChannel, currentUserId, currentChannelTeammateU
const chips = useMemo(() => { const chips = useMemo(() => {
const customChip = { const customChip = {
event: 'prefilled_message_selected_custom', event: 'prefilled_message_selected_custom',
messageId: '', message: defineMessage({
message: '', id: '',
displayId: t('create_post.prewritten.custom'), defaultMessage: '',
display: 'Custom message...', }),
display: defineMessage({
id: 'create_post.prewritten.custom',
defaultMessage: 'Custom message...',
}),
leadingIcon: '', leadingIcon: '',
}; };
@@ -47,26 +49,38 @@ const PrewrittenChips = ({currentChannel, currentUserId, currentChannelTeammateU
return [ return [
{ {
event: 'prefilled_message_selected_team_hi', event: 'prefilled_message_selected_team_hi',
messageId: t('create_post.prewritten.tip.team_hi_message'), message: defineMessage({
message: ':wave: Hi team!', id: 'create_post.prewritten.tip.team_hi_message',
displayId: t('create_post.prewritten.tip.team_hi'), defaultMessage: ':wave: Hi team!',
display: 'Hi team!', }),
display: defineMessage({
id: 'create_post.prewritten.tip.team_hi',
defaultMessage: 'Hi team!',
}),
leadingIcon: 'wave', leadingIcon: 'wave',
}, },
{ {
event: 'prefilled_message_selected_team_excited', event: 'prefilled_message_selected_team_excited',
messageId: t('create_post.prewritten.tip.team_excited_message'), message: defineMessage({
message: ':raised_hands: Excited to be here!', id: 'create_post.prewritten.tip.team_excited_message',
displayId: t('create_post.prewritten.tip.team_excited'), defaultMessage: ':raised_hands: Excited to be here!',
display: 'Excited to be here!', }),
display: defineMessage({
id: 'create_post.prewritten.tip.team_excited',
defaultMessage: 'Excited to be here!',
}),
leadingIcon: 'raised_hands', leadingIcon: 'raised_hands',
}, },
{ {
event: 'prefilled_message_selected_team_hey', event: 'prefilled_message_selected_team_hey',
messageId: t('create_post.prewritten.tip.team_hey_message'), message: defineMessage({
message: ':smile: Hey everyone!', id: 'create_post.prewritten.tip.team_hey_message',
displayId: t('create_post.prewritten.tip.team_hey'), defaultMessage: ':smile: Hey everyone!',
display: 'Hey everyone!', }),
display: defineMessage({
id: 'create_post.prewritten.tip.team_hey',
defaultMessage: 'Hey everyone!',
}),
leadingIcon: 'smile', leadingIcon: 'smile',
}, },
customChip, customChip,
@@ -77,18 +91,26 @@ const PrewrittenChips = ({currentChannel, currentUserId, currentChannelTeammateU
return [ return [
{ {
event: 'prefilled_message_selected_self_note', event: 'prefilled_message_selected_self_note',
messageId: t('create_post.prewritten.tip.self_note'), message: defineMessage({
message: 'Note to self...', id: 'create_post.prewritten.tip.self_note',
displayId: t('create_post.prewritten.tip.self_note'), defaultMessage: 'Note to self...',
display: 'Note to self...', }),
display: defineMessage({
id: 'create_post.prewritten.tip.self_note',
defaultMessage: 'Note to self...',
}),
leadingIcon: '', leadingIcon: '',
}, },
{ {
event: 'prefilled_message_selected_self_should', event: 'prefilled_message_selected_self_should',
messageId: t('create_post.prewritten.tip.self_should'), message: defineMessage({
message: 'Tomorrow I should...', id: 'create_post.prewritten.tip.self_should',
displayId: t('create_post.prewritten.tip.self_should'), defaultMessage: 'Tomorrow I should...',
display: 'Tomorrow I should...', }),
display: defineMessage({
id: 'create_post.prewritten.tip.self_should',
defaultMessage: 'Tomorrow I should...',
}),
leadingIcon: '', leadingIcon: '',
}, },
customChip, customChip,
@@ -98,18 +120,26 @@ const PrewrittenChips = ({currentChannel, currentUserId, currentChannelTeammateU
return [ return [
{ {
event: 'prefilled_message_selected_dm_hey', event: 'prefilled_message_selected_dm_hey',
messageId: t('create_post.prewritten.tip.dm_hey_message'), message: defineMessage({
message: ':wave: Hey @{username}', id: 'create_post.prewritten.tip.dm_hey_message',
displayId: t('create_post.prewritten.tip.dm_hey'), defaultMessage: ':wave: Hey @{username}',
display: 'Hey', }),
display: defineMessage({
id: 'create_post.prewritten.tip.dm_hey',
defaultMessage: 'Hey',
}),
leadingIcon: 'wave', leadingIcon: 'wave',
}, },
{ {
event: 'prefilled_message_selected_dm_hello', event: 'prefilled_message_selected_dm_hello',
messageId: t('create_post.prewritten.tip.dm_hello_message'), message: defineMessage({
message: ':v: Oh hello', id: 'create_post.prewritten.tip.dm_hello_message',
displayId: t('create_post.prewritten.tip.dm_hello'), defaultMessage: ':v: Oh hello',
display: 'Oh hello', }),
display: defineMessage({
id: 'create_post.prewritten.tip.dm_hello',
defaultMessage: 'Oh hello',
}),
leadingIcon: 'v', leadingIcon: 'v',
}, },
customChip, customChip,
@@ -118,14 +148,14 @@ const PrewrittenChips = ({currentChannel, currentUserId, currentChannelTeammateU
return ( return (
<ChipContainer> <ChipContainer>
{chips.map(({event, messageId, message, displayId, display, leadingIcon}) => { {chips.map(({event, message, display, leadingIcon}) => {
const values = {username: currentChannelTeammateUsername}; const values = {username: currentChannelTeammateUsername};
const messageToPrefill = messageId ? formatMessage( const messageToPrefill = message.id ? formatMessage(
{id: messageId, defaultMessage: message}, message,
values, values,
) : message; ) : '';
const additionalMarkup = displayId === 'create_post.prewritten.tip.dm_hey' ? ( const additionalMarkup = message.id === 'create_post.prewritten.tip.dm_hey' ? (
<UsernameMention> <UsernameMention>
{'@'}{currentChannelTeammateUsername} {'@'}{currentChannelTeammateUsername}
</UsernameMention> </UsernameMention>
@@ -133,9 +163,9 @@ const PrewrittenChips = ({currentChannel, currentUserId, currentChannelTeammateU
return ( return (
<Chip <Chip
key={displayId} key={display.id}
id={displayId} id={display.id}
defaultMessage={display} defaultMessage={display.defaultMessage}
additionalMarkup={additionalMarkup} additionalMarkup={additionalMarkup}
values={values} values={values}
onClick={() => { onClick={() => {
@@ -144,7 +174,7 @@ const PrewrittenChips = ({currentChannel, currentUserId, currentChannelTeammateU
} }
prefillMessage(messageToPrefill, true); prefillMessage(messageToPrefill, true);
}} }}
otherOption={!messageId} otherOption={!message.id}
leadingIcon={leadingIcon} leadingIcon={leadingIcon}
/> />
); );

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

@@ -2,7 +2,7 @@
// See LICENSE.txt for license information. // See LICENSE.txt for license information.
import React, {memo} from 'react'; import React, {memo} from 'react';
import {useIntl} from 'react-intl'; import {defineMessages, useIntl} from 'react-intl';
import type {MessageDescriptor} from 'react-intl'; import type {MessageDescriptor} from 'react-intl';
import styled from 'styled-components'; import styled from 'styled-components';
@@ -28,7 +28,6 @@ import OverlayTrigger from 'components/overlay_trigger';
import Tooltip from 'components/tooltip'; import Tooltip from 'components/tooltip';
import Constants from 'utils/constants'; import Constants from 'utils/constants';
import {t} from 'utils/i18n';
import type {MarkdownMode} from 'utils/markdown/apply_markdown'; import type {MarkdownMode} from 'utils/markdown/apply_markdown';
export const IconContainer = styled.button` export const IconContainer = styled.button`
@@ -93,17 +92,17 @@ const MAP_MARKDOWN_MODE_TO_ICON: Record<FormattingIconProps['mode'], React.FC<Ic
ol: FormatListNumberedIcon, ol: FormatListNumberedIcon,
}; };
const MAP_MARKDOWN_MODE_TO_ARIA_LABEL: Record<FormattingIconProps['mode'], MessageDescriptor> = { const MAP_MARKDOWN_MODE_TO_ARIA_LABEL: Record<FormattingIconProps['mode'], MessageDescriptor> = defineMessages({
bold: {id: t('accessibility.button.bold'), defaultMessage: 'bold'}, bold: {id: 'accessibility.button.bold', defaultMessage: 'bold'},
italic: {id: t('accessibility.button.italic'), defaultMessage: 'italic'}, italic: {id: 'accessibility.button.italic', defaultMessage: 'italic'},
link: {id: t('accessibility.button.link'), defaultMessage: 'link'}, link: {id: 'accessibility.button.link', defaultMessage: 'link'},
strike: {id: t('accessibility.button.strike'), defaultMessage: 'strike through'}, strike: {id: 'accessibility.button.strike', defaultMessage: 'strike through'},
code: {id: t('accessibility.button.code'), defaultMessage: 'code'}, code: {id: 'accessibility.button.code', defaultMessage: 'code'},
heading: {id: t('accessibility.button.heading'), defaultMessage: 'heading'}, heading: {id: 'accessibility.button.heading', defaultMessage: 'heading'},
quote: {id: t('accessibility.button.quote'), defaultMessage: 'quote'}, quote: {id: 'accessibility.button.quote', defaultMessage: 'quote'},
ul: {id: t('accessibility.button.bulleted_list'), defaultMessage: 'bulleted list'}, ul: {id: 'accessibility.button.bulleted_list', defaultMessage: 'bulleted list'},
ol: {id: t('accessibility.button.numbered_list'), defaultMessage: 'numbered list'}, ol: {id: 'accessibility.button.numbered_list', defaultMessage: 'numbered list'},
}; });
const MAP_MARKDOWN_MODE_TO_KEYBOARD_SHORTCUTS: Record<FormattingIconProps['mode'], KeyboardShortcutDescriptor> = { const MAP_MARKDOWN_MODE_TO_KEYBOARD_SHORTCUTS: Record<FormattingIconProps['mode'], KeyboardShortcutDescriptor> = {
bold: KEYBOARD_SHORTCUTS.msgMarkdownBold, bold: KEYBOARD_SHORTCUTS.msgMarkdownBold,

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

@@ -7,8 +7,6 @@ import styled from 'styled-components';
import {SendIcon} from '@mattermost/compass-icons/components'; import {SendIcon} from '@mattermost/compass-icons/components';
import {t} from 'utils/i18n';
type SendButtonProps = { type SendButtonProps = {
handleSubmit: (e: React.FormEvent) => void; handleSubmit: (e: React.FormEvent) => void;
disabled: boolean; disabled: boolean;
@@ -66,7 +64,7 @@ const SendButton = ({disabled, handleSubmit}: SendButtonProps) => {
size={18} size={18}
color='currentColor' color='currentColor'
aria-label={formatMessage({ aria-label={formatMessage({
id: t('create_post.icon'), id: 'create_post.icon',
defaultMessage: 'Create a post', defaultMessage: 'Create a post',
})} })}
/> />

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

@@ -2,13 +2,11 @@
// See LICENSE.txt for license information. // See LICENSE.txt for license information.
import React from 'react'; import React from 'react';
import {FormattedMessage} from 'react-intl'; import {FormattedMessage, defineMessages} from 'react-intl';
import ConfirmModalRedux from 'components/confirm_modal_redux'; import ConfirmModalRedux from 'components/confirm_modal_redux';
import FormattedMarkdownMessage from 'components/formatted_markdown_message'; import FormattedMarkdownMessage from 'components/formatted_markdown_message';
import {t} from 'utils/i18n';
type Props = { type Props = {
mentions: string[]; mentions: string[];
memberNotifyCount: number; memberNotifyCount: number;
@@ -31,14 +29,10 @@ export default class NotifyConfirmModal extends React.PureComponent<Props> {
/> />
); );
if (channelTimezoneCount > 0) { if (channelTimezoneCount > 0) {
const atHereMsg = 'By using **@here** you are about to send notifications to up to **{totalMembers} other people** in **{timezones, number} {timezones, plural, one {timezone} other {timezones}}**. Are you sure you want to do this?'; const message = mentions.length === 1 && mentions[0] === '@here' ? messages.atHereTimezones : messages.atAllTimezones;
const atAllChannelMsg = 'By using **@all** or **@channel** you are about to send notifications to **{totalMembers} people** in **{timezones, number} {timezones, plural, one {timezone} other {timezones}}**. Are you sure you want to do this?';
const msg = mentions.length === 1 && mentions[0] === '@here' ? atHereMsg : atAllChannelMsg;
const msgID = mentions.length === 1 && mentions[0] === '@here' ? t('notify_here.question_timezone') : t('notify_all.question_timezone');
notifyAllMessage = ( notifyAllMessage = (
<FormattedMarkdownMessage <FormattedMarkdownMessage
id={msgID} {...message}
defaultMessage={msg}
values={{ values={{
totalMembers: memberNotifyCount, totalMembers: memberNotifyCount,
timezones: channelTimezoneCount, timezones: channelTimezoneCount,
@@ -46,14 +40,10 @@ export default class NotifyConfirmModal extends React.PureComponent<Props> {
/> />
); );
} else { } else {
const atHereMsg = 'By using **@here** you are about to send notifications to up to **{totalMembers} other people**. Are you sure you want to do this?'; const message = mentions.length === 1 && mentions[0] === '@here' ? messages.atHere : messages.atAll;
const atAllChannelMsg = 'By using **@all** or **@channel** you are about to send notifications to **{totalMembers} people**. Are you sure you want to do this?';
const msg = mentions.length === 1 && mentions[0] === '@here' ? atHereMsg : atAllChannelMsg;
const msgID = mentions.length === 1 && mentions[0] === '@here' ? t('notify_here.question') : t('notify_all.question');
notifyAllMessage = ( notifyAllMessage = (
<FormattedMarkdownMessage <FormattedMarkdownMessage
id={msgID} {...message}
defaultMessage={msg}
values={{ values={{
totalMembers: memberNotifyCount, totalMembers: memberNotifyCount,
}} }}
@@ -139,3 +129,22 @@ export default class NotifyConfirmModal extends React.PureComponent<Props> {
); );
} }
} }
const messages = defineMessages({
atAll: {
id: 'notify_all.question',
defaultMessage: 'By using **@all** or **@channel** you are about to send notifications to **{totalMembers} people**. Are you sure you want to do this?',
},
atAllTimezones: {
id: 'notify_all.question_timezone',
defaultMessage: 'By using **@all** or **@channel** you are about to send notifications to **{totalMembers} people** in **{timezones, number} {timezones, plural, one {timezone} other {timezones}}**. Are you sure you want to do this?',
},
atHere: {
id: 'notify_here.question',
defaultMessage: 'By using **@here** you are about to send notifications to up to **{totalMembers} other people**. Are you sure you want to do this?',
},
atHereTimezones: {
id: 'notify_here.question_timezone',
defaultMessage: 'By using **@here** you are about to send notifications to up to **{totalMembers} other people** in **{timezones, number} {timezones, plural, one {timezone} other {timezones}}**. Are you sure you want to do this?',
},
});

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

@@ -3,7 +3,7 @@
import React from 'react'; import React from 'react';
import type {ReactNode} from 'react'; import type {ReactNode} from 'react';
import {FormattedDate, FormattedMessage, FormattedTime} from 'react-intl'; import {FormattedDate, FormattedMessage, FormattedTime, defineMessages} from 'react-intl';
import type {Channel} from '@mattermost/types/channels'; import type {Channel} from '@mattermost/types/channels';
import type {Post} from '@mattermost/types/posts'; import type {Post} from '@mattermost/types/posts';
@@ -17,7 +17,6 @@ import CombinedSystemMessage from 'components/post_view/combined_system_message'
import GMConversionMessage from 'components/post_view/gm_conversion_message/gm_conversion_message'; import GMConversionMessage from 'components/post_view/gm_conversion_message/gm_conversion_message';
import PostAddChannelMember from 'components/post_view/post_add_channel_member'; import PostAddChannelMember from 'components/post_view/post_add_channel_member';
import {t} from 'utils/i18n';
import type {TextFormattingOptions} from 'utils/text_formatting'; import type {TextFormattingOptions} from 'utils/text_formatting';
import {getSiteURL} from 'utils/url'; import {getSiteURL} from 'utils/url';
@@ -491,20 +490,39 @@ export function renderReminderSystemBotMessage(post: Post, currentTeam: Team): R
); );
} }
t('app.post.move_thread_command.direct_or_group.multiple_messages'); // These messages are used by app.MoveThread on the server
t('app.post.move_thread_command.direct_or_group.one_message'); defineMessages({
t('app.post.move_thread_command.channel.multiple_messages'); channelMultipleMessages: {
t('app.post.move_thread_command.channel.one_message'); id: 'app.post.move_thread_command.channel.multiple_messages',
t('app.post.move_thread.from_another_channel'); defaultMessage: 'A thread with {numMessages, number} messages has been moved: {link}\n',
},
channelOneMessage: {
id: 'app.post.move_thread_command.channel.one_message',
defaultMessage: 'A message has been moved: {link}\n',
},
dmMultipleMessages: {
id: 'app.post.move_thread_command.direct_or_group.multiple_messages',
defaultMessage: 'A thread with {numMessages, number} messages has been moved to a Direct/Group Message\n',
},
dmOneMessage: {
id: 'app.post.move_thread_command.direct_or_group.one_message',
defaultMessage: 'A message has been moved to a Direct/Group Message\n',
},
fromAnotherChannel: {
id: 'app.post.move_thread.from_another_channel',
defaultMessage: 'This thread was moved from another channel',
},
});
export function renderWranglerSystemMessage(post: Post): ReactNode { export function renderWranglerSystemMessage(post: Post): ReactNode {
let values = {} as any; let values = {} as any;
const id = post.props.TranslationID; const id = post.props.TranslationID;
if (post.props && post.props.MovedThreadPermalink) { if (post.props && post.props.MovedThreadPermalink) {
values = { values = {
Link: post.props.MovedThreadPermalink, link: post.props.MovedThreadPermalink,
}; };
if (post.props.NumMessages > 1) { if (post.props.NumMessages > 1) {
values.NumMessages = post.props.NumMessages; values.number = post.props.NumMessages;
} }
} }
return ( return (

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

@@ -2,7 +2,7 @@
// See LICENSE.txt for license information. // See LICENSE.txt for license information.
import React from 'react'; import React from 'react';
import {injectIntl} from 'react-intl'; import {defineMessages, injectIntl} from 'react-intl';
import type {IntlShape, MessageDescriptor} from 'react-intl'; import type {IntlShape, MessageDescriptor} from 'react-intl';
import type {UserProfile} from '@mattermost/types/users'; import type {UserProfile} from '@mattermost/types/users';
@@ -11,8 +11,6 @@ import {Posts} from 'mattermost-redux/constants';
import Markdown from 'components/markdown'; import Markdown from 'components/markdown';
import {t} from 'utils/i18n';
import LastUsers from './last_users'; import LastUsers from './last_users';
const { const {
@@ -21,168 +19,168 @@ const {
} = Posts.POST_TYPES; } = Posts.POST_TYPES;
const postTypeMessage = { const postTypeMessage = {
[JOIN_CHANNEL]: { [JOIN_CHANNEL]: defineMessages({
one: { one: {
id: t('combined_system_message.joined_channel.one'), id: 'combined_system_message.joined_channel.one',
defaultMessage: '{firstUser} **joined the channel**.', defaultMessage: '{firstUser} **joined the channel**.',
}, },
one_you: { one_you: {
id: t('combined_system_message.joined_channel.one_you'), id: 'combined_system_message.joined_channel.one_you',
defaultMessage: 'You **joined the channel**.', defaultMessage: 'You **joined the channel**.',
}, },
two: { two: {
id: t('combined_system_message.joined_channel.two'), id: 'combined_system_message.joined_channel.two',
defaultMessage: '{firstUser} and {secondUser} **joined the channel**.', defaultMessage: '{firstUser} and {secondUser} **joined the channel**.',
}, },
many_expanded: { many_expanded: {
id: t('combined_system_message.joined_channel.many_expanded'), id: 'combined_system_message.joined_channel.many_expanded',
defaultMessage: '{users} and {lastUser} **joined the channel**.', defaultMessage: '{users} and {lastUser} **joined the channel**.',
}, },
}, }),
[ADD_TO_CHANNEL]: { [ADD_TO_CHANNEL]: defineMessages({
one: { one: {
id: t('combined_system_message.added_to_channel.one'), id: 'combined_system_message.added_to_channel.one',
defaultMessage: '{firstUser} **added to the channel** by {actor}.', defaultMessage: '{firstUser} **added to the channel** by {actor}.',
}, },
one_you: { one_you: {
id: t('combined_system_message.added_to_channel.one_you'), id: 'combined_system_message.added_to_channel.one_you',
defaultMessage: 'You were **added to the channel** by {actor}.', defaultMessage: 'You were **added to the channel** by {actor}.',
}, },
two: { two: {
id: t('combined_system_message.added_to_channel.two'), id: 'combined_system_message.added_to_channel.two',
defaultMessage: '{firstUser} and {secondUser} **added to the channel** by {actor}.', defaultMessage: '{firstUser} and {secondUser} **added to the channel** by {actor}.',
}, },
many_expanded: { many_expanded: {
id: t('combined_system_message.added_to_channel.many_expanded'), id: 'combined_system_message.added_to_channel.many_expanded',
defaultMessage: '{users} and {lastUser} were **added to the channel** by {actor}.', defaultMessage: '{users} and {lastUser} were **added to the channel** by {actor}.',
}, },
}, }),
[REMOVE_FROM_CHANNEL]: { [REMOVE_FROM_CHANNEL]: defineMessages({
one: { one: {
id: t('combined_system_message.removed_from_channel.one'), id: 'combined_system_message.removed_from_channel.one',
defaultMessage: '{firstUser} was **removed from the channel**.', defaultMessage: '{firstUser} was **removed from the channel**.',
}, },
one_you: { one_you: {
id: t('combined_system_message.removed_from_channel.one_you'), id: 'combined_system_message.removed_from_channel.one_you',
defaultMessage: 'You were **removed from the channel**.', defaultMessage: 'You were **removed from the channel**.',
}, },
two: { two: {
id: t('combined_system_message.removed_from_channel.two'), id: 'combined_system_message.removed_from_channel.two',
defaultMessage: '{firstUser} and {secondUser} were **removed from the channel**.', defaultMessage: '{firstUser} and {secondUser} were **removed from the channel**.',
}, },
many_expanded: { many_expanded: {
id: t('combined_system_message.removed_from_channel.many_expanded'), id: 'combined_system_message.removed_from_channel.many_expanded',
defaultMessage: '{users} and {lastUser} were **removed from the channel**.', defaultMessage: '{users} and {lastUser} were **removed from the channel**.',
}, },
}, }),
[LEAVE_CHANNEL]: { [LEAVE_CHANNEL]: defineMessages({
one: { one: {
id: t('combined_system_message.left_channel.one'), id: 'combined_system_message.left_channel.one',
defaultMessage: '{firstUser} **left the channel**.', defaultMessage: '{firstUser} **left the channel**.',
}, },
one_you: { one_you: {
id: t('combined_system_message.left_channel.one_you'), id: 'combined_system_message.left_channel.one_you',
defaultMessage: 'You **left the channel**.', defaultMessage: 'You **left the channel**.',
}, },
two: { two: {
id: t('combined_system_message.left_channel.two'), id: 'combined_system_message.left_channel.two',
defaultMessage: '{firstUser} and {secondUser} **left the channel**.', defaultMessage: '{firstUser} and {secondUser} **left the channel**.',
}, },
many_expanded: { many_expanded: {
id: t('combined_system_message.left_channel.many_expanded'), id: 'combined_system_message.left_channel.many_expanded',
defaultMessage: '{users} and {lastUser} **left the channel**.', defaultMessage: '{users} and {lastUser} **left the channel**.',
}, },
}, }),
[JOIN_LEAVE_CHANNEL]: { [JOIN_LEAVE_CHANNEL]: defineMessages({
one: { one: {
id: t('combined_system_message.join_left_channel.one'), id: 'combined_system_message.join_left_channel.one',
defaultMessage: '{firstUser} **joined and left the channel**.', defaultMessage: '{firstUser} **joined and left the channel**.',
}, },
one_you: { one_you: {
id: t('combined_system_message.join_left_channel.one_you'), id: 'combined_system_message.join_left_channel.one_you',
defaultMessage: 'You **joined and left the channel**.', defaultMessage: 'You **joined and left the channel**.',
}, },
two: { two: {
id: t('combined_system_message.join_left_channel.two'), id: 'combined_system_message.join_left_channel.two',
defaultMessage: '{firstUser} and {secondUser} **joined and left the channel**.', defaultMessage: '{firstUser} and {secondUser} **joined and left the channel**.',
}, },
many_expanded: { many_expanded: {
id: t('combined_system_message.join_left_channel.many_expanded'), id: 'combined_system_message.join_left_channel.many_expanded',
defaultMessage: '{users} and {lastUser} **joined and left the channel**.', defaultMessage: '{users} and {lastUser} **joined and left the channel**.',
}, },
}, }),
[JOIN_TEAM]: { [JOIN_TEAM]: defineMessages({
one: { one: {
id: t('combined_system_message.joined_team.one'), id: 'combined_system_message.joined_team.one',
defaultMessage: '{firstUser} **joined the team**.', defaultMessage: '{firstUser} **joined the team**.',
}, },
one_you: { one_you: {
id: t('combined_system_message.joined_team.one_you'), id: 'combined_system_message.joined_team.one_you',
defaultMessage: 'You **joined the team**.', defaultMessage: 'You **joined the team**.',
}, },
two: { two: {
id: t('combined_system_message.joined_team.two'), id: 'combined_system_message.joined_team.two',
defaultMessage: '{firstUser} and {secondUser} **joined the team**.', defaultMessage: '{firstUser} and {secondUser} **joined the team**.',
}, },
many_expanded: { many_expanded: {
id: t('combined_system_message.joined_team.many_expanded'), id: 'combined_system_message.joined_team.many_expanded',
defaultMessage: '{users} and {lastUser} **joined the team**.', defaultMessage: '{users} and {lastUser} **joined the team**.',
}, },
}, }),
[ADD_TO_TEAM]: { [ADD_TO_TEAM]: defineMessages({
one: { one: {
id: t('combined_system_message.added_to_team.one'), id: 'combined_system_message.added_to_team.one',
defaultMessage: '{firstUser} **added to the team** by {actor}.', defaultMessage: '{firstUser} **added to the team** by {actor}.',
}, },
one_you: { one_you: {
id: t('combined_system_message.added_to_team.one_you'), id: 'combined_system_message.added_to_team.one_you',
defaultMessage: 'You were **added to the team** by {actor}.', defaultMessage: 'You were **added to the team** by {actor}.',
}, },
two: { two: {
id: t('combined_system_message.added_to_team.two'), id: 'combined_system_message.added_to_team.two',
defaultMessage: '{firstUser} and {secondUser} **added to the team** by {actor}.', defaultMessage: '{firstUser} and {secondUser} **added to the team** by {actor}.',
}, },
many_expanded: { many_expanded: {
id: t('combined_system_message.added_to_team.many_expanded'), id: 'combined_system_message.added_to_team.many_expanded',
defaultMessage: '{users} and {lastUser} were **added to the team** by {actor}.', defaultMessage: '{users} and {lastUser} were **added to the team** by {actor}.',
}, },
}, }),
[REMOVE_FROM_TEAM]: { [REMOVE_FROM_TEAM]: defineMessages({
one: { one: {
id: t('combined_system_message.removed_from_team.one'), id: 'combined_system_message.removed_from_team.one',
defaultMessage: '{firstUser} was **removed from the team**.', defaultMessage: '{firstUser} was **removed from the team**.',
}, },
one_you: { one_you: {
id: t('combined_system_message.removed_from_team.one_you'), id: 'combined_system_message.removed_from_team.one_you',
defaultMessage: 'You were **removed from the team**.', defaultMessage: 'You were **removed from the team**.',
}, },
two: { two: {
id: t('combined_system_message.removed_from_team.two'), id: 'combined_system_message.removed_from_team.two',
defaultMessage: '{firstUser} and {secondUser} were **removed from the team**.', defaultMessage: '{firstUser} and {secondUser} were **removed from the team**.',
}, },
many_expanded: { many_expanded: {
id: t('combined_system_message.removed_from_team.many_expanded'), id: 'combined_system_message.removed_from_team.many_expanded',
defaultMessage: '{users} and {lastUser} were **removed from the team**.', defaultMessage: '{users} and {lastUser} were **removed from the team**.',
}, },
}, }),
[LEAVE_TEAM]: { [LEAVE_TEAM]: defineMessages({
one: { one: {
id: t('combined_system_message.left_team.one'), id: 'combined_system_message.left_team.one',
defaultMessage: '{firstUser} **left the team**.', defaultMessage: '{firstUser} **left the team**.',
}, },
one_you: { one_you: {
id: t('combined_system_message.left_team.one_you'), id: 'combined_system_message.left_team.one_you',
defaultMessage: 'You **left the team**.', defaultMessage: 'You **left the team**.',
}, },
two: { two: {
id: t('combined_system_message.left_team.two'), id: 'combined_system_message.left_team.two',
defaultMessage: '{firstUser} and {secondUser} **left the team**.', defaultMessage: '{firstUser} and {secondUser} **left the team**.',
}, },
many_expanded: { many_expanded: {
id: t('combined_system_message.left_team.many_expanded'), id: 'combined_system_message.left_team.many_expanded',
defaultMessage: '{users} and {lastUser} **left the team**.', defaultMessage: '{users} and {lastUser} **left the team**.',
}, },
}, }),
}; };
export type Props = { export type Props = {
@@ -246,7 +244,7 @@ export class CombinedSystemMessage extends React.PureComponent<Props> {
return acc; return acc;
}, {}); }, {});
const currentUserDisplayName = formatMessage({id: t('combined_system_message.you'), defaultMessage: 'You'}); const currentUserDisplayName = formatMessage({id: 'combined_system_message.you', defaultMessage: 'You'});
if (allUserIds.includes(currentUserId)) { if (allUserIds.includes(currentUserId)) {
usernames[currentUserId] = currentUserDisplayName; usernames[currentUserId] = currentUserDisplayName;
} else if (allUsernames.includes(currentUsername)) { } else if (allUsernames.includes(currentUsername)) {
@@ -262,7 +260,7 @@ export class CombinedSystemMessage extends React.PureComponent<Props> {
const allUsernames = this.getAllUsernames(); const allUsernames = this.getAllUsernames();
const {formatMessage} = this.props.intl; const {formatMessage} = this.props.intl;
const someone = formatMessage({id: t('channel_loader.someone'), defaultMessage: 'Someone'}); const someone = formatMessage({id: 'channel_loader.someone', defaultMessage: 'Someone'});
const usernames = userIdsArray. const usernames = userIdsArray.
filter((userId) => { filter((userId) => {

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

@@ -2,54 +2,53 @@
// See LICENSE.txt for license information. // See LICENSE.txt for license information.
import React from 'react'; import React from 'react';
import {injectIntl} from 'react-intl'; import {defineMessages, injectIntl} from 'react-intl';
import type {IntlShape, MessageDescriptor} from 'react-intl'; import type {IntlShape, MessageDescriptor} from 'react-intl';
import {Posts} from 'mattermost-redux/constants'; import {Posts} from 'mattermost-redux/constants';
import Markdown from 'components/markdown'; import Markdown from 'components/markdown';
import {t} from 'utils/i18n';
import type {TextFormattingOptions} from 'utils/text_formatting'; import type {TextFormattingOptions} from 'utils/text_formatting';
const typeMessage = { const typeMessage = defineMessages({
[Posts.POST_TYPES.ADD_TO_CHANNEL]: { [Posts.POST_TYPES.ADD_TO_CHANNEL]: {
id: t('last_users_message.added_to_channel.type'), id: 'last_users_message.added_to_channel.type',
defaultMessage: 'were **added to the channel** by {actor}.', defaultMessage: 'were **added to the channel** by {actor}.',
}, },
[Posts.POST_TYPES.JOIN_CHANNEL]: { [Posts.POST_TYPES.JOIN_CHANNEL]: {
id: t('last_users_message.joined_channel.type'), id: 'last_users_message.joined_channel.type',
defaultMessage: '**joined the channel**.', defaultMessage: '**joined the channel**.',
}, },
[Posts.POST_TYPES.LEAVE_CHANNEL]: { [Posts.POST_TYPES.LEAVE_CHANNEL]: {
id: t('last_users_message.left_channel.type'), id: 'last_users_message.left_channel.type',
defaultMessage: '**left the channel**.', defaultMessage: '**left the channel**.',
}, },
[Posts.POST_TYPES.JOIN_LEAVE_CHANNEL]: { [Posts.POST_TYPES.JOIN_LEAVE_CHANNEL]: {
id: t('last_users_message.joined_left_channel.type'), id: 'last_users_message.joined_left_channel.type',
defaultMessage: '**joined and left the channel**.', defaultMessage: '**joined and left the channel**.',
}, },
[Posts.POST_TYPES.REMOVE_FROM_CHANNEL]: { [Posts.POST_TYPES.REMOVE_FROM_CHANNEL]: {
id: t('last_users_message.removed_from_channel.type'), id: 'last_users_message.removed_from_channel.type',
defaultMessage: 'were **removed from the channel**.', defaultMessage: 'were **removed from the channel**.',
}, },
[Posts.POST_TYPES.ADD_TO_TEAM]: { [Posts.POST_TYPES.ADD_TO_TEAM]: {
id: t('last_users_message.added_to_team.type'), id: 'last_users_message.added_to_team.type',
defaultMessage: 'were **added to the team** by {actor}.', defaultMessage: 'were **added to the team** by {actor}.',
}, },
[Posts.POST_TYPES.JOIN_TEAM]: { [Posts.POST_TYPES.JOIN_TEAM]: {
id: t('last_users_message.joined_team.type'), id: 'last_users_message.joined_team.type',
defaultMessage: '**joined the team**.', defaultMessage: '**joined the team**.',
}, },
[Posts.POST_TYPES.LEAVE_TEAM]: { [Posts.POST_TYPES.LEAVE_TEAM]: {
id: t('last_users_message.left_team.type'), id: 'last_users_message.left_team.type',
defaultMessage: '**left the team**.', defaultMessage: '**left the team**.',
}, },
[Posts.POST_TYPES.REMOVE_FROM_TEAM]: { [Posts.POST_TYPES.REMOVE_FROM_TEAM]: {
id: t('last_users_message.removed_from_team.type'), id: 'last_users_message.removed_from_team.type',
defaultMessage: 'were **removed from the team**.', defaultMessage: 'were **removed from the team**.',
}, },
}; });
type Props = { type Props = {
actor?: string; actor?: string;

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

@@ -12,7 +12,6 @@ import {sendAddToChannelEphemeralPost} from 'actions/global_actions';
import AtMention from 'components/at_mention'; import AtMention from 'components/at_mention';
import {Constants} from 'utils/constants'; import {Constants} from 'utils/constants';
import {t} from 'utils/i18n';
interface Actions { interface Actions {
addChannelMember: (channelId: string, userId: string, rootId: string) => void; addChannelMember: (channelId: string, userId: string, rootId: string) => void;
@@ -152,33 +151,50 @@ export default class PostAddChannelMember extends React.PureComponent<Props, Sta
return null; return null;
} }
let linkId; let link;
let linkText;
if (channelType === Constants.PRIVATE_CHANNEL) { if (channelType === Constants.PRIVATE_CHANNEL) {
linkId = t('post_body.check_for_out_of_channel_mentions.link.private'); link = (
linkText = 'add them to this private channel'; <FormattedMessage
id='post_body.check_for_out_of_channel_mentions.link.private'
defaultMessage='add them to this private channel'
/>
);
} else if (channelType === Constants.OPEN_CHANNEL) { } else if (channelType === Constants.OPEN_CHANNEL) {
linkId = t('post_body.check_for_out_of_channel_mentions.link.public'); link = (
linkText = 'add them to the channel'; <FormattedMessage
id='post_body.check_for_out_of_channel_mentions.link.public'
defaultMessage='add them to the channel'
/>
);
} }
let outOfChannelMessageID; let outOfChannelMessagePart;
let outOfChannelMessageText;
const outOfChannelAtMentions = this.generateAtMentions(usernames); const outOfChannelAtMentions = this.generateAtMentions(usernames);
if (usernames.length === 1) { if (usernames.length === 1) {
outOfChannelMessageID = t('post_body.check_for_out_of_channel_mentions.message.one'); outOfChannelMessagePart = (
outOfChannelMessageText = 'did not get notified by this mention because they are not in the channel. Would you like to '; <FormattedMessage
id='post_body.check_for_out_of_channel_mentions.message.one'
defaultMessage='did not get notified by this mention because they are not in the channel. Would you like to '
/>
);
} else if (usernames.length > 1) { } else if (usernames.length > 1) {
outOfChannelMessageID = t('post_body.check_for_out_of_channel_mentions.message.multiple'); outOfChannelMessagePart = (
outOfChannelMessageText = 'did not get notified by this mention because they are not in the channel. Would you like to '; <FormattedMessage
id='post_body.check_for_out_of_channel_mentions.message.multiple'
defaultMessage='did not get notified by this mention because they are not in the channel. Would you like to '
/>
);
} }
let outOfGroupsMessageID; let outOfGroupsMessagePart;
let outOfGroupsMessageText;
const outOfGroupsAtMentions = this.generateAtMentions(noGroupsUsernames); const outOfGroupsAtMentions = this.generateAtMentions(noGroupsUsernames);
if (noGroupsUsernames.length) { if (noGroupsUsernames.length) {
outOfGroupsMessageID = t('post_body.check_for_out_of_channel_groups_mentions.message'); outOfGroupsMessagePart = (
outOfGroupsMessageText = 'did not get notified by this mention because they are not in the channel. They cannot be added to the channel because they are not a member of the linked groups. To add them to this channel, they must be added to the linked groups.'; <FormattedMessage
id='post_body.check_for_out_of_channel_groups_mentions.message'
defaultMessage='did not get notified by this mention because they are not in the channel. They cannot be added to the channel because they are not a member of the linked groups. To add them to this channel, they must be added to the linked groups.'
/>
);
} }
let outOfChannelMessage = null; let outOfChannelMessage = null;
@@ -189,18 +205,12 @@ export default class PostAddChannelMember extends React.PureComponent<Props, Sta
<p> <p>
{outOfChannelAtMentions} {outOfChannelAtMentions}
{' '} {' '}
<FormattedMessage {outOfChannelMessagePart}
id={outOfChannelMessageID}
defaultMessage={outOfChannelMessageText}
/>
<a <a
className='PostBody_addChannelMemberLink' className='PostBody_addChannelMemberLink'
onClick={this.handleAddChannelMember} onClick={this.handleAddChannelMember}
> >
<FormattedMessage {link}
id={linkId}
defaultMessage={linkText}
/>
</a> </a>
<FormattedMessage <FormattedMessage
id={'post_body.check_for_out_of_channel_mentions.message_last'} id={'post_body.check_for_out_of_channel_mentions.message_last'}
@@ -215,10 +225,7 @@ export default class PostAddChannelMember extends React.PureComponent<Props, Sta
<p> <p>
{outOfGroupsAtMentions} {outOfGroupsAtMentions}
{' '} {' '}
<FormattedMessage {outOfGroupsMessagePart}
id={outOfGroupsMessageID}
defaultMessage={outOfGroupsMessageText}
/>
</p> </p>
); );
} }

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

@@ -3,7 +3,7 @@
import classNames from 'classnames'; import classNames from 'classnames';
import React, {useCallback, useEffect, useRef, useState} from 'react'; import React, {useCallback, useEffect, useRef, useState} from 'react';
import {FormattedMessage} from 'react-intl'; import {FormattedMessage, useIntl} from 'react-intl';
import OverlayTrigger from 'components/overlay_trigger'; import OverlayTrigger from 'components/overlay_trigger';
import Tooltip from 'components/tooltip'; import Tooltip from 'components/tooltip';
@@ -11,8 +11,6 @@ import FlagIcon from 'components/widgets/icons/flag_icon';
import FlagIconFilled from 'components/widgets/icons/flag_icon_filled'; import FlagIconFilled from 'components/widgets/icons/flag_icon_filled';
import Constants, {Locations, A11yCustomEventTypes} from 'utils/constants'; import Constants, {Locations, A11yCustomEventTypes} from 'utils/constants';
import {t} from 'utils/i18n';
import {localizeMessage} from 'utils/utils';
export type Actions = { export type Actions = {
flagPost: (postId: string) => void; flagPost: (postId: string) => void;
@@ -35,6 +33,8 @@ const PostFlagIcon = ({
postId, postId,
location = Locations.CENTER, location = Locations.CENTER,
}: Props) => { }: Props) => {
const intl = useIntl();
const buttonRef = useRef<HTMLButtonElement>(null); const buttonRef = useRef<HTMLButtonElement>(null);
const [a11yActive, setA11yActive] = useState(false); const [a11yActive, setA11yActive] = useState(false);
@@ -92,17 +92,24 @@ const PostFlagIcon = ({
id='flagTooltip' id='flagTooltip'
className='hidden-xs' className='hidden-xs'
> >
<FormattedMessage {isFlagged ? (
id={isFlagged ? t('flag_post.unflag') : t('flag_post.flag')} <FormattedMessage
defaultMessage={isFlagged ? 'Remove from Saved' : 'Save Message'} id='flag_post.unflag'
/> defaultMessage='Remove from Saved'
/>
) : (
<FormattedMessage
id='flag_post.flag'
defaultMessage='Save Message'
/>
)}
</Tooltip> </Tooltip>
} }
> >
<button <button
ref={buttonRef} ref={buttonRef}
id={`${location}_flagIcon_${postId}`} id={`${location}_flagIcon_${postId}`}
aria-label={isFlagged ? localizeMessage('flag_post.unflag', 'Remove from Saved').toLowerCase() : localizeMessage('flag_post.flag', 'Save').toLowerCase()} aria-label={isFlagged ? intl.formatMessage({id: 'flag_post.unflag', defaultMessage: 'Remove from Saved'}).toLowerCase() : intl.formatMessage({id: 'flag_post.flag', defaultMessage: 'Save'}).toLowerCase()}
className='post-menu__item' className='post-menu__item'
onClick={handlePress} onClick={handlePress}
> >

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

@@ -2,13 +2,11 @@
// See LICENSE.txt for license information. // See LICENSE.txt for license information.
import React from 'react'; import React from 'react';
import {FormattedMessage, injectIntl} from 'react-intl'; import {FormattedMessage, defineMessages, injectIntl} from 'react-intl';
import type {IntlShape} from 'react-intl'; import type {IntlShape} from 'react-intl';
import FlagIconFilled from 'components/widgets/icons/flag_icon_filled'; import FlagIconFilled from 'components/widgets/icons/flag_icon_filled';
import {t} from 'utils/i18n';
export type Props = { export type Props = {
intl: IntlShape; intl: IntlShape;
isFlagged: boolean; isFlagged: boolean;
@@ -36,11 +34,6 @@ enum MessageInfoKey {
} }
class PostPreHeader extends React.PureComponent<Props> { class PostPreHeader extends React.PureComponent<Props> {
messageInfos = {
flagged: {id: t('post_pre_header.flagged'), defaultMessage: 'Saved'},
pinned: {id: t('post_pre_header.pinned'), defaultMessage: 'Pinned'},
};
getPostStatus(isFlagged: boolean, isPinned?: boolean): PostPinnedOrFlagged { getPostStatus(isFlagged: boolean, isPinned?: boolean): PostPinnedOrFlagged {
if (isFlagged) { if (isFlagged) {
if (isPinned) { if (isPinned) {
@@ -116,8 +109,7 @@ class PostPreHeader extends React.PureComponent<Props> {
<span> <span>
<a onClick={() => this.handleLinkClick(messageKey, channelId)}> <a onClick={() => this.handleLinkClick(messageKey, channelId)}>
<FormattedMessage <FormattedMessage
id={this.messageInfos[messageKey].id} {...messages[messageKey]}
defaultMessage={this.messageInfos[messageKey].defaultMessage}
/> />
</a> </a>
</span> </span>
@@ -127,15 +119,13 @@ class PostPreHeader extends React.PureComponent<Props> {
<span> <span>
<a onClick={() => this.handleLinkClick(MessageInfoKey.Pinned, channelId)}> <a onClick={() => this.handleLinkClick(MessageInfoKey.Pinned, channelId)}>
<FormattedMessage <FormattedMessage
id={this.messageInfos[MessageInfoKey.Pinned].id} {...messages[MessageInfoKey.Pinned]}
defaultMessage={this.messageInfos[MessageInfoKey.Pinned].defaultMessage}
/> />
</a> </a>
<span className='post-pre-header__link-separator'>{'\u2B24'}</span> <span className='post-pre-header__link-separator'>{'\u2B24'}</span>
<a onClick={() => this.handleLinkClick(MessageInfoKey.Flagged)}> <a onClick={() => this.handleLinkClick(MessageInfoKey.Flagged)}>
<FormattedMessage <FormattedMessage
id={this.messageInfos[MessageInfoKey.Flagged].id} {...messages[MessageInfoKey.Flagged]}
defaultMessage={this.messageInfos[MessageInfoKey.Flagged].defaultMessage}
/> />
</a> </a>
</span> </span>
@@ -146,4 +136,15 @@ class PostPreHeader extends React.PureComponent<Props> {
} }
} }
const messages = defineMessages({
[MessageInfoKey.Flagged]: {
id: 'post_pre_header.flagged',
defaultMessage: 'Saved',
},
[MessageInfoKey.Pinned]: {
id: 'post_pre_header.pinned',
defaultMessage: 'Pinned',
},
});
export default injectIntl(PostPreHeader); export default injectIntl(PostPreHeader);

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

@@ -19,7 +19,6 @@ import LoadingImagePreview from 'components/loading_image_preview';
import OverlayTrigger from 'components/overlay_trigger'; import OverlayTrigger from 'components/overlay_trigger';
import Tooltip from 'components/tooltip'; import Tooltip from 'components/tooltip';
import {t} from 'utils/i18n';
import {localizeMessage, copyToClipboard} from 'utils/utils'; import {localizeMessage, copyToClipboard} from 'utils/utils';
const MIN_IMAGE_SIZE = 48; const MIN_IMAGE_SIZE = 48;
@@ -244,13 +243,13 @@ export default class SizeAwareImage extends React.PureComponent<Props, State> {
> >
{this.state.linkCopiedRecently ? ( {this.state.linkCopiedRecently ? (
<FormattedMessage <FormattedMessage
id={t('single_image_view.copied_link_tooltip')} id='single_image_view.copied_link_tooltip'
defaultMessage={'Copied'} defaultMessage='Copied'
/> />
) : ( ) : (
<FormattedMessage <FormattedMessage
id={t('single_image_view.copy_link_tooltip')} id='single_image_view.copy_link_tooltip'
defaultMessage={'Copy link'} defaultMessage='Copy link'
/> />
)} )}
</Tooltip> </Tooltip>

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

@@ -2825,9 +2825,9 @@
"app.channel.post_update_channel_purpose_message.removed": "{username} removed the channel purpose (was: {old})", "app.channel.post_update_channel_purpose_message.removed": "{username} removed the channel purpose (was: {old})",
"app.channel.post_update_channel_purpose_message.updated_from": "{username} updated the channel purpose from: {old} to: {new}", "app.channel.post_update_channel_purpose_message.updated_from": "{username} updated the channel purpose from: {old} to: {new}",
"app.channel.post_update_channel_purpose_message.updated_to": "{username} updated the channel purpose to: {new}", "app.channel.post_update_channel_purpose_message.updated_to": "{username} updated the channel purpose to: {new}",
"app.post.move_thread_command.channel.multiple_messages": "A thread with {{.NumMessages}} messages has been moved: {{.Link}}\n", "app.post.move_thread_command.channel.multiple_messages": "A thread with {numMessages, number} messages has been moved: {link}\n",
"app.post.move_thread_command.channel.one_message": "A message has been moved: {{.Link}}\n", "app.post.move_thread_command.channel.one_message": "A message has been moved: {link}\n",
"app.post.move_thread_command.direct_or_group.multiple_messages": "A thread with {{.NumMessages}} messages has been moved to a Direct/Group Message\n", "app.post.move_thread_command.direct_or_group.multiple_messages": "A thread with {numMessages, number} messages has been moved to a Direct/Group Message\n",
"app.post.move_thread_command.direct_or_group.one_message": "A message has been moved to a Direct/Group Message\n", "app.post.move_thread_command.direct_or_group.one_message": "A message has been moved to a Direct/Group Message\n",
"app.post.move_thread.from_another_channel": "This thread was moved from another channel", "app.post.move_thread.from_another_channel": "This thread was moved from another channel",
"apps.error": "Error: {error}", "apps.error": "Error: {error}",