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 ) => {