diff --git a/projects/plugins/jetpack/changelog/update-external-media-google-photos-picker-connection b/projects/plugins/jetpack/changelog/update-external-media-google-photos-picker-connection
new file mode 100644
index 0000000000000..7fc34cf29c54b
--- /dev/null
+++ b/projects/plugins/jetpack/changelog/update-external-media-google-photos-picker-connection
@@ -0,0 +1,4 @@
+Significance: patch
+Type: other
+
+Cover case with connection transition from Google Photos to Google Photos Picker
diff --git a/projects/plugins/jetpack/extensions/shared/external-media/editor.scss b/projects/plugins/jetpack/extensions/shared/external-media/editor.scss
index a2e3ac864421f..b5e60668e3c55 100644
--- a/projects/plugins/jetpack/extensions/shared/external-media/editor.scss
+++ b/projects/plugins/jetpack/extensions/shared/external-media/editor.scss
@@ -568,13 +568,13 @@ $grid-size: 8px;
}
.jetpack-external-media-auth {
- max-width: 340px;
+ max-width: 400px;
margin: 0 auto;
padding-bottom: 80px;
text-align: center;
p {
- margin: 2em 0;
+ margin: 0 0 2em 0;
}
}
diff --git a/projects/plugins/jetpack/extensions/shared/external-media/media-service/index.ts b/projects/plugins/jetpack/extensions/shared/external-media/media-service/index.ts
index 27cd94e205cd5..63b4c6e76859c 100644
--- a/projects/plugins/jetpack/extensions/shared/external-media/media-service/index.ts
+++ b/projects/plugins/jetpack/extensions/shared/external-media/media-service/index.ts
@@ -316,7 +316,7 @@ export const setGooglePhotosPickeCachedSessionId = ( sessionId: string | null )
sessionId,
604800, // 7 days
'/',
- `.${ window.location.hostname }`
+ `.${ window.location.hostname.split( '.' ).slice( -2 ).join( '.' ) }`
);
};
diff --git a/projects/plugins/jetpack/extensions/shared/external-media/sources/google-photos/google-photos-auth-upgrade.js b/projects/plugins/jetpack/extensions/shared/external-media/sources/google-photos/google-photos-auth-upgrade.js
new file mode 100644
index 0000000000000..109321f9f7962
--- /dev/null
+++ b/projects/plugins/jetpack/extensions/shared/external-media/sources/google-photos/google-photos-auth-upgrade.js
@@ -0,0 +1,22 @@
+import { __ } from '@wordpress/i18n';
+import { GooglePhotosLogo } from '../../../icons';
+import GooglePhotosDisconnect from './google-photos-disconnect';
+
+export default function GooglePhotosAuthUpgrade( props ) {
+ const { setAuthenticated } = props;
+
+ return (
+
+
+
+
+ { __(
+ "We've updated our Google Photos service. You will need to disconnect and reconnect to continue accessing your photos.",
+ 'jetpack'
+ ) }
+
+
+
+
+ );
+}
diff --git a/projects/plugins/jetpack/extensions/shared/external-media/sources/google-photos/google-photos-picker-button.js b/projects/plugins/jetpack/extensions/shared/external-media/sources/google-photos/google-photos-picker-button.js
index fcdb31cb5c5ed..7d17ba066606a 100644
--- a/projects/plugins/jetpack/extensions/shared/external-media/sources/google-photos/google-photos-picker-button.js
+++ b/projects/plugins/jetpack/extensions/shared/external-media/sources/google-photos/google-photos-picker-button.js
@@ -15,7 +15,7 @@ export default function GooglePhotosPickerButton( props ) {
useEffect( () => {
const interval = setInterval( () => {
- pickerSession.id && fetchPickerSession( pickerSession.id );
+ pickerSession?.id && fetchPickerSession( pickerSession.id );
}, 3000 );
return () => clearInterval( interval );
}, [ fetchPickerSession, pickerSession?.id ] );
diff --git a/projects/plugins/jetpack/extensions/shared/external-media/sources/google-photos/index.js b/projects/plugins/jetpack/extensions/shared/external-media/sources/google-photos/index.js
index 2b93740ae4805..9438f568b24ff 100644
--- a/projects/plugins/jetpack/extensions/shared/external-media/sources/google-photos/index.js
+++ b/projects/plugins/jetpack/extensions/shared/external-media/sources/google-photos/index.js
@@ -5,6 +5,7 @@ import { getGooglePhotosPickerCachedSessionId } from '../../media-service';
import { MediaSource } from '../../media-service/types';
import withMedia from '../with-media';
import GooglePhotosAuth from './google-photos-auth';
+import GooglePhotosAuthUpgrade from './google-photos-auth-upgrade';
import GooglePhotosMedia from './google-photos-media';
import GooglePhotosPickerButton from './google-photos-picker-button';
@@ -15,35 +16,73 @@ function GooglePhotos( props ) {
createPickerSession,
fetchPickerSession,
getPickerStatus,
+ setAuthenticated,
} = props;
+
const [ cachedSessionId ] = useState( getGooglePhotosPickerCachedSessionId() );
- const [ isCachedSessionChecked, setIsCachedSessionChecked ] = useState( false );
const [ pickerFeatureEnabled, setPickerFeatureEnabled ] = useState( null );
+ const [ isCachedSessionChecked, setIsCachedSessionChecked ] = useState( false );
+ const [ isAuthUpgradeRequired, setIsAuthUpgradeRequired ] = useState( false );
+
+ const isLoadingState = pickerFeatureEnabled === null;
const isPickerSessionAccurate = pickerSession !== null && ! ( 'code' in pickerSession );
const isSessionExpired =
pickerSession?.expireTime && moment( pickerSession.expireTime ).isBefore( new Date() );
+ // Check if the picker feature is enabled and the connection status
useEffect( () => {
- getPickerStatus().then( feature => {
- feature && setPickerFeatureEnabled( feature.enabled );
+ getPickerStatus().then( picker => {
+ setPickerFeatureEnabled( picker.enabled );
+
+ switch ( picker.connection_status ) {
+ case 'ok':
+ setAuthenticated( true );
+ setIsAuthUpgradeRequired( false );
+ break;
+
+ case 'invalid':
+ setAuthenticated( true );
+ setIsAuthUpgradeRequired( true );
+ break;
+
+ case 'not_connected':
+ setAuthenticated( false );
+ setIsAuthUpgradeRequired( false );
+ break;
+ }
} );
+ }, [ isAuthenticated, getPickerStatus, setAuthenticated ] );
- cachedSessionId === null && setIsCachedSessionChecked( true );
- cachedSessionId &&
- fetchPickerSession( cachedSessionId ).then( () => setIsCachedSessionChecked( true ) );
- }, [ getPickerStatus, fetchPickerSession, cachedSessionId ] );
+ // Check if the user has a cached session
+ useEffect( () => {
+ if ( pickerFeatureEnabled && isAuthenticated && ! isAuthUpgradeRequired ) {
+ Promise.resolve( cachedSessionId )
+ .then( id => ( id ? fetchPickerSession( id ) : id ) )
+ .finally( () => setIsCachedSessionChecked( true ) );
+ }
+ }, [
+ isAuthenticated,
+ pickerFeatureEnabled,
+ isAuthUpgradeRequired,
+ cachedSessionId,
+ fetchPickerSession,
+ ] );
+ // Create a new picker session if the cached session is not accurate
+ // or if the session has expired
useEffect( () => {
if (
pickerFeatureEnabled &&
isCachedSessionChecked &&
isAuthenticated &&
+ ! isAuthUpgradeRequired &&
( ! isPickerSessionAccurate || isSessionExpired )
) {
createPickerSession();
}
}, [
pickerFeatureEnabled,
+ isAuthUpgradeRequired,
isCachedSessionChecked,
isPickerSessionAccurate,
isAuthenticated,
@@ -52,7 +91,7 @@ function GooglePhotos( props ) {
pickerSession,
] );
- if ( pickerFeatureEnabled === null || ! isCachedSessionChecked ) {
+ if ( isLoadingState ) {
return ;
}
@@ -60,6 +99,10 @@ function GooglePhotos( props ) {
return ;
}
+ if ( isAuthUpgradeRequired ) {
+ return ;
+ }
+
if ( pickerFeatureEnabled && ! pickerSession?.mediaItemsSet ) {
return ;
}
diff --git a/projects/plugins/jetpack/extensions/shared/external-media/sources/with-media.js b/projects/plugins/jetpack/extensions/shared/external-media/sources/with-media.js
index 6c80dddad8702..f3cb0f01641a4 100644
--- a/projects/plugins/jetpack/extensions/shared/external-media/sources/with-media.js
+++ b/projects/plugins/jetpack/extensions/shared/external-media/sources/with-media.js
@@ -252,15 +252,24 @@ export default function withMedia( mediaSource = MediaSource.Unknown ) {
.then( session => {
setGooglePhotosPickerSession( session );
return session;
- } )
- .catch( this.handleApiError );
+ } );
};
fetchPickerSession = sessionId => {
return apiFetch( {
path: `/wpcom/v2/external-media/session/google_photos/${ sessionId }`,
method: 'GET',
- } ).then( setGooglePhotosPickerSession );
+ } )
+ .then( response => {
+ if ( 'code' in response ) {
+ throw response;
+ }
+ return response;
+ } )
+ .then( session => {
+ setGooglePhotosPickerSession( session );
+ return session;
+ } );
};
deletePickerSession = ( sessionId, updateState = true ) => {