forked from OKEAMAH/jetpack
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Social: Add share status info (Automattic#39073)
* Create REST endpoint * Add share status logic to the store * Update dependencies * Show share status * Add changelog * Fix button size * Fix up versions * @wordpress/* packages are a nightmare to work with TypeScript * Handle the case when all the connections are disabled and the post is not shared to any connection * Add a message when there is timeout * Fix typo * Make use of usePostMeta
- Loading branch information
1 parent
5281706
commit 9462203
Showing
19 changed files
with
346 additions
and
8 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
4 changes: 4 additions & 0 deletions
4
projects/js-packages/publicize-components/changelog/add-social-share-status-info
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
Significance: patch | ||
Type: added | ||
|
||
Added share status info to Jetpack sidebar |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
18 changes: 13 additions & 5 deletions
18
projects/js-packages/publicize-components/src/components/post-publish-share-status/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,29 +1,37 @@ | ||
import { useSelect } from '@wordpress/data'; | ||
import { PluginPostPublishPanel } from '@wordpress/edit-post'; | ||
import { store as editorStore } from '@wordpress/editor'; | ||
import { usePostMeta } from '../../hooks/use-post-meta'; | ||
import { store as socialStore } from '../../social-store'; | ||
import { ShareStatusModal } from '../share-status-modal'; | ||
import { ShareStatus } from './share-status'; | ||
|
||
/** | ||
* Post publish share status component. | ||
* | ||
* @return {import('react').ReactNode} - Post publish share status component. | ||
*/ | ||
export function PostPublishShareStatus() { | ||
const { featureFlags } = useSelect( select => { | ||
const { isPublicizeEnabled: willPostBeShared } = usePostMeta(); | ||
const { featureFlags, postId, isPostPublised } = useSelect( select => { | ||
const store = select( socialStore ); | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- `@wordpress/editor` is a nightmare to work with TypeScript | ||
const _editorStore = select( editorStore ) as any; | ||
|
||
return { | ||
featureFlags: store.featureFlags(), | ||
postId: _editorStore.getCurrentPostId(), | ||
isPostPublised: _editorStore.isCurrentPostPublished(), | ||
}; | ||
}, [] ); | ||
|
||
if ( ! featureFlags.useShareStatus ) { | ||
if ( ! featureFlags.useShareStatus || ! willPostBeShared || ! isPostPublised ) { | ||
return null; | ||
} | ||
|
||
return ( | ||
<PluginPostPublishPanel id="publicize-share-status"> | ||
Your post was successfully shared in 4 connections. | ||
<ShareStatusModal /> | ||
<ShareStatus postId={ postId } /> | ||
</PluginPostPublishPanel> | ||
); | ||
} |
122 changes: 122 additions & 0 deletions
122
...s-packages/publicize-components/src/components/post-publish-share-status/share-status.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
import { Button } from '@automattic/jetpack-components'; | ||
import { Spinner } from '@wordpress/components'; | ||
import { useDispatch, useSelect } from '@wordpress/data'; | ||
import { getDate, isInTheFuture } from '@wordpress/date'; | ||
import { store as editorStore } from '@wordpress/editor'; | ||
import { useEffect } from '@wordpress/element'; | ||
import { __, _n, sprintf } from '@wordpress/i18n'; | ||
import { store as socialStore } from '../../social-store'; | ||
import Notice from '../notice'; | ||
import { ShareStatusModal } from '../share-status-modal'; | ||
import styles from './styles.module.scss'; | ||
|
||
export type ShareStatusProps = { | ||
postId: number; | ||
}; | ||
|
||
const ONE_MINUTE_IN_MS = 60 * 1000; | ||
|
||
/** | ||
* Share status component. | ||
* | ||
* @param {ShareStatusProps} props - Component props. | ||
* | ||
* @return {import('react').ReactNode} - Share status UI. | ||
*/ | ||
export function ShareStatus( { postId }: ShareStatusProps ) { | ||
const shareStatus = useSelect( | ||
select => select( socialStore ).getPostShareStatus( postId ), | ||
[ postId ] | ||
); | ||
|
||
// Whether the post has been published more than one minute ago. | ||
const hasBeenMoreThanOneMinute = useSelect( select => { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- `@wordpress/editor` is a nightmare to work with TypeScript | ||
const date = ( select( editorStore ) as any ).getEditedPostAttribute( 'date' ); | ||
|
||
const oneMinuteAfterPostDate = new Date( Number( getDate( date ) ) + ONE_MINUTE_IN_MS ); | ||
|
||
// @ts-expect-error isInTheFuture is typed incorrectly as it should accept a Date object apart from a string. | ||
return ! isInTheFuture( oneMinuteAfterPostDate ); | ||
}, [] ); | ||
|
||
// @ts-expect-error `invalidateResolution` exists in every store | ||
const { invalidateResolution } = useDispatch( socialStore ); | ||
|
||
useEffect( () => { | ||
if ( ! hasBeenMoreThanOneMinute && ! shareStatus.loading && ! shareStatus.done ) { | ||
// Fire the next request as soon as the previous one is done but we are not done yet. | ||
invalidateResolution( 'getPostShareStatus', [ postId ] ); | ||
} | ||
}, [ | ||
hasBeenMoreThanOneMinute, | ||
invalidateResolution, | ||
postId, | ||
shareStatus.loading, | ||
shareStatus.done, | ||
] ); | ||
|
||
if ( shareStatus.loading ) { | ||
return ( | ||
<div className={ styles[ 'loading-block' ] }> | ||
<Spinner /> | ||
<span className={ styles[ 'loading-text' ] }> | ||
{ __( 'Sharing to your social media…', 'jetpack' ) } | ||
</span> | ||
</div> | ||
); | ||
} | ||
|
||
const numberOfFailedShares = shareStatus.shares.filter( | ||
share => share.status === 'failure' | ||
).length; | ||
|
||
if ( numberOfFailedShares > 0 ) { | ||
return ( | ||
<Notice type="warning"> | ||
<p> | ||
{ sprintf( | ||
/* translators: %d: number of failed shares */ | ||
_n( | ||
'Your post was unable to be shared to %d connection.', | ||
'Your post was unable to be shared to %d connections.', | ||
numberOfFailedShares, | ||
'jetpack' | ||
), | ||
numberOfFailedShares | ||
) } | ||
</p> | ||
<Button variant="link" size="small"> | ||
{ __( 'Review status and try again', 'jetpack' ) } | ||
</Button> | ||
</Notice> | ||
); | ||
} | ||
|
||
if ( ! shareStatus.done ) { | ||
return <span>{ __( 'The request to share your post is still in progress.', 'jetpack' ) }</span>; | ||
} | ||
|
||
if ( ! shareStatus.shares.length ) { | ||
return <span>{ __( 'Your post was not shared.', 'jetpack' ) }</span>; | ||
} | ||
|
||
return ( | ||
<> | ||
<b>{ __( 'Your post was shared.', 'jetpack' ) }</b> { '🎉' } | ||
<p> | ||
{ sprintf( | ||
/* translators: %d: number of connections to which a post was shared */ | ||
_n( | ||
'You post was successfuly shared to %d connection.', | ||
'You post was successfuly shared to %d connections.', | ||
shareStatus.shares.length, | ||
'jetpack' | ||
), | ||
shareStatus.shares.length | ||
) } | ||
</p> | ||
<ShareStatusModal /> | ||
</> | ||
); | ||
} |
12 changes: 12 additions & 0 deletions
12
...packages/publicize-components/src/components/post-publish-share-status/styles.module.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
.loading-block { | ||
display: flex; | ||
align-items: center; | ||
|
||
:global(.components-spinner) { | ||
margin-top: 0px; | ||
} | ||
} | ||
|
||
.loading-text { | ||
color: var(--jp-gray-40); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 2 additions & 0 deletions
2
projects/js-packages/publicize-components/src/social-store/actions/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
37 changes: 37 additions & 0 deletions
37
projects/js-packages/publicize-components/src/social-store/actions/share-status.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { SocialStoreState } from '../types'; | ||
import { FETCH_POST_SHARE_STATUS, RECEIVE_POST_SHARE_STATUS } from './constants'; | ||
|
||
/** | ||
* Returns an action object used in signalling that the post share status | ||
* has been requested and is loading. | ||
* | ||
* @param {number} postId - Post ID. | ||
* @param {boolean} [loading] - Loading status. | ||
* @return {object} Action object. | ||
*/ | ||
export function fetchPostShareStatus( postId: number, loading = true ) { | ||
return { | ||
type: FETCH_POST_SHARE_STATUS, | ||
postId, | ||
loading, | ||
}; | ||
} | ||
|
||
/** | ||
* Returns an action object used in signalling that the post share status has been received. | ||
* | ||
* @param {SocialStoreState[ 'shareStaus' ][ number ]} shareStatus - Post share status. | ||
* @param {number} postId - Post ID. | ||
* | ||
* @return {object} Action object. | ||
*/ | ||
export function receivePostShareStaus( | ||
shareStatus: SocialStoreState[ 'shareStatus' ][ number ], | ||
postId: number | ||
) { | ||
return { | ||
type: RECEIVE_POST_SHARE_STATUS, | ||
shareStatus, | ||
postId, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
42 changes: 42 additions & 0 deletions
42
projects/js-packages/publicize-components/src/social-store/reducer/share-status.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { FETCH_POST_SHARE_STATUS, RECEIVE_POST_SHARE_STATUS } from '../actions/constants'; | ||
import { fetchPostShareStatus, receivePostShareStaus } from '../actions/share-status'; | ||
import { SocialStoreState } from '../types'; | ||
|
||
type Action = | ||
| ReturnType< typeof fetchPostShareStatus | typeof receivePostShareStaus > | ||
| { type: 'default' }; | ||
|
||
/** | ||
* Connection data reducer | ||
* | ||
* @param {SocialStoreState['shareStaus']} state - State object. | ||
* @param {Action} action - Action object. | ||
* | ||
* @return {SocialStoreState['shareStaus']} - The updated state. | ||
*/ | ||
export function shareStatus( | ||
state: SocialStoreState[ 'shareStatus' ] = {}, | ||
action: Action | ||
): SocialStoreState[ 'shareStatus' ] { | ||
switch ( action.type ) { | ||
case FETCH_POST_SHARE_STATUS: | ||
return { | ||
...state, | ||
[ action.postId ]: { | ||
shares: [], | ||
...state?.[ action.postId ], | ||
loading: action.loading ?? true, | ||
}, | ||
}; | ||
case RECEIVE_POST_SHARE_STATUS: | ||
return { | ||
...state, | ||
[ action.postId ]: { | ||
...action.shareStatus, | ||
loading: false, | ||
}, | ||
}; | ||
} | ||
|
||
return state; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.