Skip to content

Commit

Permalink
Social | Fix reconnection for broken Bluesky connections (#39844)
Browse files Browse the repository at this point in the history
  • Loading branch information
manzoorwanijk authored Oct 22, 2024
1 parent 1527079 commit f401cfb
Show file tree
Hide file tree
Showing 11 changed files with 73 additions and 22 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: fixed

Fixed reconnection for broken Bluesky connections
Original file line number Diff line number Diff line change
Expand Up @@ -58,20 +58,27 @@ export function Reconnect( { connection, service, variant = 'link' }: ReconnectP
return;
}

await setReconnectingAccount(
// Join service name and external ID
// just in case the external ID alone is not unique.
`${ connection.service_name }:${ connection.external_id }`
);
await setReconnectingAccount( connection );

const formData = new FormData();

if ( service.ID === 'mastodon' ) {
formData.set( 'instance', connection.external_display );
}

requestAccess( formData );
}, [ connection, deleteConnectionById, requestAccess, service.ID, setReconnectingAccount ] );
if ( service.ID === 'bluesky' ) {
openConnectionsModal();
} else {
requestAccess( formData );
}
}, [
connection,
deleteConnectionById,
openConnectionsModal,
requestAccess,
service.ID,
setReconnectingAccount,
] );

if ( ! connection.can_disconnect ) {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export function ConfirmationForm( { keyringResult, onComplete, isAdmin }: Confir
// If user account is supported, add it to the list
if ( ! service.external_users_only ) {
options.push( {
label: keyringResult.external_display,
label: keyringResult.external_display || keyringResult.external_name,
value: keyringResult.external_ID,
profile_picture: keyringResult.external_profile_picture,
} );
Expand Down Expand Up @@ -150,7 +150,7 @@ export function ConfirmationForm( { keyringResult, onComplete, isAdmin }: Confir
);

if ( reconnectingAccount ) {
setReconnectingAccount( '' );
setReconnectingAccount( undefined );
}

// Do not await the connection creation to unblock the UI
Expand Down Expand Up @@ -215,7 +215,8 @@ export function ConfirmationForm( { keyringResult, onComplete, isAdmin }: Confir
// If we are reconnecting an account, preselect it,
// otherwise, preselect the first account
const defaultChecked = reconnectingAccount
? reconnectingAccount === `${ service?.ID }:${ option.value }`
? reconnectingAccount.service_name === service?.ID &&
reconnectingAccount.external_id === option.value
: index === 0;

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,15 @@ export const ManageConnectionsModal = () => {
};
}, [] );

const { setKeyringResult, closeConnectionsModal } = useDispatch( store );
const { setKeyringResult, closeConnectionsModal, setReconnectingAccount } = useDispatch( store );

const [ isSmall ] = useBreakpointMatch( 'sm' );

const closeModal = useCallback( () => {
setKeyringResult( null );
setReconnectingAccount( undefined );
closeConnectionsModal();
}, [ closeConnectionsModal, setKeyringResult ] );
}, [ closeConnectionsModal, setKeyringResult, setReconnectingAccount ] );

const hasKeyringResult = Boolean( keyringResult?.ID );

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { Alert } from '@automattic/jetpack-components';
import { ExternalLink } from '@wordpress/components';
import { useSelect } from '@wordpress/data';
import { createInterpolateElement, useId } from '@wordpress/element';
import { __, _x } from '@wordpress/i18n';
import { store } from '../../social-store';
import { SupportedService } from '../services/use-supported-services';
import styles from './style.module.scss';

Expand All @@ -17,6 +20,8 @@ type CustomInputsProps = {
export function CustomInputs( { service }: CustomInputsProps ) {
const id = useId();

const reconnectingAccount = useSelect( select => select( store ).getReconnectingAccount(), [] );

if ( 'mastodon' === service.ID ) {
return (
<div className={ styles[ 'fields-item' ] }>
Expand Down Expand Up @@ -58,6 +63,11 @@ export function CustomInputs( { service }: CustomInputsProps ) {
required
type="text"
name="handle"
defaultValue={
reconnectingAccount?.service_name === 'bluesky'
? reconnectingAccount?.external_name
: undefined
}
autoComplete="off"
autoCapitalize="off"
autoCorrect="off"
Expand Down Expand Up @@ -93,6 +103,11 @@ export function CustomInputs( { service }: CustomInputsProps ) {
aria-describedby={ `${ id }-password-description` }
placeholder={ 'xxxx-xxxx-xxxx-xxxx' }
/>
{ reconnectingAccount?.service_name === 'bluesky' && (
<Alert level="error" showIcon={ false }>
{ __( 'Please provide an app password to fix the connection.', 'jetpack' ) }
</Alert>
) }
</div>
</>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { Button, useBreakpointMatch } from '@automattic/jetpack-components';
import { Panel, PanelBody } from '@wordpress/components';
import { useReducer } from '@wordpress/element';
import { useEffect, useReducer, useRef } from '@wordpress/element';
import { __, _x } from '@wordpress/i18n';
import { Icon, chevronDown, chevronUp } from '@wordpress/icons';
import { ConnectForm } from './connect-form';
import { ServiceItemDetails, ServicesItemDetailsProps } from './service-item-details';
import { ServiceStatus } from './service-status';
import styles from './style.module.scss';

export type ServicesItemProps = ServicesItemDetailsProps;
export type ServicesItemProps = ServicesItemDetailsProps & {
isPanelDefaultOpen?: boolean;
};

/**
* Service item component
Expand All @@ -17,10 +19,22 @@ export type ServicesItemProps = ServicesItemDetailsProps;
*
* @return {import('react').ReactNode} Service item component
*/
export function ServiceItem( { service, serviceConnections }: ServicesItemProps ) {
export function ServiceItem( {
service,
serviceConnections,
isPanelDefaultOpen,
}: ServicesItemProps ) {
const [ isSmall ] = useBreakpointMatch( 'sm' );

const [ isPanelOpen, togglePanel ] = useReducer( state => ! state, false );
const [ isPanelOpen, togglePanel ] = useReducer( state => ! state, isPanelDefaultOpen );
const panelRef = useRef< HTMLDivElement >( null );

useEffect( () => {
if ( isPanelDefaultOpen ) {
panelRef.current?.scrollIntoView( { block: 'center', behavior: 'smooth' } );
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [] );

const areCustomInputsVisible = isPanelOpen && service.needsCustomInputs;

Expand Down Expand Up @@ -94,7 +108,7 @@ export function ServiceItem( { service, serviceConnections }: ServicesItemProps
</div>
</div>

<Panel className={ styles[ 'service-panel' ] }>
<Panel className={ styles[ 'service-panel' ] } ref={ panelRef }>
<PanelBody opened={ isPanelOpen } onToggle={ togglePanel }>
<ServiceItemDetails service={ service } serviceConnections={ serviceConnections } />
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,17 @@ export function ServicesList() {
}, {} );
}, [] );

const reconnectingAccount = useSelect( select => select( store ).getReconnectingAccount(), [] );

return (
<ul className={ styles.services }>
{ supportedServices.map( service => (
<li key={ service.ID } className={ styles[ 'service-list-item' ] }>
<ServiceItem service={ service } serviceConnections={ connections[ service.ID ] || [] } />
<ServiceItem
service={ service }
serviceConnections={ connections[ service.ID ] || [] }
isPanelDefaultOpen={ reconnectingAccount?.service_name === service.ID }
/>
</li>
) ) }
</ul>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,10 @@ export function useRequestAccess( { service, onConfirm }: RequestAccessOptions )
}

url.searchParams.set( 'handle', handle );
url.searchParams.set( 'app_password', formData.get( 'app_password' ).toString().trim() );
url.searchParams.set(
'app_password',
( formData.get( 'app_password' )?.toString() || '' ).trim()
);
break;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ export function updatingConnection( connectionId, updating = true ) {
/**
* Sets the reconnecting account.
*
* @param {string} reconnectingAccount - Account being reconnected.
* @param {import('../types').Connection} reconnectingAccount - Account being reconnected.
*
* @return {object} Reconnecting account action.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ export function getUpdatingConnections( state ) {
* @return {import("../types").ConnectionData['reconnectingAccount']} The account being reconnected.
*/
export function getReconnectingAccount( state ) {
return state.connectionData?.reconnectingAccount ?? '';
return state.connectionData?.reconnectingAccount;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export type ConnectionData = {
connections: Connection[];
deletingConnections?: Array< number | string >;
updatingConnections?: Array< number | string >;
reconnectingAccount?: string;
reconnectingAccount?: Connection;
keyringResult?: KeyringResult;
};

Expand Down

0 comments on commit f401cfb

Please sign in to comment.