Skip to content
19 changes: 17 additions & 2 deletions src/hooks/use-i18n-data.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createI18n, I18n } from '@wordpress/i18n';
import { createI18n, I18n, defaultI18n } from '@wordpress/i18n';
import { I18nProvider } from '@wordpress/react-i18n';
import { createContext, useContext, useEffect, useMemo, useState, useCallback } from 'react';
import { getIpcApi } from '../lib/get-ipc-api';
Expand All @@ -21,8 +21,23 @@ export const I18nDataProvider = ( { children }: { children: React.ReactNode } )
const [ locale, setLocale ] = useState< SupportedLocale >( 'en' );

const initI18n = useCallback( async ( localeKey: SupportedLocale ) => {
const newI18n = createI18n( getLocaleData( localeKey )?.messages );
const translations = getLocaleData( localeKey )?.messages;
const newI18n = createI18n( translations );
setI18n( newI18n );
// Update default I18n data to reflect language change when using
// I18n functions from `@wordpress/i18n` package.
// Note we need to update this in both the renderer and main processes.
if ( translations ) {
defaultI18n.setLocaleData( translations );
getIpcApi().setDefaultLocaleData( translations );
} else {
// In case we don't find translations, we reset the locale data to
// fallback to the default translations.
defaultI18n.resetLocaleData();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we remove that, as we do it via ipc?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I've tested we need both. The object defaultI18n object is created globally so we need to update it for each process, the main and renderer.

getIpcApi().resetDefaultLocaleData();
}
// App menu is reloaded to ensure the items show the translated strings.
getIpcApi().setupAppMenu();
}, [] );

useEffect( () => {
Expand Down
15 changes: 14 additions & 1 deletion src/ipc-handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
import fs from 'fs';
import nodePath from 'path';
import * as Sentry from '@sentry/electron/main';
import { LocaleData, defaultI18n } from '@wordpress/i18n';
import archiver from 'archiver';
import { DEFAULT_PHP_VERSION } from '../vendor/wp-now/src/constants';
import { SIZE_LIMIT_BYTES } from './constants';
Expand All @@ -35,7 +36,7 @@ import { sortSites } from './lib/sort-sites';
import { installSqliteIntegration, keepSqliteIntegrationUpdated } from './lib/sqlite-versions';
import * as windowsHelpers from './lib/windows-helpers';
import { writeLogToFile, type LogLevel } from './logging';
import { popupMenu } from './menu';
import { popupMenu, setupMenu } from './menu';
import { SiteServer, createSiteWorkingDirectory } from './site-server';
import { DEFAULT_SITE_PATH, getResourcesPath, getSiteThumbnailPath } from './storage/paths';
import { loadUserData, saveUserData } from './storage/user-data';
Expand Down Expand Up @@ -703,6 +704,10 @@ export async function showNotification(
new Notification( options ).show();
}

export function setupAppMenu( _event: IpcMainInvokeEvent ) {
setupMenu();
}

export function popupAppMenu( _event: IpcMainInvokeEvent ) {
popupMenu();
}
Expand All @@ -713,3 +718,11 @@ export async function promptWindowsSpeedUpSites(
) {
await windowsHelpers.promptWindowsSpeedUpSites( { skipIfAlreadyPrompted } );
}

export function setDefaultLocaleData( _event: IpcMainInvokeEvent, locale?: LocaleData ) {
defaultI18n.setLocaleData( locale );
}

export function resetDefaultLocaleData( _event: IpcMainInvokeEvent ) {
defaultI18n.resetLocaleData();
}
5 changes: 2 additions & 3 deletions src/main-window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { MAIN_MIN_HEIGHT, MAIN_MIN_WIDTH, WINDOWS_TITLEBAR_HEIGHT } from './cons
import { isEmptyDir } from './lib/fs-utils';
import { portFinder } from './lib/port-finder';
import { keepSqliteIntegrationUpdated } from './lib/sqlite-versions';
import { setupMenu } from './menu';
import { removeMenu } from './menu';
import { UserData } from './storage/storage-types';
import { loadUserData, saveUserData } from './storage/user-data';

Expand Down Expand Up @@ -91,10 +91,9 @@ export function createMainWindow(): BrowserWindow {
} );

mainWindow.on( 'closed', () => {
setupMenu( null );
removeMenu();
mainWindow = null;
} );
setupMenu( mainWindow );

return mainWindow;
}
Expand Down
34 changes: 20 additions & 14 deletions src/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,27 @@ import { promptWindowsSpeedUpSites } from './lib/windows-helpers';
import { withMainWindow } from './main-window';
import { isUpdateReadyToInstall, manualCheckForUpdates } from './updates';

export function setupMenu( mainWindow: BrowserWindow | null ) {
if ( ! mainWindow && process.platform !== 'darwin' ) {
export function setupMenu() {
withMainWindow( ( mainWindow ) => {
if ( ! mainWindow && process.platform !== 'darwin' ) {
Menu.setApplicationMenu( null );
return;
}
const menu = getAppMenu( mainWindow );
if ( process.platform === 'darwin' ) {
Menu.setApplicationMenu( menu );
return;
}
// Make menu accessible in development for non-macOS platforms
if ( process.env.NODE_ENV === 'development' ) {
mainWindow?.setMenu( menu );
return;
}
Menu.setApplicationMenu( null );
return;
}
const menu = getAppMenu( mainWindow );
if ( process.platform === 'darwin' ) {
Menu.setApplicationMenu( menu );
return;
}
// Make menu accessible in development for non-macOS platforms
if ( process.env.NODE_ENV === 'development' ) {
mainWindow?.setMenu( menu );
return;
}
} );
}

export function removeMenu() {
Menu.setApplicationMenu( null );
}

Expand Down
5 changes: 5 additions & 0 deletions src/preload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import '@sentry/electron/preload';
import { SaveDialogOptions, contextBridge, ipcRenderer } from 'electron';
import { LocaleData } from '@wordpress/i18n';
import { ExportOptions } from './lib/import-export/export/types';
import { BackupArchiveInfo } from './lib/import-export/import/types';
import { promptWindowsSpeedUpSites } from './lib/windows-helpers';
Expand Down Expand Up @@ -62,9 +63,13 @@ const api: IpcApi = {
// Use .send instead of .invoke because logging is fire-and-forget
logRendererMessage: ( level: LogLevel, ...args: any[] ) =>
ipcRenderer.send( 'logRendererMessage', level, ...args ),
setupAppMenu: () => ipcRenderer.invoke( 'setupAppMenu' ),
popupAppMenu: () => ipcRenderer.invoke( 'popupAppMenu' ),
promptWindowsSpeedUpSites: ( ...args: Parameters< typeof promptWindowsSpeedUpSites > ) =>
ipcRenderer.invoke( 'promptWindowsSpeedUpSites', ...args ),
setDefaultLocaleData: ( locale?: LocaleData ) =>
ipcRenderer.invoke( 'setDefaultLocaleData', locale ),
resetDefaultLocaleData: () => ipcRenderer.invoke( 'resetDefaultLocaleData' ),
};

contextBridge.exposeInMainWorld( 'ipcApi', api );
Expand Down