Proper i18n for search result headers "<sender> to <receiver>"
This commit is contained in:
parent
83eccee42e
commit
f329d9234a
3 changed files with 78 additions and 15 deletions
|
@ -1108,9 +1108,25 @@
|
||||||
"message": "To",
|
"message": "To",
|
||||||
"description": "Label for the receiver of a message"
|
"description": "Label for the receiver of a message"
|
||||||
},
|
},
|
||||||
|
"icu:searchResultHeader--sender-to-group": {
|
||||||
|
"messageformat": "{sender} to {receiverGroup}",
|
||||||
|
"description": "Shown for search result items - like 'Jon to Friends Group'"
|
||||||
|
},
|
||||||
|
"icu:searchResultHeader--sender-to-you": {
|
||||||
|
"messageformat": "{sender} to You",
|
||||||
|
"description": "Shown for search result items - like 'Jon to You"
|
||||||
|
},
|
||||||
|
"icu:searchResultHeader--you-to-group": {
|
||||||
|
"messageformat": "You to {receiverGroup}",
|
||||||
|
"description": "Shown for search result items - like 'You to Friends Group'"
|
||||||
|
},
|
||||||
|
"icu:searchResultHeader--you-to-receiver": {
|
||||||
|
"messageformat": "You to {receiverContact}",
|
||||||
|
"description": "Shown for search result items - like 'You to Jon'"
|
||||||
|
},
|
||||||
"toJoiner": {
|
"toJoiner": {
|
||||||
"message": "to",
|
"message": "to",
|
||||||
"description": "Joiner for message search results - like 'Jon' to 'Friends Group'"
|
"description": "(deleted 2023/02/02) Joiner for message search results - like 'Jon' to 'Friends Group'"
|
||||||
},
|
},
|
||||||
"sent": {
|
"sent": {
|
||||||
"message": "Sent",
|
"message": "Sent",
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import type { ReactNode } from 'react';
|
||||||
|
|
||||||
import type { FormatXMLElementFn } from 'intl-messageformat';
|
import type { FormatXMLElementFn } from 'intl-messageformat';
|
||||||
import type { LocalizerType, RenderTextCallbackType } from '../types/Util';
|
import type { LocalizerType, RenderTextCallbackType } from '../types/Util';
|
||||||
|
@ -12,6 +13,7 @@ import { strictAssert } from '../util/assert';
|
||||||
export type FullJSXType =
|
export type FullJSXType =
|
||||||
| FormatXMLElementFn<JSX.Element | string>
|
| FormatXMLElementFn<JSX.Element | string>
|
||||||
| Array<JSX.Element | string>
|
| Array<JSX.Element | string>
|
||||||
|
| ReactNode
|
||||||
| JSX.Element
|
| JSX.Element
|
||||||
| string;
|
| string;
|
||||||
export type IntlComponentsType =
|
export type IntlComponentsType =
|
||||||
|
|
|
@ -20,6 +20,7 @@ import type {
|
||||||
ShowConversationType,
|
ShowConversationType,
|
||||||
} from '../../state/ducks/conversations';
|
} from '../../state/ducks/conversations';
|
||||||
import type { PreferredBadgeSelectorType } from '../../state/selectors/badges';
|
import type { PreferredBadgeSelectorType } from '../../state/selectors/badges';
|
||||||
|
import { Intl } from '../Intl';
|
||||||
|
|
||||||
export type PropsDataType = {
|
export type PropsDataType = {
|
||||||
isSelected?: boolean;
|
isSelected?: boolean;
|
||||||
|
@ -44,16 +45,14 @@ export type PropsDataType = {
|
||||||
| 'profileName'
|
| 'profileName'
|
||||||
| 'sharedGroupNames'
|
| 'sharedGroupNames'
|
||||||
| 'title'
|
| 'title'
|
||||||
|
| 'type'
|
||||||
| 'unblurredAvatarPath'
|
| 'unblurredAvatarPath'
|
||||||
>;
|
>;
|
||||||
|
|
||||||
to: {
|
to: Pick<
|
||||||
groupName?: string;
|
ConversationType,
|
||||||
phoneNumber?: string;
|
'isMe' | 'phoneNumber' | 'profileName' | 'title' | 'type'
|
||||||
title: string;
|
>;
|
||||||
isMe?: boolean;
|
|
||||||
profileName?: string;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
type PropsHousekeepingType = {
|
type PropsHousekeepingType = {
|
||||||
|
@ -164,14 +163,60 @@ export const MessageSearchResult: FunctionComponent<PropsType> = React.memo(
|
||||||
let headerName: ReactNode;
|
let headerName: ReactNode;
|
||||||
if (isNoteToSelf) {
|
if (isNoteToSelf) {
|
||||||
headerName = i18n('noteToSelf');
|
headerName = i18n('noteToSelf');
|
||||||
|
} else if (from.isMe) {
|
||||||
|
if (to.type === 'group') {
|
||||||
|
headerName = (
|
||||||
|
<span>
|
||||||
|
<Intl
|
||||||
|
i18n={i18n}
|
||||||
|
id="icu:searchResultHeader--you-to-group"
|
||||||
|
components={{
|
||||||
|
receiverGroup: renderPerson(i18n, to),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
headerName = (
|
||||||
|
<span>
|
||||||
|
<Intl
|
||||||
|
i18n={i18n}
|
||||||
|
id="icu:searchResultHeader--you-to-receiver"
|
||||||
|
components={{
|
||||||
|
receiverContact: renderPerson(i18n, to),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// This isn't perfect because (1) it doesn't work with RTL languages (2)
|
// eslint-disable-next-line no-lonely-if
|
||||||
// capitalization may be incorrect for some languages, like English.
|
if (to.type === 'group') {
|
||||||
headerName = (
|
headerName = (
|
||||||
<span>
|
<span>
|
||||||
{renderPerson(i18n, from)} {i18n('toJoiner')} {renderPerson(i18n, to)}
|
<Intl
|
||||||
</span>
|
i18n={i18n}
|
||||||
);
|
id="icu:searchResultHeader--sender-to-group"
|
||||||
|
components={{
|
||||||
|
sender: renderPerson(i18n, from),
|
||||||
|
receiverGroup: renderPerson(i18n, to),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
headerName = (
|
||||||
|
<span>
|
||||||
|
<Intl
|
||||||
|
i18n={i18n}
|
||||||
|
id="icu:searchResultHeader--sender-to-you"
|
||||||
|
components={{
|
||||||
|
sender: renderPerson(i18n, from),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const snippetBodyRanges = getFilteredBodyRanges(snippet, body, bodyRanges);
|
const snippetBodyRanges = getFilteredBodyRanges(snippet, body, bodyRanges);
|
||||||
|
|
Loading…
Add table
Reference in a new issue