From c1c230fada45c33411b30122993373e8e6ef88db Mon Sep 17 00:00:00 2001 From: Rahul Gavande Date: Mon, 29 Dec 2025 20:02:30 +0530 Subject: [PATCH 1/5] Sync: Show file upload progress in % in the UI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add sync-upload-progress IPC event to send upload progress from main process - Update Tus onProgress callback to send progress percentage (0-100%) - Store raw upload progress in SyncPushState for display - Display upload percentage next to 'Uploading Studio site…' message - Progress updates in real-time as chunks are uploaded via Tus protocol Fixes STU-1144 --- src/hooks/sync-sites/use-sync-push.ts | 30 +++++++++++++++++++ src/ipc-utils.ts | 1 + .../sync/components/sync-connected-sites.tsx | 9 ++++++ src/modules/sync/lib/ipc-handlers.ts | 10 ++++++- 4 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/hooks/sync-sites/use-sync-push.ts b/src/hooks/sync-sites/use-sync-push.ts index 6552b0afe3..9bd995ee86 100644 --- a/src/hooks/sync-sites/use-sync-push.ts +++ b/src/hooks/sync-sites/use-sync-push.ts @@ -27,6 +27,7 @@ export type SyncPushState = { status: PushStateProgressInfo; selectedSite: SiteDetails; remoteSiteUrl: string; + uploadProgress?: number; // Raw upload percentage (0-100%) when uploading }; type PushSiteOptions = { @@ -324,6 +325,7 @@ export function useSyncPush( { if ( response.success ) { updatePushState( selectedSite.id, remoteSiteId, { status: pushStatesProgressInfo.creatingRemoteBackup, + uploadProgress: undefined, // Clear upload progress when transitioning to next state } ); } else { throw response; @@ -392,12 +394,40 @@ export function useSyncPush( { useIpcListener( 'sync-upload-resumed', ( _event, payload: { selectedSiteId: string; remoteSiteId: number } ) => { + const currentState = getPushState( payload.selectedSiteId, payload.remoteSiteId ); updatePushState( payload.selectedSiteId, payload.remoteSiteId, { status: pushStatesProgressInfo.uploading, + // Keep existing uploadProgress if available, otherwise it will be set by sync-upload-progress + uploadProgress: currentState?.uploadProgress, } ); } ); + useIpcListener( + 'sync-upload-progress', + ( _event, payload: { selectedSiteId: string; remoteSiteId: number; progress: number } ) => { + const currentState = getPushState( payload.selectedSiteId, payload.remoteSiteId ); + // Only update progress if we're in the uploading state + if ( currentState && currentState.status.key === 'uploading' ) { + // Map upload progress (0-100%) to the uploading state range (40-50%) + const uploadingProgressRange = + pushStatesProgressInfo.creatingRemoteBackup.progress - + pushStatesProgressInfo.uploading.progress; + const mappedProgress = + pushStatesProgressInfo.uploading.progress + + ( payload.progress / 100 ) * uploadingProgressRange; + + updatePushState( payload.selectedSiteId, payload.remoteSiteId, { + status: { + ...currentState.status, + progress: mappedProgress, + }, + uploadProgress: payload.progress, // Store raw upload percentage (0-100%) + } ); + } + } + ); + const isAnySitePushing = useMemo< boolean >( () => { return Object.values( pushStates ).some( ( state ) => isKeyPushing( state.status.key ) ); }, [ pushStates, isKeyPushing ] ); diff --git a/src/ipc-utils.ts b/src/ipc-utils.ts index 9893ac9934..e5e8de413b 100644 --- a/src/ipc-utils.ts +++ b/src/ipc-utils.ts @@ -40,6 +40,7 @@ export interface IpcEvents { 'site-context-menu-action': [ { action: string; siteId: string } ]; 'sync-upload-paused': [ { error: string; selectedSiteId: string; remoteSiteId: number } ]; 'sync-upload-resumed': [ { selectedSiteId: string; remoteSiteId: number } ]; + 'sync-upload-progress': [ { selectedSiteId: string; remoteSiteId: number; progress: number } ]; 'snapshot-error': [ { operationId: crypto.UUID; data: SnapshotEventData } ]; 'snapshot-fatal-error': [ { operationId: crypto.UUID; data: { message: string } } ]; 'snapshot-output': [ { operationId: crypto.UUID; data: SnapshotEventData } ]; diff --git a/src/modules/sync/components/sync-connected-sites.tsx b/src/modules/sync/components/sync-connected-sites.tsx index 2a6a2f48aa..800629c91a 100644 --- a/src/modules/sync/components/sync-connected-sites.tsx +++ b/src/modules/sync/components/sync-connected-sites.tsx @@ -217,6 +217,12 @@ const SyncConnectedSitesSectionItem = ( { const hasPushFinished = pushState && isKeyFinished( pushState.status.key ); const hasPushCancelled = pushState && isKeyCancelled( pushState.status.key ); + // Get raw upload percentage (0-100%) when in uploading state + const uploadPercentage = + pushState?.status.key === 'uploading' && pushState.uploadProgress !== undefined + ? Math.round( pushState.uploadProgress ) + : null; + return (
{ pushState.status.message } + { uploadPercentage !== null && ( + { uploadPercentage }% + ) }
diff --git a/src/modules/sync/lib/ipc-handlers.ts b/src/modules/sync/lib/ipc-handlers.ts index d38a936187..f30c5fb90a 100644 --- a/src/modules/sync/lib/ipc-handlers.ts +++ b/src/modules/sync/lib/ipc-handlers.ts @@ -194,7 +194,7 @@ export async function pushArchive( console.error( '[TUS] Upload error', error ); reject( error ); }, - onProgress: () => { + onProgress: ( bytesSent: number, bytesTotal: number ) => { if ( isUploadingPaused ) { isUploadingPaused = false; void sendIpcEventToRenderer( 'sync-upload-resumed', { @@ -207,6 +207,14 @@ export async function pushArchive( if ( ! hasUploadStarted ) { hasUploadStarted = true; } + + // Calculate upload progress percentage (0-100) + const uploadProgress = bytesTotal > 0 ? ( bytesSent / bytesTotal ) * 100 : 0; + void sendIpcEventToRenderer( 'sync-upload-progress', { + selectedSiteId: selectedSiteId, + remoteSiteId: remoteSiteId, + progress: uploadProgress, + } ); }, onSuccess: ( payload ) => { if ( ! payload.lastResponse ) { From cb08ec811a207fabbbc6b476dcf4626c2c38bc3b Mon Sep 17 00:00:00 2001 From: Rahul Gavande Date: Tue, 30 Dec 2025 11:12:40 +0530 Subject: [PATCH 2/5] Refactor: Move upload progress logic to useSyncStatesProgressInfo hook MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Move upload progress mapping logic to useSyncStatesProgressInfo hook - Add getPushUploadMessage helper for i18n-formatted messages - Add isKeyUploading helper function - Update message format to show percentage in parentheses: 'Uploading site (98%)…' - Follow i18n best practices using sprintf for formatted messages - Centralize all progress-related calculations in one place --- src/hooks/sync-sites/use-sync-push.ts | 18 +++---- src/hooks/use-sync-states-progress-info.ts | 52 ++++++++++++++++++- .../sync/components/sync-connected-sites.tsx | 16 +++--- 3 files changed, 64 insertions(+), 22 deletions(-) diff --git a/src/hooks/sync-sites/use-sync-push.ts b/src/hooks/sync-sites/use-sync-push.ts index 9bd995ee86..3b56df0c0a 100644 --- a/src/hooks/sync-sites/use-sync-push.ts +++ b/src/hooks/sync-sites/use-sync-push.ts @@ -27,7 +27,7 @@ export type SyncPushState = { status: PushStateProgressInfo; selectedSite: SiteDetails; remoteSiteUrl: string; - uploadProgress?: number; // Raw upload percentage (0-100%) when uploading + uploadProgress?: number; }; type PushSiteOptions = { @@ -100,11 +100,13 @@ export function useSyncPush( { const { pushStatesProgressInfo, isKeyPushing, + isKeyUploading, isKeyImporting, isKeyFinished, isKeyFailed, isKeyCancelled, getPushStatusWithProgress, + mapUploadProgressToOverallProgress, } = useSyncStatesProgressInfo(); const updatePushState = useCallback< UpdateState< SyncPushState > >( @@ -397,7 +399,6 @@ export function useSyncPush( { const currentState = getPushState( payload.selectedSiteId, payload.remoteSiteId ); updatePushState( payload.selectedSiteId, payload.remoteSiteId, { status: pushStatesProgressInfo.uploading, - // Keep existing uploadProgress if available, otherwise it will be set by sync-upload-progress uploadProgress: currentState?.uploadProgress, } ); } @@ -407,22 +408,15 @@ export function useSyncPush( { 'sync-upload-progress', ( _event, payload: { selectedSiteId: string; remoteSiteId: number; progress: number } ) => { const currentState = getPushState( payload.selectedSiteId, payload.remoteSiteId ); - // Only update progress if we're in the uploading state - if ( currentState && currentState.status.key === 'uploading' ) { - // Map upload progress (0-100%) to the uploading state range (40-50%) - const uploadingProgressRange = - pushStatesProgressInfo.creatingRemoteBackup.progress - - pushStatesProgressInfo.uploading.progress; - const mappedProgress = - pushStatesProgressInfo.uploading.progress + - ( payload.progress / 100 ) * uploadingProgressRange; + if ( currentState && isKeyUploading( currentState.status.key ) ) { + const mappedProgress = mapUploadProgressToOverallProgress( payload.progress ); updatePushState( payload.selectedSiteId, payload.remoteSiteId, { status: { ...currentState.status, progress: mappedProgress, }, - uploadProgress: payload.progress, // Store raw upload percentage (0-100%) + uploadProgress: payload.progress, } ); } } diff --git a/src/hooks/use-sync-states-progress-info.ts b/src/hooks/use-sync-states-progress-info.ts index 4864b40b0c..7d4ed5e356 100644 --- a/src/hooks/use-sync-states-progress-info.ts +++ b/src/hooks/use-sync-states-progress-info.ts @@ -1,3 +1,4 @@ +import { sprintf } from '@wordpress/i18n'; import { useI18n } from '@wordpress/react-i18n'; import { useCallback, useMemo } from 'react'; import { ImportProgressState } from './use-import-export'; @@ -104,7 +105,7 @@ export function useSyncStatesProgressInfo() { uploading: { key: 'uploading', progress: 40, - message: __( 'Uploading Studio site…' ), + message: __( 'Uploading site…' ), }, uploadingPaused: { key: 'uploadingPaused', @@ -174,6 +175,10 @@ export function useSyncStatesProgressInfo() { return key === 'uploadingPaused'; }; + const isKeyUploading = useCallback( ( key: PushStateProgressInfo[ 'key' ] | undefined ) => { + return key === 'uploading'; + }, [] ); + const isKeyImporting = ( key: PushStateProgressInfo[ 'key' ] | undefined ) => { const pushingStateKeys: PushStateProgressInfo[ 'key' ][] = [ 'creatingRemoteBackup', @@ -294,6 +299,47 @@ export function useSyncStatesProgressInfo() { ] ); + const getPushUploadPercentage = useCallback( + ( + statusKey: PushStateProgressInfo[ 'key' ] | undefined, + uploadProgress: number | undefined + ): number | null => { + if ( isKeyUploading( statusKey ) && uploadProgress !== undefined ) { + return Math.round( uploadProgress ); + } + return null; + }, + [ isKeyUploading ] + ); + + const getPushUploadMessage = useCallback( + ( message: string, uploadPercentage: number | null ): string => { + if ( uploadPercentage !== null ) { + // translators: %d is the upload progress percentage + return sprintf( __( 'Uploading site (%d%%)…' ), uploadPercentage ); + } + return message; + }, + [ __ ] + ); + + const mapUploadProgressToOverallProgress = useCallback( + ( uploadProgress: number ): number => { + // Map upload progress (0-100%) to the uploading state range (40-50%) + const uploadingProgressRange = + pushStatesProgressInfo.creatingRemoteBackup.progress - + pushStatesProgressInfo.uploading.progress; + return ( + pushStatesProgressInfo.uploading.progress + + ( uploadProgress / 100 ) * uploadingProgressRange + ); + }, + [ + pushStatesProgressInfo.creatingRemoteBackup.progress, + pushStatesProgressInfo.uploading.progress, + ] + ); + return { pullStatesProgressInfo, pushStatesProgressInfo, @@ -303,9 +349,13 @@ export function useSyncStatesProgressInfo() { isKeyFinished, isKeyFailed, isKeyCancelled, + isKeyUploading, getBackupStatusWithProgress, getPullStatusWithProgress, getPushStatusWithProgress, + getPushUploadPercentage, + getPushUploadMessage, + mapUploadProgressToOverallProgress, isKeyUploadingPaused, }; } diff --git a/src/modules/sync/components/sync-connected-sites.tsx b/src/modules/sync/components/sync-connected-sites.tsx index 800629c91a..40af65606a 100644 --- a/src/modules/sync/components/sync-connected-sites.tsx +++ b/src/modules/sync/components/sync-connected-sites.tsx @@ -199,6 +199,8 @@ const SyncConnectedSitesSectionItem = ( { isKeyFailed, isKeyCancelled, getPullStatusWithProgress, + getPushUploadPercentage, + getPushUploadMessage, isKeyUploadingPaused, } = useSyncStatesProgressInfo(); @@ -217,11 +219,10 @@ const SyncConnectedSitesSectionItem = ( { const hasPushFinished = pushState && isKeyFinished( pushState.status.key ); const hasPushCancelled = pushState && isKeyCancelled( pushState.status.key ); - // Get raw upload percentage (0-100%) when in uploading state - const uploadPercentage = - pushState?.status.key === 'uploading' && pushState.uploadProgress !== undefined - ? Math.round( pushState.uploadProgress ) - : null; + const uploadPercentage = getPushUploadPercentage( + pushState?.status.key, + pushState?.uploadProgress + ); return (
@@ -328,10 +329,7 @@ const SyncConnectedSitesSectionItem = ( {
- { pushState.status.message } - { uploadPercentage !== null && ( - { uploadPercentage }% - ) } + { getPushUploadMessage( pushState.status.message, uploadPercentage ) }
From e539e074bfba4b564f3193984a61fb41cb4c02fb Mon Sep 17 00:00:00 2001 From: Rahul Gavande Date: Tue, 6 Jan 2026 10:41:44 +0530 Subject: [PATCH 3/5] Refactor: Move pure functions outside hook --- src/hooks/use-sync-states-progress-info.ts | 153 ++++++++++----------- 1 file changed, 74 insertions(+), 79 deletions(-) diff --git a/src/hooks/use-sync-states-progress-info.ts b/src/hooks/use-sync-states-progress-info.ts index 7d4ed5e356..7f24314e6c 100644 --- a/src/hooks/use-sync-states-progress-info.ts +++ b/src/hooks/use-sync-states-progress-info.ts @@ -57,6 +57,80 @@ const DOWNLOADING_INITIAL_VALUE = 60; const IN_PROGRESS_TO_DOWNLOADING_STEP = DOWNLOADING_INITIAL_VALUE - IN_PROGRESS_INITIAL_VALUE; const PULL_IMPORTING_INITIAL_VALUE = 80; +export function isKeyPulling( key: PullStateProgressInfo[ 'key' ] | undefined ): boolean { + const pullingStateKeys: PullStateProgressInfo[ 'key' ][] = [ + 'in-progress', + 'downloading', + 'importing', + ]; + if ( ! key ) { + return false; + } + return pullingStateKeys.includes( key ); +} + +export function isKeyPushing( key: PushStateProgressInfo[ 'key' ] | undefined ): boolean { + const pushingStateKeys: PushStateProgressInfo[ 'key' ][] = [ + 'creatingBackup', + 'uploading', + 'creatingRemoteBackup', + 'applyingChanges', + 'finishing', + ]; + if ( ! key ) { + return false; + } + return pushingStateKeys.includes( key ); +} + +export function isKeyUploadingPaused( key: PushStateProgressInfo[ 'key' ] | undefined ): boolean { + return key === 'uploadingPaused'; +} + +export function isKeyUploading( key: PushStateProgressInfo[ 'key' ] | undefined ): boolean { + return key === 'uploading'; +} + +export function isKeyImporting( key: PushStateProgressInfo[ 'key' ] | undefined ): boolean { + const pushingStateKeys: PushStateProgressInfo[ 'key' ][] = [ + 'creatingRemoteBackup', + 'applyingChanges', + 'finishing', + ]; + if ( ! key ) { + return false; + } + return pushingStateKeys.includes( key ); +} + +export function isKeyFinished( + key: PullStateProgressInfo[ 'key' ] | PushStateProgressInfo[ 'key' ] | undefined +): boolean { + return key === 'finished'; +} + +export function isKeyFailed( + key: PullStateProgressInfo[ 'key' ] | PushStateProgressInfo[ 'key' ] | undefined +): boolean { + return key === 'failed'; +} + +export function isKeyCancelled( + key: PullStateProgressInfo[ 'key' ] | PushStateProgressInfo[ 'key' ] | undefined +): boolean { + return key === 'cancelled'; +} + +export function getPushUploadPercentage( + statusKey: PushStateProgressInfo[ 'key' ] | undefined, + uploadProgress: number | undefined +): number | null { + if ( isKeyUploading( statusKey ) && uploadProgress !== undefined ) { + return Math.round( uploadProgress ); + } + return null; +} + export function useSyncStatesProgressInfo() { const { __ } = useI18n(); const pullStatesProgressInfo = useMemo( () => { @@ -145,72 +219,6 @@ export function useSyncStatesProgressInfo() { } as const satisfies PushStateProgressInfoValues; }, [ __ ] ); - const isKeyPulling = ( key: PullStateProgressInfo[ 'key' ] | undefined ) => { - const pullingStateKeys: PullStateProgressInfo[ 'key' ][] = [ - 'in-progress', - 'downloading', - 'importing', - ]; - if ( ! key ) { - return false; - } - return pullingStateKeys.includes( key ); - }; - - const isKeyPushing = ( key: PushStateProgressInfo[ 'key' ] | undefined ) => { - const pushingStateKeys: PushStateProgressInfo[ 'key' ][] = [ - 'creatingBackup', - 'uploading', - 'creatingRemoteBackup', - 'applyingChanges', - 'finishing', - ]; - if ( ! key ) { - return false; - } - return pushingStateKeys.includes( key ); - }; - - const isKeyUploadingPaused = ( key: PushStateProgressInfo[ 'key' ] | undefined ) => { - return key === 'uploadingPaused'; - }; - - const isKeyUploading = useCallback( ( key: PushStateProgressInfo[ 'key' ] | undefined ) => { - return key === 'uploading'; - }, [] ); - - const isKeyImporting = ( key: PushStateProgressInfo[ 'key' ] | undefined ) => { - const pushingStateKeys: PushStateProgressInfo[ 'key' ][] = [ - 'creatingRemoteBackup', - 'applyingChanges', - 'finishing', - ]; - if ( ! key ) { - return false; - } - return pushingStateKeys.includes( key ); - }; - const isKeyFinished = useCallback( - ( key: PullStateProgressInfo[ 'key' ] | PushStateProgressInfo[ 'key' ] | undefined ) => { - return key === 'finished'; - }, - [] - ); - - const isKeyFailed = useCallback( - ( key: PullStateProgressInfo[ 'key' ] | PushStateProgressInfo[ 'key' ] | undefined ) => { - return key === 'failed'; - }, - [] - ); - - const isKeyCancelled = useCallback( - ( key: PullStateProgressInfo[ 'key' ] | PushStateProgressInfo[ 'key' ] | undefined ) => { - return key === 'cancelled'; - }, - [] - ); - const getBackupStatusWithProgress = useCallback( ( hasBackupCompleted: boolean, @@ -299,19 +307,6 @@ export function useSyncStatesProgressInfo() { ] ); - const getPushUploadPercentage = useCallback( - ( - statusKey: PushStateProgressInfo[ 'key' ] | undefined, - uploadProgress: number | undefined - ): number | null => { - if ( isKeyUploading( statusKey ) && uploadProgress !== undefined ) { - return Math.round( uploadProgress ); - } - return null; - }, - [ isKeyUploading ] - ); - const getPushUploadMessage = useCallback( ( message: string, uploadPercentage: number | null ): string => { if ( uploadPercentage !== null ) { From 434606cc7b3c00e69f09fc71c961a837b209e50c Mon Sep 17 00:00:00 2001 From: Rahul Gavande Date: Tue, 6 Jan 2026 10:52:11 +0530 Subject: [PATCH 4/5] Refactor: Change exported functions to internal hook. --- src/hooks/use-sync-states-progress-info.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/hooks/use-sync-states-progress-info.ts b/src/hooks/use-sync-states-progress-info.ts index 7f24314e6c..8e9201cdf7 100644 --- a/src/hooks/use-sync-states-progress-info.ts +++ b/src/hooks/use-sync-states-progress-info.ts @@ -57,7 +57,7 @@ const DOWNLOADING_INITIAL_VALUE = 60; const IN_PROGRESS_TO_DOWNLOADING_STEP = DOWNLOADING_INITIAL_VALUE - IN_PROGRESS_INITIAL_VALUE; const PULL_IMPORTING_INITIAL_VALUE = 80; -export function isKeyPulling( key: PullStateProgressInfo[ 'key' ] | undefined ): boolean { +function isKeyPulling( key: PullStateProgressInfo[ 'key' ] | undefined ): boolean { const pullingStateKeys: PullStateProgressInfo[ 'key' ][] = [ 'in-progress', 'downloading', @@ -69,7 +69,7 @@ export function isKeyPulling( key: PullStateProgressInfo[ 'key' ] | undefined ): return pullingStateKeys.includes( key ); } -export function isKeyPushing( key: PushStateProgressInfo[ 'key' ] | undefined ): boolean { +function isKeyPushing( key: PushStateProgressInfo[ 'key' ] | undefined ): boolean { const pushingStateKeys: PushStateProgressInfo[ 'key' ][] = [ 'creatingBackup', 'uploading', @@ -83,15 +83,15 @@ export function isKeyPushing( key: PushStateProgressInfo[ 'key' ] | undefined ): return pushingStateKeys.includes( key ); } -export function isKeyUploadingPaused( key: PushStateProgressInfo[ 'key' ] | undefined ): boolean { +function isKeyUploadingPaused( key: PushStateProgressInfo[ 'key' ] | undefined ): boolean { return key === 'uploadingPaused'; } -export function isKeyUploading( key: PushStateProgressInfo[ 'key' ] | undefined ): boolean { +function isKeyUploading( key: PushStateProgressInfo[ 'key' ] | undefined ): boolean { return key === 'uploading'; } -export function isKeyImporting( key: PushStateProgressInfo[ 'key' ] | undefined ): boolean { +function isKeyImporting( key: PushStateProgressInfo[ 'key' ] | undefined ): boolean { const pushingStateKeys: PushStateProgressInfo[ 'key' ][] = [ 'creatingRemoteBackup', 'applyingChanges', @@ -103,25 +103,25 @@ export function isKeyImporting( key: PushStateProgressInfo[ 'key' ] | undefined return pushingStateKeys.includes( key ); } -export function isKeyFinished( +function isKeyFinished( key: PullStateProgressInfo[ 'key' ] | PushStateProgressInfo[ 'key' ] | undefined ): boolean { return key === 'finished'; } -export function isKeyFailed( +function isKeyFailed( key: PullStateProgressInfo[ 'key' ] | PushStateProgressInfo[ 'key' ] | undefined ): boolean { return key === 'failed'; } -export function isKeyCancelled( +function isKeyCancelled( key: PullStateProgressInfo[ 'key' ] | PushStateProgressInfo[ 'key' ] | undefined ): boolean { return key === 'cancelled'; } -export function getPushUploadPercentage( +function getPushUploadPercentage( statusKey: PushStateProgressInfo[ 'key' ] | undefined, uploadProgress: number | undefined ): number | null { From 9d16c4251c06627a5baff3f4a92635b5a1f77dfb Mon Sep 17 00:00:00 2001 From: Rahul Gavande Date: Tue, 6 Jan 2026 11:08:12 +0530 Subject: [PATCH 5/5] Centralize upload progress message formatting in hook --- src/hooks/use-sync-states-progress-info.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/hooks/use-sync-states-progress-info.ts b/src/hooks/use-sync-states-progress-info.ts index 8e9201cdf7..313cec11a4 100644 --- a/src/hooks/use-sync-states-progress-info.ts +++ b/src/hooks/use-sync-states-progress-info.ts @@ -219,6 +219,8 @@ export function useSyncStatesProgressInfo() { } as const satisfies PushStateProgressInfoValues; }, [ __ ] ); + const uploadingProgressMessageTemplate = useMemo( () => __( 'Uploading site (%d%%)…' ), [ __ ] ); + const getBackupStatusWithProgress = useCallback( ( hasBackupCompleted: boolean, @@ -311,11 +313,11 @@ export function useSyncStatesProgressInfo() { ( message: string, uploadPercentage: number | null ): string => { if ( uploadPercentage !== null ) { // translators: %d is the upload progress percentage - return sprintf( __( 'Uploading site (%d%%)…' ), uploadPercentage ); + return sprintf( uploadingProgressMessageTemplate, uploadPercentage ); } return message; }, - [ __ ] + [ uploadingProgressMessageTemplate ] ); const mapUploadProgressToOverallProgress = useCallback(