Skip to content

Commit

Permalink
Backport Language Picker
Browse files Browse the repository at this point in the history
  • Loading branch information
jamiebuilds-signal committed Nov 8, 2023
1 parent 20356ac commit e6de7d8
Show file tree
Hide file tree
Showing 38 changed files with 838 additions and 74 deletions.
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ ts/protobuf/*.d.ts
ts/protobuf/*.js
stylesheets/manifest.css
ts/util/lint/exceptions.json
build/locale-display-names.json

# Third-party files
node_modules/**
Expand Down
2 changes: 2 additions & 0 deletions .storybook/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ window.SignalContext = {
getHourCyclePreference: () => HourCyclePreference.UnknownPreference,
getPreferredSystemLocales: () => ['en'],
getResolvedMessagesLocaleDirection: () => 'ltr',
getLocaleOverride: () => null,
getLocaleDisplayNames: () => ({ en: { en: 'English' } }),
};

window.i18n = i18n;
Expand Down
36 changes: 36 additions & 0 deletions _locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -5831,6 +5831,42 @@
"messageformat": "You will no longer be able to share or view stories. Story updates you have recently shared will also be deleted.",
"description": "Confirmation modal body for disabling stories"
},
"icu:Preferences__Language__Label": {
"messageformat": "Language",
"description": "Language setting label"
},
"icu:Preferences__Language__ModalTitle": {
"messageformat": "Language",
"description": "Language setting modal title"
},
"icu:Preferences__Language__SystemLanguage": {
"messageformat": "System Language",
"description": "Option for system language"
},
"icu:Preferences__Language__SearchLanguages": {
"messageformat": "Search languages",
"description": "Placholder for language preference search box"
},
"icu:Preferences__Language__NoResults": {
"messageformat": "No results for “{searchTerm}”",
"description": "When no results are found for language preference search"
},
"icu:Preferences__LanguageModal__Set": {
"messageformat": "Set",
"description": "Button to set language preference"
},
"icu:Preferences__LanguageModal__Restart__Title": {
"messageformat": "Restart Signal to apply",
"description": "Title for restart Signal modal to apply language changes"
},
"icu:Preferences__LanguageModal__Restart__Description": {
"messageformat": "To change the language, the app needs to restart.",
"description": "Description for restart Signal modal to apply language changes"
},
"icu:Preferences__LanguageModal__Restart__Button": {
"messageformat": "Restart",
"description": "Button to restart Signal to apply language changes"
},
"icu:DialogUpdate--version-available": {
"messageformat": "Update to version {version} available",
"description": "Tooltip for new update available"
Expand Down
28 changes: 26 additions & 2 deletions app/locale.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,28 @@ function getLocaleMessages(locale: string): LocaleMessagesType {
return JSON.parse(readFileSync(targetFile, 'utf-8'));
}

export type LocaleDisplayNames = Record<string, Record<string, string>>;

function getLocaleDisplayNames(): LocaleDisplayNames {
const targetFile = join(
__dirname,
'..',
'build',
'locale-display-names.json'
);
return JSON.parse(readFileSync(targetFile, 'utf-8'));
}

export type LocaleDirection = 'ltr' | 'rtl';

export type LocaleType = {
availableLocales: Array<string>;
i18n: LocalizerType;
name: string;
direction: LocaleDirection;
messages: LocaleMessagesType;
hourCyclePreference: HourCyclePreference;
localeDisplayNames: LocaleDisplayNames;
};

function getLocaleDirection(
Expand Down Expand Up @@ -65,10 +79,12 @@ function getLocaleDirection(
}

function finalize(
availableLocales: Array<string>,
messages: LocaleMessagesType,
backupMessages: LocaleMessagesType,
localeName: string,
hourCyclePreference: HourCyclePreference,
localeDisplayNames: LocaleDisplayNames,
logger: LoggerType
): LocaleType {
// We start with english, then overwrite that with anything present in locale
Expand All @@ -80,11 +96,13 @@ function finalize(
logger.info(`locale: Text info direction for ${localeName}: ${direction}`);

return {
availableLocales,
i18n,
name: localeName,
direction,
messages: finalMessages,
hourCyclePreference,
localeDisplayNames,
};
}

Expand All @@ -99,10 +117,12 @@ export function _getAvailableLocales(): Array<string> {

export function load({
preferredSystemLocales,
localeOverride,
hourCyclePreference,
logger,
}: {
preferredSystemLocales: Array<string>;
localeOverride: string | null;
hourCyclePreference: HourCyclePreference;
logger: LoggerType;
}): LocaleType {
Expand All @@ -117,10 +137,11 @@ export function load({
const availableLocales = _getAvailableLocales();

logger.info('locale: Supported locales:', availableLocales.join(', '));
logger.info('locale: Preferred locales: ', preferredSystemLocales.join(', '));
logger.info('locale: Preferred locales:', preferredSystemLocales.join(', '));
logger.info('locale: Locale Override:', localeOverride);

const matchedLocale = LocaleMatcher.match(
preferredSystemLocales,
localeOverride != null ? [localeOverride] : preferredSystemLocales,
availableLocales,
'en',
{ algorithm: 'best fit' }
Expand All @@ -130,12 +151,15 @@ export function load({

const matchedLocaleMessages = getLocaleMessages(matchedLocale);
const englishMessages = getLocaleMessages('en');
const languageDisplayNames = getLocaleDisplayNames();

return finalize(
availableLocales,
matchedLocaleMessages,
englishMessages,
matchedLocale,
hourCyclePreference,
languageDisplayNames,
logger
);
}
44 changes: 42 additions & 2 deletions app/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ const consoleLogger = createBufferedConsoleLogger();
// These will be set after app fires the 'ready' event
let logger: LoggerType | undefined;
let preferredSystemLocales: Array<string> | undefined;
let localeOverride: string | null | undefined;
let resolvedTranslationsLocale: LocaleType | undefined;
let settingsChannel: SettingsChannel | undefined;

Expand Down Expand Up @@ -374,6 +375,26 @@ async function getBackgroundColor(
throw missingCaseError(theme);
}

async function getLocaleOverrideSetting(): Promise<string | null> {
const fastValue = ephemeralConfig.get('localeOverride');
// eslint-disable-next-line eqeqeq -- Checking for null explicitly
if (typeof fastValue === 'string' || fastValue === null) {
getLogger().info('got fast localeOverride setting', fastValue);
return fastValue;
}

const json = await sql.sqlCall('getItemById', 'localeOverride');

// Default to `null` if setting doesn't exist yet
const slowValue = typeof json?.value === 'string' ? json.value : null;

ephemeralConfig.set('localeOverride', slowValue);

getLogger().info('got slow localeOverride setting', slowValue);

return slowValue;
}

let systemTrayService: SystemTrayService | undefined;
const systemTraySettingCache = new SystemTraySettingCache(
sql,
Expand Down Expand Up @@ -426,6 +447,13 @@ function getPreferredSystemLocales(): Array<string> {
return preferredSystemLocales;
}

function getLocaleOverride(): string | null {
if (typeof localeOverride === 'undefined') {
throw new Error('getLocaleOverride: Locale not yet initialized!');
}
return localeOverride;
}

function getResolvedMessagesLocale(): LocaleType {
if (!resolvedTranslationsLocale) {
throw new Error('getResolvedMessagesLocale: Locale not yet initialized!');
Expand Down Expand Up @@ -821,6 +849,7 @@ async function createWindow() {
setupSpellChecker(
mainWindow,
getPreferredSystemLocales(),
getLocaleOverride(),
getResolvedMessagesLocale().i18n,
getLogger()
);
Expand Down Expand Up @@ -1799,11 +1828,15 @@ app.on('ready', async () => {
// Write buffered information into newly created logger.
consoleLogger.writeBufferInto(logger);

sqlInitPromise = initializeSQL(userDataPath);

if (!resolvedTranslationsLocale) {
preferredSystemLocales = resolveCanonicalLocales(
loadPreferredSystemLocales()
);

localeOverride = await getLocaleOverrideSetting();

const hourCyclePreference = getHourCyclePreference();
logger.info(`app.ready: hour cycle preference: ${hourCyclePreference}`);

Expand All @@ -1814,13 +1847,12 @@ app.on('ready', async () => {
);
resolvedTranslationsLocale = loadLocale({
preferredSystemLocales,
localeOverride,
hourCyclePreference,
logger: getLogger(),
});
}

sqlInitPromise = initializeSQL(userDataPath);

// First run: configure Signal to minimize to tray. Additionally, on Windows
// enable auto-start with start-in-tray so that starting from a Desktop icon
// would still show the window.
Expand Down Expand Up @@ -2397,10 +2429,12 @@ ipc.on('get-config', async event => {

const parsed = rendererConfigSchema.safeParse({
name: packageJson.productName,
availableLocales: getResolvedMessagesLocale().availableLocales,
resolvedTranslationsLocale: getResolvedMessagesLocale().name,
resolvedTranslationsLocaleDirection: getResolvedMessagesLocale().direction,
hourCyclePreference: getResolvedMessagesLocale().hourCyclePreference,
preferredSystemLocales: getPreferredSystemLocales(),
localeOverride: getLocaleOverride(),
version: app.getVersion(),
buildCreation: config.get<number>('buildCreation'),
buildExpiration: config.get<number>('buildExpiration'),
Expand Down Expand Up @@ -2468,6 +2502,12 @@ ipc.on('locale-data', event => {
event.returnValue = getResolvedMessagesLocale().messages;
});

// Ingested in preload.js via a sendSync call
ipc.on('locale-display-names', event => {
// eslint-disable-next-line no-param-reassign
event.returnValue = getResolvedMessagesLocale().localeDisplayNames;
});

// TODO DESKTOP-5241
ipc.on('OS.getHasCustomTitleBar', event => {
// eslint-disable-next-line no-param-reassign
Expand Down
16 changes: 10 additions & 6 deletions app/spell_check.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export function getLanguages(
export const setup = (
browserWindow: BrowserWindow,
preferredSystemLocales: ReadonlyArray<string>,
localeOverride: string | null,
i18n: LocalizerType,
logger: LoggerType
): void => {
Expand All @@ -74,13 +75,16 @@ export const setup = (
logger.info('spellcheck: dictionary initialized:', lang);
});

// Locale override should be combined with other preferences rather than
// replace them entirely.
const combinedLocales =
localeOverride != null
? [localeOverride, ...preferredSystemLocales]
: preferredSystemLocales;

const availableLocales = session.availableSpellCheckerLanguages;
const languages = getLanguages(
preferredSystemLocales,
availableLocales,
'en'
);
console.log('spellcheck: user locales:', preferredSystemLocales);
const languages = getLanguages(combinedLocales, availableLocales, 'en');
console.log('spellcheck: user locales:', combinedLocales);
console.log(
'spellcheck: available spellchecker languages:',
availableLocales
Expand Down
1 change: 1 addition & 0 deletions build/locale-display-names.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions images/icons/v3/globe/globe.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"build-release": "yarn run build",
"sign-release": "node ts/updater/generateSignature.js",
"notarize": "echo 'No longer necessary'",
"get-strings": "node ts/scripts/get-strings.js && node ts/scripts/gen-nsis-script.js && node ts/scripts/gen-locales-config.js",
"get-strings": "ts-node ts/scripts/get-strings.ts && ts-node ts/scripts/gen-nsis-script.ts && ts-node ts/scripts/gen-locales-config.ts && ts-node ./ts/scripts/build-locale-display-names.ts",
"push-strings": "node ts/scripts/remove-strings.js && node ts/scripts/push-strings.js",
"get-expire-time": "node ts/scripts/get-expire-time.js",
"copy-components": "node ts/scripts/copy.js",
Expand Down Expand Up @@ -271,6 +271,7 @@
"core-js": "2.6.9",
"cross-env": "5.2.0",
"css-loader": "3.2.0",
"csv-parse": "5.5.2",
"danger": "11.1.2",
"debug": "4.3.3",
"electron": "25.9.3",
Expand Down Expand Up @@ -398,7 +399,9 @@
}
},
"signDlls": true,
"signExts": [".node"],
"signExts": [
".node"
],
"target": [
"nsis"
]
Expand Down
10 changes: 6 additions & 4 deletions stylesheets/components/Modal.scss
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,17 @@
}

&__header {
&--with-back-button .module-Modal__title {
text-align: center;
}
}

&__headerTitle {
align-items: center;
display: flex;
justify-content: space-between;
padding-block: 16px 1em;
padding-inline: 16px;

&--with-back-button .module-Modal__title {
text-align: center;
}
}

&__title {
Expand Down
Loading

0 comments on commit e6de7d8

Please sign in to comment.