Normalize i18n() calls to prepare for ICU migration

This commit is contained in:
Jamie Kyle 2023-03-28 11:26:46 -07:00 committed by GitHub
parent 7c8e7c1013
commit c02c8d9640
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 377 additions and 273 deletions

View file

@ -213,6 +213,16 @@ const typescriptRules = {
'@typescript-eslint/consistent-type-imports': 'error',
// Future: Maybe switch to never and always use `satisfies`
'@typescript-eslint/consistent-type-assertions': [
'error',
{
assertionStyle: 'as',
// Future: Maybe switch to allow-as-parameter or never
objectLiteralTypeAssertions: 'allow',
},
],
// Already enforced by TypeScript
'consistent-return': 'off',

View file

@ -1404,7 +1404,7 @@ export class SignalProtocolStore extends EventEmitter {
const sessionResets = window.storage.get(
'sessionResets',
<SessionResetsType>{}
{} as SessionResetsType
);
const lastReset = sessionResets[id];

View file

@ -184,7 +184,7 @@ export function isOverHourIntoPast(timestamp: number): boolean {
export async function cleanupSessionResets(): Promise<void> {
const sessionResets = window.storage.get(
'sessionResets',
<SessionResetsType>{}
{} as SessionResetsType
);
const keys = Object.keys(sessionResets);

View file

@ -21,9 +21,11 @@ export type PropsType = Readonly<{
onClose: () => void;
}>;
const UNITS = ['seconds', 'minutes', 'hours', 'days', 'weeks'];
const UNITS = ['seconds', 'minutes', 'hours', 'days', 'weeks'] as const;
const UNIT_TO_SEC = new Map<string, number>([
export type Unit = typeof UNITS[number];
const UNIT_TO_SEC = new Map<Unit, number>([
['seconds', 1],
['minutes', 60],
['hours', 60 * 60],
@ -31,7 +33,7 @@ const UNIT_TO_SEC = new Map<string, number>([
['weeks', 7 * 24 * 60 * 60],
]);
const RANGES = new Map<string, [number, number]>([
const RANGES = new Map<Unit, [number, number]>([
['seconds', [1, 60]],
['minutes', [1, 60]],
['hours', [1, 24]],
@ -48,7 +50,7 @@ export function DisappearingTimeDialog(props: PropsType): JSX.Element {
onClose,
} = props;
let initialUnit = 'seconds';
let initialUnit: Unit = 'seconds';
let initialUnitValue = 1;
for (const unit of UNITS) {
const sec = UNIT_TO_SEC.get(unit) || 1;
@ -62,7 +64,7 @@ export function DisappearingTimeDialog(props: PropsType): JSX.Element {
}
const [unitValue, setUnitValue] = useState(initialUnitValue);
const [unit, setUnit] = useState(initialUnit);
const [unit, setUnit] = useState<Unit>(initialUnit);
const range = RANGES.get(unit) || [1, 1];
@ -108,9 +110,9 @@ export function DisappearingTimeDialog(props: PropsType): JSX.Element {
moduleClassName={`${CSS_MODULE}__time-boxes__units`}
value={unit}
onChange={newUnit => {
setUnit(newUnit);
setUnit(newUnit as Unit);
const ranges = RANGES.get(newUnit);
const ranges = RANGES.get(newUnit as Unit);
if (!ranges) {
return;
}
@ -121,7 +123,13 @@ export function DisappearingTimeDialog(props: PropsType): JSX.Element {
options={UNITS.map(unitName => {
return {
value: unitName,
text: i18n(`DisappearingTimeDialog__${unitName}`),
text: {
seconds: i18n('DisappearingTimeDialog__seconds'),
minutes: i18n('DisappearingTimeDialog__minutes'),
hours: i18n('DisappearingTimeDialog__hours'),
days: i18n('DisappearingTimeDialog__days'),
weeks: i18n('DisappearingTimeDialog__weeks'),
}[unitName],
};
})}
/>

View file

@ -177,9 +177,11 @@ function OverflowAreaScrollMarker({
type="button"
className={`${baseClassName}__button`}
onClick={onClick}
aria-label={i18n(
`calling__overflow__scroll-${placement === 'top' ? 'up' : 'down'}`
)}
aria-label={
placement === 'top'
? i18n('calling__overflow__scroll-up')
: i18n('calling__overflow__scroll-down')
}
/>
</div>
);

View file

@ -96,28 +96,30 @@ type DefaultBio = {
shortName: string;
};
const DEFAULT_BIOS: Array<DefaultBio> = [
{
i18nLabel: 'Bio--speak-freely',
shortName: 'wave',
},
{
i18nLabel: 'Bio--encrypted',
shortName: 'zipper_mouth_face',
},
{
i18nLabel: 'Bio--free-to-chat',
shortName: '+1',
},
{
i18nLabel: 'Bio--coffee-lover',
shortName: 'coffee',
},
{
i18nLabel: 'Bio--taking-break',
shortName: 'mobile_phone_off',
},
];
function getDefaultBios(i18n: LocalizerType): Array<DefaultBio> {
return [
{
i18nLabel: i18n('Bio--speak-freely'),
shortName: 'wave',
},
{
i18nLabel: i18n('Bio--encrypted'),
shortName: 'zipper_mouth_face',
},
{
i18nLabel: i18n('Bio--free-to-chat'),
shortName: '+1',
},
{
i18nLabel: i18n('Bio--coffee-lover'),
shortName: 'coffee',
},
{
i18nLabel: i18n('Bio--taking-break'),
shortName: 'mobile_phone_off',
},
];
}
export function ProfileEditor({
aboutEmoji,
@ -371,6 +373,8 @@ export function ProfileEditor({
(stagedProfile.aboutText === fullBio.aboutText &&
stagedProfile.aboutEmoji === fullBio.aboutEmoji);
const defaultBios = getDefaultBios(i18n);
content = (
<>
<Input
@ -415,7 +419,7 @@ export function ProfileEditor({
whenToShowRemainingCount={40}
/>
{DEFAULT_BIOS.map(defaultBio => (
{defaultBios.map(defaultBio => (
<PanelRow
className="ProfileEditor__row"
key={defaultBio.shortName}
@ -424,16 +428,14 @@ export function ProfileEditor({
<Emoji shortName={defaultBio.shortName} size={24} />
</div>
}
// eslint-disable-next-line local-rules/valid-i18n-keys
label={i18n(defaultBio.i18nLabel)}
label={defaultBio.i18nLabel}
onClick={() => {
const emojiData = getEmojiData(defaultBio.shortName, skinTone);
setStagedProfile(profileData => ({
...profileData,
aboutEmoji: unifiedToEmoji(emojiData.unified),
// eslint-disable-next-line local-rules/valid-i18n-keys
aboutText: i18n(defaultBio.i18nLabel),
aboutText: defaultBio.i18nLabel,
}));
}}
/>

View file

@ -44,191 +44,241 @@ type KeyType =
| 'Y'
| '1 to 9';
type ShortcutType = {
id: string;
description: string;
keys: Array<Array<KeyType>>;
};
const NAVIGATION_SHORTCUTS: Array<ShortcutType> = [
{
description: 'Keyboard--navigate-by-section',
keys: [['commandOrCtrl', 'T']],
},
{
description: 'Keyboard--previous-conversation',
keys: [
['optionOrAlt', '↑'],
['ctrl', 'shift', 'tab'],
],
},
{
description: 'Keyboard--next-conversation',
keys: [
['optionOrAlt', '↓'],
['ctrl', 'tab'],
],
},
{
description: 'Keyboard--previous-unread-conversation',
keys: [['optionOrAlt', 'shift', '↑']],
},
{
description: 'Keyboard--next-unread-conversation',
keys: [['optionOrAlt', 'shift', '↓']],
},
{
description: 'Keyboard--conversation-by-index',
keys: [['commandOrCtrl', '1 to 9']],
},
{
description: 'Keyboard--preferences',
keys: [['commandOrCtrl', ',']],
},
{
description: 'Keyboard--open-conversation-menu',
keys: [['commandOrCtrl', 'shift', 'L']],
},
{
description: 'Keyboard--new-conversation',
keys: [['commandOrCtrl', 'N']],
},
{
description: 'Keyboard--search',
keys: [['commandOrCtrl', 'F']],
},
{
description: 'Keyboard--search-in-conversation',
keys: [['commandOrCtrl', 'shift', 'F']],
},
{
description: 'Keyboard--focus-composer',
keys: [['commandOrCtrl', 'shift', 'T']],
},
{
description: 'Keyboard--open-all-media-view',
keys: [['commandOrCtrl', 'shift', 'M']],
},
{
description: 'Keyboard--open-emoji-chooser',
keys: [['commandOrCtrl', 'shift', 'J']],
},
{
description: 'Keyboard--open-sticker-chooser',
keys: [['commandOrCtrl', 'shift', 'S']],
},
{
description: 'Keyboard--begin-recording-voice-note',
keys: [['commandOrCtrl', 'shift', 'V']],
},
{
description: 'Keyboard--archive-conversation',
keys: [['commandOrCtrl', 'shift', 'A']],
},
{
description: 'Keyboard--unarchive-conversation',
keys: [['commandOrCtrl', 'shift', 'U']],
},
{
description: 'Keyboard--scroll-to-top',
keys: [['commandOrCtrl', '↑']],
},
{
description: 'Keyboard--scroll-to-bottom',
keys: [['commandOrCtrl', '↓']],
},
{
description: 'Keyboard--close-curent-conversation',
keys: [['commandOrCtrl', 'shift', 'C']],
},
];
function getNavigationShortcuts(i18n: LocalizerType): Array<ShortcutType> {
return [
{
id: 'Keyboard--navigate-by-section',
description: i18n('Keyboard--navigate-by-section'),
keys: [['commandOrCtrl', 'T']],
},
{
id: 'Keyboard--previous-conversation',
description: i18n('Keyboard--previous-conversation'),
keys: [
['optionOrAlt', '↑'],
['ctrl', 'shift', 'tab'],
],
},
{
id: 'Keyboard--next-conversation',
description: i18n('Keyboard--next-conversation'),
keys: [
['optionOrAlt', '↓'],
['ctrl', 'tab'],
],
},
{
id: 'Keyboard--previous-unread-conversation',
description: i18n('Keyboard--previous-unread-conversation'),
keys: [['optionOrAlt', 'shift', '↑']],
},
{
id: 'Keyboard--next-unread-conversation',
description: i18n('Keyboard--next-unread-conversation'),
keys: [['optionOrAlt', 'shift', '↓']],
},
{
id: 'Keyboard--conversation-by-index',
description: i18n('Keyboard--conversation-by-index'),
keys: [['commandOrCtrl', '1 to 9']],
},
{
id: 'Keyboard--preferences',
description: i18n('Keyboard--preferences'),
keys: [['commandOrCtrl', ',']],
},
{
id: 'Keyboard--open-conversation-menu',
description: i18n('Keyboard--open-conversation-menu'),
keys: [['commandOrCtrl', 'shift', 'L']],
},
{
id: 'Keyboard--new-conversation',
description: i18n('Keyboard--new-conversation'),
keys: [['commandOrCtrl', 'N']],
},
{
id: 'Keyboard--search',
description: i18n('Keyboard--search'),
keys: [['commandOrCtrl', 'F']],
},
{
id: 'Keyboard--search-in-conversation',
description: i18n('Keyboard--search-in-conversation'),
keys: [['commandOrCtrl', 'shift', 'F']],
},
{
id: 'Keyboard--focus-composer',
description: i18n('Keyboard--focus-composer'),
keys: [['commandOrCtrl', 'shift', 'T']],
},
{
id: 'Keyboard--open-all-media-view',
description: i18n('Keyboard--open-all-media-view'),
keys: [['commandOrCtrl', 'shift', 'M']],
},
{
id: 'Keyboard--open-emoji-chooser',
description: i18n('Keyboard--open-emoji-chooser'),
keys: [['commandOrCtrl', 'shift', 'J']],
},
{
id: 'Keyboard--open-sticker-chooser',
description: i18n('Keyboard--open-sticker-chooser'),
keys: [['commandOrCtrl', 'shift', 'S']],
},
{
id: 'Keyboard--begin-recording-voice-note',
description: i18n('Keyboard--begin-recording-voice-note'),
keys: [['commandOrCtrl', 'shift', 'V']],
},
{
id: 'Keyboard--archive-conversation',
description: i18n('Keyboard--archive-conversation'),
keys: [['commandOrCtrl', 'shift', 'A']],
},
{
id: 'Keyboard--unarchive-conversation',
description: i18n('Keyboard--unarchive-conversation'),
keys: [['commandOrCtrl', 'shift', 'U']],
},
{
id: 'Keyboard--scroll-to-top',
description: i18n('Keyboard--scroll-to-top'),
keys: [['commandOrCtrl', '↑']],
},
{
id: 'Keyboard--scroll-to-bottom',
description: i18n('Keyboard--scroll-to-bottom'),
keys: [['commandOrCtrl', '↓']],
},
{
id: 'Keyboard--close-curent-conversation',
description: i18n('Keyboard--close-curent-conversation'),
keys: [['commandOrCtrl', 'shift', 'C']],
},
];
}
const MESSAGE_SHORTCUTS: Array<ShortcutType> = [
{
description: 'Keyboard--default-message-action',
keys: [['enter']],
},
{
description: 'Keyboard--view-details-for-selected-message',
keys: [['commandOrCtrl', 'D']],
},
{
description: 'Keyboard--toggle-reply',
keys: [['commandOrCtrl', 'shift', 'R']],
},
{
description: 'Keyboard--toggle-reaction-picker',
keys: [['commandOrCtrl', 'shift', 'E']],
},
{
description: 'Keyboard--save-attachment',
keys: [['commandOrCtrl', 'S']],
},
{
description: 'Keyboard--delete-messages',
keys: [['commandOrCtrl', 'shift', 'D']],
},
];
function getMessageShortcuts(i18n: LocalizerType): Array<ShortcutType> {
return [
{
id: 'Keyboard--default-message-action',
description: i18n('Keyboard--default-message-action'),
keys: [['enter']],
},
{
id: 'Keyboard--view-details-for-selected-message',
description: i18n('Keyboard--view-details-for-selected-message'),
keys: [['commandOrCtrl', 'D']],
},
{
id: 'Keyboard--toggle-reply',
description: i18n('Keyboard--toggle-reply'),
keys: [['commandOrCtrl', 'shift', 'R']],
},
{
id: 'Keyboard--toggle-reaction-picker',
description: i18n('Keyboard--toggle-reaction-picker'),
keys: [['commandOrCtrl', 'shift', 'E']],
},
{
id: 'Keyboard--save-attachment',
description: i18n('Keyboard--save-attachment'),
keys: [['commandOrCtrl', 'S']],
},
{
id: 'Keyboard--delete-message',
description: i18n('Keyboard--delete-message'),
keys: [['commandOrCtrl', 'shift', 'D']],
},
];
}
const COMPOSER_SHORTCUTS: Array<ShortcutType> = [
{
description: 'Keyboard--add-newline',
keys: [['shift', 'enter']],
},
{
description: 'Keyboard--expand-composer',
keys: [['commandOrCtrl', 'shift', 'X']],
},
{
description: 'Keyboard--send-in-expanded-composer',
keys: [['commandOrCtrl', 'enter']],
},
{
description: 'Keyboard--attach-file',
keys: [['commandOrCtrl', 'U']],
},
{
description: 'Keyboard--remove-draft-link-preview',
keys: [['commandOrCtrl', 'P']],
},
{
description: 'Keyboard--remove-draft-attachments',
keys: [['commandOrCtrl', 'shift', 'P']],
},
];
function getComposerShortcuts(i18n: LocalizerType): Array<ShortcutType> {
return [
{
id: 'Keyboard--add-newline',
description: i18n('Keyboard--add-newline'),
keys: [['shift', 'enter']],
},
{
id: 'Keyboard--expand-composer',
description: i18n('Keyboard--expand-composer'),
keys: [['commandOrCtrl', 'shift', 'X']],
},
{
id: 'Keyboard--send-in-expanded-composer',
description: i18n('Keyboard--send-in-expanded-composer'),
keys: [['commandOrCtrl', 'enter']],
},
{
id: 'Keyboard--attach-file',
description: i18n('Keyboard--attach-file'),
keys: [['commandOrCtrl', 'U']],
},
{
id: 'Keyboard--remove-draft-link-preview',
description: i18n('Keyboard--remove-draft-link-preview'),
keys: [['commandOrCtrl', 'P']],
},
{
id: 'Keyboard--remove-draft-attachments',
description: i18n('Keyboard--remove-draft-attachments'),
keys: [['commandOrCtrl', 'shift', 'P']],
},
];
}
const CALLING_SHORTCUTS: Array<ShortcutType> = [
{
description: 'Keyboard--toggle-audio',
keys: [['shift', 'M']],
},
{
description: 'Keyboard--toggle-video',
keys: [['shift', 'V']],
},
{
description: 'icu:Keyboard--accept-video-call',
keys: [['ctrlOrAlt', 'shift', 'V']],
},
{
description: 'icu:Keyboard--accept-call-without-video',
keys: [['ctrlOrAlt', 'shift', 'A']],
},
{
description: 'Keyboard--decline-call',
keys: [['ctrlOrAlt', 'shift', 'D']],
},
{
description: 'Keyboard--start-audio-call',
keys: [['ctrlOrAlt', 'shift', 'C']],
},
{
description: 'Keyboard--start-video-call',
keys: [['ctrlOrAlt', 'shift', 'Y']],
},
{
description: 'Keyboard--hang-up',
keys: [['ctrlOrAlt', 'shift', 'E']],
},
];
function getCallingShortcuts(i18n: LocalizerType): Array<ShortcutType> {
return [
{
id: 'Keyboard--toggle-audio',
description: i18n('Keyboard--toggle-audio'),
keys: [['shift', 'M']],
},
{
id: 'Keyboard--toggle-video',
description: i18n('Keyboard--toggle-video'),
keys: [['shift', 'V']],
},
{
id: 'icu:Keyboard--accept-video-call',
description: i18n('icu:Keyboard--accept-video-call'),
keys: [['ctrlOrAlt', 'shift', 'V']],
},
{
id: 'icu:Keyboard--accept-call-without-video',
description: i18n('icu:Keyboard--accept-call-without-video'),
keys: [['ctrlOrAlt', 'shift', 'A']],
},
{
id: 'Keyboard--decline-call',
description: i18n('Keyboard--decline-call'),
keys: [['ctrlOrAlt', 'shift', 'D']],
},
{
id: 'Keyboard--start-audio-call',
description: i18n('Keyboard--start-audio-call'),
keys: [['ctrlOrAlt', 'shift', 'C']],
},
{
id: 'Keyboard--start-video-call',
description: i18n('Keyboard--start-video-call'),
keys: [['ctrlOrAlt', 'shift', 'Y']],
},
{
id: 'Keyboard--hang-up',
description: i18n('Keyboard--hang-up'),
keys: [['ctrlOrAlt', 'shift', 'E']],
},
];
}
export function ShortcutGuide(props: Props): JSX.Element {
const { i18n, close, hasInstalledStickers, platform } = props;
@ -262,7 +312,7 @@ export function ShortcutGuide(props: Props): JSX.Element {
{i18n('Keyboard--navigation-header')}
</div>
<div className="module-shortcut-guide__section-list">
{NAVIGATION_SHORTCUTS.map((shortcut, index) => {
{getNavigationShortcuts(i18n).map((shortcut, index) => {
if (
!hasInstalledStickers &&
shortcut.description === 'Keyboard--open-sticker-chooser'
@ -279,7 +329,7 @@ export function ShortcutGuide(props: Props): JSX.Element {
{i18n('Keyboard--messages-header')}
</div>
<div className="module-shortcut-guide__section-list">
{MESSAGE_SHORTCUTS.map((shortcut, index) =>
{getMessageShortcuts(i18n).map((shortcut, index) =>
renderShortcut(shortcut, index, isMacOS, i18n)
)}
</div>
@ -289,7 +339,7 @@ export function ShortcutGuide(props: Props): JSX.Element {
{i18n('Keyboard--composer-header')}
</div>
<div className="module-shortcut-guide__section-list">
{COMPOSER_SHORTCUTS.map((shortcut, index) =>
{getComposerShortcuts(i18n).map((shortcut, index) =>
renderShortcut(shortcut, index, isMacOS, i18n)
)}
</div>
@ -299,7 +349,7 @@ export function ShortcutGuide(props: Props): JSX.Element {
{i18n('Keyboard--calling-header')}
</div>
<div className="module-shortcut-guide__section-list">
{CALLING_SHORTCUTS.map((shortcut, index) =>
{getCallingShortcuts(i18n).map((shortcut, index) =>
renderShortcut(shortcut, index, isMacOS, i18n)
)}
</div>
@ -319,8 +369,7 @@ function renderShortcut(
return (
<div key={index} className="module-shortcut-guide__shortcut">
<div className="module-shortcut-guide__shortcut__description">
{/* eslint-disable-next-line local-rules/valid-i18n-keys */}
{i18n(shortcut.description)}
{shortcut.description}
</div>
<div className="module-shortcut-guide__shortcut__key-container">
{shortcut.keys.map(keys => (

View file

@ -37,32 +37,35 @@ export type PropsType = {
const contactSortCollator = new window.Intl.Collator();
function getI18nKey(sendStatus: SendStatus | undefined): string {
function getSendStatusLabel(
sendStatus: SendStatus | undefined,
i18n: LocalizerType
): string {
if (sendStatus === SendStatus.Failed) {
return 'MessageDetailsHeader--Failed';
return i18n('MessageDetailsHeader--Failed');
}
if (sendStatus === SendStatus.Viewed) {
return 'MessageDetailsHeader--Viewed';
return i18n('MessageDetailsHeader--Viewed');
}
if (sendStatus === SendStatus.Read) {
return 'MessageDetailsHeader--Read';
return i18n('MessageDetailsHeader--Read');
}
if (sendStatus === SendStatus.Delivered) {
return 'MessageDetailsHeader--Delivered';
return i18n('MessageDetailsHeader--Delivered');
}
if (sendStatus === SendStatus.Sent) {
return 'MessageDetailsHeader--Sent';
return i18n('MessageDetailsHeader--Sent');
}
if (sendStatus === SendStatus.Pending) {
return 'MessageDetailsHeader--Pending';
return i18n('MessageDetailsHeader--Pending');
}
return 'from';
return i18n('from');
}
export function StoryDetailsModal({
@ -105,17 +108,19 @@ export function StoryDetailsModal({
return null;
}
const i18nKey = getI18nKey(sendStatus);
const sendStatusLabel = getSendStatusLabel(sendStatus, i18n);
const sortedContacts = [...contacts].sort((a, b) =>
contactSortCollator.compare(a.recipient.title, b.recipient.title)
);
return (
<div key={i18nKey} className="StoryDetailsModal__contact-group">
<div
key={sendStatusLabel}
className="StoryDetailsModal__contact-group"
>
<div className="StoryDetailsModal__contact-group__header">
{/* eslint-disable-next-line local-rules/valid-i18n-keys */}
{i18n(i18nKey)}
{sendStatusLabel}
</div>
{sortedContacts.map(status => {
const contact = status.recipient;

View file

@ -23,13 +23,15 @@ export function UsernameOnboardingModalBody({
<div className={CLASS}>
<div className={`${CLASS}__large-at`} />
<div className={`${CLASS}__title`}>{i18n(`icu:${CLASS}__title`)}</div>
<div className={`${CLASS}__title`}>
{i18n('icu:UsernameOnboardingModalBody__title')}
</div>
<div className={`${CLASS}__row`}>
<div className={`${CLASS}__row__icon ${CLASS}__row__icon--number`} />
<div className={`${CLASS}__row__body`}>
{i18n(`icu:${CLASS}__row__number`)}
{i18n('icu:UsernameOnboardingModalBody__row__number')}
</div>
</div>
@ -37,7 +39,7 @@ export function UsernameOnboardingModalBody({
<div className={`${CLASS}__row__icon ${CLASS}__row__icon--link`} />
<div className={`${CLASS}__row__body`}>
{i18n(`icu:${CLASS}__row__link`)}
{i18n('icu:UsernameOnboardingModalBody__row__link')}
</div>
</div>
@ -45,7 +47,7 @@ export function UsernameOnboardingModalBody({
<div className={`${CLASS}__row__icon ${CLASS}__row__icon--lock`} />
<div className={`${CLASS}__row__body`}>
{i18n(`icu:${CLASS}__row__lock`)}
{i18n('icu:UsernameOnboardingModalBody__row__lock')}
</div>
</div>
@ -56,12 +58,12 @@ export function UsernameOnboardingModalBody({
rel="noreferrer"
target="_blank"
>
{i18n(`icu:${CLASS}__learn-more`)}
{i18n('icu:UsernameOnboardingModalBody__learn-more')}
</a>
</div>
<Button className={`${CLASS}__submit`} onClick={onNext}>
{i18n(`icu:${CLASS}__continue`)}
{i18n('icu:UsernameOnboardingModalBody__continue')}
</Button>
</div>
);

View file

@ -571,7 +571,10 @@ export class Message extends React.PureComponent<Props, State> {
}
if (giftBadge) {
const description = i18n(`icu:message--donation--unopened--${direction}`);
const description =
direction === 'incoming'
? i18n('icu:message--donation--unopened--incoming')
: i18n('icu:message--donation--unopened--outgoing');
const isDescriptionRTL = getDirection(description) === 'rtl';
if (giftBadge.state === GiftBadgeStates.Unopened && !isDescriptionRTL) {

View file

@ -49,13 +49,23 @@ export function MessageRequestActionsConfirmation({
onChangeState(MessageRequestState.default);
}}
title={
<Intl
i18n={i18n}
id={`MessageRequests--block-${conversationType}-confirm-title`}
components={{
title: <ContactName key="name" title={title} />,
}}
/>
conversationType === 'direct' ? (
<Intl
i18n={i18n}
id="MessageRequests--block-direct-confirm-title"
components={{
title: <ContactName key="name" title={title} />,
}}
/>
) : (
<Intl
i18n={i18n}
id="MessageRequests--block-group-confirm-title"
components={{
title: <ContactName key="name" title={title} />,
}}
/>
)
}
actions={[
...(conversationType === 'direct'
@ -74,7 +84,9 @@ export function MessageRequestActionsConfirmation({
},
]}
>
{i18n(`MessageRequests--block-${conversationType}-confirm-body`)}
{conversationType === 'direct'
? i18n('MessageRequests--block-direct-confirm-body')
: i18n('MessageRequests--block-group-confirm-body')}
</ConfirmationDialog>
);
}
@ -104,7 +116,9 @@ export function MessageRequestActionsConfirmation({
},
]}
>
{i18n(`MessageRequests--unblock-${conversationType}-confirm-body`)}
{conversationType === 'direct'
? i18n('MessageRequests--unblock-direct-confirm-body')
: i18n('MessageRequests--unblock-group-confirm-body')}
</ConfirmationDialog>
);
}
@ -128,13 +142,18 @@ export function MessageRequestActionsConfirmation({
}
actions={[
{
text: i18n(`MessageRequests--delete-${conversationType}`),
text:
conversationType === 'direct'
? i18n('MessageRequests--delete-direct')
: i18n('MessageRequests--delete-group'),
action: () => deleteConversation(conversationId),
style: 'negative',
},
]}
>
{i18n(`MessageRequests--delete-${conversationType}-confirm-body`)}
{conversationType === 'direct'
? i18n('MessageRequests--delete-direct-confirm-body')
: i18n('MessageRequests--delete-group-confirm-body')}
</ConfirmationDialog>
);
}

View file

@ -285,12 +285,13 @@ function getConfirmationMessage({
// Requesting a membership since they weren't added by anyone
if (membershipType === StageType.DENY_REQUEST) {
const params = {
name: firstMembership.member.title,
};
return isAccessControlEnabled(conversation.accessControlAddFromInviteLink)
? i18n('PendingRequests--deny-for--with-link', params)
: i18n('PendingRequests--deny-for', params);
? i18n('PendingRequests--deny-for--with-link', {
name: firstMembership.member.title,
})
: i18n('PendingRequests--deny-for', {
name: firstMembership.member.title,
});
}
if (membershipType === StageType.APPROVE_REQUEST) {

View file

@ -30,7 +30,7 @@ async function clearResetsTracking(idForTracking: string | undefined) {
const sessionResets = window.storage.get(
'sessionResets',
<SessionResetsType>{}
{} as SessionResetsType
);
delete sessionResets[idForTracking];
await window.storage.put('sessionResets', sessionResets);

View file

@ -765,7 +765,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
fromContact?.getTitle() ?? window.i18n('unknownContact');
return {
emoji,
text: window.i18n('icu:message--giftBadge--preview--sent', {
text: window.i18n('icu:message--donation--preview--sent', {
recipient,
}),
};
@ -776,10 +776,10 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
emoji,
text:
giftBadge.state === GiftBadgeStates.Unopened
? window.i18n('icu:message--giftBadge--preview--unopened', {
? window.i18n('icu:message--donation--preview--unopened', {
sender,
})
: window.i18n('icu:message--giftBadge--preview--redeemed'),
: window.i18n('icu:message--donation--preview--redeemed'),
};
}

View file

@ -83,9 +83,9 @@ async function notifyForCall(
icon: isVideoCall
? 'images/icons/v2/video-solid-24.svg'
: 'images/icons/v2/phone-right-solid-24.svg',
message: window.i18n(
isVideoCall ? 'incomingVideoCall' : 'incomingAudioCall'
),
message: isVideoCall
? window.i18n('incomingVideoCall')
: window.i18n('incomingAudioCall'),
onNotificationClick: () => {
window.IPC.showWindow();
},

View file

@ -100,10 +100,11 @@ describe('both/state/ducks/audioPlayer', () => {
it('active is not changed when changing the conversation', () => {
const state = getInitializedState();
const updated = rootReducer(state, <TargetedConversationChangedActionType>{
const action: TargetedConversationChangedActionType = {
type: TARGETED_CONVERSATION_CHANGED,
payload: { id: 'any' },
});
payload: { conversationId: 'any' },
};
const updated = rootReducer(state, action);
const content = updated.audioPlayer.active?.content;
assert.isTrue(content && AudioPlayerContent.isVoiceNote(content));

View file

@ -60,9 +60,10 @@ describe('NativeThemeListener', () => {
const listener = createNativeThemeListener(ipc, holder);
ipc.emit('native-theme:changed', null, <NativeThemeState>{
const state: NativeThemeState = {
shouldUseDarkColors: false,
});
};
ipc.emit('native-theme:changed', null, state);
assert.strictEqual(holder.systemTheme, 'light');
assert.strictEqual(listener.getSystemTheme(), 'light');
@ -80,8 +81,9 @@ describe('NativeThemeListener', () => {
done();
});
ipc.emit('native-theme:changed', null, <NativeThemeState>{
const state: NativeThemeState = {
shouldUseDarkColors: false,
});
};
ipc.emit('native-theme:changed', null, state);
});
});