From c02c8d9640ca8644f6a7eaab0cfa71d9dafa0534 Mon Sep 17 00:00:00 2001 From: Jamie Kyle <113370520+jamiebuilds-signal@users.noreply.github.com> Date: Tue, 28 Mar 2023 11:26:46 -0700 Subject: [PATCH] Normalize i18n() calls to prepare for ICU migration --- .eslintrc.js | 10 + ts/SignalProtocolStore.ts | 2 +- ts/background.ts | 2 +- ts/components/DisappearingTimeDialog.tsx | 24 +- ts/components/GroupCallOverflowArea.tsx | 8 +- ts/components/ProfileEditor.tsx | 56 +-- ts/components/ShortcutGuide.tsx | 417 ++++++++++-------- ts/components/StoryDetailsModal.tsx | 29 +- ts/components/UsernameOnboardingModalBody.tsx | 14 +- ts/components/conversation/Message.tsx | 5 +- .../MessageRequestActionsConfirmation.tsx | 41 +- .../conversation-details/PendingInvites.tsx | 11 +- ts/jobs/helpers/sendNullMessage.ts | 2 +- ts/models/messages.ts | 6 +- ts/state/smart/CallManager.tsx | 6 +- ts/test-both/state/ducks/audioPlayer_test.ts | 7 +- .../context/createNativeThemeListener_test.ts | 10 +- 17 files changed, 377 insertions(+), 273 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index b9da930820be..b9d4c7e78eb7 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -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', diff --git a/ts/SignalProtocolStore.ts b/ts/SignalProtocolStore.ts index 60ab3f68cae1..2b4130a68b21 100644 --- a/ts/SignalProtocolStore.ts +++ b/ts/SignalProtocolStore.ts @@ -1404,7 +1404,7 @@ export class SignalProtocolStore extends EventEmitter { const sessionResets = window.storage.get( 'sessionResets', - {} + {} as SessionResetsType ); const lastReset = sessionResets[id]; diff --git a/ts/background.ts b/ts/background.ts index 27129d8769b4..6e587287b0ee 100644 --- a/ts/background.ts +++ b/ts/background.ts @@ -184,7 +184,7 @@ export function isOverHourIntoPast(timestamp: number): boolean { export async function cleanupSessionResets(): Promise { const sessionResets = window.storage.get( 'sessionResets', - {} + {} as SessionResetsType ); const keys = Object.keys(sessionResets); diff --git a/ts/components/DisappearingTimeDialog.tsx b/ts/components/DisappearingTimeDialog.tsx index eb1a37233386..c13aa150fd17 100644 --- a/ts/components/DisappearingTimeDialog.tsx +++ b/ts/components/DisappearingTimeDialog.tsx @@ -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([ +export type Unit = typeof UNITS[number]; + +const UNIT_TO_SEC = new Map([ ['seconds', 1], ['minutes', 60], ['hours', 60 * 60], @@ -31,7 +33,7 @@ const UNIT_TO_SEC = new Map([ ['weeks', 7 * 24 * 60 * 60], ]); -const RANGES = new Map([ +const RANGES = new Map([ ['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(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], }; })} /> diff --git a/ts/components/GroupCallOverflowArea.tsx b/ts/components/GroupCallOverflowArea.tsx index 4605057926fe..faa1ba3d1650 100644 --- a/ts/components/GroupCallOverflowArea.tsx +++ b/ts/components/GroupCallOverflowArea.tsx @@ -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') + } /> ); diff --git a/ts/components/ProfileEditor.tsx b/ts/components/ProfileEditor.tsx index d6e5b0a60890..d326e6fcbfea 100644 --- a/ts/components/ProfileEditor.tsx +++ b/ts/components/ProfileEditor.tsx @@ -96,28 +96,30 @@ type DefaultBio = { shortName: string; }; -const DEFAULT_BIOS: Array = [ - { - 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 { + 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 = ( <> - {DEFAULT_BIOS.map(defaultBio => ( + {defaultBios.map(defaultBio => ( } - // 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, })); }} /> diff --git a/ts/components/ShortcutGuide.tsx b/ts/components/ShortcutGuide.tsx index 34dad13bb604..cab6062686f2 100644 --- a/ts/components/ShortcutGuide.tsx +++ b/ts/components/ShortcutGuide.tsx @@ -44,191 +44,241 @@ type KeyType = | 'Y' | '1 to 9'; type ShortcutType = { + id: string; description: string; keys: Array>; }; -const NAVIGATION_SHORTCUTS: Array = [ - { - 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 { + 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 = [ - { - 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 { + 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 = [ - { - 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 { + 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 = [ - { - 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 { + 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')}
- {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')}
- {MESSAGE_SHORTCUTS.map((shortcut, index) => + {getMessageShortcuts(i18n).map((shortcut, index) => renderShortcut(shortcut, index, isMacOS, i18n) )}
@@ -289,7 +339,7 @@ export function ShortcutGuide(props: Props): JSX.Element { {i18n('Keyboard--composer-header')}
- {COMPOSER_SHORTCUTS.map((shortcut, index) => + {getComposerShortcuts(i18n).map((shortcut, index) => renderShortcut(shortcut, index, isMacOS, i18n) )}
@@ -299,7 +349,7 @@ export function ShortcutGuide(props: Props): JSX.Element { {i18n('Keyboard--calling-header')}
- {CALLING_SHORTCUTS.map((shortcut, index) => + {getCallingShortcuts(i18n).map((shortcut, index) => renderShortcut(shortcut, index, isMacOS, i18n) )}
@@ -319,8 +369,7 @@ function renderShortcut( return (
- {/* eslint-disable-next-line local-rules/valid-i18n-keys */} - {i18n(shortcut.description)} + {shortcut.description}
{shortcut.keys.map(keys => ( diff --git a/ts/components/StoryDetailsModal.tsx b/ts/components/StoryDetailsModal.tsx index 2d11408629b4..cd2aec5e1990 100644 --- a/ts/components/StoryDetailsModal.tsx +++ b/ts/components/StoryDetailsModal.tsx @@ -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 ( -
+
- {/* eslint-disable-next-line local-rules/valid-i18n-keys */} - {i18n(i18nKey)} + {sendStatusLabel}
{sortedContacts.map(status => { const contact = status.recipient; diff --git a/ts/components/UsernameOnboardingModalBody.tsx b/ts/components/UsernameOnboardingModalBody.tsx index a7a555fdb27a..93bd597efce3 100644 --- a/ts/components/UsernameOnboardingModalBody.tsx +++ b/ts/components/UsernameOnboardingModalBody.tsx @@ -23,13 +23,15 @@ export function UsernameOnboardingModalBody({
-
{i18n(`icu:${CLASS}__title`)}
+
+ {i18n('icu:UsernameOnboardingModalBody__title')} +
- {i18n(`icu:${CLASS}__row__number`)} + {i18n('icu:UsernameOnboardingModalBody__row__number')}
@@ -37,7 +39,7 @@ export function UsernameOnboardingModalBody({
- {i18n(`icu:${CLASS}__row__link`)} + {i18n('icu:UsernameOnboardingModalBody__row__link')}
@@ -45,7 +47,7 @@ export function UsernameOnboardingModalBody({
- {i18n(`icu:${CLASS}__row__lock`)} + {i18n('icu:UsernameOnboardingModalBody__row__lock')}
@@ -56,12 +58,12 @@ export function UsernameOnboardingModalBody({ rel="noreferrer" target="_blank" > - {i18n(`icu:${CLASS}__learn-more`)} + {i18n('icu:UsernameOnboardingModalBody__learn-more')}
); diff --git a/ts/components/conversation/Message.tsx b/ts/components/conversation/Message.tsx index d5f4bdb53120..83c98b00c565 100644 --- a/ts/components/conversation/Message.tsx +++ b/ts/components/conversation/Message.tsx @@ -571,7 +571,10 @@ export class Message extends React.PureComponent { } 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) { diff --git a/ts/components/conversation/MessageRequestActionsConfirmation.tsx b/ts/components/conversation/MessageRequestActionsConfirmation.tsx index 5d50af521ab9..39fb3c876029 100644 --- a/ts/components/conversation/MessageRequestActionsConfirmation.tsx +++ b/ts/components/conversation/MessageRequestActionsConfirmation.tsx @@ -49,13 +49,23 @@ export function MessageRequestActionsConfirmation({ onChangeState(MessageRequestState.default); }} title={ - , - }} - /> + conversationType === 'direct' ? ( + , + }} + /> + ) : ( + , + }} + /> + ) } 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')} ); } @@ -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')} ); } @@ -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')} ); } diff --git a/ts/components/conversation/conversation-details/PendingInvites.tsx b/ts/components/conversation/conversation-details/PendingInvites.tsx index 54b4b87df7f7..c5956f41ad24 100644 --- a/ts/components/conversation/conversation-details/PendingInvites.tsx +++ b/ts/components/conversation/conversation-details/PendingInvites.tsx @@ -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) { diff --git a/ts/jobs/helpers/sendNullMessage.ts b/ts/jobs/helpers/sendNullMessage.ts index 44dbc2e577e7..6352fda07c58 100644 --- a/ts/jobs/helpers/sendNullMessage.ts +++ b/ts/jobs/helpers/sendNullMessage.ts @@ -30,7 +30,7 @@ async function clearResetsTracking(idForTracking: string | undefined) { const sessionResets = window.storage.get( 'sessionResets', - {} + {} as SessionResetsType ); delete sessionResets[idForTracking]; await window.storage.put('sessionResets', sessionResets); diff --git a/ts/models/messages.ts b/ts/models/messages.ts index afcc29a2282e..d8657c170ea0 100644 --- a/ts/models/messages.ts +++ b/ts/models/messages.ts @@ -765,7 +765,7 @@ export class MessageModel extends window.Backbone.Model { 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 { 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'), }; } diff --git a/ts/state/smart/CallManager.tsx b/ts/state/smart/CallManager.tsx index 0f11e241b9c7..530076d16c26 100644 --- a/ts/state/smart/CallManager.tsx +++ b/ts/state/smart/CallManager.tsx @@ -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(); }, diff --git a/ts/test-both/state/ducks/audioPlayer_test.ts b/ts/test-both/state/ducks/audioPlayer_test.ts index b627a1da8657..df77854d9ca5 100644 --- a/ts/test-both/state/ducks/audioPlayer_test.ts +++ b/ts/test-both/state/ducks/audioPlayer_test.ts @@ -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, { + 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)); diff --git a/ts/test-electron/context/createNativeThemeListener_test.ts b/ts/test-electron/context/createNativeThemeListener_test.ts index 04ce83561c83..cb664bcb9d28 100644 --- a/ts/test-electron/context/createNativeThemeListener_test.ts +++ b/ts/test-electron/context/createNativeThemeListener_test.ts @@ -60,9 +60,10 @@ describe('NativeThemeListener', () => { const listener = createNativeThemeListener(ipc, holder); - ipc.emit('native-theme:changed', null, { + 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, { + const state: NativeThemeState = { shouldUseDarkColors: false, - }); + }; + ipc.emit('native-theme:changed', null, state); }); });