Fully migrate to ICU

This commit is contained in:
Jamie Kyle 2023-03-29 17:03:25 -07:00 committed by GitHub
parent d4e7177ba6
commit 5e647c55d1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
274 changed files with 7948 additions and 1944 deletions

View file

@ -3,8 +3,8 @@
const crypto = require('crypto'); const crypto = require('crypto');
const messages = require('../../_locales/en/messages.json'); const globalMessages = require('../../_locales/en/messages.json');
const messageKeys = Object.keys(messages).sort((a, b) => { const messageKeys = Object.keys(globalMessages).sort((a, b) => {
return a.localeCompare(b); return a.localeCompare(b);
}); });
@ -72,10 +72,23 @@ function getIntlElementMessageKey(node) {
return valueToMessageKey(value); return valueToMessageKey(value);
} }
function isValidMessageKey(key) { function isValidMessageKey(messages, key) {
return Object.hasOwn(messages, key); return Object.hasOwn(messages, key);
} }
function isIcuMessageKey(messages, key) {
if (!key.startsWith('icu:')) {
return false;
}
const message = messages[key];
return message?.messageformat != null;
}
function isDeletedMessageKey(messages, key) {
const description = messages[key]?.description;
return description?.toLowerCase().startsWith('(deleted ');
}
module.exports = { module.exports = {
messagesCacheKey, messagesCacheKey,
meta: { meta: {
@ -89,6 +102,31 @@ module.exports = {
messagesCacheKey: { messagesCacheKey: {
type: 'string', type: 'string',
}, },
__mockMessages__: {
type: 'object',
patternProperties: {
'.*': {
oneOf: [
{
type: 'object',
properties: {
message: { type: 'string' },
description: { type: 'string' },
},
required: ['message'],
},
{
type: 'object',
properties: {
messageformat: { type: 'string' },
description: { type: 'string' },
},
required: ['messageformat'],
},
],
},
},
},
}, },
required: ['messagesCacheKey'], required: ['messagesCacheKey'],
additionalProperties: false, additionalProperties: false,
@ -103,6 +141,9 @@ module.exports = {
); );
} }
const mockMessages = context.options[0].__mockMessages__;
const messages = mockMessages ?? globalMessages;
return { return {
JSXOpeningElement(node) { JSXOpeningElement(node) {
if (!isIntlElement(node)) { if (!isIntlElement(node)) {
@ -120,14 +161,29 @@ module.exports = {
return; return;
} }
if (isValidMessageKey(key)) { if (!isValidMessageKey(messages, key)) {
context.report({
node,
message: `<Intl> id "${key}" not found in _locales/en/messages.json`,
});
return; return;
} }
context.report({ if (!isIcuMessageKey(messages, key)) {
node, context.report({
message: `<Intl> id "${key}" not found in _locales/en/messages.json`, node,
}); message: `<Intl> id "${key}" is not an ICU message in _locales/en/messages.json`,
});
return;
}
if (isDeletedMessageKey(messages, key)) {
context.report({
node,
message: `<Intl> id "${key}" is marked as deleted in _locales/en/messages.json`,
});
return;
}
}, },
CallExpression(node) { CallExpression(node) {
if (!isI18nCall(node)) { if (!isI18nCall(node)) {
@ -145,14 +201,28 @@ module.exports = {
return; return;
} }
if (isValidMessageKey(key)) { if (!isValidMessageKey(messages, key)) {
context.report({
node,
message: `i18n() key "${key}" not found in _locales/en/messages.json`,
});
return; return;
} }
context.report({ if (!isIcuMessageKey(messages, key)) {
node, context.report({
message: `i18n() key "${key}" not found in _locales/en/messages.json`, node,
}); message: `i18n() key "${key}" is not an ICU message in _locales/en/messages.json`,
});
return;
}
if (isDeletedMessageKey(messages, key)) {
context.report({
node,
message: `i18n() key "${key}" is marked as deleted in _locales/en/messages.json`,
});
}
}, },
}; };
}, },

View file

@ -6,6 +6,19 @@ const RuleTester = require('eslint').RuleTester;
const messagesCacheKey = rule.messagesCacheKey; const messagesCacheKey = rule.messagesCacheKey;
const __mockMessages__ = {
legacy_real_message: {
message: 'Legacy $message$',
},
'icu:real_message': {
messageformat: 'ICU {message}',
},
'icu:deleted_message': {
messageformat: 'shouldnt use me anymore',
description: '(deleted 01/01/1970)',
},
};
// Need to load so mocha doesn't complain about polluting the global namespace // Need to load so mocha doesn't complain about polluting the global namespace
require('@typescript-eslint/parser'); require('@typescript-eslint/parser');
@ -23,22 +36,55 @@ const ruleTester = new RuleTester({
ruleTester.run('valid-i18n-keys', rule, { ruleTester.run('valid-i18n-keys', rule, {
valid: [ valid: [
{ {
code: `i18n("AddCaptionModal__title")`, code: `i18n("icu:real_message")`,
options: [{ messagesCacheKey }], options: [{ messagesCacheKey, __mockMessages__ }],
}, },
{ {
code: `window.i18n("AddCaptionModal__title")`, code: `window.i18n("icu:real_message")`,
options: [{ messagesCacheKey }], options: [{ messagesCacheKey, __mockMessages__ }],
}, },
{ {
code: `let jsx = <Intl id="AddCaptionModal__title"/>`, code: `let jsx = <Intl id="icu:real_message"/>`,
options: [{ messagesCacheKey }], options: [{ messagesCacheKey, __mockMessages__ }],
}, },
], ],
invalid: [ invalid: [
{ {
code: 'i18n(`AddCaptionModal__${title}`)', code: `i18n("legacy_real_message")`,
options: [{ messagesCacheKey }], options: [{ messagesCacheKey, __mockMessages__ }],
errors: [
{
message:
'i18n() key "legacy_real_message" is not an ICU message in _locales/en/messages.json',
type: 'CallExpression',
},
],
},
{
code: `window.i18n("legacy_real_message")`,
options: [{ messagesCacheKey, __mockMessages__ }],
errors: [
{
message:
'i18n() key "legacy_real_message" is not an ICU message in _locales/en/messages.json',
type: 'CallExpression',
},
],
},
{
code: `let jsx = <Intl id="legacy_real_message"/>`,
options: [{ messagesCacheKey, __mockMessages__ }],
errors: [
{
message:
'<Intl> id "legacy_real_message" is not an ICU message in _locales/en/messages.json',
type: 'JSXOpeningElement',
},
],
},
{
code: 'i18n(`icu:real_${message}`)',
options: [{ messagesCacheKey, __mockMessages__ }],
errors: [ errors: [
{ {
message: "i18n()'s first argument should always be a literal string", message: "i18n()'s first argument should always be a literal string",
@ -47,8 +93,8 @@ ruleTester.run('valid-i18n-keys', rule, {
], ],
}, },
{ {
code: 'window.i18n(`AddCaptionModal__${title}`)', code: 'window.i18n(`icu:real_${message}`)',
options: [{ messagesCacheKey }], options: [{ messagesCacheKey, __mockMessages__ }],
errors: [ errors: [
{ {
message: "i18n()'s first argument should always be a literal string", message: "i18n()'s first argument should always be a literal string",
@ -57,8 +103,8 @@ ruleTester.run('valid-i18n-keys', rule, {
], ],
}, },
{ {
code: `let jsx = <Intl id={"AddCaptionModal__title"}/>`, code: `let jsx = <Intl id={"icu:real_message"}/>`,
options: [{ messagesCacheKey }], options: [{ messagesCacheKey, __mockMessages__ }],
errors: [ errors: [
{ {
message: message:
@ -68,8 +114,8 @@ ruleTester.run('valid-i18n-keys', rule, {
], ],
}, },
{ {
code: 'let jsx = <Intl id={`AddCaptionModal__title`}/>', code: 'let jsx = <Intl id={`icu:real_message`}/>',
options: [{ messagesCacheKey }], options: [{ messagesCacheKey, __mockMessages__ }],
errors: [ errors: [
{ {
message: message:
@ -79,8 +125,8 @@ ruleTester.run('valid-i18n-keys', rule, {
], ],
}, },
{ {
code: 'let jsx = <Intl id={`AddCaptionModal__${title}`}/>', code: 'let jsx = <Intl id={`icu:real_${message}`}/>',
options: [{ messagesCacheKey }], options: [{ messagesCacheKey, __mockMessages__ }],
errors: [ errors: [
{ {
message: message:
@ -91,7 +137,7 @@ ruleTester.run('valid-i18n-keys', rule, {
}, },
{ {
code: `i18n("THIS_KEY_SHOULD_NEVER_EXIST")`, code: `i18n("THIS_KEY_SHOULD_NEVER_EXIST")`,
options: [{ messagesCacheKey }], options: [{ messagesCacheKey, __mockMessages__ }],
errors: [ errors: [
{ {
message: message:
@ -101,8 +147,8 @@ ruleTester.run('valid-i18n-keys', rule, {
], ],
}, },
{ {
code: `i18n(cond ? "AddCaptionModal__title" : "AddCaptionModal__title")`, code: `i18n(cond ? "icu:real_message" : "icu:real_message")`,
options: [{ messagesCacheKey }], options: [{ messagesCacheKey, __mockMessages__ }],
errors: [ errors: [
{ {
message: "i18n()'s first argument should always be a literal string", message: "i18n()'s first argument should always be a literal string",
@ -112,7 +158,7 @@ ruleTester.run('valid-i18n-keys', rule, {
}, },
{ {
code: `i18n(42)`, code: `i18n(42)`,
options: [{ messagesCacheKey }], options: [{ messagesCacheKey, __mockMessages__ }],
errors: [ errors: [
{ {
message: "i18n()'s first argument should always be a literal string", message: "i18n()'s first argument should always be a literal string",
@ -122,7 +168,7 @@ ruleTester.run('valid-i18n-keys', rule, {
}, },
{ {
code: `let jsx = <Intl id="THIS_KEY_SHOULD_NEVER_EXIST"/>`, code: `let jsx = <Intl id="THIS_KEY_SHOULD_NEVER_EXIST"/>`,
options: [{ messagesCacheKey }], options: [{ messagesCacheKey, __mockMessages__ }],
errors: [ errors: [
{ {
message: message:
@ -132,8 +178,8 @@ ruleTester.run('valid-i18n-keys', rule, {
], ],
}, },
{ {
code: `let jsx = <Intl id={cond ? "AddCaptionModal__title" : "AddCaptionModal__title"}/>`, code: `let jsx = <Intl id={cond ? "icu:real_message" : "icu:real_message"}/>`,
options: [{ messagesCacheKey }], options: [{ messagesCacheKey, __mockMessages__ }],
errors: [ errors: [
{ {
message: message:
@ -144,7 +190,7 @@ ruleTester.run('valid-i18n-keys', rule, {
}, },
{ {
code: `let jsx = <Intl id={42}/>`, code: `let jsx = <Intl id={42}/>`,
options: [{ messagesCacheKey }], options: [{ messagesCacheKey, __mockMessages__ }],
errors: [ errors: [
{ {
message: message:
@ -153,5 +199,27 @@ ruleTester.run('valid-i18n-keys', rule, {
}, },
], ],
}, },
{
code: `i18n("icu:deleted_message")`,
options: [{ messagesCacheKey, __mockMessages__ }],
errors: [
{
message:
'i18n() key "icu:deleted_message" is marked as deleted in _locales/en/messages.json',
type: 'CallExpression',
},
],
},
{
code: `let jsx = <Intl id="icu:deleted_message"/>`,
options: [{ messagesCacheKey, __mockMessages__ }],
errors: [
{
message:
'<Intl> id "icu:deleted_message" is marked as deleted in _locales/en/messages.json',
type: 'JSXOpeningElement',
},
],
},
], ],
}); });

File diff suppressed because it is too large Load diff

View file

@ -155,7 +155,7 @@ export class SystemTrayService {
id: 'toggleWindowVisibility', id: 'toggleWindowVisibility',
...(browserWindow?.isVisible() ...(browserWindow?.isVisible()
? { ? {
label: this.i18n('hide'), label: this.i18n('icu:hide'),
click: () => { click: () => {
log.info( log.info(
'System tray service: hiding the window from the context menu' 'System tray service: hiding the window from the context menu'
@ -167,7 +167,7 @@ export class SystemTrayService {
}, },
} }
: { : {
label: this.i18n('show'), label: this.i18n('icu:show'),
click: () => { click: () => {
log.info( log.info(
'System tray service: showing the window from the context menu' 'System tray service: showing the window from the context menu'
@ -181,7 +181,7 @@ export class SystemTrayService {
}, },
{ {
id: 'quit', id: 'quit',
label: this.i18n('quit'), label: this.i18n('icu:quit'),
click: () => { click: () => {
log.info( log.info(
'System tray service: quitting the app from the context menu' 'System tray service: quitting the app from the context menu'
@ -227,7 +227,7 @@ export class SystemTrayService {
} }
}); });
result.setToolTip(this.i18n('signalDesktop')); result.setToolTip(this.i18n('icu:signalDesktop'));
return result; return result;
} }

View file

@ -41,8 +41,8 @@ function handleError(prefix: string, error: Error): void {
} }
export const updateLocale = (locale: LocaleType): void => { export const updateLocale = (locale: LocaleType): void => {
quitText = locale.i18n('quit'); quitText = locale.i18n('icu:quit');
copyErrorAndQuitText = locale.i18n('copyErrorAndQuit'); copyErrorAndQuitText = locale.i18n('icu:copyErrorAndQuit');
}; };
function _getError(reason: unknown): Error { function _getError(reason: unknown): Error {

View file

@ -930,10 +930,10 @@ async function createWindow() {
const n = new Notification({ const n = new Notification({
title: getResolvedMessagesLocale().i18n( title: getResolvedMessagesLocale().i18n(
'minimizeToTrayNotification--title' 'icu:minimizeToTrayNotification--title'
), ),
body: getResolvedMessagesLocale().i18n( body: getResolvedMessagesLocale().i18n(
'minimizeToTrayNotification--body' 'icu:minimizeToTrayNotification--body'
), ),
}); });
@ -1199,7 +1199,7 @@ async function showScreenShareWindow(sourceName: string) {
minimizable: false, minimizable: false,
resizable: false, resizable: false,
show: false, show: false,
title: getResolvedMessagesLocale().i18n('screenShareWindow'), title: getResolvedMessagesLocale().i18n('icu:screenShareWindow'),
titleBarStyle: nonMainTitleBarStyle, titleBarStyle: nonMainTitleBarStyle,
width, width,
webPreferences: { webPreferences: {
@ -1251,7 +1251,7 @@ async function showAbout() {
width: 500, width: 500,
height: 500, height: 500,
resizable: false, resizable: false,
title: getResolvedMessagesLocale().i18n('aboutSignalDesktop'), title: getResolvedMessagesLocale().i18n('icu:aboutSignalDesktop'),
titleBarStyle: nonMainTitleBarStyle, titleBarStyle: nonMainTitleBarStyle,
titleBarOverlay, titleBarOverlay,
autoHideMenuBar: true, autoHideMenuBar: true,
@ -1302,7 +1302,7 @@ async function showSettingsWindow() {
height: 700, height: 700,
frame: true, frame: true,
resizable: false, resizable: false,
title: getResolvedMessagesLocale().i18n('signalDesktopPreferences'), title: getResolvedMessagesLocale().i18n('icu:signalDesktopPreferences'),
titleBarStyle: mainTitleBarStyle, titleBarStyle: mainTitleBarStyle,
titleBarOverlay, titleBarOverlay,
autoHideMenuBar: true, autoHideMenuBar: true,
@ -1384,7 +1384,7 @@ async function showDebugLogWindow() {
width: 700, width: 700,
height: 500, height: 500,
resizable: false, resizable: false,
title: getResolvedMessagesLocale().i18n('debugLog'), title: getResolvedMessagesLocale().i18n('icu:debugLog'),
titleBarStyle: nonMainTitleBarStyle, titleBarStyle: nonMainTitleBarStyle,
titleBarOverlay, titleBarOverlay,
autoHideMenuBar: true, autoHideMenuBar: true,
@ -1449,7 +1449,7 @@ function showPermissionsPopupWindow(forCalling: boolean, forCamera: boolean) {
width: Math.min(400, size[0]), width: Math.min(400, size[0]),
height: Math.min(150, size[1]), height: Math.min(150, size[1]),
resizable: false, resizable: false,
title: getResolvedMessagesLocale().i18n('allowAccess'), title: getResolvedMessagesLocale().i18n('icu:allowAccess'),
titleBarStyle: nonMainTitleBarStyle, titleBarStyle: nonMainTitleBarStyle,
autoHideMenuBar: true, autoHideMenuBar: true,
backgroundColor: await getBackgroundColor(), backgroundColor: await getBackgroundColor(),
@ -1587,13 +1587,13 @@ const onDatabaseError = async (error: string) => {
const buttonIndex = dialog.showMessageBoxSync({ const buttonIndex = dialog.showMessageBoxSync({
buttons: [ buttons: [
getResolvedMessagesLocale().i18n('deleteAndRestart'), getResolvedMessagesLocale().i18n('icu:deleteAndRestart'),
getResolvedMessagesLocale().i18n('copyErrorAndQuit'), getResolvedMessagesLocale().i18n('icu:copyErrorAndQuit'),
], ],
defaultId: 1, defaultId: 1,
cancelId: 1, cancelId: 1,
detail: redactAll(error), detail: redactAll(error),
message: getResolvedMessagesLocale().i18n('databaseError'), message: getResolvedMessagesLocale().i18n('icu:databaseError'),
noLink: true, noLink: true,
type: 'error', type: 'error',
}); });

View file

@ -42,14 +42,14 @@ export const createTemplate = (
const template: MenuListType = [ const template: MenuListType = [
{ {
label: i18n('mainMenuFile'), label: i18n('icu:mainMenuFile'),
submenu: [ submenu: [
{ {
label: i18n('mainMenuCreateStickers'), label: i18n('icu:mainMenuCreateStickers'),
click: openArtCreator, click: openArtCreator,
}, },
{ {
label: i18n('mainMenuSettings'), label: i18n('icu:mainMenuSettings'),
accelerator: 'CommandOrControl+,', accelerator: 'CommandOrControl+,',
click: showSettings, click: showSettings,
}, },
@ -58,78 +58,78 @@ export const createTemplate = (
}, },
{ {
role: 'quit', role: 'quit',
label: i18n('appMenuQuit'), label: i18n('icu:appMenuQuit'),
}, },
], ],
}, },
{ {
label: i18n('mainMenuEdit'), label: i18n('icu:mainMenuEdit'),
submenu: [ submenu: [
{ {
role: 'undo', role: 'undo',
label: i18n('editMenuUndo'), label: i18n('icu:editMenuUndo'),
}, },
{ {
role: 'redo', role: 'redo',
label: i18n('editMenuRedo'), label: i18n('icu:editMenuRedo'),
}, },
{ {
type: 'separator', type: 'separator',
}, },
{ {
role: 'cut', role: 'cut',
label: i18n('editMenuCut'), label: i18n('icu:editMenuCut'),
}, },
{ {
role: 'copy', role: 'copy',
label: i18n('editMenuCopy'), label: i18n('icu:editMenuCopy'),
}, },
{ {
role: 'paste', role: 'paste',
label: i18n('editMenuPaste'), label: i18n('icu:editMenuPaste'),
}, },
{ {
role: 'pasteAndMatchStyle', role: 'pasteAndMatchStyle',
label: i18n('editMenuPasteAndMatchStyle'), label: i18n('icu:editMenuPasteAndMatchStyle'),
}, },
{ {
role: 'delete', role: 'delete',
label: i18n('editMenuDelete'), label: i18n('icu:editMenuDelete'),
}, },
{ {
role: 'selectAll', role: 'selectAll',
label: i18n('editMenuSelectAll'), label: i18n('icu:editMenuSelectAll'),
}, },
], ],
}, },
{ {
label: i18n('mainMenuView'), label: i18n('icu:mainMenuView'),
submenu: [ submenu: [
{ {
role: 'resetZoom', role: 'resetZoom',
label: i18n('viewMenuResetZoom'), label: i18n('icu:viewMenuResetZoom'),
}, },
{ {
accelerator: 'CmdOrCtrl+=', accelerator: 'CmdOrCtrl+=',
role: 'zoomIn', role: 'zoomIn',
label: i18n('viewMenuZoomIn'), label: i18n('icu:viewMenuZoomIn'),
}, },
{ {
role: 'zoomOut', role: 'zoomOut',
label: i18n('viewMenuZoomOut'), label: i18n('icu:viewMenuZoomOut'),
}, },
{ {
type: 'separator', type: 'separator',
}, },
{ {
role: 'togglefullscreen', role: 'togglefullscreen',
label: i18n('viewMenuToggleFullScreen'), label: i18n('icu:viewMenuToggleFullScreen'),
}, },
{ {
type: 'separator', type: 'separator',
}, },
{ {
label: i18n('debugLog'), label: i18n('icu:debugLog'),
click: showDebugLog, click: showDebugLog,
}, },
...(devTools ...(devTools
@ -139,14 +139,14 @@ export const createTemplate = (
}, },
{ {
role: 'toggleDevTools' as const, role: 'toggleDevTools' as const,
label: i18n('viewMenuToggleDevTools'), label: i18n('icu:viewMenuToggleDevTools'),
}, },
] ]
: []), : []),
...(devTools && platform !== 'linux' ...(devTools && platform !== 'linux'
? [ ? [
{ {
label: i18n('forceUpdate'), label: i18n('icu:forceUpdate'),
click: forceUpdate, click: forceUpdate,
}, },
] ]
@ -154,21 +154,21 @@ export const createTemplate = (
], ],
}, },
{ {
label: i18n('mainMenuWindow'), label: i18n('icu:mainMenuWindow'),
role: 'window', role: 'window',
submenu: [ submenu: [
{ {
role: 'minimize', role: 'minimize',
label: i18n('windowMenuMinimize'), label: i18n('icu:windowMenuMinimize'),
}, },
], ],
}, },
{ {
label: i18n('mainMenuHelp'), label: i18n('icu:mainMenuHelp'),
role: 'help', role: 'help',
submenu: [ submenu: [
{ {
label: i18n('helpMenuShowKeyboardShortcuts'), label: i18n('icu:helpMenuShowKeyboardShortcuts'),
accelerator: 'CmdOrCtrl+/', accelerator: 'CmdOrCtrl+/',
click: showKeyboardShortcuts, click: showKeyboardShortcuts,
}, },
@ -176,25 +176,25 @@ export const createTemplate = (
type: 'separator', type: 'separator',
}, },
{ {
label: i18n('contactUs'), label: i18n('icu:contactUs'),
click: openContactUs, click: openContactUs,
}, },
{ {
label: i18n('goToReleaseNotes'), label: i18n('icu:goToReleaseNotes'),
click: openReleaseNotes, click: openReleaseNotes,
}, },
{ {
label: i18n('goToForums'), label: i18n('icu:goToForums'),
click: openForums, click: openForums,
}, },
{ {
label: i18n('goToSupportPage'), label: i18n('icu:goToSupportPage'),
click: openSupportPage, click: openSupportPage,
}, },
...(isProduction ...(isProduction
? [ ? [
{ {
label: i18n('joinTheBeta'), label: i18n('icu:joinTheBeta'),
click: openJoinTheBeta, click: openJoinTheBeta,
}, },
] ]
@ -203,7 +203,7 @@ export const createTemplate = (
type: 'separator', type: 'separator',
}, },
{ {
label: i18n('aboutSignalDesktop'), label: i18n('icu:aboutSignalDesktop'),
click: showAbout, click: showAbout,
}, },
], ],
@ -217,7 +217,7 @@ export const createTemplate = (
// These are in reverse order, since we're prepending them one at a time // These are in reverse order, since we're prepending them one at a time
if (options.development) { if (options.development) {
fileMenu.submenu.unshift({ fileMenu.submenu.unshift({
label: i18n('menuSetupAsStandalone'), label: i18n('icu:menuSetupAsStandalone'),
click: setupAsStandalone, click: setupAsStandalone,
}); });
} }
@ -226,7 +226,7 @@ export const createTemplate = (
type: 'separator', type: 'separator',
}); });
fileMenu.submenu.unshift({ fileMenu.submenu.unshift({
label: i18n('menuSetupAsNewDevice'), label: i18n('icu:menuSetupAsNewDevice'),
click: setupAsNewDevice, click: setupAsNewDevice,
}); });
} else { } else {
@ -270,7 +270,7 @@ function updateForMac(
type: 'separator', type: 'separator',
}, },
{ {
label: i18n('windowMenuClose'), label: i18n('icu:windowMenuClose'),
accelerator: 'CmdOrCtrl+W', accelerator: 'CmdOrCtrl+W',
role: 'close', role: 'close',
} }
@ -281,17 +281,17 @@ function updateForMac(
// Add the OSX-specific Signal Desktop menu at the far left // Add the OSX-specific Signal Desktop menu at the far left
template.unshift({ template.unshift({
label: i18n('signalDesktop'), label: i18n('icu:signalDesktop'),
submenu: [ submenu: [
{ {
label: i18n('aboutSignalDesktop'), label: i18n('icu:aboutSignalDesktop'),
click: showAbout, click: showAbout,
}, },
{ {
type: 'separator', type: 'separator',
}, },
{ {
label: i18n('mainMenuSettings'), label: i18n('icu:mainMenuSettings'),
accelerator: 'CommandOrControl+,', accelerator: 'CommandOrControl+,',
click: showSettings, click: showSettings,
}, },
@ -299,29 +299,29 @@ function updateForMac(
type: 'separator', type: 'separator',
}, },
{ {
label: i18n('appMenuServices'), label: i18n('icu:appMenuServices'),
role: 'services', role: 'services',
}, },
{ {
type: 'separator', type: 'separator',
}, },
{ {
label: i18n('appMenuHide'), label: i18n('icu:appMenuHide'),
role: 'hide', role: 'hide',
}, },
{ {
label: i18n('appMenuHideOthers'), label: i18n('icu:appMenuHideOthers'),
role: 'hideOthers', role: 'hideOthers',
}, },
{ {
label: i18n('appMenuUnhide'), label: i18n('icu:appMenuUnhide'),
role: 'unhide', role: 'unhide',
}, },
{ {
type: 'separator', type: 'separator',
}, },
{ {
label: i18n('appMenuQuit'), label: i18n('icu:appMenuQuit'),
role: 'quit', role: 'quit',
}, },
], ],
@ -334,15 +334,15 @@ function updateForMac(
type: 'separator', type: 'separator',
}, },
{ {
label: i18n('speech'), label: i18n('icu:speech'),
submenu: [ submenu: [
{ {
role: 'startSpeaking', role: 'startSpeaking',
label: i18n('editMenuStartSpeaking'), label: i18n('icu:editMenuStartSpeaking'),
}, },
{ {
role: 'stopSpeaking', role: 'stopSpeaking',
label: i18n('editMenuStopSpeaking'), label: i18n('icu:editMenuStopSpeaking'),
}, },
], ],
} }
@ -355,16 +355,16 @@ function updateForMac(
// eslint-disable-next-line no-param-reassign // eslint-disable-next-line no-param-reassign
template[4].submenu = [ template[4].submenu = [
{ {
label: i18n('windowMenuMinimize'), label: i18n('icu:windowMenuMinimize'),
accelerator: 'CmdOrCtrl+M', accelerator: 'CmdOrCtrl+M',
role: 'minimize', role: 'minimize',
}, },
{ {
label: i18n('windowMenuZoom'), label: i18n('icu:windowMenuZoom'),
role: 'zoom', role: 'zoom',
}, },
{ {
label: i18n('show'), label: i18n('icu:show'),
accelerator: 'CmdOrCtrl+Shift+0', accelerator: 'CmdOrCtrl+Shift+0',
click: showWindow, click: showWindow,
}, },
@ -373,7 +373,7 @@ function updateForMac(
}, },
{ {
role: 'front', role: 'front',
label: i18n('windowMenuBringAllToFront'), label: i18n('icu:windowMenuBringAllToFront'),
}, },
]; ];

View file

@ -68,7 +68,7 @@ export const setup = (
); );
} else { } else {
template.push({ template.push({
label: i18n('contextMenuNoSuggestions'), label: i18n('icu:contextMenuNoSuggestions'),
enabled: false, enabled: false,
}); });
} }
@ -77,18 +77,18 @@ export const setup = (
if (params.isEditable) { if (params.isEditable) {
if (editFlags.canUndo) { if (editFlags.canUndo) {
template.push({ label: i18n('editMenuUndo'), role: 'undo' }); template.push({ label: i18n('icu:editMenuUndo'), role: 'undo' });
} }
// This is only ever `true` if undo was triggered via the context menu // This is only ever `true` if undo was triggered via the context menu
// (not ctrl/cmd+z) // (not ctrl/cmd+z)
if (editFlags.canRedo) { if (editFlags.canRedo) {
template.push({ label: i18n('editMenuRedo'), role: 'redo' }); template.push({ label: i18n('icu:editMenuRedo'), role: 'redo' });
} }
if (editFlags.canUndo || editFlags.canRedo) { if (editFlags.canUndo || editFlags.canRedo) {
template.push({ type: 'separator' }); template.push({ type: 'separator' });
} }
if (editFlags.canCut) { if (editFlags.canCut) {
template.push({ label: i18n('editMenuCut'), role: 'cut' }); template.push({ label: i18n('icu:editMenuCut'), role: 'cut' });
} }
} }
@ -100,7 +100,7 @@ export const setup = (
click = () => { click = () => {
clipboard.writeText(params.linkURL); clipboard.writeText(params.linkURL);
}; };
label = i18n('contextMenuCopyLink'); label = i18n('icu:contextMenuCopyLink');
} else if (isImage) { } else if (isImage) {
click = () => { click = () => {
const parsedSrcUrl = maybeParseUrl(params.srcURL); const parsedSrcUrl = maybeParseUrl(params.srcURL);
@ -113,9 +113,9 @@ export const setup = (
); );
clipboard.writeImage(image); clipboard.writeImage(image);
}; };
label = i18n('contextMenuCopyImage'); label = i18n('icu:contextMenuCopyImage');
} else { } else {
label = i18n('editMenuCopy'); label = i18n('icu:editMenuCopy');
} }
template.push({ template.push({
@ -126,12 +126,12 @@ export const setup = (
} }
if (editFlags.canPaste && !isImage) { if (editFlags.canPaste && !isImage) {
template.push({ label: i18n('editMenuPaste'), role: 'paste' }); template.push({ label: i18n('icu:editMenuPaste'), role: 'paste' });
} }
if (editFlags.canPaste && !isImage) { if (editFlags.canPaste && !isImage) {
template.push({ template.push({
label: i18n('editMenuPasteAndMatchStyle'), label: i18n('icu:editMenuPasteAndMatchStyle'),
role: 'pasteAndMatchStyle', role: 'pasteAndMatchStyle',
}); });
} }
@ -140,7 +140,7 @@ export const setup = (
// results in all the UI being selected // results in all the UI being selected
if (editFlags.canSelectAll && params.isEditable) { if (editFlags.canSelectAll && params.isEditable) {
template.push({ template.push({
label: i18n('editMenuSelectAll'), label: i18n('icu:editMenuSelectAll'),
role: 'selectAll', role: 'selectAll',
}); });
} }

View file

@ -628,10 +628,10 @@ export async function startApp(): Promise<void> {
showConfirmationDialog({ showConfirmationDialog({
dialogName: 'deleteOldIndexedDBData', dialogName: 'deleteOldIndexedDBData',
onTopOfEverything: true, onTopOfEverything: true,
cancelText: window.i18n('quit'), cancelText: window.i18n('icu:quit'),
confirmStyle: 'negative', confirmStyle: 'negative',
title: window.i18n('deleteOldIndexedDBData'), title: window.i18n('icu:deleteOldIndexedDBData'),
okText: window.i18n('deleteOldData'), okText: window.i18n('icu:deleteOldData'),
reject: () => reject(), reject: () => reject(),
resolve: () => resolve(), resolve: () => resolve(),
}); });
@ -915,7 +915,7 @@ export async function startApp(): Promise<void> {
} }
setAppLoadingScreenMessage( setAppLoadingScreenMessage(
window.i18n('optimizingApplication'), window.i18n('icu:optimizingApplication'),
window.i18n window.i18n
); );
@ -934,7 +934,7 @@ export async function startApp(): Promise<void> {
log.error('SQL failed to initialize', Errors.toLogFormat(err)); log.error('SQL failed to initialize', Errors.toLogFormat(err));
} }
setAppLoadingScreenMessage(window.i18n('loading'), window.i18n); setAppLoadingScreenMessage(window.i18n('icu:loading'), window.i18n);
let isMigrationWithIndexComplete = false; let isMigrationWithIndexComplete = false;
let isIdleTaskProcessing = false; let isIdleTaskProcessing = false;

View file

@ -51,12 +51,12 @@ export function About({
className="acknowledgments" className="acknowledgments"
href="https://github.com/signalapp/Signal-Desktop/blob/main/ACKNOWLEDGMENTS.md" href="https://github.com/signalapp/Signal-Desktop/blob/main/ACKNOWLEDGMENTS.md"
> >
{i18n('softwareAcknowledgments')} {i18n('icu:softwareAcknowledgments')}
</a> </a>
</div> </div>
<div> <div>
<a className="privacy" href="https://signal.org/legal"> <a className="privacy" href="https://signal.org/legal">
{i18n('privacyPolicy')} {i18n('icu:privacyPolicy')}
</a> </a>
</div> </div>
</div> </div>

View file

@ -63,18 +63,18 @@ export function AddCaptionModal({
hasFooterDivider={!isScrolledBottom} hasFooterDivider={!isScrolledBottom}
moduleClassName="AddCaptionModal" moduleClassName="AddCaptionModal"
padded={false} padded={false}
title={i18n('AddCaptionModal__title')} title={i18n('icu:AddCaptionModal__title')}
onClose={onClose} onClose={onClose}
modalFooter={ modalFooter={
<Button onClick={handleSubmit}> <Button onClick={handleSubmit}>
{i18n('AddCaptionModal__submit-button')} {i18n('icu:AddCaptionModal__submit-button')}
</Button> </Button>
} }
> >
<RenderCompositionTextArea <RenderCompositionTextArea
maxLength={1500} maxLength={1500}
whenToShowRemainingCount={1450} whenToShowRemainingCount={1450}
placeholder={i18n('AddCaptionModal__placeholder')} placeholder={i18n('icu:AddCaptionModal__placeholder')}
onChange={setMessageText} onChange={setMessageText}
scrollerRef={scrollerRef} scrollerRef={scrollerRef}
draftText={draftText} draftText={draftText}

View file

@ -36,18 +36,23 @@ export function AddGroupMemberErrorDialog(props: PropsType): JSX.Element {
switch (props.mode) { switch (props.mode) {
case AddGroupMemberErrorDialogMode.MaximumGroupSize: { case AddGroupMemberErrorDialogMode.MaximumGroupSize: {
const { maximumNumberOfContacts } = props; const { maximumNumberOfContacts } = props;
title = i18n('chooseGroupMembers__maximum-group-size__title'); title = i18n('icu:chooseGroupMembers__maximum-group-size__title');
body = i18n('chooseGroupMembers__maximum-group-size__body', { body = i18n('icu:chooseGroupMembers__maximum-group-size__body', {
max: maximumNumberOfContacts.toString(), max: maximumNumberOfContacts.toString(),
}); });
break; break;
} }
case AddGroupMemberErrorDialogMode.RecommendedMaximumGroupSize: { case AddGroupMemberErrorDialogMode.RecommendedMaximumGroupSize: {
const { recommendedMaximumNumberOfContacts } = props; const { recommendedMaximumNumberOfContacts } = props;
title = i18n('chooseGroupMembers__maximum-recommended-group-size__title'); title = i18n(
body = i18n('chooseGroupMembers__maximum-recommended-group-size__body', { 'icu:chooseGroupMembers__maximum-recommended-group-size__title'
max: recommendedMaximumNumberOfContacts.toString(), );
}); body = i18n(
'icu:chooseGroupMembers__maximum-recommended-group-size__body',
{
max: recommendedMaximumNumberOfContacts.toString(),
}
);
break; break;
} }
default: default:

View file

@ -171,14 +171,14 @@ export function AddUserToAnotherGroupModal({
hasXButton hasXButton
i18n={i18n} i18n={i18n}
onClose={toggleAddUserToAnotherGroupModal} onClose={toggleAddUserToAnotherGroupModal}
title={i18n('AddUserToAnotherGroupModal__title')} title={i18n('icu:AddUserToAnotherGroupModal__title')}
moduleClassName="AddUserToAnotherGroupModal" moduleClassName="AddUserToAnotherGroupModal"
padded={false} padded={false}
> >
<div className="AddUserToAnotherGroupModal__main-body"> <div className="AddUserToAnotherGroupModal__main-body">
<SearchInput <SearchInput
i18n={i18n} i18n={i18n}
placeholder={i18n('contactSearchPlaceholder')} placeholder={i18n('icu:contactSearchPlaceholder')}
onChange={handleSearchInputChange} onChange={handleSearchInputChange}
ref={inputRef} ref={inputRef}
value={searchTerm} value={searchTerm}
@ -217,12 +217,12 @@ export function AddUserToAnotherGroupModal({
{selectedGroupId && selectedGroup && ( {selectedGroupId && selectedGroup && (
<ConfirmationDialog <ConfirmationDialog
dialogName="AddUserToAnotherGroupModal__confirm" dialogName="AddUserToAnotherGroupModal__confirm"
title={i18n('AddUserToAnotherGroupModal__confirm-title')} title={i18n('icu:AddUserToAnotherGroupModal__confirm-title')}
i18n={i18n} i18n={i18n}
onClose={() => setSelectedGroupId(undefined)} onClose={() => setSelectedGroupId(undefined)}
actions={[ actions={[
{ {
text: i18n('AddUserToAnotherGroupModal__confirm-add'), text: i18n('icu:AddUserToAnotherGroupModal__confirm-add'),
style: 'affirmative', style: 'affirmative',
action: () => { action: () => {
showToast(ToastType.AddingUserToGroup, { showToast(ToastType.AddingUserToGroup, {
@ -240,7 +240,7 @@ export function AddUserToAnotherGroupModal({
}, },
]} ]}
> >
{i18n('AddUserToAnotherGroupModal__confirm-message', { {i18n('icu:AddUserToAnotherGroupModal__confirm-message', {
contact: contact.title, contact: contact.title,
group: selectedGroup.title, group: selectedGroup.title,
})} })}

View file

@ -28,7 +28,7 @@ export function Alert({
<Modal <Modal
i18n={i18n} i18n={i18n}
modalFooter={ modalFooter={
<Button onClick={onClose}>{i18n('Confirmation--confirm')}</Button> <Button onClick={onClose}>{i18n('icu:Confirmation--confirm')}</Button>
} }
modalName="Alert" modalName="Alert"
onClose={onClose} onClose={onClose}

View file

@ -33,7 +33,7 @@ export function AnnouncementsOnlyGroupBanner({
modalName="AnnouncmentsOnlyGroupBanner" modalName="AnnouncmentsOnlyGroupBanner"
i18n={i18n} i18n={i18n}
onClose={() => setIsShowingAdmins(false)} onClose={() => setIsShowingAdmins(false)}
title={i18n('AnnouncementsOnlyGroupBanner--modal')} title={i18n('icu:AnnouncementsOnlyGroupBanner--modal')}
> >
{groupAdmins.map(admin => ( {groupAdmins.map(admin => (
<ConversationListItem <ConversationListItem
@ -53,7 +53,7 @@ export function AnnouncementsOnlyGroupBanner({
<div className="AnnouncementsOnlyGroupBanner__banner"> <div className="AnnouncementsOnlyGroupBanner__banner">
<Intl <Intl
i18n={i18n} i18n={i18n}
id="AnnouncementsOnlyGroupBanner--announcements-only" id="icu:AnnouncementsOnlyGroupBanner--announcements-only"
components={{ components={{
admins: ( admins: (
<button <button
@ -61,7 +61,7 @@ export function AnnouncementsOnlyGroupBanner({
type="button" type="button"
onClick={() => setIsShowingAdmins(true)} onClick={() => setIsShowingAdmins(true)}
> >
{i18n('AnnouncementsOnlyGroupBanner--admins')} {i18n('icu:AnnouncementsOnlyGroupBanner--admins')}
</button> </button>
), ),
}} }}

View file

@ -180,7 +180,7 @@ export function Avatar({
}} }}
/> />
{blur === AvatarBlur.BlurPictureWithClickToView && ( {blur === AvatarBlur.BlurPictureWithClickToView && (
<div className="module-Avatar__click-to-view">{i18n('view')}</div> <div className="module-Avatar__click-to-view">{i18n('icu:view')}</div>
)} )}
</> </>
); );
@ -283,7 +283,7 @@ export function Avatar({
return ( return (
<div <div
aria-label={i18n('contactAvatarAlt', { aria-label={i18n('icu:contactAvatarAlt', {
name: title, name: title,
})} })}
className={classNames( className={classNames(

View file

@ -21,7 +21,7 @@ export function AvatarColorPicker({
return ( return (
<> <>
<div className="AvatarEditor__avatar-selector-title"> <div className="AvatarEditor__avatar-selector-title">
{i18n('AvatarColorPicker--choose')} {i18n('icu:AvatarColorPicker--choose')}
</div> </div>
<div className="AvatarEditor__avatars"> <div className="AvatarEditor__avatars">
{AvatarColors.map(color => ( {AvatarColors.map(color => (

View file

@ -196,13 +196,13 @@ export function AvatarEditor({
}} }}
type="button" type="button"
> >
{i18n('text')} {i18n('icu:text')}
</button> </button>
</div> </div>
</div> </div>
<hr className="AvatarEditor__divider" /> <hr className="AvatarEditor__divider" />
<div className="AvatarEditor__avatar-selector-title"> <div className="AvatarEditor__avatar-selector-title">
{i18n('AvatarEditor--choose')} {i18n('icu:AvatarEditor--choose')}
</div> </div>
<div className="AvatarEditor__avatars"> <div className="AvatarEditor__avatars">
{localAvatarData.map(avatarData => ( {localAvatarData.map(avatarData => (

View file

@ -37,10 +37,10 @@ export function AvatarModalButtons({
}} }}
variant={ButtonVariant.Secondary} variant={ButtonVariant.Secondary}
> >
{i18n('cancel')} {i18n('icu:cancel')}
</Button> </Button>
<Button disabled={!hasChanges} onClick={onSave}> <Button disabled={!hasChanges} onClick={onSave}>
{i18n('save')} {i18n('icu:save')}
</Button> </Button>
{confirmDiscardAction && ( {confirmDiscardAction && (
<ConfirmDiscardDialog <ConfirmDiscardDialog

View file

@ -83,7 +83,7 @@ export function AvatarPopup(props: Props): JSX.Element {
)} )}
/> />
<div className="module-avatar-popup__item__text"> <div className="module-avatar-popup__item__text">
{i18n('mainMenuSettings')} {i18n('icu:mainMenuSettings')}
</div> </div>
</button> </button>
<button <button
@ -98,7 +98,7 @@ export function AvatarPopup(props: Props): JSX.Element {
)} )}
/> />
<div className="module-avatar-popup__item__text"> <div className="module-avatar-popup__item__text">
{i18n('avatarMenuViewArchive')} {i18n('icu:avatarMenuViewArchive')}
</div> </div>
</button> </button>
{hasPendingUpdate && ( {hasPendingUpdate && (
@ -114,7 +114,7 @@ export function AvatarPopup(props: Props): JSX.Element {
)} )}
/> />
<div className="module-avatar-popup__item__text"> <div className="module-avatar-popup__item__text">
{i18n('avatarMenuUpdateAvailable')} {i18n('icu:avatarMenuUpdateAvailable')}
</div> </div>
<div className="module-avatar-popup__item--badge" /> <div className="module-avatar-popup__item--badge" />
</button> </button>

View file

@ -188,7 +188,7 @@ export function AvatarPreview({
)} )}
{imageStatus === ImageStatus.HasImage && onClear && ( {imageStatus === ImageStatus.HasImage && onClear && (
<button <button
aria-label={i18n('delete')} aria-label={i18n('icu:delete')}
className="AvatarPreview__clear" className="AvatarPreview__clear"
onClick={onClear} onClick={onClear}
tabIndex={-1} tabIndex={-1}

View file

@ -73,7 +73,7 @@ export function AvatarUploadButton({
}} }}
type="button" type="button"
> >
{i18n('photo')} {i18n('icu:photo')}
</button> </button>
<input <input
accept=".gif,.jpg,.jpeg,.png,.webp,image/gif,image/jpeg,image/png,image/webp" accept=".gif,.jpg,.jpeg,.png,.webp,image/gif,image/jpeg,image/png,image/webp"

View file

@ -101,7 +101,7 @@ function BadgeDialogWithBadges({
> >
<div className="BadgeDialog__contents"> <div className="BadgeDialog__contents">
<button <button
aria-label={i18n('previous')} aria-label={i18n('icu:previous')}
className="BadgeDialog__nav BadgeDialog__nav--previous" className="BadgeDialog__nav BadgeDialog__nav--previous"
disabled={currentBadgeIndex === 0} disabled={currentBadgeIndex === 0}
onClick={() => navigate(-1)} onClick={() => navigate(-1)}
@ -127,7 +127,7 @@ function BadgeDialogWithBadges({
onClick={onShowInstructions} onClick={onShowInstructions}
size={ButtonSize.Large} size={ButtonSize.Large}
> >
{i18n('BadgeDialog__become-a-sustainer-button')} {i18n('icu:BadgeDialog__become-a-sustainer-button')}
</Button> </Button>
)} )}
<BadgeCarouselIndex <BadgeCarouselIndex
@ -136,7 +136,7 @@ function BadgeDialogWithBadges({
/> />
</div> </div>
<button <button
aria-label={i18n('next')} aria-label={i18n('icu:next')}
className="BadgeDialog__nav BadgeDialog__nav--next" className="BadgeDialog__nav BadgeDialog__nav--next"
disabled={currentBadgeIndex === badges.length - 1} disabled={currentBadgeIndex === badges.length - 1}
onClick={() => navigate(1)} onClick={() => navigate(1)}

View file

@ -19,15 +19,15 @@ export function BadgeSustainerInstructionsDialog({
onClose={onClose} onClose={onClose}
> >
<h1 className="BadgeSustainerInstructionsDialog__header"> <h1 className="BadgeSustainerInstructionsDialog__header">
{i18n('BadgeSustainerInstructions__header')} {i18n('icu:BadgeSustainerInstructions__header')}
</h1> </h1>
<h2 className="BadgeSustainerInstructionsDialog__subheader"> <h2 className="BadgeSustainerInstructionsDialog__subheader">
{i18n('BadgeSustainerInstructions__subheader')} {i18n('icu:BadgeSustainerInstructions__subheader')}
</h2> </h2>
<ol className="BadgeSustainerInstructionsDialog__instructions"> <ol className="BadgeSustainerInstructionsDialog__instructions">
<li>{i18n('BadgeSustainerInstructions__instructions__1')}</li> <li>{i18n('icu:BadgeSustainerInstructions__instructions__1')}</li>
<li>{i18n('BadgeSustainerInstructions__instructions__2')}</li> <li>{i18n('icu:BadgeSustainerInstructions__instructions__2')}</li>
<li>{i18n('BadgeSustainerInstructions__instructions__3')}</li> <li>{i18n('icu:BadgeSustainerInstructions__instructions__3')}</li>
</ol> </ol>
</Modal> </Modal>
); );

View file

@ -48,7 +48,7 @@ export function BetterAvatarBubble({
> >
{onDelete && ( {onDelete && (
<button <button
aria-label={i18n('delete')} aria-label={i18n('icu:delete')}
className="BetterAvatarBubble__delete" className="BetterAvatarBubble__delete"
onClick={onDelete} onClick={onDelete}
tabIndex={-1} tabIndex={-1}

View file

@ -362,7 +362,7 @@ function ActiveCallManager({
{activeCall.callMode === CallMode.Group && {activeCall.callMode === CallMode.Group &&
activeCall.conversationsWithSafetyNumberChanges.length ? ( activeCall.conversationsWithSafetyNumberChanges.length ? (
<SafetyNumberChangeDialog <SafetyNumberChangeDialog
confirmText={i18n('continueCall')} confirmText={i18n('icu:continueCall')}
contacts={[ contacts={[
{ {
story: undefined, story: undefined,

View file

@ -34,7 +34,7 @@ export function CallNeedPermissionScreen({
i18n, i18n,
close, close,
}: Props): JSX.Element { }: Props): JSX.Element {
const title = conversation.title || i18n('unknownContact'); const title = conversation.title || i18n('icu:unknownContact');
const autoCloseAtRef = useRef<number>(Date.now() + AUTO_CLOSE_MS); const autoCloseAtRef = useRef<number>(Date.now() + AUTO_CLOSE_MS);
useEffect(() => { useEffect(() => {
@ -63,7 +63,7 @@ export function CallNeedPermissionScreen({
<p className="module-call-need-permission-screen__text"> <p className="module-call-need-permission-screen__text">
<Intl <Intl
i18n={i18n} i18n={i18n}
id="callNeedPermission" id="icu:callNeedPermission"
components={{ components={{
title: <ContactName title={title} />, title: <ContactName title={title} />,
}} }}
@ -77,7 +77,7 @@ export function CallNeedPermissionScreen({
close(); close();
}} }}
> >
{i18n('close')} {i18n('icu:close')}
</button> </button>
</div> </div>
); );

View file

@ -115,12 +115,12 @@ function DirectCallHeaderMessage({
}, [joinedAt]); }, [joinedAt]);
if (callState === CallState.Reconnecting) { if (callState === CallState.Reconnecting) {
return <>{i18n('callReconnecting')}</>; return <>{i18n('icu:callReconnecting')}</>;
} }
if (callState === CallState.Accepted && acceptedDuration) { if (callState === CallState.Accepted && acceptedDuration) {
return ( return (
<> <>
{i18n('callDuration', { {i18n('icu:callDuration', {
duration: renderDuration(acceptedDuration), duration: renderDuration(acceptedDuration),
})} })}
</> </>
@ -318,11 +318,11 @@ export function CallScreen({
if (isRinging) { if (isRinging) {
headerTitle = undefined; headerTitle = undefined;
} else if (currentPresenter) { } else if (currentPresenter) {
headerTitle = i18n('calling__presenting--person-ongoing', { headerTitle = i18n('icu:calling__presenting--person-ongoing', {
name: currentPresenter.title, name: currentPresenter.title,
}); });
} else if (!activeCall.remoteParticipants.length) { } else if (!activeCall.remoteParticipants.length) {
headerTitle = i18n('calling__in-this-call--zero'); headerTitle = i18n('icu:calling__in-this-call--zero');
} }
isConnected = isConnected =
@ -378,7 +378,7 @@ export function CallScreen({
size={AvatarSize.EIGHTY} size={AvatarSize.EIGHTY}
/> />
<div className="module-calling__camera-is-off"> <div className="module-calling__camera-is-off">
{i18n('calling__your-video-is-off')} {i18n('icu:calling__your-video-is-off')}
</div> </div>
</CallBackgroundBlur> </CallBackgroundBlur>
)} )}

View file

@ -52,62 +52,62 @@ export function CallingButton({
let disabled = false; let disabled = false;
if (buttonType === CallingButtonType.AUDIO_DISABLED) { if (buttonType === CallingButtonType.AUDIO_DISABLED) {
classNameSuffix = 'audio--disabled'; classNameSuffix = 'audio--disabled';
tooltipContent = i18n('calling__button--audio-disabled'); tooltipContent = i18n('icu:calling__button--audio-disabled');
label = i18n('calling__button--audio__label'); label = i18n('icu:calling__button--audio__label');
disabled = true; disabled = true;
} else if (buttonType === CallingButtonType.AUDIO_OFF) { } else if (buttonType === CallingButtonType.AUDIO_OFF) {
classNameSuffix = 'audio--off'; classNameSuffix = 'audio--off';
tooltipContent = i18n('calling__button--audio-on'); tooltipContent = i18n('icu:calling__button--audio-on');
label = i18n('calling__button--audio__label'); label = i18n('icu:calling__button--audio__label');
} else if (buttonType === CallingButtonType.AUDIO_ON) { } else if (buttonType === CallingButtonType.AUDIO_ON) {
classNameSuffix = 'audio--on'; classNameSuffix = 'audio--on';
tooltipContent = i18n('calling__button--audio-off'); tooltipContent = i18n('icu:calling__button--audio-off');
label = i18n('calling__button--audio__label'); label = i18n('icu:calling__button--audio__label');
} else if (buttonType === CallingButtonType.VIDEO_DISABLED) { } else if (buttonType === CallingButtonType.VIDEO_DISABLED) {
classNameSuffix = 'video--disabled'; classNameSuffix = 'video--disabled';
tooltipContent = i18n('calling__button--video-disabled'); tooltipContent = i18n('icu:calling__button--video-disabled');
disabled = true; disabled = true;
label = i18n('calling__button--video__label'); label = i18n('icu:calling__button--video__label');
} else if (buttonType === CallingButtonType.VIDEO_OFF) { } else if (buttonType === CallingButtonType.VIDEO_OFF) {
classNameSuffix = 'video--off'; classNameSuffix = 'video--off';
tooltipContent = i18n('calling__button--video-on'); tooltipContent = i18n('icu:calling__button--video-on');
label = i18n('calling__button--video__label'); label = i18n('icu:calling__button--video__label');
} else if (buttonType === CallingButtonType.VIDEO_ON) { } else if (buttonType === CallingButtonType.VIDEO_ON) {
classNameSuffix = 'video--on'; classNameSuffix = 'video--on';
tooltipContent = i18n('calling__button--video-off'); tooltipContent = i18n('icu:calling__button--video-off');
label = i18n('calling__button--video__label'); label = i18n('icu:calling__button--video__label');
} else if (buttonType === CallingButtonType.HANG_UP) { } else if (buttonType === CallingButtonType.HANG_UP) {
classNameSuffix = 'hangup'; classNameSuffix = 'hangup';
tooltipContent = i18n('calling__hangup'); tooltipContent = i18n('icu:calling__hangup');
label = i18n('calling__hangup'); label = i18n('icu:calling__hangup');
} else if (buttonType === CallingButtonType.RING_DISABLED) { } else if (buttonType === CallingButtonType.RING_DISABLED) {
classNameSuffix = 'ring--disabled'; classNameSuffix = 'ring--disabled';
disabled = true; disabled = true;
tooltipContent = i18n( tooltipContent = i18n(
'calling__button--ring__disabled-because-group-is-too-large' 'icu:calling__button--ring__disabled-because-group-is-too-large'
); );
label = i18n('calling__button--ring__label'); label = i18n('icu:calling__button--ring__label');
} else if (buttonType === CallingButtonType.RING_OFF) { } else if (buttonType === CallingButtonType.RING_OFF) {
classNameSuffix = 'ring--off'; classNameSuffix = 'ring--off';
tooltipContent = i18n('calling__button--ring__on'); tooltipContent = i18n('icu:calling__button--ring__on');
label = i18n('calling__button--ring__label'); label = i18n('icu:calling__button--ring__label');
} else if (buttonType === CallingButtonType.RING_ON) { } else if (buttonType === CallingButtonType.RING_ON) {
classNameSuffix = 'ring--on'; classNameSuffix = 'ring--on';
tooltipContent = i18n('calling__button--ring__off'); tooltipContent = i18n('icu:calling__button--ring__off');
label = i18n('calling__button--ring__label'); label = i18n('icu:calling__button--ring__label');
} else if (buttonType === CallingButtonType.PRESENTING_DISABLED) { } else if (buttonType === CallingButtonType.PRESENTING_DISABLED) {
classNameSuffix = 'presenting--disabled'; classNameSuffix = 'presenting--disabled';
tooltipContent = i18n('calling__button--presenting-disabled'); tooltipContent = i18n('icu:calling__button--presenting-disabled');
disabled = true; disabled = true;
label = i18n('calling__button--presenting__label'); label = i18n('icu:calling__button--presenting__label');
} else if (buttonType === CallingButtonType.PRESENTING_ON) { } else if (buttonType === CallingButtonType.PRESENTING_ON) {
classNameSuffix = 'presenting--on'; classNameSuffix = 'presenting--on';
tooltipContent = i18n('calling__button--presenting-off'); tooltipContent = i18n('icu:calling__button--presenting-off');
label = i18n('calling__button--presenting__label'); label = i18n('icu:calling__button--presenting__label');
} else if (buttonType === CallingButtonType.PRESENTING_OFF) { } else if (buttonType === CallingButtonType.PRESENTING_OFF) {
classNameSuffix = 'presenting--off'; classNameSuffix = 'presenting--off';
tooltipContent = i18n('calling__button--presenting-on'); tooltipContent = i18n('icu:calling__button--presenting-on');
label = i18n('calling__button--presenting__label'); label = i18n('icu:calling__button--presenting__label');
} }
const className = classNames( const className = classNames(

View file

@ -23,7 +23,7 @@ function localizeDefault(i18n: LocalizerType, deviceLabel: string): string {
return deviceLabel.toLowerCase().startsWith('default') return deviceLabel.toLowerCase().startsWith('default')
? deviceLabel.replace( ? deviceLabel.replace(
/default/i, /default/i,
i18n('callingDeviceSelection__select--default') i18n('icu:callingDeviceSelection__select--default')
) )
: deviceLabel; : deviceLabel;
} }
@ -36,7 +36,7 @@ function renderAudioOptions(
if (!devices.length) { if (!devices.length) {
return ( return (
<option aria-selected> <option aria-selected>
{i18n('callingDeviceSelection__select--no-device')} {i18n('icu:callingDeviceSelection__select--no-device')}
</option> </option>
); );
} }
@ -68,7 +68,7 @@ function renderVideoOptions(
if (!devices.length) { if (!devices.length) {
return ( return (
<option aria-selected> <option aria-selected>
{i18n('callingDeviceSelection__select--no-device')} {i18n('icu:callingDeviceSelection__select--no-device')}
</option> </option>
); );
} }
@ -147,16 +147,16 @@ export function CallingDeviceSelection({
className="module-calling-device-selection__close-button" className="module-calling-device-selection__close-button"
onClick={toggleSettings} onClick={toggleSettings}
tabIndex={0} tabIndex={0}
aria-label={i18n('close')} aria-label={i18n('icu:close')}
/> />
</div> </div>
<h1 className="module-calling-device-selection__title"> <h1 className="module-calling-device-selection__title">
{i18n('callingDeviceSelection__settings')} {i18n('icu:callingDeviceSelection__settings')}
</h1> </h1>
<label htmlFor="video" className="module-calling-device-selection__label"> <label htmlFor="video" className="module-calling-device-selection__label">
{i18n('callingDeviceSelection__label--video')} {i18n('icu:callingDeviceSelection__label--video')}
</label> </label>
<div className="module-calling-device-selection__select"> <div className="module-calling-device-selection__select">
<select <select
@ -173,7 +173,7 @@ export function CallingDeviceSelection({
htmlFor="audio-input" htmlFor="audio-input"
className="module-calling-device-selection__label" className="module-calling-device-selection__label"
> >
{i18n('callingDeviceSelection__label--audio-input')} {i18n('icu:callingDeviceSelection__label--audio-input')}
</label> </label>
<div className="module-calling-device-selection__select"> <div className="module-calling-device-selection__select">
<select <select
@ -194,7 +194,7 @@ export function CallingDeviceSelection({
htmlFor="audio-output" htmlFor="audio-output"
className="module-calling-device-selection__label" className="module-calling-device-selection__label"
> >
{i18n('callingDeviceSelection__label--audio-output')} {i18n('icu:callingDeviceSelection__label--audio-output')}
</label> </label>
<div className="module-calling-device-selection__select"> <div className="module-calling-device-selection__select">
<select <select

View file

@ -49,13 +49,13 @@ export function CallingHeader({
{isGroupCall && participantCount ? ( {isGroupCall && participantCount ? (
<div className="module-calling-tools__button"> <div className="module-calling-tools__button">
<Tooltip <Tooltip
content={i18n('calling__participants', { content={i18n('icu:calling__participants', {
people: String(participantCount), people: String(participantCount),
})} })}
theme={Theme.Dark} theme={Theme.Dark}
> >
<button <button
aria-label={i18n('calling__participants', { aria-label={i18n('icu:calling__participants', {
people: String(participantCount), people: String(participantCount),
})} })}
className={classNames( className={classNames(
@ -77,11 +77,11 @@ export function CallingHeader({
) : null} ) : null}
<div className="module-calling-tools__button"> <div className="module-calling-tools__button">
<Tooltip <Tooltip
content={i18n('callingDeviceSelection__settings')} content={i18n('icu:callingDeviceSelection__settings')}
theme={Theme.Dark} theme={Theme.Dark}
> >
<button <button
aria-label={i18n('callingDeviceSelection__settings')} aria-label={i18n('icu:callingDeviceSelection__settings')}
className="CallingButton__settings" className="CallingButton__settings"
onClick={toggleSettings} onClick={toggleSettings}
type="button" type="button"
@ -93,16 +93,16 @@ export function CallingHeader({
<Tooltip <Tooltip
content={ content={
isInSpeakerView isInSpeakerView
? i18n('calling__switch-view--to-grid') ? i18n('icu:calling__switch-view--to-grid')
: i18n('calling__switch-view--to-speaker') : i18n('icu:calling__switch-view--to-speaker')
} }
theme={Theme.Dark} theme={Theme.Dark}
> >
<button <button
aria-label={ aria-label={
isInSpeakerView isInSpeakerView
? i18n('calling__switch-view--to-grid') ? i18n('icu:calling__switch-view--to-grid')
: i18n('calling__switch-view--to-speaker') : i18n('icu:calling__switch-view--to-speaker')
} }
className={ className={
isInSpeakerView isInSpeakerView
@ -117,9 +117,9 @@ export function CallingHeader({
)} )}
{togglePip && ( {togglePip && (
<div className="module-calling-tools__button"> <div className="module-calling-tools__button">
<Tooltip content={i18n('calling__pip--on')} theme={Theme.Dark}> <Tooltip content={i18n('icu:calling__pip--on')} theme={Theme.Dark}>
<button <button
aria-label={i18n('calling__pip--on')} aria-label={i18n('icu:calling__pip--on')}
className="CallingButton__pip" className="CallingButton__pip"
onClick={togglePip} onClick={togglePip}
type="button" type="button"
@ -129,9 +129,9 @@ export function CallingHeader({
)} )}
{onCancel && ( {onCancel && (
<div className="module-calling-tools__button"> <div className="module-calling-tools__button">
<Tooltip content={i18n('cancel')} theme={Theme.Dark}> <Tooltip content={i18n('icu:cancel')} theme={Theme.Dark}>
<button <button
aria-label={i18n('cancel')} aria-label={i18n('icu:cancel')}
className="CallingButton__cancel" className="CallingButton__cancel"
onClick={onCancel} onClick={onCancel}
type="button" type="button"

View file

@ -234,7 +234,7 @@ export function CallingLobby({
onClick={() => setIsMutedToastVisible(false)} onClick={() => setIsMutedToastVisible(false)}
> >
{i18n( {i18n(
'calling__lobby-automatically-muted-because-there-are-a-lot-of-people' 'icu:calling__lobby-automatically-muted-because-there-are-a-lot-of-people'
)} )}
</CallingToast> </CallingToast>
@ -266,7 +266,7 @@ export function CallingLobby({
}` }`
)} )}
> >
{i18n('calling__your-video-is-off')} {i18n('icu:calling__your-video-is-off')}
</div> </div>
<div className="module-calling__buttons module-calling__buttons--inline"> <div className="module-calling__buttons module-calling__buttons--inline">

View file

@ -46,10 +46,12 @@ export function CallingLobbyJoinButton({
const [height, setHeight] = useState<undefined | number>(); const [height, setHeight] = useState<undefined | number>();
const childrenByVariant: Record<CallingLobbyJoinButtonVariant, ReactChild> = { const childrenByVariant: Record<CallingLobbyJoinButtonVariant, ReactChild> = {
[CallingLobbyJoinButtonVariant.CallIsFull]: i18n('calling__call-is-full'), [CallingLobbyJoinButtonVariant.CallIsFull]: i18n(
'icu:calling__call-is-full'
),
[CallingLobbyJoinButtonVariant.Loading]: <Spinner svgSize="small" />, [CallingLobbyJoinButtonVariant.Loading]: <Spinner svgSize="small" />,
[CallingLobbyJoinButtonVariant.Join]: i18n('calling__join'), [CallingLobbyJoinButtonVariant.Join]: i18n('icu:calling__join'),
[CallingLobbyJoinButtonVariant.Start]: i18n('calling__start'), [CallingLobbyJoinButtonVariant.Start]: i18n('icu:calling__start'),
}; };
return ( return (

View file

@ -79,11 +79,12 @@ export const CallingParticipantsList = React.memo(
<div className="module-calling-participants-list"> <div className="module-calling-participants-list">
<div className="module-calling-participants-list__header"> <div className="module-calling-participants-list__header">
<div className="module-calling-participants-list__title"> <div className="module-calling-participants-list__title">
{!participants.length && i18n('calling__in-this-call--zero')} {!participants.length &&
i18n('icu:calling__in-this-call--zero')}
{participants.length === 1 && {participants.length === 1 &&
i18n('calling__in-this-call--one')} i18n('icu:calling__in-this-call--one')}
{participants.length > 1 && {participants.length > 1 &&
i18n('calling__in-this-call--many', { i18n('icu:calling__in-this-call--many', {
people: String(participants.length), people: String(participants.length),
})} })}
</div> </div>
@ -92,7 +93,7 @@ export const CallingParticipantsList = React.memo(
className="module-calling-participants-list__close" className="module-calling-participants-list__close"
onClick={onClose} onClick={onClose}
tabIndex={0} tabIndex={0}
aria-label={i18n('close')} aria-label={i18n('icu:close')}
/> />
</div> </div>
<ul className="module-calling-participants-list__list"> <ul className="module-calling-participants-list__list">
@ -123,7 +124,7 @@ export const CallingParticipantsList = React.memo(
/> />
{ourUuid && participant.uuid === ourUuid ? ( {ourUuid && participant.uuid === ourUuid ? (
<span className="module-calling-participants-list__name"> <span className="module-calling-participants-list__name">
{i18n('you')} {i18n('icu:you')}
</span> </span>
) : ( ) : (
<> <>

View file

@ -299,13 +299,13 @@ export function CallingPip({
) : null} ) : null}
<div className="module-calling-pip__actions"> <div className="module-calling-pip__actions">
<button <button
aria-label={i18n('calling__hangup')} aria-label={i18n('icu:calling__hangup')}
className="module-calling-pip__button--hangup" className="module-calling-pip__button--hangup"
onClick={hangUp} onClick={hangUp}
type="button" type="button"
/> />
<button <button
aria-label={i18n('calling__pip--off')} aria-label={i18n('icu:calling__pip--off')}
className="module-calling-pip__button--pip" className="module-calling-pip__button--pip"
onClick={togglePip} onClick={togglePip}
type="button" type="button"

View file

@ -52,9 +52,9 @@ export function CallingPreCallInfo({
}: PropsType): JSX.Element { }: PropsType): JSX.Element {
let subtitle: string; let subtitle: string;
if (ringMode === RingMode.IsRinging) { if (ringMode === RingMode.IsRinging) {
subtitle = i18n('outgoingCallRinging'); subtitle = i18n('icu:outgoingCallRinging');
} else if (isCallFull) { } else if (isCallFull) {
subtitle = i18n('calling__call-is-full'); subtitle = i18n('icu:calling__call-is-full');
} else if (peekedParticipants.length) { } else if (peekedParticipants.length) {
// It should be rare to see yourself in this list, but it's possible if (1) you rejoin // It should be rare to see yourself in this list, but it's possible if (1) you rejoin
// quickly, causing the server to return stale state (2) you have joined on another // quickly, causing the server to return stale state (2) you have joined on another
@ -63,7 +63,7 @@ export function CallingPreCallInfo({
const participantNames = peekedParticipants.map(participant => { const participantNames = peekedParticipants.map(participant => {
if (participant.uuid === me.uuid) { if (participant.uuid === me.uuid) {
hasYou = true; hasYou = true;
return i18n('you'); return i18n('icu:you');
} }
return getParticipantName(participant); return getParticipantName(participant);
}); });
@ -71,26 +71,26 @@ export function CallingPreCallInfo({
switch (participantNames.length) { switch (participantNames.length) {
case 1: case 1:
subtitle = hasYou subtitle = hasYou
? i18n('calling__pre-call-info--another-device-in-call') ? i18n('icu:calling__pre-call-info--another-device-in-call')
: i18n('calling__pre-call-info--1-person-in-call', { : i18n('icu:calling__pre-call-info--1-person-in-call', {
first: participantNames[0], first: participantNames[0],
}); });
break; break;
case 2: case 2:
subtitle = i18n('calling__pre-call-info--2-people-in-call', { subtitle = i18n('icu:calling__pre-call-info--2-people-in-call', {
first: participantNames[0], first: participantNames[0],
second: participantNames[1], second: participantNames[1],
}); });
break; break;
case 3: case 3:
subtitle = i18n('calling__pre-call-info--3-people-in-call', { subtitle = i18n('icu:calling__pre-call-info--3-people-in-call', {
first: participantNames[0], first: participantNames[0],
second: participantNames[1], second: participantNames[1],
third: participantNames[2], third: participantNames[2],
}); });
break; break;
default: default:
subtitle = i18n('calling__pre-call-info--many-people-in-call', { subtitle = i18n('icu:calling__pre-call-info--many-people-in-call', {
first: participantNames[0], first: participantNames[0],
second: participantNames[1], second: participantNames[1],
others: String(participantNames.length - 2), others: String(participantNames.length - 2),
@ -116,25 +116,25 @@ export function CallingPreCallInfo({
switch (memberNames.length) { switch (memberNames.length) {
case 0: case 0:
subtitle = i18n('calling__pre-call-info--empty-group'); subtitle = i18n('icu:calling__pre-call-info--empty-group');
break; break;
case 1: { case 1: {
subtitle = ring subtitle = ring
? i18n('calling__pre-call-info--will-ring-1', { ? i18n('icu:calling__pre-call-info--will-ring-1', {
person: memberNames[0], person: memberNames[0],
}) })
: i18n('calling__pre-call-info--will-notify-1', { : i18n('icu:calling__pre-call-info--will-notify-1', {
person: memberNames[0], person: memberNames[0],
}); });
break; break;
} }
case 2: { case 2: {
subtitle = ring subtitle = ring
? i18n('calling__pre-call-info--will-ring-2', { ? i18n('icu:calling__pre-call-info--will-ring-2', {
first: memberNames[0], first: memberNames[0],
second: memberNames[1], second: memberNames[1],
}) })
: i18n('calling__pre-call-info--will-notify-2', { : i18n('icu:calling__pre-call-info--will-notify-2', {
first: memberNames[0], first: memberNames[0],
second: memberNames[1], second: memberNames[1],
}); });
@ -142,12 +142,12 @@ export function CallingPreCallInfo({
} }
case 3: { case 3: {
subtitle = ring subtitle = ring
? i18n('calling__pre-call-info--will-ring-3', { ? i18n('icu:calling__pre-call-info--will-ring-3', {
first: memberNames[0], first: memberNames[0],
second: memberNames[1], second: memberNames[1],
third: memberNames[2], third: memberNames[2],
}) })
: i18n('calling__pre-call-info--will-notify-3', { : i18n('icu:calling__pre-call-info--will-notify-3', {
first: memberNames[0], first: memberNames[0],
second: memberNames[1], second: memberNames[1],
third: memberNames[2], third: memberNames[2],
@ -156,12 +156,12 @@ export function CallingPreCallInfo({
} }
default: { default: {
subtitle = ring subtitle = ring
? i18n('calling__pre-call-info--will-ring-many', { ? i18n('icu:calling__pre-call-info--will-ring-many', {
first: memberNames[0], first: memberNames[0],
second: memberNames[1], second: memberNames[1],
others: String(memberNames.length - 2), others: String(memberNames.length - 2),
}) })
: i18n('calling__pre-call-info--will-notify-many', { : i18n('icu:calling__pre-call-info--will-notify-many', {
first: memberNames[0], first: memberNames[0],
second: memberNames[1], second: memberNames[1],
others: String(memberNames.length - 2), others: String(memberNames.length - 2),

View file

@ -21,7 +21,7 @@ export function CallingScreenSharingController({
return ( return (
<div className="module-CallingScreenSharingController"> <div className="module-CallingScreenSharingController">
<div className="module-CallingScreenSharingController__text"> <div className="module-CallingScreenSharingController__text">
{i18n('calling__presenting--info', { {i18n('icu:calling__presenting--info', {
window: presentedSourceName, window: presentedSourceName,
})} })}
</div> </div>
@ -31,10 +31,10 @@ export function CallingScreenSharingController({
onClick={onStopSharing} onClick={onStopSharing}
variant={ButtonVariant.Destructive} variant={ButtonVariant.Destructive}
> >
{i18n('calling__presenting--stop')} {i18n('icu:calling__presenting--stop')}
</Button> </Button>
<button <button
aria-label={i18n('close')} aria-label={i18n('icu:close')}
className="module-CallingScreenSharingController__close" className="module-CallingScreenSharingController__close"
onClick={onCloseController} onClick={onCloseController}
type="button" type="button"

View file

@ -85,13 +85,13 @@ export function CallingSelectPresentingSourcesModal({
const footer = ( const footer = (
<> <>
<Button onClick={() => setPresenting()} variant={ButtonVariant.Secondary}> <Button onClick={() => setPresenting()} variant={ButtonVariant.Secondary}>
{i18n('cancel')} {i18n('icu:cancel')}
</Button> </Button>
<Button <Button
disabled={!sourceToPresent} disabled={!sourceToPresent}
onClick={() => setPresenting(sourceToPresent)} onClick={() => setPresenting(sourceToPresent)}
> >
{i18n('calling__SelectPresentingSourcesModal--confirm')} {i18n('icu:calling__SelectPresentingSourcesModal--confirm')}
</Button> </Button>
</> </>
); );
@ -106,11 +106,11 @@ export function CallingSelectPresentingSourcesModal({
setPresenting(); setPresenting();
}} }}
theme={Theme.Dark} theme={Theme.Dark}
title={i18n('calling__SelectPresentingSourcesModal--title')} title={i18n('icu:calling__SelectPresentingSourcesModal--title')}
modalFooter={footer} modalFooter={footer}
> >
<div className="module-CallingSelectPresentingSourcesModal__title"> <div className="module-CallingSelectPresentingSourcesModal__title">
{i18n('calling__SelectPresentingSourcesModal--entireScreen')} {i18n('icu:calling__SelectPresentingSourcesModal--entireScreen')}
</div> </div>
<div className="module-CallingSelectPresentingSourcesModal__sources"> <div className="module-CallingSelectPresentingSourcesModal__sources">
{(sources.true ?? []).map(source => ( {(sources.true ?? []).map(source => (
@ -123,7 +123,7 @@ export function CallingSelectPresentingSourcesModal({
))} ))}
</div> </div>
<div className="module-CallingSelectPresentingSourcesModal__title"> <div className="module-CallingSelectPresentingSourcesModal__title">
{i18n('calling__SelectPresentingSourcesModal--window')} {i18n('icu:calling__SelectPresentingSourcesModal--window')}
</div> </div>
<div className="module-CallingSelectPresentingSourcesModal__sources"> <div className="module-CallingSelectPresentingSourcesModal__sources">
{(sources.false ?? []).map(source => ( {(sources.false ?? []).map(source => (

View file

@ -27,7 +27,7 @@ function getReconnectingToast({ activeCall, i18n }: PropsType): ToastType {
activeCall.connectionState === GroupCallConnectionState.Reconnecting activeCall.connectionState === GroupCallConnectionState.Reconnecting
) { ) {
return { return {
message: i18n('callReconnecting'), message: i18n('icu:callReconnecting'),
type: 'static', type: 'static',
}; };
} }
@ -72,12 +72,12 @@ function useScreenSharingToast({ activeCall, i18n }: PropsType): ToastType {
if (previousPresenterId === ME) { if (previousPresenterId === ME) {
setResult({ setResult({
type: 'dismissable', type: 'dismissable',
message: i18n('calling__presenting--you-stopped'), message: i18n('icu:calling__presenting--you-stopped'),
}); });
} else if (previousPresenterTitle) { } else if (previousPresenterTitle) {
setResult({ setResult({
type: 'dismissable', type: 'dismissable',
message: i18n('calling__presenting--person-stopped', { message: i18n('icu:calling__presenting--person-stopped', {
name: previousPresenterTitle, name: previousPresenterTitle,
}), }),
}); });

View file

@ -37,10 +37,10 @@ export function CaptchaDialog(props: Readonly<PropsType>): JSX.Element {
const footer = ( const footer = (
<> <>
<Button onClick={onCancelClick} variant={ButtonVariant.Secondary}> <Button onClick={onCancelClick} variant={ButtonVariant.Secondary}>
{i18n('cancel')} {i18n('icu:cancel')}
</Button> </Button>
<Button onClick={onSkipClick} variant={ButtonVariant.Destructive}> <Button onClick={onSkipClick} variant={ButtonVariant.Destructive}>
{i18n('CaptchaDialog--can_close__skip-verification')} {i18n('icu:CaptchaDialog--can_close__skip-verification')}
</Button> </Button>
</> </>
); );
@ -49,13 +49,13 @@ export function CaptchaDialog(props: Readonly<PropsType>): JSX.Element {
modalName="CaptchaDialog" modalName="CaptchaDialog"
moduleClassName="module-Modal" moduleClassName="module-Modal"
i18n={i18n} i18n={i18n}
title={i18n('CaptchaDialog--can-close__title')} title={i18n('icu:CaptchaDialog--can-close__title')}
onClose={() => setIsClosing(false)} onClose={() => setIsClosing(false)}
key="skip" key="skip"
modalFooter={footer} modalFooter={footer}
> >
<section> <section>
<p>{i18n('CaptchaDialog--can-close__body')}</p> <p>{i18n('icu:CaptchaDialog--can-close__body')}</p>
</section> </section>
</Modal> </Modal>
); );
@ -94,15 +94,15 @@ export function CaptchaDialog(props: Readonly<PropsType>): JSX.Element {
modalName="CaptchaDialog.pending" modalName="CaptchaDialog.pending"
moduleClassName="module-Modal--important" moduleClassName="module-Modal--important"
i18n={i18n} i18n={i18n}
title={i18n('CaptchaDialog__title')} title={i18n('icu:CaptchaDialog__title')}
hasXButton hasXButton
onClose={() => setIsClosing(true)} onClose={() => setIsClosing(true)}
key="primary" key="primary"
modalFooter={footer} modalFooter={footer}
> >
<section> <section>
<p>{i18n('CaptchaDialog__first-paragraph')}</p> <p>{i18n('icu:CaptchaDialog__first-paragraph')}</p>
<p>{i18n('CaptchaDialog__second-paragraph')}</p> <p>{i18n('icu:CaptchaDialog__second-paragraph')}</p>
</section> </section>
</Modal> </Modal>
); );

View file

@ -130,7 +130,7 @@ export function ChatColorPicker({
{ {
action: resetDefaultChatColor, action: resetDefaultChatColor,
style: 'affirmative', style: 'affirmative',
text: i18n('ChatColorPicker__confirm-reset-default'), text: i18n('icu:ChatColorPicker__confirm-reset-default'),
}, },
{ {
action: () => { action: () => {
@ -138,16 +138,16 @@ export function ChatColorPicker({
resetAllChatColors(); resetAllChatColors();
}, },
style: 'affirmative', style: 'affirmative',
text: i18n('ChatColorPicker__resetAll'), text: i18n('icu:ChatColorPicker__resetAll'),
}, },
]} ]}
i18n={i18n} i18n={i18n}
onClose={() => { onClose={() => {
setConfirmResetWhat(false); setConfirmResetWhat(false);
}} }}
title={i18n('ChatColorPicker__resetDefault')} title={i18n('icu:ChatColorPicker__resetDefault')}
> >
{i18n('ChatColorPicker__confirm-reset-message')} {i18n('icu:ChatColorPicker__confirm-reset-message')}
</ConfirmationDialog> </ConfirmationDialog>
) : null} ) : null}
{confirmResetAll ? ( {confirmResetAll ? (
@ -157,16 +157,16 @@ export function ChatColorPicker({
{ {
action: resetAllChatColors, action: resetAllChatColors,
style: 'affirmative', style: 'affirmative',
text: i18n('ChatColorPicker__confirm-reset'), text: i18n('icu:ChatColorPicker__confirm-reset'),
}, },
]} ]}
i18n={i18n} i18n={i18n}
onClose={() => { onClose={() => {
setConfirmResetAll(false); setConfirmResetAll(false);
}} }}
title={i18n('ChatColorPicker__resetAll')} title={i18n('icu:ChatColorPicker__resetAll')}
> >
{i18n('ChatColorPicker__confirm-reset-message')} {i18n('icu:ChatColorPicker__confirm-reset-message')}
</ConfirmationDialog> </ConfirmationDialog>
) : null} ) : null}
<SampleMessageBubbles <SampleMessageBubbles
@ -227,7 +227,7 @@ export function ChatColorPicker({
); );
})} })}
<div <div
aria-label={i18n('ChatColorPicker__custom-color--label')} aria-label={i18n('icu:ChatColorPicker__custom-color--label')}
className="ChatColorPicker__bubble ChatColorPicker__bubble--custom" className="ChatColorPicker__bubble ChatColorPicker__bubble--custom"
onClick={() => onClick={() =>
setCustomColorToEdit({ id: undefined, value: undefined }) setCustomColorToEdit({ id: undefined, value: undefined })
@ -246,14 +246,14 @@ export function ChatColorPicker({
<hr /> <hr />
{conversationId ? ( {conversationId ? (
<PanelRow <PanelRow
label={i18n('ChatColorPicker__reset')} label={i18n('icu:ChatColorPicker__reset')}
onClick={() => { onClick={() => {
colorSelected({ conversationId }); colorSelected({ conversationId });
}} }}
/> />
) : null} ) : null}
<PanelRow <PanelRow
label={i18n('ChatColorPicker__resetAll')} label={i18n('icu:ChatColorPicker__resetAll')}
onClick={() => { onClick={() => {
if (isGlobal) { if (isGlobal) {
setConfirmResetWhat(true); setConfirmResetWhat(true);
@ -339,16 +339,16 @@ function CustomColorBubble({
{ {
action: onDelete, action: onDelete,
style: 'negative', style: 'negative',
text: i18n('ChatColorPicker__context--delete'), text: i18n('icu:ChatColorPicker__context--delete'),
}, },
]} ]}
i18n={i18n} i18n={i18n}
onClose={() => { onClose={() => {
setConfirmDeleteCount(undefined); setConfirmDeleteCount(undefined);
}} }}
title={i18n('ChatColorPicker__delete--title')} title={i18n('icu:ChatColorPicker__delete--title')}
> >
{i18n('ChatColorPicker__delete--message', { {i18n('icu:ChatColorPicker__delete--message', {
num: String(confirmDeleteCount), num: String(confirmDeleteCount),
})} })}
</ConfirmationDialog> </ConfirmationDialog>
@ -372,7 +372,7 @@ function CustomColorBubble({
onEdit(); onEdit();
}} }}
> >
{i18n('ChatColorPicker__context--edit')} {i18n('icu:ChatColorPicker__context--edit')}
</MenuItem> </MenuItem>
<MenuItem <MenuItem
attributes={{ attributes={{
@ -385,7 +385,7 @@ function CustomColorBubble({
onDupe(); onDupe();
}} }}
> >
{i18n('ChatColorPicker__context--duplicate')} {i18n('icu:ChatColorPicker__context--duplicate')}
</MenuItem> </MenuItem>
<MenuItem <MenuItem
attributes={{ attributes={{
@ -405,7 +405,7 @@ function CustomColorBubble({
} }
}} }}
> >
{i18n('ChatColorPicker__context--delete')} {i18n('icu:ChatColorPicker__context--delete')}
</MenuItem> </MenuItem>
</ContextMenu> </ContextMenu>
</> </>
@ -442,7 +442,7 @@ function CustomColorEditorWrapper({
moduleClassName="ChatColorPicker__modal" moduleClassName="ChatColorPicker__modal"
noMouseClose noMouseClose
onClose={onClose} onClose={onClose}
title={i18n('CustomColorEditor__title')} title={i18n('icu:CustomColorEditor__title')}
> >
{editor} {editor}
</Modal> </Modal>

View file

@ -20,7 +20,7 @@ export function ClearingData({ deleteAllData, i18n }: PropsType): JSX.Element {
<div className="inner"> <div className="inner">
<div className="step-body"> <div className="step-body">
<span className="banner-icon delete" /> <span className="banner-icon delete" />
<div className="header">{i18n('deleteAllDataProgress')}</div> <div className="header">{i18n('icu:deleteAllDataProgress')}</div>
</div> </div>
<div className="progress"> <div className="progress">
<div className="bar-container"> <div className="bar-container">

View file

@ -457,7 +457,7 @@ export function CompositionArea({
type="button" type="button"
className="CompositionArea__attach-file" className="CompositionArea__attach-file"
onClick={launchAttachmentPicker} onClick={launchAttachmentPicker}
aria-label={i18n('CompositionArea--attach-file')} aria-label={i18n('icu:CompositionArea--attach-file')}
/> />
</div> </div>
); );
@ -470,7 +470,7 @@ export function CompositionArea({
type="button" type="button"
className="CompositionArea__send-button" className="CompositionArea__send-button"
onClick={handleForceSend} onClick={handleForceSend}
aria-label={i18n('sendMessageToContact')} aria-label={i18n('icu:sendMessageToContact')}
/> />
</div> </div>
</> </>
@ -605,7 +605,7 @@ export function CompositionArea({
> >
{isFetchingUUID ? ( {isFetchingUUID ? (
<Spinner <Spinner
ariaLabel={i18n('CompositionArea--sms-only__spinner-label')} ariaLabel={i18n('icu:CompositionArea--sms-only__spinner-label')}
role="presentation" role="presentation"
moduleClassName="module-image-spinner" moduleClassName="module-image-spinner"
svgSize="small" svgSize="small"
@ -613,10 +613,10 @@ export function CompositionArea({
) : ( ) : (
<> <>
<h2 className="CompositionArea--sms-only__title"> <h2 className="CompositionArea--sms-only__title">
{i18n('CompositionArea--sms-only__title')} {i18n('icu:CompositionArea--sms-only__title')}
</h2> </h2>
<p className="CompositionArea--sms-only__body"> <p className="CompositionArea--sms-only__body">
{i18n('CompositionArea--sms-only__body')} {i18n('icu:CompositionArea--sms-only__body')}
</p> </p>
</> </>
)} )}
@ -728,7 +728,7 @@ export function CompositionArea({
// This prevents the user from tabbing here // This prevents the user from tabbing here
tabIndex={-1} tabIndex={-1}
onClick={handleToggleLarge} onClick={handleToggleLarge}
aria-label={i18n('CompositionArea--expand')} aria-label={i18n('icu:CompositionArea--expand')}
/> />
</div> </div>
<div <div

View file

@ -622,7 +622,7 @@ export function CompositionInput(props: Props): React.ReactElement {
}, },
}} }}
formats={['emoji', 'mention']} formats={['emoji', 'mention']}
placeholder={placeholder || i18n('sendMessage')} placeholder={placeholder || i18n('icu:sendMessage')}
readOnly={disabled} readOnly={disabled}
ref={element => { ref={element => {
if (element) { if (element) {

View file

@ -111,16 +111,16 @@ export function CompositionRecording({
i18n={i18n} i18n={i18n}
onCancel={onCancel} onCancel={onCancel}
onClose={noop} onClose={noop}
cancelText={i18n('discard')} cancelText={i18n('icu:discard')}
actions={[ actions={[
{ {
text: i18n('sendAnyway'), text: i18n('icu:sendAnyway'),
style: 'affirmative', style: 'affirmative',
action: onSend, action: onSend,
}, },
]} ]}
> >
{i18n('voiceRecordingInterruptedMax')} {i18n('icu:voiceRecordingInterruptedMax')}
</ConfirmationDialog> </ConfirmationDialog>
); );
} else if ( } else if (
@ -132,10 +132,10 @@ export function CompositionRecording({
i18n={i18n} i18n={i18n}
onCancel={onCancel} onCancel={onCancel}
onClose={noop} onClose={noop}
cancelText={i18n('ok')} cancelText={i18n('icu:ok')}
actions={[]} actions={[]}
> >
{i18n('voiceNoteError')} {i18n('icu:voiceNoteError')}
</ConfirmationDialog> </ConfirmationDialog>
); );
} }

View file

@ -101,8 +101,8 @@ export function CompositionRecordingDraft({
mod={active?.playing ? 'pause' : 'play'} mod={active?.playing ? 'pause' : 'play'}
label={ label={
active?.playing active?.playing
? i18n('MessageAudio--pause') ? i18n('icu:MessageAudio--pause')
: i18n('MessageAudio--play') : i18n('icu:MessageAudio--play')
} }
onClick={handlePlaybackClick} onClick={handlePlaybackClick}
/> />

View file

@ -22,14 +22,14 @@ export function ConfirmDiscardDialog({
actions={[ actions={[
{ {
action: onDiscard, action: onDiscard,
text: i18n('discard'), text: i18n('icu:discard'),
style: 'negative', style: 'negative',
}, },
]} ]}
i18n={i18n} i18n={i18n}
onClose={onClose} onClose={onClose}
> >
{i18n('ConfirmDiscardDialog--discard')} {i18n('icu:ConfirmDiscardDialog--discard')}
</ConfirmationDialog> </ConfirmationDialog>
); );
} }

View file

@ -120,7 +120,7 @@ export const ConfirmationDialog = React.memo(function ConfirmationDialogInner({
(hasActions ? ButtonVariant.Secondary : ButtonVariant.Primary) (hasActions ? ButtonVariant.Secondary : ButtonVariant.Primary)
} }
> >
{cancelText || i18n('confirmation-dialog--Cancel')} {cancelText || i18n('icu:confirmation-dialog--Cancel')}
</Button> </Button>
) : null} ) : null}
{actions.map((action, i) => ( {actions.map((action, i) => (

View file

@ -42,7 +42,7 @@ export function ContactPill({
unblurredAvatarPath, unblurredAvatarPath,
onClickRemove, onClickRemove,
}: PropsType): JSX.Element { }: PropsType): JSX.Element {
const removeLabel = i18n('ContactPill--remove'); const removeLabel = i18n('icu:ContactPill--remove');
return ( return (
<div className="module-ContactPill"> <div className="module-ContactPill">

View file

@ -289,7 +289,7 @@ export function ContextMenu<T>({
)} )}
> >
<button <button
aria-label={ariaLabel || i18n('ContextMenu--button')} aria-label={ariaLabel || i18n('icu:ContextMenu--button')}
className={classNames( className={classNames(
getClassName('__button'), getClassName('__button'),
isMenuShowing ? getClassName('__button--active') : undefined isMenuShowing ? getClassName('__button--active') : undefined

View file

@ -605,22 +605,22 @@ export function Headers(): JSX.Element {
{ {
type: RowType.Header, type: RowType.Header,
// eslint-disable-next-line @typescript-eslint/no-shadow // eslint-disable-next-line @typescript-eslint/no-shadow
getHeaderText: i18n => i18n('conversationsHeader'), getHeaderText: i18n => i18n('icu:conversationsHeader'),
}, },
{ {
type: RowType.Header, type: RowType.Header,
// eslint-disable-next-line @typescript-eslint/no-shadow // eslint-disable-next-line @typescript-eslint/no-shadow
getHeaderText: i18n => i18n('messagesHeader'), getHeaderText: i18n => i18n('icu:messagesHeader'),
}, },
{ {
type: RowType.Header, type: RowType.Header,
// eslint-disable-next-line @typescript-eslint/no-shadow // eslint-disable-next-line @typescript-eslint/no-shadow
getHeaderText: i18n => i18n('findByUsernameHeader'), getHeaderText: i18n => i18n('icu:findByUsernameHeader'),
}, },
{ {
type: RowType.Header, type: RowType.Header,
// eslint-disable-next-line @typescript-eslint/no-shadow // eslint-disable-next-line @typescript-eslint/no-shadow
getHeaderText: i18n => i18n('findByPhoneNumberHeader'), getHeaderText: i18n => i18n('icu:findByPhoneNumberHeader'),
}, },
]} ]}
/> />
@ -634,7 +634,7 @@ export function FindByPhoneNumber(): JSX.Element {
{ {
type: RowType.Header, type: RowType.Header,
// eslint-disable-next-line @typescript-eslint/no-shadow // eslint-disable-next-line @typescript-eslint/no-shadow
getHeaderText: i18n => i18n('findByPhoneNumberHeader'), getHeaderText: i18n => i18n('icu:findByPhoneNumberHeader'),
}, },
{ {
type: RowType.StartNewConversation, type: RowType.StartNewConversation,
@ -679,7 +679,7 @@ export function FindByUsername(): JSX.Element {
{ {
type: RowType.Header, type: RowType.Header,
// eslint-disable-next-line @typescript-eslint/no-shadow // eslint-disable-next-line @typescript-eslint/no-shadow
getHeaderText: i18n => i18n('findByUsernameHeader'), getHeaderText: i18n => i18n('icu:findByUsernameHeader'),
}, },
{ {
type: RowType.UsernameSearchResult, type: RowType.UsernameSearchResult,
@ -752,7 +752,7 @@ export function KitchenSink(): JSX.Element {
{ {
type: RowType.Header, type: RowType.Header,
// eslint-disable-next-line @typescript-eslint/no-shadow // eslint-disable-next-line @typescript-eslint/no-shadow
getHeaderText: i18n => i18n('contactsHeader'), getHeaderText: i18n => i18n('icu:contactsHeader'),
}, },
{ {
type: RowType.Contact, type: RowType.Contact,
@ -761,7 +761,7 @@ export function KitchenSink(): JSX.Element {
{ {
type: RowType.Header, type: RowType.Header,
// eslint-disable-next-line @typescript-eslint/no-shadow // eslint-disable-next-line @typescript-eslint/no-shadow
getHeaderText: i18n => i18n('messagesHeader'), getHeaderText: i18n => i18n('icu:messagesHeader'),
}, },
{ {
type: RowType.Conversation, type: RowType.Conversation,
@ -774,7 +774,7 @@ export function KitchenSink(): JSX.Element {
{ {
type: RowType.Header, type: RowType.Header,
// eslint-disable-next-line @typescript-eslint/no-shadow // eslint-disable-next-line @typescript-eslint/no-shadow
getHeaderText: i18n => i18n('findByUsernameHeader'), getHeaderText: i18n => i18n('icu:findByUsernameHeader'),
}, },
{ {
type: RowType.UsernameSearchResult, type: RowType.UsernameSearchResult,

View file

@ -247,14 +247,14 @@ export function ConversationList({
case RowType.ArchiveButton: case RowType.ArchiveButton:
result = ( result = (
<button <button
aria-label={i18n('archivedConversations')} aria-label={i18n('icu:archivedConversations')}
className="module-conversation-list__item--archive-button" className="module-conversation-list__item--archive-button"
onClick={onClickArchiveButton} onClick={onClickArchiveButton}
type="button" type="button"
> >
<div className="module-conversation-list__item--archive-button__icon" /> <div className="module-conversation-list__item--archive-button__icon" />
<span className="module-conversation-list__item--archive-button__text"> <span className="module-conversation-list__item--archive-button__text">
{i18n('archivedConversations')} {i18n('icu:archivedConversations')}
</span> </span>
<span className="module-conversation-list__item--archive-button__archived-count"> <span className="module-conversation-list__item--archive-button__archived-count">
{row.archivedConversationsCount} {row.archivedConversationsCount}
@ -355,10 +355,10 @@ export function ConversationList({
const { badges, title, unreadCount, lastMessage } = itemProps; const { badges, title, unreadCount, lastMessage } = itemProps;
result = ( result = (
<div <div
aria-label={i18n('ConversationList__aria-label', { aria-label={i18n('icu:ConversationList__aria-label', {
lastMessage: lastMessage:
get(lastMessage, 'text') || get(lastMessage, 'text') ||
i18n('ConversationList__last-message-undefined'), i18n('icu:ConversationList__last-message-undefined'),
title, title,
unreadCount: String(unreadCount), unreadCount: String(unreadCount),
})} })}

View file

@ -40,7 +40,7 @@ export function CrashReportDialog(props: Readonly<PropsType>): JSX.Element {
onClick={onEraseClick} onClick={onEraseClick}
variant={ButtonVariant.Secondary} variant={ButtonVariant.Secondary}
> >
{i18n('CrashReportDialog__erase')} {i18n('icu:CrashReportDialog__erase')}
</Button> </Button>
<Button <Button
disabled={isPending} disabled={isPending}
@ -51,7 +51,7 @@ export function CrashReportDialog(props: Readonly<PropsType>): JSX.Element {
{isPending ? ( {isPending ? (
<Spinner size="22px" svgSize="small" /> <Spinner size="22px" svgSize="small" />
) : ( ) : (
i18n('CrashReportDialog__submit') i18n('icu:CrashReportDialog__submit')
)} )}
</Button> </Button>
</> </>
@ -62,12 +62,12 @@ export function CrashReportDialog(props: Readonly<PropsType>): JSX.Element {
modalName="CrashReportDialog" modalName="CrashReportDialog"
moduleClassName="module-Modal--important" moduleClassName="module-Modal--important"
i18n={i18n} i18n={i18n}
title={i18n('CrashReportDialog__title')} title={i18n('icu:CrashReportDialog__title')}
hasXButton hasXButton
onClose={eraseCrashReports} onClose={eraseCrashReports}
modalFooter={footer} modalFooter={footer}
> >
<section>{i18n('CrashReportDialog__body')}</section> <section>{i18n('icu:CrashReportDialog__body')}</section>
</Modal> </Modal>
); );
} }

View file

@ -78,11 +78,11 @@ export function CustomColorEditor({
tabs={[ tabs={[
{ {
id: TabViews.Solid, id: TabViews.Solid,
label: i18n('CustomColorEditor__solid'), label: i18n('icu:CustomColorEditor__solid'),
}, },
{ {
id: TabViews.Gradient, id: TabViews.Gradient,
label: i18n('CustomColorEditor__gradient'), label: i18n('icu:CustomColorEditor__gradient'),
}, },
]} ]}
> >
@ -114,7 +114,7 @@ export function CustomColorEditor({
)} )}
</div> </div>
<div className="CustomColorEditor__slider-container"> <div className="CustomColorEditor__slider-container">
{i18n('CustomColorEditor__hue')} {i18n('icu:CustomColorEditor__hue')}
<Slider <Slider
handleStyle={{ handleStyle={{
backgroundColor: getHSL({ backgroundColor: getHSL({
@ -122,7 +122,7 @@ export function CustomColorEditor({
saturation: 100, saturation: 100,
}), }),
}} }}
label={i18n('CustomColorEditor__hue')} label={i18n('icu:CustomColorEditor__hue')}
moduleClassName="CustomColorEditor__hue-slider" moduleClassName="CustomColorEditor__hue-slider"
onChange={(percentage: number) => { onChange={(percentage: number) => {
setColor({ setColor({
@ -138,7 +138,7 @@ export function CustomColorEditor({
/> />
</div> </div>
<div className="CustomColorEditor__slider-container"> <div className="CustomColorEditor__slider-container">
{i18n('CustomColorEditor__saturation')} {i18n('icu:CustomColorEditor__saturation')}
<Slider <Slider
containerStyle={getCustomColorStyle({ containerStyle={getCustomColorStyle({
deg: 180, deg: 180,
@ -150,7 +150,7 @@ export function CustomColorEditor({
color[selectedColorKnob] || ULTRAMARINE_ISH_VALUES color[selectedColorKnob] || ULTRAMARINE_ISH_VALUES
), ),
}} }}
label={i18n('CustomColorEditor__saturation')} label={i18n('icu:CustomColorEditor__saturation')}
moduleClassName="CustomColorEditor__saturation-slider" moduleClassName="CustomColorEditor__saturation-slider"
onChange={(value: number) => { onChange={(value: number) => {
setColor({ setColor({
@ -167,7 +167,7 @@ export function CustomColorEditor({
</div> </div>
<div className="CustomColorEditor__footer"> <div className="CustomColorEditor__footer">
<Button variant={ButtonVariant.Secondary} onClick={onClose}> <Button variant={ButtonVariant.Secondary} onClick={onClose}>
{i18n('cancel')} {i18n('icu:cancel')}
</Button> </Button>
<Button <Button
onClick={() => { onClick={() => {
@ -175,7 +175,7 @@ export function CustomColorEditor({
onClose(); onClose();
}} }}
> >
{i18n('save')} {i18n('icu:save')}
</Button> </Button>
</div> </div>
</> </>

View file

@ -118,7 +118,7 @@ export function CustomizingPreferredReactionsModal({
}} }}
variant={ButtonVariant.SecondaryAffirmative} variant={ButtonVariant.SecondaryAffirmative}
> >
{i18n('reset')} {i18n('icu:reset')}
</Button> </Button>
<Button <Button
disabled={!canSave} disabled={!canSave}
@ -131,7 +131,7 @@ export function CustomizingPreferredReactionsModal({
} }
}} }}
> >
{i18n('save')} {i18n('icu:save')}
</Button> </Button>
</> </>
); );
@ -145,7 +145,7 @@ export function CustomizingPreferredReactionsModal({
onClose={() => { onClose={() => {
cancelCustomizePreferredReactionsModal(); cancelCustomizePreferredReactionsModal();
}} }}
title={i18n('CustomizingPreferredReactions__title')} title={i18n('icu:CustomizingPreferredReactions__title')}
modalFooter={footer} modalFooter={footer}
> >
<div className="module-CustomizingPreferredReactionsModal__small-emoji-picker-wrapper"> <div className="module-CustomizingPreferredReactionsModal__small-emoji-picker-wrapper">
@ -169,8 +169,8 @@ export function CustomizingPreferredReactionsModal({
))} ))}
</ReactionPickerPicker> </ReactionPickerPicker>
{hadSaveError {hadSaveError
? i18n('CustomizingPreferredReactions__had-save-error') ? i18n('icu:CustomizingPreferredReactions__had-save-error')
: i18n('CustomizingPreferredReactions__subtitle')} : i18n('icu:CustomizingPreferredReactions__subtitle')}
</div> </div>
{isSomethingSelected && ( {isSomethingSelected && (
<div <div

View file

@ -54,7 +54,9 @@ export function DebugLogWindow({
const [loadState, setLoadState] = useState<LoadState>(LoadState.NotStarted); const [loadState, setLoadState] = useState<LoadState>(LoadState.NotStarted);
const [logText, setLogText] = useState<string | undefined>(); const [logText, setLogText] = useState<string | undefined>();
const [publicLogURL, setPublicLogURL] = useState<string | undefined>(); const [publicLogURL, setPublicLogURL] = useState<string | undefined>();
const [textAreaValue, setTextAreaValue] = useState<string>(i18n('loading')); const [textAreaValue, setTextAreaValue] = useState<string>(
i18n('icu:loading')
);
const [toastType, setToastType] = useState<ToastType | undefined>(); const [toastType, setToastType] = useState<ToastType | undefined>();
const theme = useTheme(); const theme = useTheme();
@ -82,7 +84,7 @@ export function DebugLogWindow({
const linesToShow = Math.ceil(Math.min(window.innerHeight, 2000) / 5); const linesToShow = Math.ceil(Math.min(window.innerHeight, 2000) / 5);
const value = fetchedLogText.split(/\n/g, linesToShow).join('\n'); const value = fetchedLogText.split(/\n/g, linesToShow).join('\n');
setTextAreaValue(`${value}\n\n\n${i18n('debugLogLogIsIncomplete')}`); setTextAreaValue(`${value}\n\n\n${i18n('icu:debugLogLogIsIncomplete')}`);
setToastType(undefined); setToastType(undefined);
} }
@ -150,10 +152,10 @@ export function DebugLogWindow({
<div className="DebugLogWindow"> <div className="DebugLogWindow">
<div> <div>
<div className="DebugLogWindow__title"> <div className="DebugLogWindow__title">
{i18n('debugLogSuccess')} {i18n('icu:debugLogSuccess')}
</div> </div>
<p className="DebugLogWindow__subtitle"> <p className="DebugLogWindow__subtitle">
{i18n('debugLogSuccessNextSteps')} {i18n('icu:debugLogSuccessNextSteps')}
</p> </p>
</div> </div>
<div className="DebugLogWindow__container"> <div className="DebugLogWindow__container">
@ -169,9 +171,9 @@ export function DebugLogWindow({
onClick={() => openLinkInWebBrowser(supportURL)} onClick={() => openLinkInWebBrowser(supportURL)}
variant={ButtonVariant.Secondary} variant={ButtonVariant.Secondary}
> >
{i18n('reportIssue')} {i18n('icu:reportIssue')}
</Button> </Button>
<Button onClick={copyLog}>{i18n('debugLogCopy')}</Button> <Button onClick={copyLog}>{i18n('icu:debugLogCopy')}</Button>
</div> </div>
{toastElement} {toastElement}
</div> </div>
@ -192,9 +194,11 @@ export function DebugLogWindow({
> >
<div className="DebugLogWindow"> <div className="DebugLogWindow">
<div> <div>
<div className="DebugLogWindow__title">{i18n('submitDebugLog')}</div> <div className="DebugLogWindow__title">
{i18n('icu:submitDebugLog')}
</div>
<p className="DebugLogWindow__subtitle"> <p className="DebugLogWindow__subtitle">
{i18n('debugLogExplanation')} {i18n('icu:debugLogExplanation')}
</p> </p>
</div> </div>
{isLoading ? ( {isLoading ? (
@ -218,10 +222,10 @@ export function DebugLogWindow({
}} }}
variant={ButtonVariant.Secondary} variant={ButtonVariant.Secondary}
> >
{i18n('debugLogSave')} {i18n('icu:debugLogSave')}
</Button> </Button>
<Button disabled={!canSubmit} onClick={handleSubmit}> <Button disabled={!canSubmit} onClick={handleSubmit}>
{i18n('submit')} {i18n('icu:submit')}
</Button> </Button>
</div> </div>
{toastElement} {toastElement}

View file

@ -25,10 +25,10 @@ export function DialogExpiredBuild({
onClick={() => { onClick={() => {
openLinkInWebBrowser('https://signal.org/download/'); openLinkInWebBrowser('https://signal.org/download/');
}} }}
clickLabel={i18n('upgrade')} clickLabel={i18n('icu:upgrade')}
hasAction hasAction
> >
{i18n('expiredWarning')}{' '} {i18n('icu:expiredWarning')}{' '}
</LeftPaneDialog> </LeftPaneDialog>
); );
} }

View file

@ -65,8 +65,8 @@ export function DialogNetworkStatus({
containerWidthBreakpoint={containerWidthBreakpoint} containerWidthBreakpoint={containerWidthBreakpoint}
type="warning" type="warning"
icon={spinner} icon={spinner}
title={i18n('connecting')} title={i18n('icu:connecting')}
subtitle={i18n('connectingHangOn')} subtitle={i18n('icu:connectingHangOn')}
/> />
); );
} }
@ -76,10 +76,10 @@ export function DialogNetworkStatus({
containerWidthBreakpoint={containerWidthBreakpoint} containerWidthBreakpoint={containerWidthBreakpoint}
type="warning" type="warning"
icon="network" icon="network"
title={isOnline ? i18n('disconnected') : i18n('offline')} title={isOnline ? i18n('icu:disconnected') : i18n('icu:offline')}
subtitle={i18n('checkNetworkConnection')} subtitle={i18n('icu:checkNetworkConnection')}
hasAction hasAction
clickLabel={i18n('connect')} clickLabel={i18n('icu:connect')}
onClick={reconnect} onClick={reconnect}
/> />
); );

View file

@ -24,9 +24,9 @@ export function DialogRelink({
containerWidthBreakpoint={containerWidthBreakpoint} containerWidthBreakpoint={containerWidthBreakpoint}
type="warning" type="warning"
icon="relink" icon="relink"
clickLabel={i18n('unlinkedWarning')} clickLabel={i18n('icu:unlinkedWarning')}
onClick={relinkDevice} onClick={relinkDevice}
title={i18n('unlinked')} title={i18n('icu:unlinked')}
hasAction hasAction
/> />
); );

View file

@ -45,7 +45,7 @@ export function DialogUpdate({
<LeftPaneDialog <LeftPaneDialog
containerWidthBreakpoint={containerWidthBreakpoint} containerWidthBreakpoint={containerWidthBreakpoint}
type="warning" type="warning"
title={i18n('cannotUpdate')} title={i18n('icu:cannotUpdate')}
> >
<span> <span>
<Intl <Intl
@ -57,7 +57,7 @@ export function DialogUpdate({
onClick={startUpdate} onClick={startUpdate}
type="button" type="button"
> >
{i18n('autoUpdateRetry')} {i18n('icu:autoUpdateRetry')}
</button> </button>
), ),
url: ( url: (
@ -77,12 +77,12 @@ export function DialogUpdate({
rel="noreferrer" rel="noreferrer"
target="_blank" target="_blank"
> >
{i18n('autoUpdateContactSupport')} {i18n('icu:autoUpdateContactSupport')}
</a> </a>
), ),
}} }}
i18n={i18n} i18n={i18n}
id="cannotUpdateDetail" id="icu:cannotUpdateDetail"
/> />
</span> </span>
</LeftPaneDialog> </LeftPaneDialog>
@ -97,7 +97,7 @@ export function DialogUpdate({
<LeftPaneDialog <LeftPaneDialog
containerWidthBreakpoint={containerWidthBreakpoint} containerWidthBreakpoint={containerWidthBreakpoint}
type="warning" type="warning"
title={i18n('cannotUpdate')} title={i18n('icu:cannotUpdate')}
> >
<span> <span>
<Intl <Intl
@ -119,12 +119,12 @@ export function DialogUpdate({
rel="noreferrer" rel="noreferrer"
target="_blank" target="_blank"
> >
{i18n('autoUpdateContactSupport')} {i18n('icu:autoUpdateContactSupport')}
</a> </a>
), ),
}} }}
i18n={i18n} i18n={i18n}
id="cannotUpdateRequireManualDetail" id="icu:cannotUpdateRequireManualDetail"
/> />
</span> </span>
</LeftPaneDialog> </LeftPaneDialog>
@ -134,11 +134,11 @@ export function DialogUpdate({
if (dialogType === DialogType.MacOS_Read_Only) { if (dialogType === DialogType.MacOS_Read_Only) {
return ( return (
<LeftPaneDialog <LeftPaneDialog
closeLabel={i18n('close')} closeLabel={i18n('icu:close')}
containerWidthBreakpoint={containerWidthBreakpoint} containerWidthBreakpoint={containerWidthBreakpoint}
hasXButton hasXButton
onClose={dismissDialog} onClose={dismissDialog}
title={i18n('cannotUpdate')} title={i18n('icu:cannotUpdate')}
type="warning" type="warning"
> >
<span> <span>
@ -148,7 +148,7 @@ export function DialogUpdate({
folder: <strong key="folder">/Applications</strong>, folder: <strong key="folder">/Applications</strong>,
}} }}
i18n={i18n} i18n={i18n}
id="readOnlyVolume" id="icu:readOnlyVolume"
/> />
</span> </span>
</LeftPaneDialog> </LeftPaneDialog>
@ -161,7 +161,7 @@ export function DialogUpdate({
} }
const versionTitle = version const versionTitle = version
? i18n('DialogUpdate--version-available', { ? i18n('icu:DialogUpdate--version-available', {
version, version,
}) })
: undefined; : undefined;
@ -188,7 +188,7 @@ export function DialogUpdate({
); );
} }
let title = i18n('autoUpdateNewVersionTitle'); let title = i18n('icu:autoUpdateNewVersionTitle');
if ( if (
downloadSize && downloadSize &&
@ -198,12 +198,12 @@ export function DialogUpdate({
title += ` (${formatFileSize(downloadSize, { round: 0 })})`; title += ` (${formatFileSize(downloadSize, { round: 0 })})`;
} }
let clickLabel = i18n('autoUpdateNewVersionMessage'); let clickLabel = i18n('icu:autoUpdateNewVersionMessage');
let type: 'warning' | undefined; let type: 'warning' | undefined;
if (dialogType === DialogType.DownloadReady) { if (dialogType === DialogType.DownloadReady) {
clickLabel = i18n('downloadNewVersionMessage'); clickLabel = i18n('icu:downloadNewVersionMessage');
} else if (dialogType === DialogType.FullDownloadReady) { } else if (dialogType === DialogType.FullDownloadReady) {
clickLabel = i18n('downloadFullNewVersionMessage'); clickLabel = i18n('icu:downloadFullNewVersionMessage');
type = 'warning'; type = 'warning';
} else if (dialogType === DialogType.DownloadedUpdate) { } else if (dialogType === DialogType.DownloadedUpdate) {
title = i18n('icu:DialogUpdate__downloaded'); title = i18n('icu:DialogUpdate__downloaded');
@ -221,7 +221,7 @@ export function DialogUpdate({
clickLabel={clickLabel} clickLabel={clickLabel}
hasXButton hasXButton
onClose={snoozeUpdate} onClose={snoozeUpdate}
closeLabel={i18n('autoUpdateIgnoreButtonLabel')} closeLabel={i18n('icu:autoUpdateIgnoreButtonLabel')}
/> />
); );
} }

View file

@ -80,11 +80,11 @@ export function DisappearingTimeDialog(props: PropsType): JSX.Element {
i18n={i18n} i18n={i18n}
theme={theme} theme={theme}
onClose={onClose} onClose={onClose}
title={i18n('DisappearingTimeDialog__title')} title={i18n('icu:DisappearingTimeDialog__title')}
hasXButton hasXButton
actions={[ actions={[
{ {
text: i18n('DisappearingTimeDialog__set'), text: i18n('icu:DisappearingTimeDialog__set'),
style: 'affirmative', style: 'affirmative',
action() { action() {
onSubmit( onSubmit(
@ -96,17 +96,17 @@ export function DisappearingTimeDialog(props: PropsType): JSX.Element {
}, },
]} ]}
> >
<p>{i18n('DisappearingTimeDialog__body')}</p> <p>{i18n('icu:DisappearingTimeDialog__body')}</p>
<section className={`${CSS_MODULE}__time-boxes`}> <section className={`${CSS_MODULE}__time-boxes`}>
<Select <Select
ariaLabel={i18n('DisappearingTimeDialog__label--value')} ariaLabel={i18n('icu:DisappearingTimeDialog__label--value')}
moduleClassName={`${CSS_MODULE}__time-boxes__value`} moduleClassName={`${CSS_MODULE}__time-boxes__value`}
value={unitValue} value={unitValue}
onChange={newValue => setUnitValue(parseInt(newValue, 10))} onChange={newValue => setUnitValue(parseInt(newValue, 10))}
options={values.map(value => ({ value, text: value.toString() }))} options={values.map(value => ({ value, text: value.toString() }))}
/> />
<Select <Select
ariaLabel={i18n('DisappearingTimeDialog__label--units')} ariaLabel={i18n('icu:DisappearingTimeDialog__label--units')}
moduleClassName={`${CSS_MODULE}__time-boxes__units`} moduleClassName={`${CSS_MODULE}__time-boxes__units`}
value={unit} value={unit}
onChange={newUnit => { onChange={newUnit => {
@ -124,11 +124,11 @@ export function DisappearingTimeDialog(props: PropsType): JSX.Element {
return { return {
value: unitName, value: unitName,
text: { text: {
seconds: i18n('DisappearingTimeDialog__seconds'), seconds: i18n('icu:DisappearingTimeDialog__seconds'),
minutes: i18n('DisappearingTimeDialog__minutes'), minutes: i18n('icu:DisappearingTimeDialog__minutes'),
hours: i18n('DisappearingTimeDialog__hours'), hours: i18n('icu:DisappearingTimeDialog__hours'),
days: i18n('DisappearingTimeDialog__days'), days: i18n('icu:DisappearingTimeDialog__days'),
weeks: i18n('DisappearingTimeDialog__weeks'), weeks: i18n('icu:DisappearingTimeDialog__weeks'),
}[unitName], }[unitName],
}; };
})} })}

View file

@ -66,8 +66,8 @@ export function DisappearingTimerSelect(props: Props): JSX.Element {
{ {
value: DurationInSeconds.fromSeconds(-1), value: DurationInSeconds.fromSeconds(-1),
text: isCustomTimeSelected text: isCustomTimeSelected
? i18n('selectedCustomDisappearingTimeOption') ? i18n('icu:selectedCustomDisappearingTimeOption')
: i18n('customDisappearingTimeOption'), : i18n('icu:customDisappearingTimeOption'),
}, },
]; ];

View file

@ -101,23 +101,23 @@ export function EditUsernameModalBody({
return undefined; return undefined;
} }
if (error === UsernameReservationError.NotEnoughCharacters) { if (error === UsernameReservationError.NotEnoughCharacters) {
return i18n('ProfileEditor--username--check-character-min', { return i18n('icu:ProfileEditor--username--check-character-min', {
min: minNickname, min: minNickname,
}); });
} }
if (error === UsernameReservationError.TooManyCharacters) { if (error === UsernameReservationError.TooManyCharacters) {
return i18n('ProfileEditor--username--check-character-max', { return i18n('icu:ProfileEditor--username--check-character-max', {
max: maxNickname, max: maxNickname,
}); });
} }
if (error === UsernameReservationError.CheckStartingCharacter) { if (error === UsernameReservationError.CheckStartingCharacter) {
return i18n('ProfileEditor--username--check-starting-character'); return i18n('icu:ProfileEditor--username--check-starting-character');
} }
if (error === UsernameReservationError.CheckCharacters) { if (error === UsernameReservationError.CheckCharacters) {
return i18n('ProfileEditor--username--check-characters'); return i18n('icu:ProfileEditor--username--check-characters');
} }
if (error === UsernameReservationError.UsernameNotAvailable) { if (error === UsernameReservationError.UsernameNotAvailable) {
return i18n('ProfileEditor--username--unavailable'); return i18n('icu:ProfileEditor--username--unavailable');
} }
// Displayed through confirmation modal below // Displayed through confirmation modal below
if ( if (
@ -157,7 +157,7 @@ export function EditUsernameModalBody({
setIsLearnMoreVisible(true); setIsLearnMoreVisible(true);
}, []); }, []);
let title = i18n('ProfileEditor--username--title'); let title = i18n('icu:ProfileEditor--username--title');
if (nickname && discriminator) { if (nickname && discriminator) {
title = `${nickname}${discriminator}`; title = `${nickname}${discriminator}`;
} }
@ -165,7 +165,7 @@ export function EditUsernameModalBody({
const learnMoreTitle = ( const learnMoreTitle = (
<> <>
<i className="EditUsernameModalBody__learn-more__hashtag" /> <i className="EditUsernameModalBody__learn-more__hashtag" />
{i18n('EditUsernameModalBody__learn-more__title')} {i18n('icu:EditUsernameModalBody__learn-more__title')}
</> </>
); );
@ -184,7 +184,7 @@ export function EditUsernameModalBody({
disabled={isConfirming} disabled={isConfirming}
onChange={onChange} onChange={onChange}
onEnter={onSave} onEnter={onSave}
placeholder={i18n('EditUsernameModalBody__username-placeholder')} placeholder={i18n('icu:EditUsernameModalBody__username-placeholder')}
value={nickname} value={nickname}
> >
{isReserving && <Spinner size="16px" svgSize="small" />} {isReserving && <Spinner size="16px" svgSize="small" />}
@ -207,14 +207,14 @@ export function EditUsernameModalBody({
!errorString ? 'EditUsernameModalBody__info--no-error' : undefined !errorString ? 'EditUsernameModalBody__info--no-error' : undefined
)} )}
> >
{i18n('EditUsernameModalBody__username-helper')} {i18n('icu:EditUsernameModalBody__username-helper')}
&nbsp; &nbsp;
<button <button
type="button" type="button"
className="EditUsernameModalBody__learn-more-button" className="EditUsernameModalBody__learn-more-button"
onClick={onLearnMore} onClick={onLearnMore}
> >
{i18n('EditUsernameModalBody__learn-more')} {i18n('icu:EditUsernameModalBody__learn-more')}
</button> </button>
</div> </div>
@ -224,13 +224,13 @@ export function EditUsernameModalBody({
onClick={onCancel} onClick={onCancel}
variant={ButtonVariant.Secondary} variant={ButtonVariant.Secondary}
> >
{i18n('cancel')} {i18n('icu:cancel')}
</Button> </Button>
<Button disabled={!canSave} onClick={onSave}> <Button disabled={!canSave} onClick={onSave}>
{isConfirming ? ( {isConfirming ? (
<Spinner size="20px" svgSize="small" direction="on-avatar" /> <Spinner size="20px" svgSize="small" direction="on-avatar" />
) : ( ) : (
i18n('save') i18n('icu:save')
)} )}
</Button> </Button>
</Modal.ButtonFooter> </Modal.ButtonFooter>
@ -243,14 +243,14 @@ export function EditUsernameModalBody({
onClose={() => setIsLearnMoreVisible(false)} onClose={() => setIsLearnMoreVisible(false)}
title={learnMoreTitle} title={learnMoreTitle}
> >
{i18n('EditUsernameModalBody__learn-more__body')} {i18n('icu:EditUsernameModalBody__learn-more__body')}
<Modal.ButtonFooter> <Modal.ButtonFooter>
<Button <Button
onClick={() => setIsLearnMoreVisible(false)} onClick={() => setIsLearnMoreVisible(false)}
variant={ButtonVariant.Secondary} variant={ButtonVariant.Secondary}
> >
{i18n('ok')} {i18n('icu:ok')}
</Button> </Button>
</Modal.ButtonFooter> </Modal.ButtonFooter>
</Modal> </Modal>
@ -259,19 +259,19 @@ export function EditUsernameModalBody({
{error === UsernameReservationError.General && ( {error === UsernameReservationError.General && (
<ConfirmationDialog <ConfirmationDialog
dialogName="EditUsernameModalBody.generalError" dialogName="EditUsernameModalBody.generalError"
cancelText={i18n('ok')} cancelText={i18n('icu:ok')}
cancelButtonVariant={ButtonVariant.Secondary} cancelButtonVariant={ButtonVariant.Secondary}
i18n={i18n} i18n={i18n}
onClose={() => setUsernameReservationError(undefined)} onClose={() => setUsernameReservationError(undefined)}
> >
{i18n('ProfileEditor--username--general-error')} {i18n('icu:ProfileEditor--username--general-error')}
</ConfirmationDialog> </ConfirmationDialog>
)} )}
{error === UsernameReservationError.ConflictOrGone && ( {error === UsernameReservationError.ConflictOrGone && (
<ConfirmationDialog <ConfirmationDialog
dialogName="EditUsernameModalBody.conflictOrGone" dialogName="EditUsernameModalBody.conflictOrGone"
cancelText={i18n('ok')} cancelText={i18n('icu:ok')}
cancelButtonVariant={ButtonVariant.Secondary} cancelButtonVariant={ButtonVariant.Secondary}
i18n={i18n} i18n={i18n}
onClose={() => { onClose={() => {

View file

@ -26,7 +26,7 @@ export function ErrorModal(props: PropsType): JSX.Element {
const footer = ( const footer = (
<Button onClick={onClose} ref={focusRef} variant={ButtonVariant.Secondary}> <Button onClick={onClose} ref={focusRef} variant={ButtonVariant.Secondary}>
{i18n('Confirmation--confirm')} {i18n('icu:Confirmation--confirm')}
</Button> </Button>
); );
@ -35,11 +35,11 @@ export function ErrorModal(props: PropsType): JSX.Element {
modalName="ErrorModal" modalName="ErrorModal"
i18n={i18n} i18n={i18n}
onClose={onClose} onClose={onClose}
title={title || i18n('ErrorModal--title')} title={title || i18n('icu:ErrorModal--title')}
modalFooter={footer} modalFooter={footer}
> >
<div className="module-error-modal__description"> <div className="module-error-modal__description">
{description || i18n('ErrorModal--description')} {description || i18n('icu:ErrorModal--description')}
</div> </div>
</Modal> </Modal>
); );

View file

@ -258,11 +258,11 @@ export function ForwardMessagesModal({
{cannotMessage && ( {cannotMessage && (
<ConfirmationDialog <ConfirmationDialog
dialogName="ForwardMessageModal.confirm" dialogName="ForwardMessageModal.confirm"
cancelText={i18n('Confirmation--confirm')} cancelText={i18n('icu:Confirmation--confirm')}
i18n={i18n} i18n={i18n}
onClose={() => setCannotMessage(false)} onClose={() => setCannotMessage(false)}
> >
{i18n('GroupV2--cannot-send')} {i18n('icu:GroupV2--cannot-send')}
</ConfirmationDialog> </ConfirmationDialog>
)} )}
<ModalHost <ModalHost
@ -283,7 +283,7 @@ export function ForwardMessagesModal({
> >
{isEditingMessage ? ( {isEditingMessage ? (
<button <button
aria-label={i18n('back')} aria-label={i18n('icu:back')}
className="module-ForwardMessageModal__header--back" className="module-ForwardMessageModal__header--back"
onClick={() => setIsEditingMessage(false)} onClick={() => setIsEditingMessage(false)}
type="button" type="button"
@ -292,7 +292,7 @@ export function ForwardMessagesModal({
</button> </button>
) : ( ) : (
<button <button
aria-label={i18n('close')} aria-label={i18n('icu:close')}
className="module-ForwardMessageModal__header--close" className="module-ForwardMessageModal__header--close"
onClick={close} onClick={close}
type="button" type="button"
@ -318,7 +318,7 @@ export function ForwardMessagesModal({
<SearchInput <SearchInput
disabled={candidateConversations.length === 0} disabled={candidateConversations.length === 0}
i18n={i18n} i18n={i18n}
placeholder={i18n('contactSearchPlaceholder')} placeholder={i18n('icu:contactSearchPlaceholder')}
onChange={event => { onChange={event => {
setSearchTerm(event.target.value); setSearchTerm(event.target.value);
}} }}
@ -370,7 +370,7 @@ export function ForwardMessagesModal({
</Measure> </Measure>
) : ( ) : (
<div className="module-ForwardMessageModal__no-candidate-contacts"> <div className="module-ForwardMessageModal__no-candidate-contacts">
{i18n('noContactsFound')} {i18n('icu:noContactsFound')}
</div> </div>
)} )}
</div> </div>
@ -388,14 +388,14 @@ export function ForwardMessagesModal({
<div> <div>
{isEditingMessage || !isLonelyDraftEditable ? ( {isEditingMessage || !isLonelyDraftEditable ? (
<Button <Button
aria-label={i18n('ForwardMessageModal--continue')} aria-label={i18n('icu:ForwardMessageModal--continue')}
className="module-ForwardMessageModal__send-button module-ForwardMessageModal__send-button--forward" className="module-ForwardMessageModal__send-button module-ForwardMessageModal__send-button--forward"
aria-disabled={!canForwardMessages} aria-disabled={!canForwardMessages}
onClick={forwardMessages} onClick={forwardMessages}
/> />
) : ( ) : (
<Button <Button
aria-label={i18n('forwardMessage')} aria-label={i18n('icu:forwardMessage')}
className="module-ForwardMessageModal__send-button module-ForwardMessageModal__send-button--continue" className="module-ForwardMessageModal__send-button module-ForwardMessageModal__send-button--continue"
disabled={!hasContactsSelected} disabled={!hasContactsSelected}
onClick={() => setIsEditingMessage(true)} onClick={() => setIsEditingMessage(true)}

View file

@ -198,11 +198,11 @@ export function GlobalModalContainer({
if (userNotFoundModalState) { if (userNotFoundModalState) {
let content: string; let content: string;
if (userNotFoundModalState.type === 'phoneNumber') { if (userNotFoundModalState.type === 'phoneNumber') {
content = i18n('startConversation--phone-number-not-found', { content = i18n('icu:startConversation--phone-number-not-found', {
phoneNumber: userNotFoundModalState.phoneNumber, phoneNumber: userNotFoundModalState.phoneNumber,
}); });
} else if (userNotFoundModalState.type === 'username') { } else if (userNotFoundModalState.type === 'username') {
content = i18n('startConversation--username-not-found', { content = i18n('icu:startConversation--username-not-found', {
atUsername: userNotFoundModalState.username, atUsername: userNotFoundModalState.username,
}); });
} else { } else {
@ -212,7 +212,7 @@ export function GlobalModalContainer({
return ( return (
<ConfirmationDialog <ConfirmationDialog
dialogName="GlobalModalContainer.userNotFound" dialogName="GlobalModalContainer.userNotFound"
cancelText={i18n('ok')} cancelText={i18n('icu:ok')}
cancelButtonVariant={ButtonVariant.Secondary} cancelButtonVariant={ButtonVariant.Secondary}
i18n={i18n} i18n={i18n}
onClose={hideUserNotFoundModal} onClose={hideUserNotFoundModal}

View file

@ -179,8 +179,8 @@ function OverflowAreaScrollMarker({
onClick={onClick} onClick={onClick}
aria-label={ aria-label={
placement === 'top' placement === 'top'
? i18n('calling__overflow__scroll-up') ? i18n('icu:calling__overflow__scroll-up')
: i18n('calling__overflow__scroll-down') : i18n('icu:calling__overflow__scroll-down')
} }
/> />
</div> </div>

View file

@ -259,7 +259,7 @@ export const GroupCallRemoteParticipant: React.FC<PropsType> = React.memo(
{showBlockInfo && ( {showBlockInfo && (
<ConfirmationDialog <ConfirmationDialog
dialogName="GroupCallRemoteParticipant.blockInfo" dialogName="GroupCallRemoteParticipant.blockInfo"
cancelText={i18n('ok')} cancelText={i18n('icu:ok')}
i18n={i18n} i18n={i18n}
onClose={() => { onClose={() => {
setShowBlockInfo(false); setShowBlockInfo(false);
@ -268,7 +268,7 @@ export const GroupCallRemoteParticipant: React.FC<PropsType> = React.memo(
<div className="module-ongoing-call__group-call-remote-participant__blocked--modal-title"> <div className="module-ongoing-call__group-call-remote-participant__blocked--modal-title">
<Intl <Intl
i18n={i18n} i18n={i18n}
id="calling__you-have-blocked" id="icu:calling__you-have-blocked"
components={{ components={{
name: <ContactName key="name" title={title} />, name: <ContactName key="name" title={title} />,
}} }}
@ -276,7 +276,7 @@ export const GroupCallRemoteParticipant: React.FC<PropsType> = React.memo(
</div> </div>
} }
> >
{i18n('calling__block-info')} {i18n('icu:calling__block-info')}
</ConfirmationDialog> </ConfirmationDialog>
)} )}
@ -344,7 +344,7 @@ export const GroupCallRemoteParticipant: React.FC<PropsType> = React.memo(
setShowBlockInfo(true); setShowBlockInfo(true);
}} }}
> >
{i18n('moreInfo')} {i18n('icu:moreInfo')}
</button> </button>
</> </>
) : ( ) : (

View file

@ -24,7 +24,9 @@ export const GroupDescriptionInput = forwardRef<HTMLInputElement, PropsType>(
expandable expandable
i18n={i18n} i18n={i18n}
onChange={onChangeValue} onChange={onChangeValue}
placeholder={i18n('setGroupMetadata__group-description-placeholder')} placeholder={i18n(
'icu:setGroupMetadata__group-description-placeholder'
)}
maxLengthCount={480} maxLengthCount={480}
maxByteCount={8192} maxByteCount={8192}
ref={ref} ref={ref}

View file

@ -57,7 +57,7 @@ export function GroupDialog(props: Readonly<PropsType>): JSX.Element {
<ModalHost modalName="GroupDialog" onClose={onClose}> <ModalHost modalName="GroupDialog" onClose={onClose}>
<div className="module-GroupDialog"> <div className="module-GroupDialog">
<button <button
aria-label={i18n('close')} aria-label={i18n('icu:close')}
type="button" type="button"
className="module-GroupDialog__close-button" className="module-GroupDialog__close-button"
onClick={() => { onClick={() => {

View file

@ -23,7 +23,7 @@ export const GroupTitleInput = forwardRef<HTMLInputElement, PropsType>(
disabled={disabled} disabled={disabled}
i18n={i18n} i18n={i18n}
onChange={onChangeValue} onChange={onChangeValue}
placeholder={i18n('setGroupMetadata__group-name-placeholder')} placeholder={i18n('icu:setGroupMetadata__group-name-placeholder')}
maxLengthCount={32} maxLengthCount={32}
ref={ref} ref={ref}
value={value} value={value}

View file

@ -66,11 +66,11 @@ export const GroupV1MigrationDialog: React.FunctionComponent<PropsType> =
} }
const title = hasMigrated const title = hasMigrated
? i18n('GroupV1--Migration--info--title') ? i18n('icu:GroupV1--Migration--info--title')
: i18n('GroupV1--Migration--migrate--title'); : i18n('icu:GroupV1--Migration--migrate--title');
const keepHistory = hasMigrated const keepHistory = hasMigrated
? i18n('GroupV1--Migration--info--keep-history') ? i18n('icu:GroupV1--Migration--info--keep-history')
: i18n('GroupV1--Migration--migrate--keep-history'); : i18n('icu:GroupV1--Migration--migrate--keep-history');
let primaryButtonText: string; let primaryButtonText: string;
let onClickPrimaryButton: () => void; let onClickPrimaryButton: () => void;
@ -81,13 +81,13 @@ export const GroupV1MigrationDialog: React.FunctionComponent<PropsType> =
onClickSecondaryButton: () => void; onClickSecondaryButton: () => void;
}; };
if (hasMigrated) { if (hasMigrated) {
primaryButtonText = i18n('Confirmation--confirm'); primaryButtonText = i18n('icu:Confirmation--confirm');
onClickPrimaryButton = closeHandler; onClickPrimaryButton = closeHandler;
} else { } else {
primaryButtonText = i18n('GroupV1--Migration--migrate'); primaryButtonText = i18n('icu:GroupV1--Migration--migrate');
onClickPrimaryButton = migrateHandler; onClickPrimaryButton = migrateHandler;
secondaryButtonProps = { secondaryButtonProps = {
secondaryButtonText: i18n('cancel'), secondaryButtonText: i18n('icu:cancel'),
onClickSecondaryButton: closeHandler, onClickSecondaryButton: closeHandler,
}; };
} }
@ -102,12 +102,12 @@ export const GroupV1MigrationDialog: React.FunctionComponent<PropsType> =
{...secondaryButtonProps} {...secondaryButtonProps}
> >
<GroupDialog.Paragraph> <GroupDialog.Paragraph>
{i18n('GroupV1--Migration--info--summary')} {i18n('icu:GroupV1--Migration--info--summary')}
</GroupDialog.Paragraph> </GroupDialog.Paragraph>
<GroupDialog.Paragraph>{keepHistory}</GroupDialog.Paragraph> <GroupDialog.Paragraph>{keepHistory}</GroupDialog.Paragraph>
{areWeInvited ? ( {areWeInvited ? (
<GroupDialog.Paragraph> <GroupDialog.Paragraph>
{i18n('GroupV1--Migration--info--invited--you')} {i18n('icu:GroupV1--Migration--info--invited--you')}
</GroupDialog.Paragraph> </GroupDialog.Paragraph>
) : ( ) : (
<> <>
@ -157,20 +157,20 @@ function renderMembers({
case 'invited': case 'invited':
text = text =
members.length === 1 members.length === 1
? i18n('GroupV1--Migration--info--invited--one') ? i18n('icu:GroupV1--Migration--info--invited--one')
: i18n('GroupV1--Migration--info--invited--many'); : i18n('icu:GroupV1--Migration--info--invited--many');
break; break;
case 'dropped': case 'dropped':
if (hasMigrated) { if (hasMigrated) {
text = text =
members.length === 1 members.length === 1
? i18n('GroupV1--Migration--info--removed--before--one') ? i18n('icu:GroupV1--Migration--info--removed--before--one')
: i18n('GroupV1--Migration--info--removed--before--many'); : i18n('icu:GroupV1--Migration--info--removed--before--many');
} else { } else {
text = text =
members.length === 1 members.length === 1
? i18n('GroupV1--Migration--info--removed--after--one') ? i18n('icu:GroupV1--Migration--info--removed--after--one')
: i18n('GroupV1--Migration--info--removed--after--many'); : i18n('icu:GroupV1--Migration--info--removed--after--many');
} }
break; break;
default: default:

View file

@ -47,12 +47,12 @@ export const GroupV2JoinDialog = React.memo(function GroupV2JoinDialogInner(
} = props; } = props;
const joinString = approvalRequired const joinString = approvalRequired
? i18n('GroupV2--join--request-to-join-button') ? i18n('icu:GroupV2--join--request-to-join-button')
: i18n('GroupV2--join--join-button'); : i18n('icu:GroupV2--join--join-button');
const memberString = const memberString =
memberCount === 1 memberCount === 1
? i18n('GroupV2--join--member-count--single') ? i18n('icu:GroupV2--join--member-count--single')
: i18n('GroupV2--join--member-count--multiple', { : i18n('icu:GroupV2--join--member-count--multiple', {
count: memberCount.toString(), count: memberCount.toString(),
}); });
@ -70,7 +70,7 @@ export const GroupV2JoinDialog = React.memo(function GroupV2JoinDialogInner(
return ( return (
<div className="module-group-v2-join-dialog"> <div className="module-group-v2-join-dialog">
<button <button
aria-label={i18n('close')} aria-label={i18n('icu:close')}
type="button" type="button"
disabled={isWorking} disabled={isWorking}
className="module-group-v2-join-dialog__close-button" className="module-group-v2-join-dialog__close-button"
@ -93,7 +93,7 @@ export const GroupV2JoinDialog = React.memo(function GroupV2JoinDialogInner(
</div> </div>
<div className="module-group-v2-join-dialog__title">{title}</div> <div className="module-group-v2-join-dialog__title">{title}</div>
<div className="module-group-v2-join-dialog__metadata"> <div className="module-group-v2-join-dialog__metadata">
{i18n('GroupV2--join--group-metadata', { {i18n('icu:GroupV2--join--group-metadata', {
memberCount: memberString, memberCount: memberString,
})} })}
</div> </div>
@ -104,11 +104,11 @@ export const GroupV2JoinDialog = React.memo(function GroupV2JoinDialogInner(
)} )}
{approvalRequired ? ( {approvalRequired ? (
<div className="module-group-v2-join-dialog__prompt--approval"> <div className="module-group-v2-join-dialog__prompt--approval">
{i18n('GroupV2--join--prompt-with-approval')} {i18n('icu:GroupV2--join--prompt-with-approval')}
</div> </div>
) : ( ) : (
<div className="module-group-v2-join-dialog__prompt"> <div className="module-group-v2-join-dialog__prompt">
{i18n('GroupV2--join--prompt')} {i18n('icu:GroupV2--join--prompt')}
</div> </div>
)} )}
<div className="module-group-v2-join-dialog__buttons"> <div className="module-group-v2-join-dialog__buttons">
@ -121,7 +121,7 @@ export const GroupV2JoinDialog = React.memo(function GroupV2JoinDialogInner(
onClick={wrappedClose} onClick={wrappedClose}
variant={ButtonVariant.Secondary} variant={ButtonVariant.Secondary}
> >
{i18n('cancel')} {i18n('icu:cancel')}
</Button> </Button>
<Button <Button
className="module-group-v2-join-dialog__button" className="module-group-v2-join-dialog__button"

View file

@ -19,7 +19,7 @@ export function InContactsIcon(props: PropsType): JSX.Element {
/* eslint-disable jsx-a11y/no-noninteractive-tabindex */ /* eslint-disable jsx-a11y/no-noninteractive-tabindex */
return ( return (
<Tooltip <Tooltip
content={i18n('contactInAddressBook')} content={i18n('icu:contactInAddressBook')}
popperModifiers={[ popperModifiers={[
{ {
name: 'preventOverflow', name: 'preventOverflow',
@ -30,7 +30,7 @@ export function InContactsIcon(props: PropsType): JSX.Element {
]} ]}
> >
<span <span
aria-label={i18n('contactInAddressBook')} aria-label={i18n('icu:contactInAddressBook')}
className={classNames('module-in-contacts-icon__icon', className)} className={classNames('module-in-contacts-icon__icon', className)}
role="img" role="img"
tabIndex={0} tabIndex={0}

View file

@ -202,7 +202,7 @@ export function Inbox({
) * 100; ) * 100;
} }
let message = i18n('loading'); let message = i18n('icu:loading');
if (envelopeTimestamp !== undefined) { if (envelopeTimestamp !== undefined) {
const daysBeforeMidnight = Math.ceil( const daysBeforeMidnight = Math.ceil(
(midnight - envelopeTimestamp) / DAY (midnight - envelopeTimestamp) / DAY
@ -262,7 +262,7 @@ export function Inbox({
<div className="no-conversation-open"> <div className="no-conversation-open">
{renderMiniPlayer({ shouldFlow: false })} {renderMiniPlayer({ shouldFlow: false })}
<div className="module-splash-screen__logo module-img--128 module-logo-blue" /> <div className="module-splash-screen__logo module-img--128 module-logo-blue" />
<h3>{i18n('welcomeToSignal')}</h3> <h3>{i18n('icu:welcomeToSignal')}</h3>
<p className="whats-new-placeholder"> <p className="whats-new-placeholder">
<WhatsNewLink <WhatsNewLink
i18n={i18n} i18n={i18n}

View file

@ -101,7 +101,7 @@ function GroupCallMessage({
case 0: case 0:
return ( return (
<Intl <Intl
id="incomingGroupCall__ringing-you" id="icu:incomingGroupCall__ringing-you"
i18n={i18n} i18n={i18n}
components={{ ringer: ringerNode }} components={{ ringer: ringerNode }}
/> />
@ -109,7 +109,7 @@ function GroupCallMessage({
case 1: case 1:
return ( return (
<Intl <Intl
id="incomingGroupCall__ringing-1-other" id="icu:incomingGroupCall__ringing-1-other"
i18n={i18n} i18n={i18n}
components={{ components={{
ringer: ringerNode, ringer: ringerNode,
@ -120,7 +120,7 @@ function GroupCallMessage({
case 2: case 2:
return ( return (
<Intl <Intl
id="incomingGroupCall__ringing-2-others" id="icu:incomingGroupCall__ringing-2-others"
i18n={i18n} i18n={i18n}
components={{ components={{
ringer: ringerNode, ringer: ringerNode,
@ -132,7 +132,7 @@ function GroupCallMessage({
case 3: case 3:
return ( return (
<Intl <Intl
id="incomingGroupCall__ringing-3-others" id="icu:incomingGroupCall__ringing-3-others"
i18n={i18n} i18n={i18n}
components={{ components={{
ringer: ringerNode, ringer: ringerNode,
@ -144,7 +144,7 @@ function GroupCallMessage({
default: default:
return ( return (
<Intl <Intl
id="incomingGroupCall__ringing-many" id="icu:incomingGroupCall__ringing-many"
i18n={i18n} i18n={i18n}
components={{ components={{
ringer: ringerNode, ringer: ringerNode,
@ -189,8 +189,8 @@ export function IncomingCallBar(props: PropsType): JSX.Element | null {
({ isVideoCall } = props); ({ isVideoCall } = props);
headerNode = <ContactName title={title} />; headerNode = <ContactName title={title} />;
messageNode = isVideoCall messageNode = isVideoCall
? i18n('incomingVideoCall') ? i18n('icu:incomingVideoCall')
: i18n('incomingAudioCall'); : i18n('icu:incomingAudioCall');
break; break;
case CallMode.Group: { case CallMode.Group: {
const { otherMembersRung, ringer } = props; const { otherMembersRung, ringer } = props;
@ -282,7 +282,7 @@ export function IncomingCallBar(props: PropsType): JSX.Element | null {
classSuffix="decline" classSuffix="decline"
onClick={declineIncomingCall} onClick={declineIncomingCall}
tabIndex={0} tabIndex={0}
tooltipContent={i18n('declineCall')} tooltipContent={i18n('icu:declineCall')}
/> />
{isVideoCall ? ( {isVideoCall ? (
<> <>
@ -290,13 +290,13 @@ export function IncomingCallBar(props: PropsType): JSX.Element | null {
classSuffix="accept-video-as-audio" classSuffix="accept-video-as-audio"
onClick={acceptAudioCall} onClick={acceptAudioCall}
tabIndex={0} tabIndex={0}
tooltipContent={i18n('acceptCallWithoutVideo')} tooltipContent={i18n('icu:acceptCallWithoutVideo')}
/> />
<CallButton <CallButton
classSuffix="accept-video" classSuffix="accept-video"
onClick={acceptVideoCall} onClick={acceptVideoCall}
tabIndex={0} tabIndex={0}
tooltipContent={i18n('acceptCall')} tooltipContent={i18n('icu:acceptCall')}
/> />
</> </>
) : ( ) : (
@ -304,7 +304,7 @@ export function IncomingCallBar(props: PropsType): JSX.Element | null {
classSuffix="accept-audio" classSuffix="accept-audio"
onClick={acceptAudioCall} onClick={acceptAudioCall}
tabIndex={0} tabIndex={0}
tooltipContent={i18n('acceptCall')} tooltipContent={i18n('icu:acceptCall')}
/> />
)} )}
</div> </div>

View file

@ -223,7 +223,7 @@ export const Input = forwardRef<
className={getClassName('__clear-icon')} className={getClassName('__clear-icon')}
onClick={() => onChange('')} onClick={() => onChange('')}
type="button" type="button"
aria-label={i18n('cancel')} aria-label={i18n('icu:cancel')}
/> />
) : null; ) : null;

View file

@ -87,7 +87,7 @@ export function LeftPaneSearchInput({
inputRef.current?.focus(); inputRef.current?.focus();
}; };
const label = searchConversation ? i18n('searchIn') : i18n('search'); const label = searchConversation ? i18n('icu:searchIn') : i18n('icu:search');
return ( return (
<SearchInput <SearchInput
@ -149,7 +149,7 @@ export function LeftPaneSearchInput({
unblurredAvatarPath={searchConversation.unblurredAvatarPath} unblurredAvatarPath={searchConversation.unblurredAvatarPath}
/> />
<button <button
aria-label={i18n('clearSearch')} aria-label={i18n('icu:clearSearch')}
className="LeftPaneSearchInput__in-conversation-pill__x-button" className="LeftPaneSearchInput__in-conversation-pill__x-button"
onClick={clearAndFocus} onClick={clearAndFocus}
type="button" type="button"

View file

@ -504,7 +504,7 @@ export function Lightbox({
type="button" type="button"
> >
<img <img
alt={i18n('lightboxImageAlt')} alt={i18n('icu:lightboxImageAlt')}
className="Lightbox__object" className="Lightbox__object"
onContextMenu={(ev: React.MouseEvent<HTMLImageElement>) => { onContextMenu={(ev: React.MouseEvent<HTMLImageElement>) => {
// These are the only image types supported by Electron's NativeImage // These are the only image types supported by Electron's NativeImage
@ -525,7 +525,7 @@ export function Lightbox({
} else { } else {
content = ( content = (
<button <button
aria-label={i18n('lightboxImageAlt')} aria-label={i18n('icu:lightboxImageAlt')}
className={classNames({ className={classNames({
Lightbox__object: true, Lightbox__object: true,
Lightbox__unsupported: true, Lightbox__unsupported: true,
@ -555,7 +555,7 @@ export function Lightbox({
} else if (isUnsupportedImageType || isUnsupportedVideoType) { } else if (isUnsupportedImageType || isUnsupportedVideoType) {
content = ( content = (
<button <button
aria-label={i18n('unsupportedAttachment')} aria-label={i18n('icu:unsupportedAttachment')}
className={classNames({ className={classNames({
Lightbox__object: true, Lightbox__object: true,
Lightbox__unsupported: true, Lightbox__unsupported: true,
@ -571,7 +571,7 @@ export function Lightbox({
content = ( content = (
<button <button
aria-label={i18n('unsupportedAttachment')} aria-label={i18n('icu:unsupportedAttachment')}
className="Lightbox__object Lightbox__unsupported Lightbox__unsupported--file" className="Lightbox__object Lightbox__unsupported Lightbox__unsupported--file"
onClick={onClose} onClick={onClose}
type="button" type="button"
@ -629,7 +629,7 @@ export function Lightbox({
<div className="Lightbox__controls"> <div className="Lightbox__controls">
{!isViewOnce ? ( {!isViewOnce ? (
<button <button
aria-label={i18n('forwardMessage')} aria-label={i18n('icu:forwardMessage')}
className="Lightbox__button Lightbox__button--forward" className="Lightbox__button Lightbox__button--forward"
onClick={handleForward} onClick={handleForward}
type="button" type="button"
@ -637,14 +637,14 @@ export function Lightbox({
) : null} ) : null}
{!isViewOnce ? ( {!isViewOnce ? (
<button <button
aria-label={i18n('save')} aria-label={i18n('icu:save')}
className="Lightbox__button Lightbox__button--save" className="Lightbox__button Lightbox__button--save"
onClick={handleSave} onClick={handleSave}
type="button" type="button"
/> />
) : null} ) : null}
<button <button
aria-label={i18n('close')} aria-label={i18n('icu:close')}
className="Lightbox__button Lightbox__button--close" className="Lightbox__button Lightbox__button--close"
onClick={closeLightbox} onClick={closeLightbox}
type="button" type="button"
@ -668,7 +668,7 @@ export function Lightbox({
{hasPrevious && ( {hasPrevious && (
<div className="Lightbox__nav-prev"> <div className="Lightbox__nav-prev">
<button <button
aria-label={i18n('previous')} aria-label={i18n('icu:previous')}
className="Lightbox__button Lightbox__button--previous" className="Lightbox__button Lightbox__button--previous"
onClick={onPrevious} onClick={onPrevious}
type="button" type="button"
@ -678,7 +678,7 @@ export function Lightbox({
{hasNext && ( {hasNext && (
<div className="Lightbox__nav-next"> <div className="Lightbox__nav-next">
<button <button
aria-label={i18n('next')} aria-label={i18n('icu:next')}
className="Lightbox__button Lightbox__button--next" className="Lightbox__button Lightbox__button--next"
onClick={onNext} onClick={onNext}
type="button" type="button"
@ -725,7 +725,7 @@ export function Lightbox({
> >
{item.thumbnailObjectUrl ? ( {item.thumbnailObjectUrl ? (
<img <img
alt={i18n('lightboxImageAlt')} alt={i18n('icu:lightboxImageAlt')}
src={item.thumbnailObjectUrl} src={item.thumbnailObjectUrl}
/> />
) : ( ) : (

View file

@ -247,10 +247,10 @@ export class MainHeader extends React.Component<PropsType, StateType> {
<div className="module-main-header__icon-container"> <div className="module-main-header__icon-container">
{areStoriesEnabled && ( {areStoriesEnabled && (
<button <button
aria-label={i18n('stories')} aria-label={i18n('icu:stories')}
className="module-main-header__stories-icon" className="module-main-header__stories-icon"
onClick={toggleStoriesView} onClick={toggleStoriesView}
title={i18n('stories')} title={i18n('icu:stories')}
type="button" type="button"
> >
{hasFailedStorySends && ( {hasFailedStorySends && (
@ -264,10 +264,10 @@ export class MainHeader extends React.Component<PropsType, StateType> {
</button> </button>
)} )}
<button <button
aria-label={i18n('newConversation')} aria-label={i18n('icu:newConversation')}
className="module-main-header__compose-icon" className="module-main-header__compose-icon"
onClick={startComposing} onClick={startComposing}
title={i18n('newConversation')} title={i18n('icu:newConversation')}
type="button" type="button"
/> />
</div> </div>

View file

@ -632,7 +632,7 @@ export function MediaEditor({
<> <>
<Slider <Slider
handleStyle={{ backgroundColor: getHSL(sliderValue) }} handleStyle={{ backgroundColor: getHSL(sliderValue) }}
label={i18n('CustomColorEditor__hue')} label={i18n('icu:CustomColorEditor__hue')}
moduleClassName="HueSlider MediaEditor__tools__tool" moduleClassName="HueSlider MediaEditor__tools__tool"
onChange={setSliderValue} onChange={setSliderValue}
value={sliderValue} value={sliderValue}
@ -642,19 +642,19 @@ export function MediaEditor({
menuOptions={[ menuOptions={[
{ {
icon: 'MediaEditor__icon--text-regular', icon: 'MediaEditor__icon--text-regular',
label: i18n('MediaEditor__text--regular'), label: i18n('icu:MediaEditor__text--regular'),
onClick: () => setTextStyle(TextStyle.Regular), onClick: () => setTextStyle(TextStyle.Regular),
value: TextStyle.Regular, value: TextStyle.Regular,
}, },
{ {
icon: 'MediaEditor__icon--text-highlight', icon: 'MediaEditor__icon--text-highlight',
label: i18n('MediaEditor__text--highlight'), label: i18n('icu:MediaEditor__text--highlight'),
onClick: () => setTextStyle(TextStyle.Highlight), onClick: () => setTextStyle(TextStyle.Highlight),
value: TextStyle.Highlight, value: TextStyle.Highlight,
}, },
{ {
icon: 'MediaEditor__icon--text-outline', icon: 'MediaEditor__icon--text-outline',
label: i18n('MediaEditor__text--outline'), label: i18n('icu:MediaEditor__text--outline'),
onClick: () => setTextStyle(TextStyle.Outline), onClick: () => setTextStyle(TextStyle.Outline),
value: TextStyle.Outline, value: TextStyle.Outline,
}, },
@ -682,7 +682,7 @@ export function MediaEditor({
}} }}
type="button" type="button"
> >
{i18n('done')} {i18n('icu:done')}
</button> </button>
</> </>
); );
@ -691,7 +691,7 @@ export function MediaEditor({
<> <>
<Slider <Slider
handleStyle={{ backgroundColor: getHSL(sliderValue) }} handleStyle={{ backgroundColor: getHSL(sliderValue) }}
label={i18n('CustomColorEditor__hue')} label={i18n('icu:CustomColorEditor__hue')}
moduleClassName="HueSlider MediaEditor__tools__tool" moduleClassName="HueSlider MediaEditor__tools__tool"
onChange={setSliderValue} onChange={setSliderValue}
value={sliderValue} value={sliderValue}
@ -701,13 +701,13 @@ export function MediaEditor({
menuOptions={[ menuOptions={[
{ {
icon: 'MediaEditor__icon--draw-pen', icon: 'MediaEditor__icon--draw-pen',
label: i18n('MediaEditor__draw--pen'), label: i18n('icu:MediaEditor__draw--pen'),
onClick: () => setDrawTool(DrawTool.Pen), onClick: () => setDrawTool(DrawTool.Pen),
value: DrawTool.Pen, value: DrawTool.Pen,
}, },
{ {
icon: 'MediaEditor__icon--draw-highlighter', icon: 'MediaEditor__icon--draw-highlighter',
label: i18n('MediaEditor__draw--highlighter'), label: i18n('icu:MediaEditor__draw--highlighter'),
onClick: () => setDrawTool(DrawTool.Highlighter), onClick: () => setDrawTool(DrawTool.Highlighter),
value: DrawTool.Highlighter, value: DrawTool.Highlighter,
}, },
@ -725,25 +725,25 @@ export function MediaEditor({
menuOptions={[ menuOptions={[
{ {
icon: 'MediaEditor__icon--width-thin', icon: 'MediaEditor__icon--width-thin',
label: i18n('MediaEditor__draw--thin'), label: i18n('icu:MediaEditor__draw--thin'),
onClick: () => setDrawWidth(DrawWidth.Thin), onClick: () => setDrawWidth(DrawWidth.Thin),
value: DrawWidth.Thin, value: DrawWidth.Thin,
}, },
{ {
icon: 'MediaEditor__icon--width-regular', icon: 'MediaEditor__icon--width-regular',
label: i18n('MediaEditor__draw--regular'), label: i18n('icu:MediaEditor__draw--regular'),
onClick: () => setDrawWidth(DrawWidth.Regular), onClick: () => setDrawWidth(DrawWidth.Regular),
value: DrawWidth.Regular, value: DrawWidth.Regular,
}, },
{ {
icon: 'MediaEditor__icon--width-medium', icon: 'MediaEditor__icon--width-medium',
label: i18n('MediaEditor__draw--medium'), label: i18n('icu:MediaEditor__draw--medium'),
onClick: () => setDrawWidth(DrawWidth.Medium), onClick: () => setDrawWidth(DrawWidth.Medium),
value: DrawWidth.Medium, value: DrawWidth.Medium,
}, },
{ {
icon: 'MediaEditor__icon--width-heavy', icon: 'MediaEditor__icon--width-heavy',
label: i18n('MediaEditor__draw--heavy'), label: i18n('icu:MediaEditor__draw--heavy'),
onClick: () => setDrawWidth(DrawWidth.Heavy), onClick: () => setDrawWidth(DrawWidth.Heavy),
value: DrawWidth.Heavy, value: DrawWidth.Heavy,
}, },
@ -766,7 +766,7 @@ export function MediaEditor({
onClick={() => setEditMode(undefined)} onClick={() => setEditMode(undefined)}
type="button" type="button"
> >
{i18n('done')} {i18n('icu:done')}
</button> </button>
</> </>
); );
@ -799,10 +799,10 @@ export function MediaEditor({
}} }}
type="button" type="button"
> >
{i18n('MediaEditor__crop--reset')} {i18n('icu:MediaEditor__crop--reset')}
</button> </button>
<button <button
aria-label={i18n('MediaEditor__crop--rotate')} aria-label={i18n('icu:MediaEditor__crop--rotate')}
className="MediaEditor__tools__tool MediaEditor__tools__button MediaEditor__tools__button--rotate" className="MediaEditor__tools__tool MediaEditor__tools__button MediaEditor__tools__button--rotate"
onClick={() => { onClick={() => {
if (!fabricCanvas) { if (!fabricCanvas) {
@ -838,7 +838,7 @@ export function MediaEditor({
type="button" type="button"
/> />
<button <button
aria-label={i18n('MediaEditor__crop--flip')} aria-label={i18n('icu:MediaEditor__crop--flip')}
className="MediaEditor__tools__tool MediaEditor__tools__button MediaEditor__tools__button--flip" className="MediaEditor__tools__tool MediaEditor__tools__button MediaEditor__tools__button--flip"
onClick={() => { onClick={() => {
if (!fabricCanvas) { if (!fabricCanvas) {
@ -857,7 +857,7 @@ export function MediaEditor({
type="button" type="button"
/> />
<button <button
aria-label={i18n('MediaEditor__crop--lock')} aria-label={i18n('icu:MediaEditor__crop--lock')}
className={classNames( className={classNames(
'MediaEditor__tools__button', 'MediaEditor__tools__button',
`MediaEditor__tools__button--crop-${ `MediaEditor__tools__button--crop-${
@ -896,7 +896,7 @@ export function MediaEditor({
}} }}
type="button" type="button"
> >
{i18n('done')} {i18n('icu:done')}
</button> </button>
</> </>
); );
@ -955,7 +955,7 @@ export function MediaEditor({
/> />
</span> </span>
) : ( ) : (
i18n('MediaEditor__caption-button') i18n('icu:MediaEditor__caption-button')
)} )}
</button> </button>
@ -984,11 +984,11 @@ export function MediaEditor({
theme={Theme.Dark} theme={Theme.Dark}
variant={ButtonVariant.Secondary} variant={ButtonVariant.Secondary}
> >
{i18n('discard')} {i18n('icu:discard')}
</Button> </Button>
<div className="MediaEditor__controls"> <div className="MediaEditor__controls">
<button <button
aria-label={i18n('MediaEditor__control--draw')} aria-label={i18n('icu:MediaEditor__control--draw')}
className={classNames({ className={classNames({
MediaEditor__control: true, MediaEditor__control: true,
'MediaEditor__control--pen': true, 'MediaEditor__control--pen': true,
@ -1002,7 +1002,7 @@ export function MediaEditor({
type="button" type="button"
/> />
<button <button
aria-label={i18n('MediaEditor__control--text')} aria-label={i18n('icu:MediaEditor__control--text')}
className={classNames({ className={classNames({
MediaEditor__control: true, MediaEditor__control: true,
'MediaEditor__control--text': true, 'MediaEditor__control--text': true,
@ -1117,7 +1117,7 @@ export function MediaEditor({
theme={Theme.Dark} theme={Theme.Dark}
/> />
<button <button
aria-label={i18n('MediaEditor__control--crop')} aria-label={i18n('icu:MediaEditor__control--crop')}
className={classNames({ className={classNames({
MediaEditor__control: true, MediaEditor__control: true,
'MediaEditor__control--crop': true, 'MediaEditor__control--crop': true,
@ -1140,7 +1140,7 @@ export function MediaEditor({
type="button" type="button"
/> />
<button <button
aria-label={i18n('MediaEditor__control--undo')} aria-label={i18n('icu:MediaEditor__control--undo')}
className="MediaEditor__control MediaEditor__control--undo" className="MediaEditor__control MediaEditor__control--undo"
disabled={!canUndo} disabled={!canUndo}
onClick={() => { onClick={() => {
@ -1152,7 +1152,7 @@ export function MediaEditor({
type="button" type="button"
/> />
<button <button
aria-label={i18n('MediaEditor__control--redo')} aria-label={i18n('icu:MediaEditor__control--redo')}
className="MediaEditor__control MediaEditor__control--redo" className="MediaEditor__control MediaEditor__control--redo"
disabled={!canRedo} disabled={!canRedo}
onClick={() => { onClick={() => {
@ -1238,7 +1238,7 @@ export function MediaEditor({
{isSending ? ( {isSending ? (
<Spinner svgSize="small" /> <Spinner svgSize="small" />
) : ( ) : (
doneButtonLabel || i18n('save') doneButtonLabel || i18n('icu:save')
)} )}
</Button> </Button>
</div> </div>

View file

@ -101,7 +101,7 @@ export function MediaQualitySelector({
<Reference> <Reference>
{({ ref }) => ( {({ ref }) => (
<button <button
aria-label={i18n('MediaQualitySelector--button')} aria-label={i18n('icu:MediaQualitySelector--button')}
className={classNames({ className={classNames({
MediaQualitySelector__button: true, MediaQualitySelector__button: true,
'MediaQualitySelector__button--hq': isHighQuality, 'MediaQualitySelector__button--hq': isHighQuality,
@ -125,11 +125,11 @@ export function MediaQualitySelector({
style={style} style={style}
> >
<div className="MediaQualitySelector__title"> <div className="MediaQualitySelector__title">
{i18n('MediaQualitySelector--title')} {i18n('icu:MediaQualitySelector--title')}
</div> </div>
<button <button
aria-label={i18n( aria-label={i18n(
'MediaQualitySelector--standard-quality-title' 'icu:MediaQualitySelector--standard-quality-title'
)} )}
className={classNames({ className={classNames({
MediaQualitySelector__option: true, MediaQualitySelector__option: true,
@ -151,18 +151,20 @@ export function MediaQualitySelector({
/> />
<div> <div>
<div className="MediaQualitySelector__option--title"> <div className="MediaQualitySelector__option--title">
{i18n('MediaQualitySelector--standard-quality-title')} {i18n(
'icu:MediaQualitySelector--standard-quality-title'
)}
</div> </div>
<div className="MediaQualitySelector__option--description"> <div className="MediaQualitySelector__option--description">
{i18n( {i18n(
'MediaQualitySelector--standard-quality-description' 'icu:MediaQualitySelector--standard-quality-description'
)} )}
</div> </div>
</div> </div>
</button> </button>
<button <button
aria-label={i18n( aria-label={i18n(
'MediaQualitySelector--high-quality-title' 'icu:MediaQualitySelector--high-quality-title'
)} )}
className={classNames({ className={classNames({
MediaQualitySelector__option: true, MediaQualitySelector__option: true,
@ -183,10 +185,12 @@ export function MediaQualitySelector({
/> />
<div> <div>
<div className="MediaQualitySelector__option--title"> <div className="MediaQualitySelector__option--title">
{i18n('MediaQualitySelector--high-quality-title')} {i18n('icu:MediaQualitySelector--high-quality-title')}
</div> </div>
<div className="MediaQualitySelector__option--description"> <div className="MediaQualitySelector__option--description">
{i18n('MediaQualitySelector--high-quality-description')} {i18n(
'icu:MediaQualitySelector--high-quality-description'
)}
</div> </div>
</div> </div>
</button> </button>

View file

@ -67,15 +67,15 @@ export function MiniPlayer({
let mod: 'play' | 'pause' | 'pending'; let mod: 'play' | 'pause' | 'pending';
switch (state) { switch (state) {
case PlayerState.playing: case PlayerState.playing:
label = i18n('MessageAudio--pause'); label = i18n('icu:MessageAudio--pause');
mod = 'pause'; mod = 'pause';
break; break;
case PlayerState.paused: case PlayerState.paused:
label = i18n('MessageAudio--play'); label = i18n('icu:MessageAudio--play');
mod = 'play'; mod = 'play';
break; break;
case PlayerState.loading: case PlayerState.loading:
label = i18n('MessageAudio--pending'); label = i18n('icu:MessageAudio--pending');
mod = 'pending'; mod = 'pending';
break; break;
default: default:
@ -121,7 +121,7 @@ export function MiniPlayer({
type="button" type="button"
className="MiniPlayer__close-button" className="MiniPlayer__close-button"
onClick={onClose} onClick={onClose}
aria-label={i18n('close')} aria-label={i18n('icu:close')}
/> />
</div> </div>
); );

View file

@ -200,7 +200,7 @@ export function ModalPage({
> >
{onBackButtonClick && ( {onBackButtonClick && (
<button <button
aria-label={i18n('back')} aria-label={i18n('icu:back')}
className={getClassName('__back-button')} className={getClassName('__back-button')}
onClick={onBackButtonClick} onClick={onBackButtonClick}
tabIndex={0} tabIndex={0}
@ -222,7 +222,7 @@ export function ModalPage({
)} )}
{hasXButton && ( {hasXButton && (
<button <button
aria-label={i18n('close')} aria-label={i18n('icu:close')}
className={getClassName('__close-button')} className={getClassName('__close-button')}
onClick={onClose} onClick={onClose}
tabIndex={0} tabIndex={0}

View file

@ -57,7 +57,7 @@ export function MyStories({
dialogName="MyStories.delete" dialogName="MyStories.delete"
actions={[ actions={[
{ {
text: i18n('delete'), text: i18n('icu:delete'),
action: () => onDelete(confirmDeleteStory), action: () => onDelete(confirmDeleteStory),
style: 'negative', style: 'negative',
}, },
@ -65,18 +65,18 @@ export function MyStories({
i18n={i18n} i18n={i18n}
onClose={() => setConfirmDeleteStory(undefined)} onClose={() => setConfirmDeleteStory(undefined)}
> >
{i18n('MyStories__delete')} {i18n('icu:MyStories__delete')}
</ConfirmationDialog> </ConfirmationDialog>
)} )}
<div className="Stories__pane__header Stories__pane__header--centered"> <div className="Stories__pane__header Stories__pane__header--centered">
<button <button
aria-label={i18n('back')} aria-label={i18n('icu:back')}
className="Stories__pane__header--back" className="Stories__pane__header--back"
onClick={onBack} onClick={onBack}
type="button" type="button"
/> />
<div className="Stories__pane__header--title"> <div className="Stories__pane__header--title">
{i18n('MyStories__title')} {i18n('icu:MyStories__title')}
</div> </div>
</div> </div>
<div className="Stories__pane__list"> <div className="Stories__pane__list">
@ -109,7 +109,7 @@ export function MyStories({
</div> </div>
{!myStories.length && ( {!myStories.length && (
<div className="Stories__pane__list--empty"> <div className="Stories__pane__list--empty">
{i18n('Stories__list-empty')} {i18n('icu:Stories__list-empty')}
</div> </div>
)} )}
</> </>
@ -151,7 +151,7 @@ function StorySent({
<div className="MyStories__story" key={story.timestamp}> <div className="MyStories__story" key={story.timestamp}>
{renderAlert()} {renderAlert()}
<button <button
aria-label={i18n('MyStories__story')} aria-label={i18n('icu:MyStories__story')}
className="StoryListItem__button MyStories__story-button" className="StoryListItem__button MyStories__story-button"
onClick={() => { onClick={() => {
if ( if (
@ -174,11 +174,11 @@ function StorySent({
<div className="StoryListItem__previews"> <div className="StoryListItem__previews">
<StoryImage <StoryImage
attachment={story.attachment} attachment={story.attachment}
firstName={i18n('you')} firstName={i18n('icu:you')}
i18n={i18n} i18n={i18n}
isMe isMe
isThumbnail isThumbnail
label={i18n('MyStories__story')} label={i18n('icu:MyStories__story')}
moduleClassName="StoryListItem__previews--image" moduleClassName="StoryListItem__previews--image"
queueStoryDownload={queueStoryDownload} queueStoryDownload={queueStoryDownload}
storyId={story.messageId} storyId={story.messageId}
@ -187,14 +187,14 @@ function StorySent({
</div> </div>
<div className="MyStories__story__details"> <div className="MyStories__story__details">
{sendStatus === ResolvedSendStatus.Sending && {sendStatus === ResolvedSendStatus.Sending &&
i18n('Stories__list--sending')} i18n('icu:Stories__list--sending')}
{sendStatus === ResolvedSendStatus.Failed && ( {sendStatus === ResolvedSendStatus.Failed && (
<div className="MyStories__story__details__failed"> <div className="MyStories__story__details__failed">
<div> <div>
{i18n('Stories__list--send_failed')} {i18n('icu:Stories__list--send_failed')}
{!wasManuallyRetried && ( {!wasManuallyRetried && (
<div className="MyStories__story__details__failed__button"> <div className="MyStories__story__details__failed__button">
{i18n('Stories__list--retry-send')} {i18n('icu:Stories__list--retry-send')}
</div> </div>
)} )}
</div> </div>
@ -203,10 +203,10 @@ function StorySent({
{sendStatus === ResolvedSendStatus.PartiallySent && ( {sendStatus === ResolvedSendStatus.PartiallySent && (
<div className="MyStories__story__details__failed"> <div className="MyStories__story__details__failed">
<div> <div>
{i18n('Stories__list--partially-sent')} {i18n('icu:Stories__list--partially-sent')}
{!wasManuallyRetried && ( {!wasManuallyRetried && (
<div className="MyStories__story__details__failed__button"> <div className="MyStories__story__details__failed__button">
{i18n('Stories__list--retry-send')} {i18n('icu:Stories__list--retry-send')}
</div> </div>
)} )}
</div> </div>
@ -231,7 +231,7 @@ function StorySent({
</button> </button>
{story.attachment && (story.attachment.path || story.attachment.data) && ( {story.attachment && (story.attachment.path || story.attachment.data) && (
<button <button
aria-label={i18n('MyStories__download')} aria-label={i18n('icu:MyStories__download')}
className="MyStories__story__download" className="MyStories__story__download"
onClick={() => { onClick={() => {
onSave(story); onSave(story);
@ -244,14 +244,14 @@ function StorySent({
menuOptions={[ menuOptions={[
{ {
icon: 'MyStories__icon--forward', icon: 'MyStories__icon--forward',
label: i18n('forward'), label: i18n('icu:forward'),
onClick: () => { onClick: () => {
onForward(story.messageId); onForward(story.messageId);
}, },
}, },
{ {
icon: 'StoryListItem__icon--info', icon: 'StoryListItem__icon--info',
label: i18n('StoryListItem__info'), label: i18n('icu:StoryListItem__info'),
onClick: () => { onClick: () => {
viewStory({ viewStory({
storyId: story.messageId, storyId: story.messageId,
@ -262,7 +262,7 @@ function StorySent({
}, },
{ {
icon: 'MyStories__icon--delete', icon: 'MyStories__icon--delete',
label: i18n('delete'), label: i18n('icu:delete'),
onClick: () => { onClick: () => {
setConfirmDeleteStory(story); setConfirmDeleteStory(story);
}, },

View file

@ -85,10 +85,10 @@ export function MyStoryButton({
</div> </div>
<div className="StoryListItem__info"> <div className="StoryListItem__info">
<div className="StoryListItem__info--title"> <div className="StoryListItem__info--title">
{i18n('Stories__mine')} {i18n('icu:Stories__mine')}
</div> </div>
<div className="StoryListItem__info--timestamp"> <div className="StoryListItem__info--timestamp">
{i18n('Stories__add')} {i18n('icu:Stories__add')}
</div> </div>
</div> </div>
</StoriesAddStoryButton> </StoriesAddStoryButton>
@ -153,21 +153,21 @@ export function MyStoryButton({
> >
<div className="StoryListItem__info"> <div className="StoryListItem__info">
<div className="StoryListItem__info--title StoryListItem__chevron"> <div className="StoryListItem__info--title StoryListItem__chevron">
{i18n('MyStories__list_item')} {i18n('icu:MyStories__list_item')}
</div> </div>
{reducedSendStatus === ResolvedSendStatus.Sending && ( {reducedSendStatus === ResolvedSendStatus.Sending && (
<span className="StoryListItem__info--sending"> <span className="StoryListItem__info--sending">
{i18n('Stories__list--sending')} {i18n('icu:Stories__list--sending')}
</span> </span>
)} )}
{reducedSendStatus === ResolvedSendStatus.Failed && ( {reducedSendStatus === ResolvedSendStatus.Failed && (
<span className="StoryListItem__info--send_failed"> <span className="StoryListItem__info--send_failed">
{i18n('Stories__list--send_failed')} {i18n('icu:Stories__list--send_failed')}
</span> </span>
)} )}
{reducedSendStatus === ResolvedSendStatus.PartiallySent && ( {reducedSendStatus === ResolvedSendStatus.PartiallySent && (
<span className="StoryListItem__info--send_failed"> <span className="StoryListItem__info--send_failed">
{i18n('Stories__list--partially-sent')} {i18n('icu:Stories__list--partially-sent')}
</span> </span>
)} )}
{reducedSendStatus === ResolvedSendStatus.Sent && ( {reducedSendStatus === ResolvedSendStatus.Sent && (
@ -180,7 +180,7 @@ export function MyStoryButton({
)} )}
</div> </div>
<div <div
aria-label={i18n('StoryListItem__label')} aria-label={i18n('icu:StoryListItem__label')}
className={classNames('StoryListItem__previews', { className={classNames('StoryListItem__previews', {
'StoryListItem__previews--multiple': hasMultiple, 'StoryListItem__previews--multiple': hasMultiple,
})} })}
@ -188,7 +188,7 @@ export function MyStoryButton({
{hasMultiple && <div className="StoryListItem__previews--more" />} {hasMultiple && <div className="StoryListItem__previews--more" />}
<StoryImage <StoryImage
attachment={newestStory.attachment} attachment={newestStory.attachment}
firstName={i18n('you')} firstName={i18n('icu:you')}
i18n={i18n} i18n={i18n}
isMe isMe
isThumbnail isThumbnail

View file

@ -31,7 +31,7 @@ export function NeedsScreenRecordingPermissionsModal({
ref={focusRef} ref={focusRef}
variant={ButtonVariant.Secondary} variant={ButtonVariant.Secondary}
> >
{i18n('calling__presenting--permission-cancel')} {i18n('icu:calling__presenting--permission-cancel')}
</Button> </Button>
<Button <Button
onClick={() => { onClick={() => {
@ -40,7 +40,7 @@ export function NeedsScreenRecordingPermissionsModal({
}} }}
variant={ButtonVariant.Primary} variant={ButtonVariant.Primary}
> >
{i18n('calling__presenting--permission-open')} {i18n('icu:calling__presenting--permission-open')}
</Button> </Button>
</> </>
); );
@ -48,16 +48,16 @@ export function NeedsScreenRecordingPermissionsModal({
<Modal <Modal
modalName="NeedsScreenRecordingPermissionsModal" modalName="NeedsScreenRecordingPermissionsModal"
i18n={i18n} i18n={i18n}
title={i18n('calling__presenting--permission-title')} title={i18n('icu:calling__presenting--permission-title')}
theme={Theme.Dark} theme={Theme.Dark}
onClose={toggleScreenRecordingPermissionsDialog} onClose={toggleScreenRecordingPermissionsDialog}
modalFooter={footer} modalFooter={footer}
> >
<p>{i18n('calling__presenting--macos-permission-description')}</p> <p>{i18n('icu:calling__presenting--macos-permission-description')}</p>
<ol style={{ paddingLeft: 16 }}> <ol style={{ paddingLeft: 16 }}>
<li>{i18n('calling__presenting--permission-instruction-step1')}</li> <li>{i18n('icu:calling__presenting--permission-instruction-step1')}</li>
<li>{i18n('calling__presenting--permission-instruction-step2')}</li> <li>{i18n('icu:calling__presenting--permission-instruction-step2')}</li>
<li>{i18n('calling__presenting--permission-instruction-step3')}</li> <li>{i18n('icu:calling__presenting--permission-instruction-step3')}</li>
</ol> </ol>
</Modal> </Modal>
); );

View file

@ -32,34 +32,38 @@ export function NewlyCreatedGroupInvitedContactsDialog({
if (contacts.length === 1) { if (contacts.length === 1) {
const contact = contacts[0]; const contact = contacts[0];
title = i18n('NewlyCreatedGroupInvitedContactsDialog--title--one'); title = i18n('icu:NewlyCreatedGroupInvitedContactsDialog--title--one');
body = ( body = (
<> <>
<GroupDialog.Paragraph> <GroupDialog.Paragraph>
<Intl <Intl
i18n={i18n} i18n={i18n}
id="NewlyCreatedGroupInvitedContactsDialog--body--user-paragraph--one" id="icu:NewlyCreatedGroupInvitedContactsDialog--body--user-paragraph--one"
components={{ name: <ContactName title={contact.title} /> }} components={{ name: <ContactName title={contact.title} /> }}
/> />
</GroupDialog.Paragraph> </GroupDialog.Paragraph>
<GroupDialog.Paragraph> <GroupDialog.Paragraph>
{i18n('NewlyCreatedGroupInvitedContactsDialog--body--info-paragraph')} {i18n(
'icu:NewlyCreatedGroupInvitedContactsDialog--body--info-paragraph'
)}
</GroupDialog.Paragraph> </GroupDialog.Paragraph>
</> </>
); );
} else { } else {
title = i18n('NewlyCreatedGroupInvitedContactsDialog--title--many', { title = i18n('icu:NewlyCreatedGroupInvitedContactsDialog--title--many', {
count: contacts.length.toString(), count: contacts.length.toString(),
}); });
body = ( body = (
<> <>
<GroupDialog.Paragraph> <GroupDialog.Paragraph>
{i18n( {i18n(
'NewlyCreatedGroupInvitedContactsDialog--body--user-paragraph--many' 'icu:NewlyCreatedGroupInvitedContactsDialog--body--user-paragraph--many'
)} )}
</GroupDialog.Paragraph> </GroupDialog.Paragraph>
<GroupDialog.Paragraph> <GroupDialog.Paragraph>
{i18n('NewlyCreatedGroupInvitedContactsDialog--body--info-paragraph')} {i18n(
'icu:NewlyCreatedGroupInvitedContactsDialog--body--info-paragraph'
)}
</GroupDialog.Paragraph> </GroupDialog.Paragraph>
<GroupDialog.Contacts <GroupDialog.Contacts
contacts={contacts} contacts={contacts}
@ -75,9 +79,9 @@ export function NewlyCreatedGroupInvitedContactsDialog({
<GroupDialog <GroupDialog
i18n={i18n} i18n={i18n}
onClickPrimaryButton={onClose} onClickPrimaryButton={onClose}
primaryButtonText={i18n('Confirmation--confirm')} primaryButtonText={i18n('icu:Confirmation--confirm')}
secondaryButtonText={i18n( secondaryButtonText={i18n(
'NewlyCreatedGroupInvitedContactsDialog--body--learn-more' 'icu:NewlyCreatedGroupInvitedContactsDialog--body--learn-more'
)} )}
onClickSecondaryButton={() => { onClickSecondaryButton={() => {
openLinkInWebBrowser( openLinkInWebBrowser(

View file

@ -36,14 +36,14 @@ export function PermissionsPopup({
ref={focusRef} ref={focusRef}
variant={ButtonVariant.Secondary} variant={ButtonVariant.Secondary}
> >
{i18n('confirmation-dialog--Cancel')} {i18n('icu:confirmation-dialog--Cancel')}
</Button> </Button>
<Button <Button
onClick={onAccept} onClick={onAccept}
ref={focusRef} ref={focusRef}
variant={ButtonVariant.Primary} variant={ButtonVariant.Primary}
> >
{i18n('allowAccess')} {i18n('icu:allowAccess')}
</Button> </Button>
</div> </div>
</div> </div>

View file

@ -65,10 +65,10 @@ export function PlaybackRateButton({
); );
const playbackRateLabels: { [key: number]: string } = { const playbackRateLabels: { [key: number]: string } = {
1: i18n('MessageAudio--playbackRate1'), 1: i18n('icu:MessageAudio--playbackRate1'),
1.5: i18n('MessageAudio--playbackRate1p5'), 1.5: i18n('icu:MessageAudio--playbackRate1p5'),
2: i18n('MessageAudio--playbackRate2'), 2: i18n('icu:MessageAudio--playbackRate2'),
0.5: i18n('MessageAudio--playbackRatep5'), 0.5: i18n('icu:MessageAudio--playbackRatep5'),
}; };
const label = playbackRate const label = playbackRate

View file

@ -360,17 +360,20 @@ export function Preferences({
<> <>
<div className="Preferences__title"> <div className="Preferences__title">
<div className="Preferences__title--header"> <div className="Preferences__title--header">
{i18n('Preferences__button--general')} {i18n('icu:Preferences__button--general')}
</div> </div>
</div> </div>
<SettingsRow> <SettingsRow>
<Control left={i18n('Preferences--device-name')} right={deviceName} /> <Control
left={i18n('icu:Preferences--device-name')}
right={deviceName}
/>
</SettingsRow> </SettingsRow>
<SettingsRow title={i18n('Preferences--system')}> <SettingsRow title={i18n('icu:Preferences--system')}>
{isAutoLaunchSupported && ( {isAutoLaunchSupported && (
<Checkbox <Checkbox
checked={hasAutoLaunch} checked={hasAutoLaunch}
label={i18n('autoLaunchDescription')} label={i18n('icu:autoLaunchDescription')}
moduleClassName="Preferences__checkbox" moduleClassName="Preferences__checkbox"
name="autoLaunch" name="autoLaunch"
onChange={onAutoLaunchChange} onChange={onAutoLaunchChange}
@ -379,7 +382,7 @@ export function Preferences({
{isHideMenuBarSupported && ( {isHideMenuBarSupported && (
<Checkbox <Checkbox
checked={hasHideMenuBar} checked={hasHideMenuBar}
label={i18n('hideMenuBar')} label={i18n('icu:hideMenuBar')}
moduleClassName="Preferences__checkbox" moduleClassName="Preferences__checkbox"
name="hideMenuBar" name="hideMenuBar"
onChange={onHideMenuBarChange} onChange={onHideMenuBarChange}
@ -389,7 +392,7 @@ export function Preferences({
<> <>
<Checkbox <Checkbox
checked={hasMinimizeToSystemTray} checked={hasMinimizeToSystemTray}
label={i18n('SystemTraySetting__minimize-to-system-tray')} label={i18n('icu:SystemTraySetting__minimize-to-system-tray')}
moduleClassName="Preferences__checkbox" moduleClassName="Preferences__checkbox"
name="system-tray-setting-minimize-to-system-tray" name="system-tray-setting-minimize-to-system-tray"
onChange={onMinimizeToSystemTrayChange} onChange={onMinimizeToSystemTrayChange}
@ -399,7 +402,7 @@ export function Preferences({
checked={hasMinimizeToAndStartInSystemTray} checked={hasMinimizeToAndStartInSystemTray}
disabled={!hasMinimizeToSystemTray} disabled={!hasMinimizeToSystemTray}
label={i18n( label={i18n(
'SystemTraySetting__minimize-to-and-start-in-system-tray' 'icu:SystemTraySetting__minimize-to-and-start-in-system-tray'
)} )}
moduleClassName="Preferences__checkbox" moduleClassName="Preferences__checkbox"
name="system-tray-setting-minimize-to-and-start-in-system-tray" name="system-tray-setting-minimize-to-and-start-in-system-tray"
@ -409,27 +412,27 @@ export function Preferences({
</> </>
)} )}
</SettingsRow> </SettingsRow>
<SettingsRow title={i18n('permissions')}> <SettingsRow title={i18n('icu:permissions')}>
<Checkbox <Checkbox
checked={hasMediaPermissions} checked={hasMediaPermissions}
label={i18n('mediaPermissionsDescription')} label={i18n('icu:mediaPermissionsDescription')}
moduleClassName="Preferences__checkbox" moduleClassName="Preferences__checkbox"
name="mediaPermissions" name="mediaPermissions"
onChange={onMediaPermissionsChange} onChange={onMediaPermissionsChange}
/> />
<Checkbox <Checkbox
checked={hasMediaCameraPermissions} checked={hasMediaCameraPermissions}
label={i18n('mediaCameraPermissionsDescription')} label={i18n('icu:mediaCameraPermissionsDescription')}
moduleClassName="Preferences__checkbox" moduleClassName="Preferences__checkbox"
name="mediaCameraPermissions" name="mediaCameraPermissions"
onChange={onMediaCameraPermissionsChange} onChange={onMediaCameraPermissionsChange}
/> />
</SettingsRow> </SettingsRow>
{isAutoDownloadUpdatesSupported && ( {isAutoDownloadUpdatesSupported && (
<SettingsRow title={i18n('Preferences--updates')}> <SettingsRow title={i18n('icu:Preferences--updates')}>
<Checkbox <Checkbox
checked={hasAutoDownloadUpdate} checked={hasAutoDownloadUpdate}
label={i18n('Preferences__download-update')} label={i18n('icu:Preferences__download-update')}
moduleClassName="Preferences__checkbox" moduleClassName="Preferences__checkbox"
name="autoDownloadUpdate" name="autoDownloadUpdate"
onChange={onAutoDownloadUpdateChange} onChange={onAutoDownloadUpdateChange}
@ -455,14 +458,14 @@ export function Preferences({
<> <>
<div className="Preferences__title"> <div className="Preferences__title">
<div className="Preferences__title--header"> <div className="Preferences__title--header">
{i18n('Preferences__button--appearance')} {i18n('icu:Preferences__button--appearance')}
</div> </div>
</div> </div>
<SettingsRow> <SettingsRow>
<Control <Control
left={ left={
<label htmlFor={themeSelectId}> <label htmlFor={themeSelectId}>
{i18n('Preferences--theme')} {i18n('icu:Preferences--theme')}
</label> </label>
} }
right={ right={
@ -471,15 +474,15 @@ export function Preferences({
onChange={onThemeChange} onChange={onThemeChange}
options={[ options={[
{ {
text: i18n('themeSystem'), text: i18n('icu:themeSystem'),
value: 'system', value: 'system',
}, },
{ {
text: i18n('themeLight'), text: i18n('icu:themeLight'),
value: 'light', value: 'light',
}, },
{ {
text: i18n('themeDark'), text: i18n('icu:themeDark'),
value: 'dark', value: 'dark',
}, },
]} ]}
@ -488,7 +491,7 @@ export function Preferences({
} }
/> />
<Control <Control
left={i18n('showChatColorEditor')} left={i18n('icu:showChatColorEditor')}
onClick={() => { onClick={() => {
setPage(Page.ChatColor); setPage(Page.ChatColor);
}} }}
@ -505,7 +508,9 @@ export function Preferences({
/> />
<Control <Control
left={ left={
<label htmlFor={zoomSelectId}>{i18n('Preferences--zoom')}</label> <label htmlFor={zoomSelectId}>
{i18n('icu:Preferences--zoom')}
</label>
} }
right={ right={
<Select <Select
@ -523,8 +528,8 @@ export function Preferences({
let spellCheckDirtyText: string | undefined; let spellCheckDirtyText: string | undefined;
if (initialSpellCheckSetting !== hasSpellCheck) { if (initialSpellCheckSetting !== hasSpellCheck) {
spellCheckDirtyText = hasSpellCheck spellCheckDirtyText = hasSpellCheck
? i18n('spellCheckWillBeEnabled') ? i18n('icu:spellCheckWillBeEnabled')
: i18n('spellCheckWillBeDisabled'); : i18n('icu:spellCheckWillBeDisabled');
} }
const lastSyncDate = new Date(lastSyncTime || 0); const lastSyncDate = new Date(lastSyncTime || 0);
@ -533,39 +538,39 @@ export function Preferences({
<> <>
<div className="Preferences__title"> <div className="Preferences__title">
<div className="Preferences__title--header"> <div className="Preferences__title--header">
{i18n('Preferences__button--chats')} {i18n('icu:Preferences__button--chats')}
</div> </div>
</div> </div>
<SettingsRow title={i18n('Preferences__button--chats')}> <SettingsRow title={i18n('icu:Preferences__button--chats')}>
<Checkbox <Checkbox
checked={hasSpellCheck} checked={hasSpellCheck}
description={spellCheckDirtyText} description={spellCheckDirtyText}
label={i18n('spellCheckDescription')} label={i18n('icu:spellCheckDescription')}
moduleClassName="Preferences__checkbox" moduleClassName="Preferences__checkbox"
name="spellcheck" name="spellcheck"
onChange={onSpellCheckChange} onChange={onSpellCheckChange}
/> />
<Checkbox <Checkbox
checked={hasLinkPreviews} checked={hasLinkPreviews}
description={i18n('Preferences__link-previews--description')} description={i18n('icu:Preferences__link-previews--description')}
disabled disabled
label={i18n('Preferences__link-previews--title')} label={i18n('icu:Preferences__link-previews--title')}
moduleClassName="Preferences__checkbox" moduleClassName="Preferences__checkbox"
name="linkPreviews" name="linkPreviews"
onChange={noop} onChange={noop}
/> />
<Control <Control
left={i18n('Preferences__sent-media-quality')} left={i18n('icu:Preferences__sent-media-quality')}
right={ right={
<Select <Select
onChange={onSentMediaQualityChange} onChange={onSentMediaQualityChange}
options={[ options={[
{ {
text: i18n('sentMediaQualityStandard'), text: i18n('icu:sentMediaQualityStandard'),
value: 'standard', value: 'standard',
}, },
{ {
text: i18n('sentMediaQualityHigh'), text: i18n('icu:sentMediaQualityHigh'),
value: 'high', value: 'high',
}, },
]} ]}
@ -579,17 +584,17 @@ export function Preferences({
<Control <Control
left={ left={
<> <>
<div>{i18n('sync')}</div> <div>{i18n('icu:sync')}</div>
<div className="Preferences__description"> <div className="Preferences__description">
{i18n('syncExplanation')}{' '} {i18n('icu:syncExplanation')}{' '}
{i18n('Preferences--lastSynced', { {i18n('icu:Preferences--lastSynced', {
date: lastSyncDate.toLocaleDateString(), date: lastSyncDate.toLocaleDateString(),
time: lastSyncDate.toLocaleTimeString(), time: lastSyncDate.toLocaleTimeString(),
})} })}
</div> </div>
{showSyncFailed && ( {showSyncFailed && (
<div className="Preferences__description Preferences__description--error"> <div className="Preferences__description Preferences__description--error">
{i18n('syncFailed')} {i18n('icu:syncFailed')}
</div> </div>
)} )}
</> </>
@ -612,7 +617,11 @@ export function Preferences({
}} }}
variant={ButtonVariant.SecondaryAffirmative} variant={ButtonVariant.SecondaryAffirmative}
> >
{nowSyncing ? <Spinner svgSize="small" /> : i18n('syncNow')} {nowSyncing ? (
<Spinner svgSize="small" />
) : (
i18n('icu:syncNow')
)}
</Button> </Button>
</div> </div>
} }
@ -626,34 +635,34 @@ export function Preferences({
<> <>
<div className="Preferences__title"> <div className="Preferences__title">
<div className="Preferences__title--header"> <div className="Preferences__title--header">
{i18n('Preferences__button--calls')} {i18n('icu:Preferences__button--calls')}
</div> </div>
</div> </div>
<SettingsRow title={i18n('calling')}> <SettingsRow title={i18n('icu:calling')}>
<Checkbox <Checkbox
checked={hasIncomingCallNotifications} checked={hasIncomingCallNotifications}
label={i18n('incomingCallNotificationDescription')} label={i18n('icu:incomingCallNotificationDescription')}
moduleClassName="Preferences__checkbox" moduleClassName="Preferences__checkbox"
name="incomingCallNotification" name="incomingCallNotification"
onChange={onIncomingCallNotificationsChange} onChange={onIncomingCallNotificationsChange}
/> />
<Checkbox <Checkbox
checked={hasCallRingtoneNotification} checked={hasCallRingtoneNotification}
label={i18n('callRingtoneNotificationDescription')} label={i18n('icu:callRingtoneNotificationDescription')}
moduleClassName="Preferences__checkbox" moduleClassName="Preferences__checkbox"
name="callRingtoneNotification" name="callRingtoneNotification"
onChange={onCallRingtoneNotificationChange} onChange={onCallRingtoneNotificationChange}
/> />
</SettingsRow> </SettingsRow>
<SettingsRow title={i18n('Preferences__devices')}> <SettingsRow title={i18n('icu:Preferences__devices')}>
<Control <Control
left={ left={
<> <>
<label className="Preferences__select-title" htmlFor="video"> <label className="Preferences__select-title" htmlFor="video">
{i18n('callingDeviceSelection__label--video')} {i18n('icu:callingDeviceSelection__label--video')}
</label> </label>
<Select <Select
ariaLabel={i18n('callingDeviceSelection__label--video')} ariaLabel={i18n('icu:callingDeviceSelection__label--video')}
disabled={!availableCameras.length} disabled={!availableCameras.length}
moduleClassName="Preferences__select" moduleClassName="Preferences__select"
name="video" name="video"
@ -667,7 +676,7 @@ export function Preferences({
: [ : [
{ {
text: i18n( text: i18n(
'callingDeviceSelection__select--no-device' 'icu:callingDeviceSelection__select--no-device'
), ),
value: 'undefined', value: 'undefined',
}, },
@ -686,10 +695,12 @@ export function Preferences({
className="Preferences__select-title" className="Preferences__select-title"
htmlFor="audio-input" htmlFor="audio-input"
> >
{i18n('callingDeviceSelection__label--audio-input')} {i18n('icu:callingDeviceSelection__label--audio-input')}
</label> </label>
<Select <Select
ariaLabel={i18n('callingDeviceSelection__label--audio-input')} ariaLabel={i18n(
'icu:callingDeviceSelection__label--audio-input'
)}
disabled={!availableMicrophones.length} disabled={!availableMicrophones.length}
moduleClassName="Preferences__select" moduleClassName="Preferences__select"
name="audio-input" name="audio-input"
@ -703,7 +714,7 @@ export function Preferences({
: [ : [
{ {
text: i18n( text: i18n(
'callingDeviceSelection__select--no-device' 'icu:callingDeviceSelection__select--no-device'
), ),
value: 'undefined', value: 'undefined',
}, },
@ -722,11 +733,11 @@ export function Preferences({
className="Preferences__select-title" className="Preferences__select-title"
htmlFor="audio-output" htmlFor="audio-output"
> >
{i18n('callingDeviceSelection__label--audio-output')} {i18n('icu:callingDeviceSelection__label--audio-output')}
</label> </label>
<Select <Select
ariaLabel={i18n( ariaLabel={i18n(
'callingDeviceSelection__label--audio-output' 'icu:callingDeviceSelection__label--audio-output'
)} )}
disabled={!availableSpeakers.length} disabled={!availableSpeakers.length}
moduleClassName="Preferences__select" moduleClassName="Preferences__select"
@ -741,7 +752,7 @@ export function Preferences({
: [ : [
{ {
text: i18n( text: i18n(
'callingDeviceSelection__select--no-device' 'icu:callingDeviceSelection__select--no-device'
), ),
value: 'undefined', value: 'undefined',
}, },
@ -754,11 +765,11 @@ export function Preferences({
right={<div />} right={<div />}
/> />
</SettingsRow> </SettingsRow>
<SettingsRow title={i18n('Preferences--advanced')}> <SettingsRow title={i18n('icu:Preferences--advanced')}>
<Checkbox <Checkbox
checked={hasRelayCalls} checked={hasRelayCalls}
description={i18n('alwaysRelayCallsDetail')} description={i18n('icu:alwaysRelayCallsDetail')}
label={i18n('alwaysRelayCallsDescription')} label={i18n('icu:alwaysRelayCallsDescription')}
moduleClassName="Preferences__checkbox" moduleClassName="Preferences__checkbox"
name="relayCalls" name="relayCalls"
onChange={onRelayCallsChange} onChange={onRelayCallsChange}
@ -771,20 +782,20 @@ export function Preferences({
<> <>
<div className="Preferences__title"> <div className="Preferences__title">
<div className="Preferences__title--header"> <div className="Preferences__title--header">
{i18n('Preferences__button--notifications')} {i18n('icu:Preferences__button--notifications')}
</div> </div>
</div> </div>
<SettingsRow> <SettingsRow>
<Checkbox <Checkbox
checked={hasNotifications} checked={hasNotifications}
label={i18n('Preferences__enable-notifications')} label={i18n('icu:Preferences__enable-notifications')}
moduleClassName="Preferences__checkbox" moduleClassName="Preferences__checkbox"
name="notifications" name="notifications"
onChange={onNotificationsChange} onChange={onNotificationsChange}
/> />
<Checkbox <Checkbox
checked={hasCallNotifications} checked={hasCallNotifications}
label={i18n('callSystemNotificationDescription')} label={i18n('icu:callSystemNotificationDescription')}
moduleClassName="Preferences__checkbox" moduleClassName="Preferences__checkbox"
name="callSystemNotification" name="callSystemNotification"
onChange={onCallNotificationsChange} onChange={onCallNotificationsChange}
@ -792,7 +803,7 @@ export function Preferences({
{isNotificationAttentionSupported && ( {isNotificationAttentionSupported && (
<Checkbox <Checkbox
checked={hasNotificationAttention} checked={hasNotificationAttention}
label={i18n('notificationDrawAttention')} label={i18n('icu:notificationDrawAttention')}
moduleClassName="Preferences__checkbox" moduleClassName="Preferences__checkbox"
name="notificationDrawAttention" name="notificationDrawAttention"
onChange={onNotificationAttentionChange} onChange={onNotificationAttentionChange}
@ -801,7 +812,7 @@ export function Preferences({
{isAudioNotificationsSupported && ( {isAudioNotificationsSupported && (
<Checkbox <Checkbox
checked={hasAudioNotifications} checked={hasAudioNotifications}
label={i18n('audioNotificationDescription')} label={i18n('icu:audioNotificationDescription')}
moduleClassName="Preferences__checkbox" moduleClassName="Preferences__checkbox"
name="audioNotification" name="audioNotification"
onChange={onAudioNotificationsChange} onChange={onAudioNotificationsChange}
@ -809,7 +820,7 @@ export function Preferences({
)} )}
<Checkbox <Checkbox
checked={hasCountMutedConversations} checked={hasCountMutedConversations}
label={i18n('countMutedConversationsDescription')} label={i18n('icu:countMutedConversationsDescription')}
moduleClassName="Preferences__checkbox" moduleClassName="Preferences__checkbox"
name="countMutedConversations" name="countMutedConversations"
onChange={onCountMutedConversationsChange} onChange={onCountMutedConversationsChange}
@ -817,23 +828,23 @@ export function Preferences({
</SettingsRow> </SettingsRow>
<SettingsRow> <SettingsRow>
<Control <Control
left={i18n('Preferences--notification-content')} left={i18n('icu:Preferences--notification-content')}
right={ right={
<Select <Select
ariaLabel={i18n('Preferences--notification-content')} ariaLabel={i18n('icu:Preferences--notification-content')}
disabled={!hasNotifications} disabled={!hasNotifications}
onChange={onNotificationContentChange} onChange={onNotificationContentChange}
options={[ options={[
{ {
text: i18n('nameAndMessage'), text: i18n('icu:nameAndMessage'),
value: 'message', value: 'message',
}, },
{ {
text: i18n('nameOnly'), text: i18n('icu:nameOnly'),
value: 'name', value: 'name',
}, },
{ {
text: i18n('noNameOrMessage'), text: i18n('icu:noNameOrMessage'),
value: 'count', value: 'count',
}, },
]} ]}
@ -852,7 +863,7 @@ export function Preferences({
<> <>
<div className="Preferences__title"> <div className="Preferences__title">
<div className="Preferences__title--header"> <div className="Preferences__title--header">
{i18n('Preferences__button--privacy')} {i18n('icu:Preferences__button--privacy')}
</div> </div>
</div> </div>
{isPhoneNumberSharingSupported ? ( {isPhoneNumberSharingSupported ? (
@ -871,23 +882,23 @@ export function Preferences({
) : null} ) : null}
<SettingsRow> <SettingsRow>
<Control <Control
left={i18n('Preferences--blocked')} left={i18n('icu:Preferences--blocked')}
right={ right={
blockedCount === 1 blockedCount === 1
? i18n('Preferences--blocked-count-singular', { ? i18n('icu:Preferences--blocked-count-singular', {
num: String(blockedCount), num: String(blockedCount),
}) })
: i18n('Preferences--blocked-count-plural', { : i18n('icu:Preferences--blocked-count-plural', {
num: String(blockedCount || 0), num: String(blockedCount || 0),
}) })
} }
/> />
</SettingsRow> </SettingsRow>
<SettingsRow title={i18n('Preferences--messaging')}> <SettingsRow title={i18n('icu:Preferences--messaging')}>
<Checkbox <Checkbox
checked={hasReadReceipts} checked={hasReadReceipts}
disabled disabled
label={i18n('Preferences--read-receipts')} label={i18n('icu:Preferences--read-receipts')}
moduleClassName="Preferences__checkbox" moduleClassName="Preferences__checkbox"
name="readReceipts" name="readReceipts"
onChange={noop} onChange={noop}
@ -895,14 +906,14 @@ export function Preferences({
<Checkbox <Checkbox
checked={hasTypingIndicators} checked={hasTypingIndicators}
disabled disabled
label={i18n('Preferences--typing-indicators')} label={i18n('icu:Preferences--typing-indicators')}
moduleClassName="Preferences__checkbox" moduleClassName="Preferences__checkbox"
name="typingIndicators" name="typingIndicators"
onChange={noop} onChange={noop}
/> />
<div className="Preferences__padding"> <div className="Preferences__padding">
<div className="Preferences__description"> <div className="Preferences__description">
{i18n('Preferences__privacy--description')} {i18n('icu:Preferences__privacy--description')}
</div> </div>
</div> </div>
</SettingsRow> </SettingsRow>
@ -919,16 +930,18 @@ export function Preferences({
left={ left={
<> <>
<div> <div>
{i18n('settings__DisappearingMessages__timer__label')} {i18n('icu:settings__DisappearingMessages__timer__label')}
</div> </div>
<div className="Preferences__description"> <div className="Preferences__description">
{i18n('settings__DisappearingMessages__footer')} {i18n('icu:settings__DisappearingMessages__footer')}
</div> </div>
</> </>
} }
right={ right={
<Select <Select
ariaLabel={i18n('settings__DisappearingMessages__timer__label')} ariaLabel={i18n(
'icu:settings__DisappearingMessages__timer__label'
)}
onChange={value => { onChange={value => {
if ( if (
value === String(universalExpireTimer) || value === String(universalExpireTimer) ||
@ -955,7 +968,7 @@ export function Preferences({
: DurationInSeconds.fromSeconds(-1), : DurationInSeconds.fromSeconds(-1),
text: isCustomDisappearingMessageValue text: isCustomDisappearingMessageValue
? formatExpirationTimer(i18n, universalExpireTimer) ? formatExpirationTimer(i18n, universalExpireTimer)
: i18n('selectedCustomDisappearingTimeOption'), : i18n('icu:selectedCustomDisappearingTimeOption'),
}, },
])} ])}
value={universalExpireTimer} value={universalExpireTimer}
@ -964,13 +977,13 @@ export function Preferences({
/> />
</SettingsRow> </SettingsRow>
{shouldShowStoriesSettings && ( {shouldShowStoriesSettings && (
<SettingsRow title={i18n('Stories__title')}> <SettingsRow title={i18n('icu:Stories__title')}>
<Control <Control
left={ left={
<label htmlFor={storiesId}> <label htmlFor={storiesId}>
<div>{i18n('Stories__settings-toggle--title')}</div> <div>{i18n('icu:Stories__settings-toggle--title')}</div>
<div className="Preferences__description"> <div className="Preferences__description">
{i18n('Stories__settings-toggle--description')} {i18n('icu:Stories__settings-toggle--description')}
</div> </div>
</label> </label>
} }
@ -980,7 +993,7 @@ export function Preferences({
onClick={() => onHasStoriesDisabledChanged(false)} onClick={() => onHasStoriesDisabledChanged(false)}
variant={ButtonVariant.Secondary} variant={ButtonVariant.Secondary}
> >
{i18n('Preferences__turn-stories-on')} {i18n('icu:Preferences__turn-stories-on')}
</Button> </Button>
) : ( ) : (
<Button <Button
@ -988,7 +1001,7 @@ export function Preferences({
onClick={() => setConfirmStoriesOff(true)} onClick={() => setConfirmStoriesOff(true)}
variant={ButtonVariant.SecondaryDestructive} variant={ButtonVariant.SecondaryDestructive}
> >
{i18n('Preferences__turn-stories-off')} {i18n('icu:Preferences__turn-stories-off')}
</Button> </Button>
) )
} }
@ -999,9 +1012,9 @@ export function Preferences({
<Control <Control
left={ left={
<> <>
<div>{i18n('clearDataHeader')}</div> <div>{i18n('icu:clearDataHeader')}</div>
<div className="Preferences__description"> <div className="Preferences__description">
{i18n('clearDataExplanation')} {i18n('icu:clearDataExplanation')}
</div> </div>
</> </>
} }
@ -1011,7 +1024,7 @@ export function Preferences({
onClick={() => setConfirmDelete(true)} onClick={() => setConfirmDelete(true)}
variant={ButtonVariant.SecondaryDestructive} variant={ButtonVariant.SecondaryDestructive}
> >
{i18n('clearDataButton')} {i18n('icu:clearDataButton')}
</Button> </Button>
</div> </div>
} }
@ -1024,16 +1037,16 @@ export function Preferences({
{ {
action: doDeleteAllData, action: doDeleteAllData,
style: 'negative', style: 'negative',
text: i18n('clearDataButton'), text: i18n('icu:clearDataButton'),
}, },
]} ]}
i18n={i18n} i18n={i18n}
onClose={() => { onClose={() => {
setConfirmDelete(false); setConfirmDelete(false);
}} }}
title={i18n('deleteAllDataHeader')} title={i18n('icu:deleteAllDataHeader')}
> >
{i18n('deleteAllDataBody')} {i18n('icu:deleteAllDataBody')}
</ConfirmationDialog> </ConfirmationDialog>
) : null} ) : null}
{confirmStoriesOff ? ( {confirmStoriesOff ? (
@ -1043,7 +1056,7 @@ export function Preferences({
{ {
action: () => onHasStoriesDisabledChanged(true), action: () => onHasStoriesDisabledChanged(true),
style: 'negative', style: 'negative',
text: i18n('Preferences__turn-stories-off--action'), text: i18n('icu:Preferences__turn-stories-off--action'),
}, },
]} ]}
i18n={i18n} i18n={i18n}
@ -1051,7 +1064,7 @@ export function Preferences({
setConfirmStoriesOff(false); setConfirmStoriesOff(false);
}} }}
> >
{i18n('Preferences__turn-stories-off--body')} {i18n('icu:Preferences__turn-stories-off--body')}
</ConfirmationDialog> </ConfirmationDialog>
) : null} ) : null}
</> </>
@ -1061,13 +1074,13 @@ export function Preferences({
<> <>
<div className="Preferences__title"> <div className="Preferences__title">
<button <button
aria-label={i18n('goBack')} aria-label={i18n('icu:goBack')}
className="Preferences__back-icon" className="Preferences__back-icon"
onClick={() => setPage(Page.Appearance)} onClick={() => setPage(Page.Appearance)}
type="button" type="button"
/> />
<div className="Preferences__title--header"> <div className="Preferences__title--header">
{i18n('ChatColorPicker__menu-title')} {i18n('icu:ChatColorPicker__menu-title')}
</div> </div>
</div> </div>
<ChatColorPicker <ChatColorPicker
@ -1094,7 +1107,7 @@ export function Preferences({
<> <>
<div className="Preferences__title"> <div className="Preferences__title">
<button <button
aria-label={i18n('goBack')} aria-label={i18n('icu:goBack')}
className="Preferences__back-icon" className="Preferences__back-icon"
onClick={() => setPage(Page.Privacy)} onClick={() => setPage(Page.Privacy)}
type="button" type="button"
@ -1191,7 +1204,7 @@ export function Preferences({
})} })}
onClick={() => setPage(Page.General)} onClick={() => setPage(Page.General)}
> >
{i18n('Preferences__button--general')} {i18n('icu:Preferences__button--general')}
</button> </button>
<button <button
type="button" type="button"
@ -1203,7 +1216,7 @@ export function Preferences({
})} })}
onClick={() => setPage(Page.Appearance)} onClick={() => setPage(Page.Appearance)}
> >
{i18n('Preferences__button--appearance')} {i18n('icu:Preferences__button--appearance')}
</button> </button>
<button <button
type="button" type="button"
@ -1214,7 +1227,7 @@ export function Preferences({
})} })}
onClick={() => setPage(Page.Chats)} onClick={() => setPage(Page.Chats)}
> >
{i18n('Preferences__button--chats')} {i18n('icu:Preferences__button--chats')}
</button> </button>
<button <button
type="button" type="button"
@ -1225,7 +1238,7 @@ export function Preferences({
})} })}
onClick={() => setPage(Page.Calls)} onClick={() => setPage(Page.Calls)}
> >
{i18n('Preferences__button--calls')} {i18n('icu:Preferences__button--calls')}
</button> </button>
<button <button
type="button" type="button"
@ -1236,7 +1249,7 @@ export function Preferences({
})} })}
onClick={() => setPage(Page.Notifications)} onClick={() => setPage(Page.Notifications)}
> >
{i18n('Preferences__button--notifications')} {i18n('icu:Preferences__button--notifications')}
</button> </button>
<button <button
type="button" type="button"
@ -1248,7 +1261,7 @@ export function Preferences({
})} })}
onClick={() => setPage(Page.Privacy)} onClick={() => setPage(Page.Privacy)}
> >
{i18n('Preferences__button--privacy')} {i18n('icu:Preferences__button--privacy')}
</button> </button>
</div> </div>
<div className="Preferences__settings-pane">{settings}</div> <div className="Preferences__settings-pane">{settings}</div>
@ -1352,7 +1365,7 @@ function localizeDefault(i18n: LocalizerType, deviceLabel: string): string {
return deviceLabel.toLowerCase().startsWith('default') return deviceLabel.toLowerCase().startsWith('default')
? deviceLabel.replace( ? deviceLabel.replace(
/default/i, /default/i,
i18n('callingDeviceSelection__select--default') i18n('icu:callingDeviceSelection__select--default')
) )
: deviceLabel; : deviceLabel;
} }

View file

@ -99,23 +99,23 @@ type DefaultBio = {
function getDefaultBios(i18n: LocalizerType): Array<DefaultBio> { function getDefaultBios(i18n: LocalizerType): Array<DefaultBio> {
return [ return [
{ {
i18nLabel: i18n('Bio--speak-freely'), i18nLabel: i18n('icu:Bio--speak-freely'),
shortName: 'wave', shortName: 'wave',
}, },
{ {
i18nLabel: i18n('Bio--encrypted'), i18nLabel: i18n('icu:Bio--encrypted'),
shortName: 'zipper_mouth_face', shortName: 'zipper_mouth_face',
}, },
{ {
i18nLabel: i18n('Bio--free-to-chat'), i18nLabel: i18n('icu:Bio--free-to-chat'),
shortName: '+1', shortName: '+1',
}, },
{ {
i18nLabel: i18n('Bio--coffee-lover'), i18nLabel: i18n('icu:Bio--coffee-lover'),
shortName: 'coffee', shortName: 'coffee',
}, },
{ {
i18nLabel: i18n('Bio--taking-break'), i18nLabel: i18n('icu:Bio--taking-break'),
shortName: 'mobile_phone_off', shortName: 'mobile_phone_off',
}, },
]; ];
@ -301,7 +301,7 @@ export function ProfileEditor({
firstName: String(newFirstName), firstName: String(newFirstName),
})); }));
}} }}
placeholder={i18n('ProfileEditor--first-name')} placeholder={i18n('icu:ProfileEditor--first-name')}
ref={focusInputRef} ref={focusInputRef}
value={stagedProfile.firstName} value={stagedProfile.firstName}
/> />
@ -316,7 +316,7 @@ export function ProfileEditor({
familyName: newFamilyName, familyName: newFamilyName,
})); }));
}} }}
placeholder={i18n('ProfileEditor--last-name')} placeholder={i18n('icu:ProfileEditor--last-name')}
value={stagedProfile.familyName} value={stagedProfile.familyName}
/> />
<Modal.ButtonFooter> <Modal.ButtonFooter>
@ -342,7 +342,7 @@ export function ProfileEditor({
}} }}
variant={ButtonVariant.Secondary} variant={ButtonVariant.Secondary}
> >
{i18n('cancel')} {i18n('icu:cancel')}
</Button> </Button>
<Button <Button
disabled={shouldDisableSave} disabled={shouldDisableSave}
@ -362,7 +362,7 @@ export function ProfileEditor({
handleBack(); handleBack();
}} }}
> >
{i18n('save')} {i18n('icu:save')}
</Button> </Button>
</Modal.ButtonFooter> </Modal.ButtonFooter>
</> </>
@ -414,7 +414,7 @@ export function ProfileEditor({
} }
}} }}
ref={focusInputRef} ref={focusInputRef}
placeholder={i18n('ProfileEditor--about-placeholder')} placeholder={i18n('icu:ProfileEditor--about-placeholder')}
value={stagedProfile.aboutText} value={stagedProfile.aboutText}
whenToShowRemainingCount={40} whenToShowRemainingCount={40}
/> />
@ -463,7 +463,7 @@ export function ProfileEditor({
}} }}
variant={ButtonVariant.Secondary} variant={ButtonVariant.Secondary}
> >
{i18n('cancel')} {i18n('icu:cancel')}
</Button> </Button>
<Button <Button
disabled={shouldDisableSave} disabled={shouldDisableSave}
@ -480,7 +480,7 @@ export function ProfileEditor({
handleBack(); handleBack();
}} }}
> >
{i18n('save')} {i18n('icu:save')}
</Button> </Button>
</Modal.ButtonFooter> </Modal.ButtonFooter>
</> </>
@ -507,7 +507,7 @@ export function ProfileEditor({
if (usernameEditState === UsernameEditState.Deleting) { if (usernameEditState === UsernameEditState.Deleting) {
actions = ( actions = (
<ConversationDetailsIcon <ConversationDetailsIcon
ariaLabel={i18n('ProfileEditor--username--deleting-username')} ariaLabel={i18n('icu:ProfileEditor--username--deleting-username')}
icon={IconType.spinner} icon={IconType.spinner}
disabled disabled
fakeButton fakeButton
@ -518,7 +518,7 @@ export function ProfileEditor({
{ {
group: 'copy', group: 'copy',
icon: 'ProfileEditor__username-menu__copy-icon', icon: 'ProfileEditor__username-menu__copy-icon',
label: i18n('ProfileEditor--username--copy'), label: i18n('icu:ProfileEditor--username--copy'),
onClick: () => { onClick: () => {
assertDev( assertDev(
username !== undefined, username !== undefined,
@ -531,7 +531,7 @@ export function ProfileEditor({
{ {
group: 'copy', group: 'copy',
icon: 'ProfileEditor__username-menu__copy-link-icon', icon: 'ProfileEditor__username-menu__copy-link-icon',
label: i18n('ProfileEditor--username--copy-link'), label: i18n('icu:ProfileEditor--username--copy-link'),
onClick: () => { onClick: () => {
assertDev( assertDev(
username !== undefined, username !== undefined,
@ -548,7 +548,7 @@ export function ProfileEditor({
group: 'delete', group: 'delete',
icon: 'ProfileEditor__username-menu__trash-icon', icon: 'ProfileEditor__username-menu__trash-icon',
label: i18n('ProfileEditor--username--delete'), label: i18n('icu:ProfileEditor--username--delete'),
onClick: () => { onClick: () => {
setUsernameEditState(UsernameEditState.ConfirmingDelete); setUsernameEditState(UsernameEditState.ConfirmingDelete);
}, },
@ -562,7 +562,7 @@ export function ProfileEditor({
menuOptions={menuOptions} menuOptions={menuOptions}
popperOptions={{ placement: 'bottom', strategy: 'absolute' }} popperOptions={{ placement: 'bottom', strategy: 'absolute' }}
moduleClassName="ProfileEditor__username-menu" moduleClassName="ProfileEditor__username-menu"
ariaLabel={i18n('ProfileEditor--username--context-menu')} ariaLabel={i18n('icu:ProfileEditor--username--context-menu')}
/> />
); );
} }
@ -574,7 +574,7 @@ export function ProfileEditor({
icon={ icon={
<i className="ProfileEditor__icon--container ProfileEditor__icon ProfileEditor__icon--username" /> <i className="ProfileEditor__icon--container ProfileEditor__icon ProfileEditor__icon--username" />
} }
label={username || i18n('ProfileEditor--username')} label={username || i18n('icu:ProfileEditor--username')}
info={username && generateUsernameLink(username, { short: true })} info={username && generateUsernameLink(username, { short: true })}
onClick={() => { onClick={() => {
openUsernameReservationModal(); openUsernameReservationModal();
@ -631,7 +631,9 @@ export function ProfileEditor({
) )
} }
label={ label={
<Emojify text={fullBio.aboutText || i18n('ProfileEditor--about')} /> <Emojify
text={fullBio.aboutText || i18n('icu:ProfileEditor--about')}
/>
} }
onClick={() => { onClick={() => {
setEditState(EditState.Bio); setEditState(EditState.Bio);
@ -649,7 +651,7 @@ export function ProfileEditor({
target="_blank" target="_blank"
rel="noreferrer" rel="noreferrer"
> >
{i18n('ProfileEditor--learnMore')} {i18n('icu:ProfileEditor--learnMore')}
</a> </a>
), ),
}} }}
@ -670,13 +672,13 @@ export function ProfileEditor({
onClose={() => setUsernameEditState(UsernameEditState.Editing)} onClose={() => setUsernameEditState(UsernameEditState.Editing)}
actions={[ actions={[
{ {
text: i18n('ProfileEditor--username--confirm-delete-button'), text: i18n('icu:ProfileEditor--username--confirm-delete-button'),
style: 'negative', style: 'negative',
action: () => deleteUsername(), action: () => deleteUsername(),
}, },
]} ]}
> >
{i18n('ProfileEditor--username--confirm-delete-body')} {i18n('icu:ProfileEditor--username--confirm-delete-body')}
</ConfirmationDialog> </ConfirmationDialog>
)} )}

View file

@ -33,12 +33,12 @@ export function ProfileEditorModal({
...restProps ...restProps
}: PropsType): JSX.Element { }: PropsType): JSX.Element {
const MODAL_TITLES_BY_EDIT_STATE: Record<EditState, string | undefined> = { const MODAL_TITLES_BY_EDIT_STATE: Record<EditState, string | undefined> = {
[EditState.BetterAvatar]: i18n('ProfileEditorModal--avatar'), [EditState.BetterAvatar]: i18n('icu:ProfileEditorModal--avatar'),
[EditState.Bio]: i18n('ProfileEditorModal--about'), [EditState.Bio]: i18n('icu:ProfileEditorModal--about'),
[EditState.None]: i18n('ProfileEditorModal--profile'), [EditState.None]: i18n('icu:ProfileEditorModal--profile'),
[EditState.ProfileName]: i18n('ProfileEditorModal--name'), [EditState.ProfileName]: i18n('icu:ProfileEditorModal--name'),
[EditState.UsernameOnboarding]: undefined, [EditState.UsernameOnboarding]: undefined,
[EditState.Username]: i18n('ProfileEditorModal--username'), [EditState.Username]: i18n('icu:ProfileEditorModal--username'),
}; };
const [modalTitle, setModalTitle] = useState( const [modalTitle, setModalTitle] = useState(
@ -49,11 +49,11 @@ export function ProfileEditorModal({
return ( return (
<ConfirmationDialog <ConfirmationDialog
dialogName="ProfileEditorModal.error" dialogName="ProfileEditorModal.error"
cancelText={i18n('Confirmation--confirm')} cancelText={i18n('icu:Confirmation--confirm')}
i18n={i18n} i18n={i18n}
onClose={toggleProfileEditorHasError} onClose={toggleProfileEditorHasError}
> >
{i18n('ProfileEditorModal--error')} {i18n('icu:ProfileEditorModal--error')}
</ConfirmationDialog> </ConfirmationDialog>
); );
} }

View file

@ -18,7 +18,7 @@ export const ProgressDialog = React.memo(function ProgressDialogInner({
<div className="module-progress-dialog__spinner"> <div className="module-progress-dialog__spinner">
<Spinner svgSize="normal" size="39px" direction="on-progress-dialog" /> <Spinner svgSize="normal" size="39px" direction="on-progress-dialog" />
</div> </div>
<div className="module-progress-dialog__text">{i18n('updating')}</div> <div className="module-progress-dialog__text">{i18n('icu:updating')}</div>
</div> </div>
); );
}); });

View file

@ -61,7 +61,7 @@ export function ReactionPickerPickerMoreButton({
}>): JSX.Element { }>): JSX.Element {
return ( return (
<button <button
aria-label={i18n('Reactions--more')} aria-label={i18n('icu:Reactions--more')}
className="module-ReactionPickerPicker__button module-ReactionPickerPicker__button--more" className="module-ReactionPickerPicker__button module-ReactionPickerPicker__button--more"
onClick={event => { onClick={event => {
event.stopPropagation(); event.stopPropagation();
@ -75,7 +75,7 @@ export function ReactionPickerPickerMoreButton({
} }
}} }}
tabIndex={0} tabIndex={0}
title={i18n('Reactions--more')} title={i18n('icu:Reactions--more')}
type="button" type="button"
> >
<div className="module-ReactionPickerPicker__button--more__dot" /> <div className="module-ReactionPickerPicker__button--more__dot" />

View file

@ -150,11 +150,11 @@ export function SafetyNumberChangeDialog({
) { ) {
let text: string; let text: string;
if (dialogState === DialogState.ExplicitReviewStep) { if (dialogState === DialogState.ExplicitReviewStep) {
text = i18n('safetyNumberChangeDialog_done'); text = i18n('icu:safetyNumberChangeDialog_done');
} else if (allVerified || totalCount === 0) { } else if (allVerified || totalCount === 0) {
text = confirmText || i18n('safetyNumberChangeDialog_send'); text = confirmText || i18n('icu:safetyNumberChangeDialog_send');
} else { } else {
text = confirmText || i18n('sendAnyway'); text = confirmText || i18n('icu:sendAnyway');
} }
return ( return (
@ -183,10 +183,10 @@ export function SafetyNumberChangeDialog({
> >
<div className="module-SafetyNumberChangeDialog__shield-icon" /> <div className="module-SafetyNumberChangeDialog__shield-icon" />
<div className="module-SafetyNumberChangeDialog__title"> <div className="module-SafetyNumberChangeDialog__title">
{i18n('safetyNumberChanges')} {i18n('icu:safetyNumberChanges')}
</div> </div>
<div className="module-SafetyNumberChangeDialog__message"> <div className="module-SafetyNumberChangeDialog__message">
{i18n('safetyNumberChangeDialog__message')} {i18n('icu:safetyNumberChangeDialog__message')}
</div> </div>
{contacts.map((section: StoryContacts) => ( {contacts.map((section: StoryContacts) => (
<ContactSection <ContactSection
@ -205,9 +205,9 @@ export function SafetyNumberChangeDialog({
let text: string; let text: string;
if (dialogState === DialogState.ExplicitReviewNeeded) { if (dialogState === DialogState.ExplicitReviewNeeded) {
text = confirmText || i18n('sendAnyway'); text = confirmText || i18n('icu:sendAnyway');
} else if (dialogState === DialogState.ExplicitReviewComplete) { } else if (dialogState === DialogState.ExplicitReviewComplete) {
text = confirmText || i18n('safetyNumberChangeDialog_send'); text = confirmText || i18n('icu:safetyNumberChangeDialog_send');
} else { } else {
throw missingCaseError(dialogState); throw missingCaseError(dialogState);
} }
@ -223,7 +223,7 @@ export function SafetyNumberChangeDialog({
if (dialogState === DialogState.ExplicitReviewNeeded) { if (dialogState === DialogState.ExplicitReviewNeeded) {
actions.unshift({ actions.unshift({
action: () => setDialogState(DialogState.ExplicitReviewStep), action: () => setDialogState(DialogState.ExplicitReviewStep),
text: i18n('safetyNumberChangeDialog__review'), text: i18n('icu:safetyNumberChangeDialog__review'),
}); });
} }
@ -242,7 +242,7 @@ export function SafetyNumberChangeDialog({
> >
<div className="module-SafetyNumberChangeDialog__shield-icon" /> <div className="module-SafetyNumberChangeDialog__shield-icon" />
<div className="module-SafetyNumberChangeDialog__title"> <div className="module-SafetyNumberChangeDialog__title">
{i18n('safetyNumberChanges')} {i18n('icu:safetyNumberChanges')}
</div> </div>
<div <div
className={classNames( className={classNames(
@ -256,7 +256,7 @@ export function SafetyNumberChangeDialog({
? i18n('icu:safetyNumberChangeDialog__many-contacts', { ? i18n('icu:safetyNumberChangeDialog__many-contacts', {
count: totalCount, count: totalCount,
}) })
: i18n('safetyNumberChangeDialog__post-review')} : i18n('icu:safetyNumberChangeDialog__post-review')}
</div> </div>
</ConfirmationDialog> </ConfirmationDialog>
); );
@ -310,7 +310,9 @@ function ContactSection({
const { distributionId } = section.story; const { distributionId } = section.story;
const uuids = section.contacts.map(contact => contact.uuid).filter(isNotNil); const uuids = section.contacts.map(contact => contact.uuid).filter(isNotNil);
const sectionName = const sectionName =
distributionId === MY_STORY_ID ? i18n('Stories__mine') : section.story.name; distributionId === MY_STORY_ID
? i18n('icu:Stories__mine')
: section.story.name;
return ( return (
<div className="module-SafetyNumberChangeDialog__section"> <div className="module-SafetyNumberChangeDialog__section">
@ -320,7 +322,7 @@ function ContactSection({
</div> </div>
{distributionId && removeFromStory && uuids.length > 1 && ( {distributionId && removeFromStory && uuids.length > 1 && (
<SectionButtonWithMenu <SectionButtonWithMenu
ariaLabel={i18n('safetyNumberChangeDialog__actions-story', { ariaLabel={i18n('icu:safetyNumberChangeDialog__actions-story', {
story: sectionName, story: sectionName,
})} })}
i18n={i18n} i18n={i18n}
@ -381,7 +383,7 @@ function SectionButtonWithMenu({
menuOptions={[ menuOptions={[
{ {
icon: 'module-SafetyNumberChangeDialog__menu-icon--delete', icon: 'module-SafetyNumberChangeDialog__menu-icon--delete',
label: i18n('safetyNumberChangeDialog__remove-all'), label: i18n('icu:safetyNumberChangeDialog__remove-all'),
onClick: () => setIsConfirming(true), onClick: () => setIsConfirming(true),
}, },
]} ]}
@ -398,7 +400,7 @@ function SectionButtonWithMenu({
removeFromStory(); removeFromStory();
setIsConfirming(false); setIsConfirming(false);
}, },
text: i18n('safetyNumberChangeDialog__remove-all'), text: i18n('icu:safetyNumberChangeDialog__remove-all'),
style: 'affirmative', style: 'affirmative',
}, },
]} ]}
@ -483,7 +485,7 @@ function ContactRow({
)} )}
{contact.isVerified && ( {contact.isVerified && (
<span className="module-SafetyNumberChangeDialog__rtl-span"> <span className="module-SafetyNumberChangeDialog__rtl-span">
{i18n('verified')} {i18n('icu:verified')}
</span> </span>
)} )}
</div> </div>
@ -491,7 +493,7 @@ function ContactRow({
</div> </div>
{distributionId && removeFromStory && uuid ? ( {distributionId && removeFromStory && uuid ? (
<RowButtonWithMenu <RowButtonWithMenu
ariaLabel={i18n('safetyNumberChangeDialog__actions-contact', { ariaLabel={i18n('icu:safetyNumberChangeDialog__actions-contact', {
contact: contact.title, contact: contact.title,
})} })}
i18n={i18n} i18n={i18n}
@ -508,7 +510,7 @@ function ContactRow({
tabIndex={0} tabIndex={0}
type="button" type="button"
> >
{i18n('view')} {i18n('icu:view')}
</button> </button>
)} )}
</li> </li>
@ -535,12 +537,12 @@ function RowButtonWithMenu({
menuOptions={[ menuOptions={[
{ {
icon: 'module-SafetyNumberChangeDialog__menu-icon--verify', icon: 'module-SafetyNumberChangeDialog__menu-icon--verify',
label: i18n('safetyNumberChangeDialog__verify-number'), label: i18n('icu:safetyNumberChangeDialog__verify-number'),
onClick: verifyContact, onClick: verifyContact,
}, },
{ {
icon: 'module-SafetyNumberChangeDialog__menu-icon--delete', icon: 'module-SafetyNumberChangeDialog__menu-icon--delete',
label: i18n('safetyNumberChangeDialog__remove'), label: i18n('icu:safetyNumberChangeDialog__remove'),
onClick: removeFromStory, onClick: removeFromStory,
}, },
]} ]}

View file

@ -22,7 +22,7 @@ export function SafetyNumberModal({
i18n={i18n} i18n={i18n}
moduleClassName="module-SafetyNumberViewer__modal" moduleClassName="module-SafetyNumberViewer__modal"
onClose={toggleSafetyNumberModal} onClose={toggleSafetyNumberModal}
title={i18n('SafetyNumberModal__title')} title={i18n('icu:SafetyNumberModal__title')}
> >
<SafetyNumberViewer <SafetyNumberViewer
i18n={i18n} i18n={i18n}

View file

@ -41,14 +41,14 @@ export function SafetyNumberViewer({
if (!contact.phoneNumber) { if (!contact.phoneNumber) {
return ( return (
<div className="module-SafetyNumberViewer"> <div className="module-SafetyNumberViewer">
<div>{i18n('cannotGenerateSafetyNumber')}</div> <div>{i18n('icu:cannotGenerateSafetyNumber')}</div>
<div className="module-SafetyNumberViewer__buttons"> <div className="module-SafetyNumberViewer__buttons">
<Button <Button
className="module-SafetyNumberViewer__button" className="module-SafetyNumberViewer__button"
onClick={() => onClose?.()} onClick={() => onClose?.()}
variant={ButtonVariant.Primary} variant={ButtonVariant.Primary}
> >
{i18n('ok')} {i18n('icu:ok')}
</Button> </Button>
</div> </div>
</div> </div>
@ -73,7 +73,7 @@ export function SafetyNumberViewer({
<div className="module-SafetyNumberViewer__number"> <div className="module-SafetyNumberViewer__number">
{safetyNumber || getPlaceholder()} {safetyNumber || getPlaceholder()}
</div> </div>
<Intl i18n={i18n} id="verifyHelp" components={{ name: boldName }} /> <Intl i18n={i18n} id="icu:verifyHelp" components={{ name: boldName }} />
<div className="module-SafetyNumberViewer__verification-status"> <div className="module-SafetyNumberViewer__verification-status">
{isVerified ? ( {isVerified ? (
<span className="module-SafetyNumberViewer__icon--verified" /> <span className="module-SafetyNumberViewer__icon--verified" />
@ -81,11 +81,15 @@ export function SafetyNumberViewer({
<span className="module-SafetyNumberViewer__icon--shield" /> <span className="module-SafetyNumberViewer__icon--shield" />
)} )}
{isVerified ? ( {isVerified ? (
<Intl i18n={i18n} id="isVerified" components={{ name: boldName }} /> <Intl
i18n={i18n}
id="icu:isVerified"
components={{ name: boldName }}
/>
) : ( ) : (
<Intl <Intl
i18n={i18n} i18n={i18n}
id="isNotVerified" id="icu:isNotVerified"
components={{ name: boldName }} components={{ name: boldName }}
/> />
)} )}

View file

@ -79,7 +79,7 @@ export function SampleMessageBubbles({
color={color} color={color}
direction={includeAnotherBubble ? 'outgoing' : 'incoming'} direction={includeAnotherBubble ? 'outgoing' : 'incoming'}
i18n={i18n} i18n={i18n}
text={i18n('ChatColorPicker__sampleBubble1')} text={i18n('icu:ChatColorPicker__sampleBubble1')}
timestampDeltaFromNow={A_FEW_DAYS_AGO} timestampDeltaFromNow={A_FEW_DAYS_AGO}
status="read" status="read"
style={firstBubbleStyle} style={firstBubbleStyle}
@ -92,7 +92,7 @@ export function SampleMessageBubbles({
<SampleMessage <SampleMessage
direction="incoming" direction="incoming"
i18n={i18n} i18n={i18n}
text={i18n('ChatColorPicker__sampleBubble2')} text={i18n('icu:ChatColorPicker__sampleBubble2')}
timestampDeltaFromNow={A_FEW_DAYS_AGO / 2} timestampDeltaFromNow={A_FEW_DAYS_AGO / 2}
status="read" status="read"
/> />
@ -104,7 +104,7 @@ export function SampleMessageBubbles({
color={color} color={color}
direction="outgoing" direction="outgoing"
i18n={i18n} i18n={i18n}
text={i18n('ChatColorPicker__sampleBubble3')} text={i18n('icu:ChatColorPicker__sampleBubble3')}
timestampDeltaFromNow={0} timestampDeltaFromNow={0}
status="delivered" status="delivered"
style={backgroundStyle} style={backgroundStyle}

View file

@ -53,7 +53,7 @@ export const SearchInput = forwardRef<HTMLInputElement, PropTypes>(
{hasSearchIcon && <i className={getClassName('__icon')} />} {hasSearchIcon && <i className={getClassName('__icon')} />}
{children} {children}
<input <input
aria-label={label || i18n('search')} aria-label={label || i18n('icu:search')}
className={classNames( className={classNames(
getClassName('__input'), getClassName('__input'),
value && getClassName('__input--with-text'), value && getClassName('__input--with-text'),
@ -85,7 +85,7 @@ export const SearchInput = forwardRef<HTMLInputElement, PropTypes>(
/> />
{value && onClear && ( {value && onClear && (
<button <button
aria-label={i18n('cancel')} aria-label={i18n('icu:cancel')}
className={getClassName('__cancel')} className={getClassName('__cancel')}
onClick={onClear} onClick={onClear}
tabIndex={-1} tabIndex={-1}

Some files were not shown because too many files have changed in this diff Show more