Fix timestamps/spellcheck to use locale override
This commit is contained in:
parent
59fa75c309
commit
fd8691b871
11 changed files with 45 additions and 11 deletions
|
@ -110,6 +110,7 @@ window.SignalContext = {
|
||||||
getHourCyclePreference: () => HourCyclePreference.UnknownPreference,
|
getHourCyclePreference: () => HourCyclePreference.UnknownPreference,
|
||||||
getPreferredSystemLocales: () => ['en'],
|
getPreferredSystemLocales: () => ['en'],
|
||||||
getResolvedMessagesLocaleDirection: () => 'ltr',
|
getResolvedMessagesLocaleDirection: () => 'ltr',
|
||||||
|
getLocaleOverride: () => null,
|
||||||
};
|
};
|
||||||
|
|
||||||
window.i18n = i18n;
|
window.i18n = i18n;
|
||||||
|
|
12
app/main.ts
12
app/main.ts
|
@ -143,6 +143,7 @@ const consoleLogger = createBufferedConsoleLogger();
|
||||||
// These will be set after app fires the 'ready' event
|
// These will be set after app fires the 'ready' event
|
||||||
let logger: LoggerType | undefined;
|
let logger: LoggerType | undefined;
|
||||||
let preferredSystemLocales: Array<string> | undefined;
|
let preferredSystemLocales: Array<string> | undefined;
|
||||||
|
let localeOverride: string | null | undefined;
|
||||||
let resolvedTranslationsLocale: LocaleType | undefined;
|
let resolvedTranslationsLocale: LocaleType | undefined;
|
||||||
let settingsChannel: SettingsChannel | undefined;
|
let settingsChannel: SettingsChannel | undefined;
|
||||||
|
|
||||||
|
@ -431,6 +432,13 @@ function getPreferredSystemLocales(): Array<string> {
|
||||||
return preferredSystemLocales;
|
return preferredSystemLocales;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getLocaleOverride(): string | null {
|
||||||
|
if (typeof localeOverride === 'undefined') {
|
||||||
|
throw new Error('getLocaleOverride: Locale not yet initialized!');
|
||||||
|
}
|
||||||
|
return localeOverride;
|
||||||
|
}
|
||||||
|
|
||||||
function getResolvedMessagesLocale(): LocaleType {
|
function getResolvedMessagesLocale(): LocaleType {
|
||||||
if (!resolvedTranslationsLocale) {
|
if (!resolvedTranslationsLocale) {
|
||||||
throw new Error('getResolvedMessagesLocale: Locale not yet initialized!');
|
throw new Error('getResolvedMessagesLocale: Locale not yet initialized!');
|
||||||
|
@ -824,6 +832,7 @@ async function createWindow() {
|
||||||
setupSpellChecker(
|
setupSpellChecker(
|
||||||
mainWindow,
|
mainWindow,
|
||||||
getPreferredSystemLocales(),
|
getPreferredSystemLocales(),
|
||||||
|
getLocaleOverride(),
|
||||||
getResolvedMessagesLocale().i18n,
|
getResolvedMessagesLocale().i18n,
|
||||||
getLogger()
|
getLogger()
|
||||||
);
|
);
|
||||||
|
@ -1809,7 +1818,7 @@ app.on('ready', async () => {
|
||||||
loadPreferredSystemLocales()
|
loadPreferredSystemLocales()
|
||||||
);
|
);
|
||||||
|
|
||||||
const localeOverride = await getLocaleOverrideSetting();
|
localeOverride = await getLocaleOverrideSetting();
|
||||||
|
|
||||||
const hourCyclePreference = getHourCyclePreference();
|
const hourCyclePreference = getHourCyclePreference();
|
||||||
logger.info(`app.ready: hour cycle preference: ${hourCyclePreference}`);
|
logger.info(`app.ready: hour cycle preference: ${hourCyclePreference}`);
|
||||||
|
@ -2400,6 +2409,7 @@ ipc.on('get-config', async event => {
|
||||||
resolvedTranslationsLocaleDirection: getResolvedMessagesLocale().direction,
|
resolvedTranslationsLocaleDirection: getResolvedMessagesLocale().direction,
|
||||||
hourCyclePreference: getResolvedMessagesLocale().hourCyclePreference,
|
hourCyclePreference: getResolvedMessagesLocale().hourCyclePreference,
|
||||||
preferredSystemLocales: getPreferredSystemLocales(),
|
preferredSystemLocales: getPreferredSystemLocales(),
|
||||||
|
localeOverride: getLocaleOverride(),
|
||||||
version: app.getVersion(),
|
version: app.getVersion(),
|
||||||
buildCreation: config.get<number>('buildCreation'),
|
buildCreation: config.get<number>('buildCreation'),
|
||||||
buildExpiration: config.get<number>('buildExpiration'),
|
buildExpiration: config.get<number>('buildExpiration'),
|
||||||
|
|
|
@ -56,6 +56,7 @@ export function getLanguages(
|
||||||
export const setup = (
|
export const setup = (
|
||||||
browserWindow: BrowserWindow,
|
browserWindow: BrowserWindow,
|
||||||
preferredSystemLocales: ReadonlyArray<string>,
|
preferredSystemLocales: ReadonlyArray<string>,
|
||||||
|
localeOverride: string | null,
|
||||||
i18n: LocalizerType,
|
i18n: LocalizerType,
|
||||||
logger: LoggerType
|
logger: LoggerType
|
||||||
): void => {
|
): void => {
|
||||||
|
@ -74,13 +75,16 @@ export const setup = (
|
||||||
logger.info('spellcheck: dictionary initialized:', lang);
|
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 availableLocales = session.availableSpellCheckerLanguages;
|
||||||
const languages = getLanguages(
|
const languages = getLanguages(combinedLocales, availableLocales, 'en');
|
||||||
preferredSystemLocales,
|
console.log('spellcheck: user locales:', combinedLocales);
|
||||||
availableLocales,
|
|
||||||
'en'
|
|
||||||
);
|
|
||||||
console.log('spellcheck: user locales:', preferredSystemLocales);
|
|
||||||
console.log(
|
console.log(
|
||||||
'spellcheck: available spellchecker languages:',
|
'spellcheck: available spellchecker languages:',
|
||||||
availableLocales
|
availableLocales
|
||||||
|
|
|
@ -33,6 +33,7 @@ global.window = {
|
||||||
getResolvedMessagesLocaleDirection: () => 'ltr',
|
getResolvedMessagesLocaleDirection: () => 'ltr',
|
||||||
getHourCyclePreference: () => HourCyclePreference.UnknownPreference,
|
getHourCyclePreference: () => HourCyclePreference.UnknownPreference,
|
||||||
getPreferredSystemLocales: () => ['en'],
|
getPreferredSystemLocales: () => ['en'],
|
||||||
|
getLocaleOverride: () => null,
|
||||||
},
|
},
|
||||||
i18n: key => `i18n(${key})`,
|
i18n: key => `i18n(${key})`,
|
||||||
storage: {
|
storage: {
|
||||||
|
|
|
@ -60,3 +60,4 @@ window.textsecure.storage.protocol = window.getSignalProtocolStore();
|
||||||
})();
|
})();
|
||||||
|
|
||||||
window.getPreferredSystemLocales = () => ['en'];
|
window.getPreferredSystemLocales = () => ['en'];
|
||||||
|
window.getLocaleOverride = () => null;
|
||||||
|
|
|
@ -12,6 +12,7 @@ const max = new Date(2023, 0, 1, 23).getTime();
|
||||||
describe('formatTimestamp', () => {
|
describe('formatTimestamp', () => {
|
||||||
let sandbox: sinon.SinonSandbox;
|
let sandbox: sinon.SinonSandbox;
|
||||||
let localesStub: sinon.SinonStub;
|
let localesStub: sinon.SinonStub;
|
||||||
|
let localeOverrideStub: sinon.SinonStub;
|
||||||
let hourCycleStub: sinon.SinonStub;
|
let hourCycleStub: sinon.SinonStub;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
@ -20,6 +21,10 @@ describe('formatTimestamp', () => {
|
||||||
window.SignalContext,
|
window.SignalContext,
|
||||||
'getPreferredSystemLocales'
|
'getPreferredSystemLocales'
|
||||||
);
|
);
|
||||||
|
localeOverrideStub = sandbox.stub(
|
||||||
|
window.SignalContext,
|
||||||
|
'getLocaleOverride'
|
||||||
|
);
|
||||||
hourCycleStub = sandbox.stub(
|
hourCycleStub = sandbox.stub(
|
||||||
window.SignalContext,
|
window.SignalContext,
|
||||||
'getHourCyclePreference'
|
'getHourCyclePreference'
|
||||||
|
@ -41,6 +46,7 @@ describe('formatTimestamp', () => {
|
||||||
}).format(time);
|
}).format(time);
|
||||||
it(`should format with locale: ${locale} (${HourCyclePreference[preference]}) @ ${timeFmt})`, () => {
|
it(`should format with locale: ${locale} (${HourCyclePreference[preference]}) @ ${timeFmt})`, () => {
|
||||||
localesStub.returns([locale]);
|
localesStub.returns([locale]);
|
||||||
|
localeOverrideStub.returns(null);
|
||||||
hourCycleStub.returns(preference);
|
hourCycleStub.returns(preference);
|
||||||
assert.equal(formatTimestamp(time, { timeStyle: 'medium' }), expected);
|
assert.equal(formatTimestamp(time, { timeStyle: 'medium' }), expected);
|
||||||
});
|
});
|
||||||
|
|
|
@ -51,6 +51,7 @@ export const rendererConfigSchema = z.object({
|
||||||
resolvedTranslationsLocaleDirection: z.enum(['ltr', 'rtl']),
|
resolvedTranslationsLocaleDirection: z.enum(['ltr', 'rtl']),
|
||||||
hourCyclePreference: HourCyclePreferenceSchema,
|
hourCyclePreference: HourCyclePreferenceSchema,
|
||||||
preferredSystemLocales: z.array(configRequiredStringSchema),
|
preferredSystemLocales: z.array(configRequiredStringSchema),
|
||||||
|
localeOverride: z.string().nullable(),
|
||||||
name: configRequiredStringSchema,
|
name: configRequiredStringSchema,
|
||||||
nodeVersion: configRequiredStringSchema,
|
nodeVersion: configRequiredStringSchema,
|
||||||
proxyUrl: configOptionalStringSchema,
|
proxyUrl: configOptionalStringSchema,
|
||||||
|
|
|
@ -67,7 +67,11 @@ const formatterCache = new Map<string, Intl.DateTimeFormat>();
|
||||||
export function getDateTimeFormatter(
|
export function getDateTimeFormatter(
|
||||||
options: Intl.DateTimeFormatOptions
|
options: Intl.DateTimeFormatOptions
|
||||||
): Intl.DateTimeFormat {
|
): Intl.DateTimeFormat {
|
||||||
const locales = window.SignalContext.getPreferredSystemLocales();
|
const preferredSystemLocales =
|
||||||
|
window.SignalContext.getPreferredSystemLocales();
|
||||||
|
const localeOverride = window.SignalContext.getLocaleOverride();
|
||||||
|
const locales =
|
||||||
|
localeOverride != null ? [localeOverride] : preferredSystemLocales;
|
||||||
const optionsWithPreferences = getOptionsWithPreferences(options);
|
const optionsWithPreferences = getOptionsWithPreferences(options);
|
||||||
const cacheKey = getCacheKey(locales, optionsWithPreferences);
|
const cacheKey = getCacheKey(locales, optionsWithPreferences);
|
||||||
const cachedFormatter = formatterCache.get(cacheKey);
|
const cachedFormatter = formatterCache.get(cacheKey);
|
||||||
|
|
|
@ -48,6 +48,7 @@ export type MinimalSignalContextType = {
|
||||||
getHourCyclePreference: () => HourCyclePreference;
|
getHourCyclePreference: () => HourCyclePreference;
|
||||||
getResolvedMessagesLocale: () => string;
|
getResolvedMessagesLocale: () => string;
|
||||||
getPreferredSystemLocales: () => Array<string>;
|
getPreferredSystemLocales: () => Array<string>;
|
||||||
|
getLocaleOverride: () => string | null;
|
||||||
getMainWindowStats: () => Promise<MainWindowStatsType>;
|
getMainWindowStats: () => Promise<MainWindowStatsType>;
|
||||||
getMenuOptions: () => Promise<MenuOptionsType>;
|
getMenuOptions: () => Promise<MenuOptionsType>;
|
||||||
getNodeVersion: () => string;
|
getNodeVersion: () => string;
|
||||||
|
|
|
@ -45,15 +45,19 @@ window.libphonenumberFormat = PhoneNumberFormat;
|
||||||
window.React = React;
|
window.React = React;
|
||||||
window.ReactDOM = ReactDOM;
|
window.ReactDOM = ReactDOM;
|
||||||
|
|
||||||
const { resolvedTranslationsLocale, preferredSystemLocales } = config;
|
const { resolvedTranslationsLocale, preferredSystemLocales, localeOverride } =
|
||||||
moment.updateLocale(resolvedTranslationsLocale, {
|
config;
|
||||||
|
|
||||||
|
moment.updateLocale(localeOverride ?? resolvedTranslationsLocale, {
|
||||||
relativeTime: {
|
relativeTime: {
|
||||||
s: window.i18n('icu:timestamp_s'),
|
s: window.i18n('icu:timestamp_s'),
|
||||||
m: window.i18n('icu:timestamp_m'),
|
m: window.i18n('icu:timestamp_m'),
|
||||||
h: window.i18n('icu:timestamp_h'),
|
h: window.i18n('icu:timestamp_h'),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
moment.locale(preferredSystemLocales);
|
moment.locale(
|
||||||
|
localeOverride != null ? [localeOverride] : preferredSystemLocales
|
||||||
|
);
|
||||||
|
|
||||||
const userDataPath = SignalContext.getPath('userData');
|
const userDataPath = SignalContext.getPath('userData');
|
||||||
window.BasePaths = {
|
window.BasePaths = {
|
||||||
|
|
|
@ -49,6 +49,7 @@ export const MinimalSignalContext: MinimalSignalContextType = {
|
||||||
config.resolvedTranslationsLocaleDirection,
|
config.resolvedTranslationsLocaleDirection,
|
||||||
getHourCyclePreference: () => config.hourCyclePreference,
|
getHourCyclePreference: () => config.hourCyclePreference,
|
||||||
getPreferredSystemLocales: () => config.preferredSystemLocales,
|
getPreferredSystemLocales: () => config.preferredSystemLocales,
|
||||||
|
getLocaleOverride: () => config.localeOverride,
|
||||||
nativeThemeListener: createNativeThemeListener(ipcRenderer, window),
|
nativeThemeListener: createNativeThemeListener(ipcRenderer, window),
|
||||||
restartApp: () => ipcRenderer.send('restart'),
|
restartApp: () => ipcRenderer.send('restart'),
|
||||||
OS: {
|
OS: {
|
||||||
|
|
Loading…
Reference in a new issue