Skip to content
39 changes: 21 additions & 18 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
globalShortcut,
Menu,
dialog,
MessageBoxSyncOptions,
} from 'electron';
import path from 'path';
import { pathToFileURL } from 'url';
Expand All @@ -25,7 +26,7 @@ import { IPC_VOID_HANDLERS } from 'src/constants';
import * as ipcHandlers from 'src/ipc-handlers';
import {
hasActiveSyncOperations,
hasCancelableSyncOperations,
hasUploadingPushOperations,
} from 'src/lib/active-sync-operations';
import { bumpAggregatedUniqueStat } from 'src/lib/bump-stats';
import { getPlatformMetric } from 'src/lib/bump-stats/lib';
Expand Down Expand Up @@ -352,19 +353,6 @@ async function appBoot() {
globalShortcut.unregisterAll();
} );

function getQuitConfirmationMessage(): string {
if ( hasCancelableSyncOperations() ) {
return __(
"There's a sync operation in progress. Quitting the app will abort that operation. Are you sure you want to quit?"
);
}

// Default message for creatingBackup, uploading, or pull operations
return __(
"There's a sync operation in progress. The process will continue on WordPress.com servers even after quitting Studio. We will send you an email when it completes. Are you sure you want to quit?"
);
}

app.on( 'before-quit', ( event ) => {
if ( ! hasActiveSyncOperations() ) {
return;
Expand All @@ -373,15 +361,30 @@ async function appBoot() {
const QUIT_APP_BUTTON_INDEX = 0;
const CANCEL_BUTTON_INDEX = 1;

const detailMessage = getQuitConfirmationMessage();
const messageInformation: Pick< MessageBoxSyncOptions, 'message' | 'detail' | 'type' > =
hasUploadingPushOperations()
? {
message: __( 'Sync is in progress' ),
detail: __(
"There's a sync operation in progress. Quitting the app will abort that operation. Are you sure you want to quit?"
),
type: 'warning',
}
: {
message: __( 'Sync will continue' ),
detail: __(
'The sync process will continue running remotely after you quit Studio. We will send you an email once it is complete.'
),
type: 'info',
};

const clickedButtonIndex = dialog.showMessageBoxSync( {
message: __( 'Sync in progress' ),
detail: detailMessage,
message: messageInformation.message,
detail: messageInformation.detail,
type: messageInformation.type,
buttons: [ __( 'Yes, quit the app' ), __( 'No, take me back' ) ],
cancelId: CANCEL_BUTTON_INDEX,
defaultId: QUIT_APP_BUTTON_INDEX,
type: 'warning',
} );

if ( clickedButtonIndex === CANCEL_BUTTON_INDEX ) {
Expand Down
18 changes: 15 additions & 3 deletions src/lib/active-sync-operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,24 @@ export function canCancelPush( key: PushStateProgressInfo[ 'key' ] | undefined )
return cancellableStateKeys.includes( key );
}

export function hasCancelableSyncOperations(): boolean {
/**
* Check if a push operation has finished uploading the backup file.
*/
export function pushBackupIsUploading( key: PushStateProgressInfo[ 'key' ] | undefined ): boolean {
const uploadingStateKeys: PushStateProgressInfo[ 'key' ][] = [ 'creatingBackup', 'uploading' ];
if ( ! key ) {
return false;
}
return uploadingStateKeys.includes( key );
}

export function hasUploadingPushOperations(): boolean {
// Iterate over all the sites and check if any operation is cancelable
let result = false;
for ( const [ , state ] of ACTIVE_SYNC_OPERATIONS ) {
if ( state && 'key' in state ) {
return canCancelPush( state.key as PushStateProgressInfo[ 'key' ] );
result = result || pushBackupIsUploading( state.key as PushStateProgressInfo[ 'key' ] );
}
}
return true;
return result;
}
16 changes: 12 additions & 4 deletions src/modules/sync/components/sync-connected-sites.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ import { useAuth } from 'src/hooks/use-auth';
import { useImportExport } from 'src/hooks/use-import-export';
import { useOffline } from 'src/hooks/use-offline';
import { useSyncStatesProgressInfo } from 'src/hooks/use-sync-states-progress-info';
import { canCancelPull, canCancelPush } from 'src/lib/active-sync-operations';
import {
pushBackupIsUploading,
canCancelPull,
canCancelPush,
} from 'src/lib/active-sync-operations';
import { cx } from 'src/lib/cx';
import { getIpcApi } from 'src/lib/get-ipc-api';
import { getLocalizedLink } from 'src/lib/get-localized-link';
Expand Down Expand Up @@ -291,9 +295,13 @@ const SyncConnectedSitesSectionItem = ( {
{ pushState?.status && isPushing && (
<div className="flex items-center gap-2 max-w-full">
<Tooltip
text={ __(
'Push is in progress. We will send you an email when it is completed.'
) }
text={
pushBackupIsUploading( pushState?.status.key )
? __( 'Push is in progress. We will send you an email when it is completed.' )
: __(
"The push is in progress and will continue running remotely. We will send you an email once it's completed."
)
}
placement="top-start"
>
<div className="flex flex-col gap-2 min-w-44 flex-shrink">
Expand Down