Match multiple locales for spellchecker
This commit is contained in:
parent
2edc47118e
commit
a4055cec40
5 changed files with 72 additions and 31 deletions
|
@ -9,6 +9,10 @@ Signal Desktop makes use of the following open source projects.
|
|||
|
||||
License: MIT
|
||||
|
||||
## @formatjs/intl-localematcher
|
||||
|
||||
License: MIT
|
||||
|
||||
## @indutny/frameless-titlebar
|
||||
|
||||
MIT License
|
||||
|
|
|
@ -800,7 +800,11 @@ async function createWindow() {
|
|||
}
|
||||
|
||||
mainWindowCreated = true;
|
||||
setupSpellChecker(mainWindow, getResolvedMessagesLocale());
|
||||
setupSpellChecker(
|
||||
mainWindow,
|
||||
getPreferredSystemLocales(),
|
||||
getResolvedMessagesLocale().i18n
|
||||
);
|
||||
if (!startInTray && windowConfig && windowConfig.maximized) {
|
||||
mainWindow.maximize();
|
||||
}
|
||||
|
|
|
@ -3,44 +3,62 @@
|
|||
|
||||
import type { BrowserWindow } from 'electron';
|
||||
import { Menu, clipboard, nativeImage } from 'electron';
|
||||
import { uniq } from 'lodash';
|
||||
import { fileURLToPath } from 'url';
|
||||
import * as LocaleMatcher from '@formatjs/intl-localematcher';
|
||||
|
||||
import { maybeParseUrl } from '../ts/util/url';
|
||||
import type { LocaleType } from './locale';
|
||||
|
||||
import type { MenuListType } from '../ts/types/menu';
|
||||
import type { LocalizerType } from '../ts/types/Util';
|
||||
|
||||
export function getLanguages(
|
||||
userLocale: string,
|
||||
availableLocales: ReadonlyArray<string>
|
||||
preferredSystemLocales: ReadonlyArray<string>,
|
||||
availableLocales: ReadonlyArray<string>,
|
||||
defaultLocale: string
|
||||
): Array<string> {
|
||||
// First attempt to find the exact locale
|
||||
const candidateLocales = uniq([userLocale, userLocale]).filter(l =>
|
||||
availableLocales.includes(l)
|
||||
);
|
||||
if (candidateLocales.length > 0) {
|
||||
return candidateLocales;
|
||||
const matchedLocales = [];
|
||||
|
||||
preferredSystemLocales.forEach(preferredSystemLocale => {
|
||||
if (preferredSystemLocale === defaultLocale) {
|
||||
matchedLocales.push(defaultLocale);
|
||||
return;
|
||||
}
|
||||
const matchedLocale = LocaleMatcher.match(
|
||||
[preferredSystemLocale],
|
||||
availableLocales as Array<string>, // bad types
|
||||
defaultLocale,
|
||||
{ algorithm: 'best fit' }
|
||||
);
|
||||
if (matchedLocale !== defaultLocale) {
|
||||
matchedLocales.push(matchedLocale);
|
||||
}
|
||||
});
|
||||
|
||||
if (matchedLocales.length === 0) {
|
||||
matchedLocales.push(defaultLocale);
|
||||
}
|
||||
|
||||
// If no languages were found then return all locales that start with the base
|
||||
const baseLocale = userLocale.split('-')[0];
|
||||
return uniq(availableLocales.filter(l => l.startsWith(baseLocale)));
|
||||
return matchedLocales;
|
||||
}
|
||||
|
||||
export const setup = (
|
||||
browserWindow: BrowserWindow,
|
||||
{ name: userLocale, i18n }: LocaleType
|
||||
preferredSystemLocales: ReadonlyArray<string>,
|
||||
i18n: LocalizerType
|
||||
): void => {
|
||||
const { session } = browserWindow.webContents;
|
||||
const availableLocales = session.availableSpellCheckerLanguages;
|
||||
const languages = getLanguages(userLocale, availableLocales);
|
||||
console.log(`spellcheck: user locale: ${userLocale}`);
|
||||
const languages = getLanguages(
|
||||
preferredSystemLocales,
|
||||
availableLocales,
|
||||
'en'
|
||||
);
|
||||
console.log('spellcheck: user locales:', preferredSystemLocales);
|
||||
console.log(
|
||||
'spellcheck: available spellchecker languages: ',
|
||||
'spellcheck: available spellchecker languages:',
|
||||
availableLocales
|
||||
);
|
||||
console.log('spellcheck: setting languages to: ', languages);
|
||||
console.log('spellcheck: setting languages to:', languages);
|
||||
session.setSpellCheckerLanguages(languages);
|
||||
|
||||
browserWindow.webContents.on('context-menu', (_event, params) => {
|
||||
|
|
|
@ -80,6 +80,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@formatjs/fast-memoize": "1.2.6",
|
||||
"@formatjs/intl-localematcher": "0.2.32",
|
||||
"@indutny/frameless-titlebar": "2.3.5",
|
||||
"@indutny/sneequals": "4.0.0",
|
||||
"@popperjs/core": "2.11.6",
|
||||
|
|
|
@ -8,34 +8,48 @@ import { getLanguages } from '../../../app/spell_check';
|
|||
describe('SpellCheck', () => {
|
||||
describe('getLanguages', () => {
|
||||
it('works with locale and base available', () => {
|
||||
assert.deepEqual(getLanguages('en-US', ['en-US', 'en-CA', 'en']), [
|
||||
assert.deepEqual(getLanguages(['en-US'], ['en-US', 'en'], 'en'), [
|
||||
'en-US',
|
||||
]);
|
||||
});
|
||||
|
||||
it('works with neither locale nor base available', () => {
|
||||
assert.deepEqual(getLanguages('en-US', ['en-NZ', 'en-CA']), [
|
||||
'en-NZ',
|
||||
'en-CA',
|
||||
it('uses icu likely subtags rules to match languages', () => {
|
||||
assert.deepEqual(getLanguages(['fa-FR'], ['fa-IR'], 'en'), ['fa-IR']);
|
||||
assert.deepEqual(getLanguages(['zh'], ['zh-Hans-CN'], 'en'), [
|
||||
'zh-Hans-CN',
|
||||
]);
|
||||
assert.deepEqual(
|
||||
getLanguages(['zh-HK'], ['zh-Hans-CN', 'zh-Hant-HK'], 'en'),
|
||||
['zh-Hant-HK']
|
||||
);
|
||||
});
|
||||
|
||||
it('matches multiple locales', () => {
|
||||
assert.deepEqual(
|
||||
getLanguages(['fr-FR', 'es'], ['fr', 'es-ES', 'en-US'], 'en'),
|
||||
['fr', 'es-ES']
|
||||
);
|
||||
});
|
||||
|
||||
it('works with only base locale available', () => {
|
||||
assert.deepEqual(getLanguages('en-US', ['en', 'en-CA']), ['en', 'en-CA']);
|
||||
assert.deepEqual(getLanguages(['en-US'], ['en'], 'en'), ['en']);
|
||||
});
|
||||
|
||||
it('works with only full locale available', () => {
|
||||
assert.deepEqual(getLanguages('en-US', ['en-CA', 'en-US']), ['en-US']);
|
||||
assert.deepEqual(getLanguages(['en-US'], ['en-CA', 'en-US'], 'en'), [
|
||||
'en-US',
|
||||
]);
|
||||
});
|
||||
|
||||
it('works with base provided and base available', () => {
|
||||
assert.deepEqual(getLanguages('en', ['en-CA', 'en-US', 'en']), ['en']);
|
||||
assert.deepEqual(getLanguages(['en'], ['en-CA', 'en-US', 'en'], 'en'), [
|
||||
'en',
|
||||
]);
|
||||
});
|
||||
|
||||
it('works with base provided and base not available', () => {
|
||||
assert.deepEqual(getLanguages('en', ['en-CA', 'en-US']), [
|
||||
'en-CA',
|
||||
'en-US',
|
||||
it('falls back to default', () => {
|
||||
assert.deepEqual(getLanguages(['fa-IR'], ['es-ES', 'fr-FR'], 'en'), [
|
||||
'en',
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue