diff --git a/src/components/app.tsx b/src/components/app.tsx index 8af9c6a64..2fe8f1829 100644 --- a/src/components/app.tsx +++ b/src/components/app.tsx @@ -2,11 +2,13 @@ import { __experimentalVStack as VStack, __experimentalHStack as HStack, } from '@wordpress/components'; +import { useEffect } from 'react'; import { useLocalizationSupport } from '../hooks/use-localization-support'; import { useOnboarding } from '../hooks/use-onboarding'; import { useSidebarVisibility } from '../hooks/use-sidebar-visibility'; import { isWindows } from '../lib/app-globals'; import { cx } from '../lib/cx'; +import { getIpcApi } from '../lib/get-ipc-api'; import MainSidebar from './main-sidebar'; import Onboarding from './onboarding'; import { SiteContentTabs } from './site-content-tabs'; @@ -19,6 +21,10 @@ export default function App() { const { needsOnboarding } = useOnboarding(); const { isSidebarVisible, toggleSidebar } = useSidebarVisibility(); + useEffect( () => { + getIpcApi().setupAppMenu( { needsOnboarding } ); + }, [ needsOnboarding ] ); + return ( <> { needsOnboarding ? ( diff --git a/src/components/onboarding.tsx b/src/components/onboarding.tsx index 90d7ee73c..5a42db717 100644 --- a/src/components/onboarding.tsx +++ b/src/components/onboarding.tsx @@ -6,10 +6,6 @@ import { FormEvent, useCallback, useEffect, useState } from 'react'; import { ACCEPTED_IMPORT_FILE_TYPES } from '../constants'; import { useAddSite } from '../hooks/use-add-site'; import { useDragAndDropFile } from '../hooks/use-drag-and-drop-file'; -import { useImportExport } from '../hooks/use-import-export'; -import { useIpcListener } from '../hooks/use-ipc-listener'; -import { useOnboarding } from '../hooks/use-onboarding'; -import { useSiteDetails } from '../hooks/use-site-details'; import { generateSiteName } from '../lib/generate-site-name'; import { getIpcApi } from '../lib/get-ipc-api'; import Button from './button'; @@ -39,7 +35,6 @@ const GradientBox = () => { export default function Onboarding() { const { __ } = useI18n(); - const { needsOnboarding } = useOnboarding(); const { setSiteName, setProposedSitePath, @@ -57,12 +52,6 @@ export default function Onboarding() { fileForImport, } = useAddSite(); const [ fileError, setFileError ] = useState( '' ); - const { importState } = useImportExport(); - const { data } = useSiteDetails(); - - const isAnySiteProcessing = data.some( - ( site ) => site.isAddingSite || importState[ site.id ]?.isNewSite - ); const siteAddedMessage = sprintf( // translators: %s is the site name. @@ -101,21 +90,24 @@ export default function Onboarding() { // eslint-disable-next-line react-hooks/exhaustive-deps }, [] ); - const onAddSite = useCallback( async () => { - // Prompt the user to enable optimizations on Windows - try { - await getIpcApi().promptWindowsSpeedUpSites( { skipIfAlreadyPrompted: true } ); - } catch ( error ) { - console.error( error ); - } + const handleSubmit = useCallback( + async ( event: FormEvent ) => { + event.preventDefault(); + try { + await getIpcApi().promptWindowsSpeedUpSites( { skipIfAlreadyPrompted: true } ); + } catch ( error ) { + console.error( error ); + } - try { - await handleAddSiteClick(); - speak( siteAddedMessage ); - } catch { - // No need to handle error here, it's already handled in handleAddSiteClick - } - }, [ handleAddSiteClick, siteAddedMessage ] ); + try { + await handleAddSiteClick(); + speak( siteAddedMessage ); + } catch { + // No need to handle error here, it's already handled in handleAddSiteClick + } + }, + [ handleAddSiteClick, siteAddedMessage ] + ); const handleImportFile = useCallback( async ( file: File ) => { @@ -125,13 +117,6 @@ export default function Onboarding() { [ setFileForImport ] ); - useIpcListener( 'add-site', () => { - if ( isAnySiteProcessing || ! needsOnboarding ) { - return; - } - onAddSite(); - } ); - return (
@@ -154,10 +139,7 @@ export default function Onboarding() { onSelectPath={ handlePathSelectorClick } error={ error } doesPathContainWordPress={ doesPathContainWordPress } - onSubmit={ async ( event: FormEvent ) => { - event.preventDefault(); - await onAddSite(); - } } + onSubmit={ handleSubmit } fileForImport={ fileForImport } setFileForImport={ setFileForImport } onFileSelected={ handleImportFile } diff --git a/src/hooks/use-i18n-data.tsx b/src/hooks/use-i18n-data.tsx index 354465d6e..d0f3cc881 100644 --- a/src/hooks/use-i18n-data.tsx +++ b/src/hooks/use-i18n-data.tsx @@ -3,6 +3,7 @@ import { I18nProvider } from '@wordpress/react-i18n'; import { createContext, useContext, useEffect, useMemo, useState, useCallback } from 'react'; import { getIpcApi } from '../lib/get-ipc-api'; import { SupportedLocale, getLocaleData } from '../lib/locale'; +import { useOnboarding } from './use-onboarding'; interface I18nDataContext { setLocale: ( localeKey: SupportedLocale ) => void; @@ -19,26 +20,30 @@ export const I18nDataProvider = ( { children }: { children: React.ReactNode } ) const [ initialized, setInitialized ] = useState< boolean >( false ); const [ i18n, setI18n ] = useState< I18n | null >( null ); const [ locale, setLocale ] = useState< SupportedLocale >( 'en' ); + const { needsOnboarding } = useOnboarding(); - const initI18n = useCallback( async ( localeKey: SupportedLocale ) => { - 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(); - getIpcApi().resetDefaultLocaleData(); - } - // App menu is reloaded to ensure the items show the translated strings. - getIpcApi().setupAppMenu(); - }, [] ); + const initI18n = useCallback( + async ( localeKey: SupportedLocale ) => { + 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(); + getIpcApi().resetDefaultLocaleData(); + } + // App menu is reloaded to ensure the items show the translated strings. + getIpcApi().setupAppMenu( { needsOnboarding } ); + }, + [ needsOnboarding ] + ); useEffect( () => { if ( initialized ) { diff --git a/src/ipc-handlers.ts b/src/ipc-handlers.ts index b31e184c0..5ee231370 100644 --- a/src/ipc-handlers.ts +++ b/src/ipc-handlers.ts @@ -714,8 +714,8 @@ export async function showNotification( new Notification( options ).show(); } -export function setupAppMenu( _event: IpcMainInvokeEvent ) { - setupMenu(); +export function setupAppMenu( _event: IpcMainInvokeEvent, config: { needsOnboarding: boolean } ) { + setupMenu( config ); } export function popupAppMenu( _event: IpcMainInvokeEvent ) { diff --git a/src/menu.ts b/src/menu.ts index e409bda32..0e66c117b 100644 --- a/src/menu.ts +++ b/src/menu.ts @@ -13,13 +13,13 @@ import { promptWindowsSpeedUpSites } from './lib/windows-helpers'; import { withMainWindow } from './main-window'; import { isUpdateReadyToInstall, manualCheckForUpdates } from './updates'; -export function setupMenu() { +export function setupMenu( config: { needsOnboarding: boolean } ) { withMainWindow( ( mainWindow ) => { if ( ! mainWindow && process.platform !== 'darwin' ) { Menu.setApplicationMenu( null ); return; } - const menu = getAppMenu( mainWindow ); + const menu = getAppMenu( mainWindow, config ); if ( process.platform === 'darwin' ) { Menu.setApplicationMenu( menu ); return; @@ -44,7 +44,10 @@ export function popupMenu() { } ); } -function getAppMenu( mainWindow: BrowserWindow | null ) { +function getAppMenu( + mainWindow: BrowserWindow | null, + { needsOnboarding = false }: { needsOnboarding?: boolean } = {} +) { const crashTestMenuItems: MenuItemConstructorOptions[] = [ { label: __( 'Test Hard Crash (dev only)' ), @@ -119,6 +122,7 @@ function getAppMenu( mainWindow: BrowserWindow | null ) { window.webContents.send( 'add-site' ); } ); }, + enabled: ! needsOnboarding, }, ...( process.platform === 'win32' ? [] diff --git a/src/preload.ts b/src/preload.ts index cf80b5a4f..4bd791d16 100644 --- a/src/preload.ts +++ b/src/preload.ts @@ -66,7 +66,8 @@ 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' ), + setupAppMenu: ( config: { needsOnboarding: boolean } ) => + ipcRenderer.invoke( 'setupAppMenu', config ), popupAppMenu: () => ipcRenderer.invoke( 'popupAppMenu' ), promptWindowsSpeedUpSites: ( ...args: Parameters< typeof promptWindowsSpeedUpSites > ) => ipcRenderer.invoke( 'promptWindowsSpeedUpSites', ...args ),