Skip to content

Commit

Permalink
Fix Jetpack Social pre publish UI (#34243)
Browse files Browse the repository at this point in the history
* Create usePostMeta hook to make the data reactive

* Remove the utils as well as the tests

* Update consumer components to use usePostMeta

* Add tests to usePostMeta

* Add changelog

* Fix up versions

* Fix import
  • Loading branch information
manzoorwanijk authored Nov 23, 2023
1 parent cf472d9 commit d790023
Show file tree
Hide file tree
Showing 35 changed files with 437 additions and 635 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: fixed

Fixed pre-publish UI reactivity for Jetpack Social
2 changes: 1 addition & 1 deletion projects/js-packages/publicize-components/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"private": true,
"name": "@automattic/jetpack-publicize-components",
"version": "0.41.6",
"version": "0.41.7-alpha",
"description": "A library of JS components required by the Publicize editor plugin",
"homepage": "https://github.com/Automattic/jetpack/tree/HEAD/projects/js-packages/publicize-components/#readme",
"bugs": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,30 @@
import { useSelect } from '@wordpress/data';
import { useCallback } from '@wordpress/element';
import { getShareMessage } from '../../utils';
import { usePostMeta } from '../../utils';

/**
* Prepares the text to share.
*
* @returns {(textWithPlaceholders: string, isUrl: boolean) => string} A function that accepts the text with placeholders and returns the text with the placeholders replaced.
*/
export function useShareButtonText() {
const { message, link } = useSelect( select => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const getEditedPostAttribute = ( select( 'core/editor' ) as any )
.getEditedPostAttribute satisfies ( attribute: string ) => unknown;
const { shareMessage } = usePostMeta();
const { message, link } = useSelect(
select => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const getEditedPostAttribute = ( select( 'core/editor' ) as any )
.getEditedPostAttribute satisfies ( attribute: string ) => unknown;

return {
link: getEditedPostAttribute( 'link' ),
message:
getShareMessage() ||
getEditedPostAttribute( 'meta' )?.jetpack_seo_html_title ||
getEditedPostAttribute( 'title' ),
};
}, [] );
return {
link: getEditedPostAttribute( 'link' ),
message:
shareMessage ||
getEditedPostAttribute( 'meta' )?.jetpack_seo_html_title ||
getEditedPostAttribute( 'title' ),
};
},
[ shareMessage ]
);

return useCallback(
( textWithPlaceholders: string, isUrl = true ) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useSelect } from '@wordpress/data';
import { decodeEntities } from '@wordpress/html-entities';
import useSocialMediaMessage from '../../hooks/use-social-media-message';
import { SOCIAL_STORE_ID, CONNECTION_SERVICE_MASTODON } from '../../social-store';
import { shouldUploadAttachedMedia } from '../../utils';
import { usePostMeta } from '../../utils';

const MastodonPreview = props => {
const { message } = useSocialMediaMessage();
Expand All @@ -16,7 +16,7 @@ const MastodonPreview = props => {
siteName: decodeEntities( getSite().title ),
};
} );
const isSocialPost = shouldUploadAttachedMedia();
const { shouldUploadAttachedMedia: isSocialPost } = usePostMeta();

const user = useSelect( select => {
const {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,16 @@
* Shows individual previews in modal window.
*/

import { Modal, TabPanel, Button } from '@wordpress/components';
import { withSelect } from '@wordpress/data';
import { Button, Modal, TabPanel } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { close } from '@wordpress/icons';
import {
getAttachedMedia,
getImageGeneratorPostSettings,
shouldUploadAttachedMedia,
} from '../../utils';
import { getSigImageUrl } from '../generated-image-preview/utils';
import { useAvailableSerivces } from './useAvailableServices';
import { getMediaSourceUrl } from './utils';
import { useAvailableSerivces } from './use-available-services';
import { usePostData } from './use-post-data';
import './modal.scss';

const SocialPreviewsModal = function SocialPreviewsModal( {
onClose,
image,
media,
title,
description,
url,
initialTabName,
} ) {
const SocialPreviewsModal = function SocialPreviewsModal( { onClose, initialTabName } ) {
const availableServices = useAvailableSerivces();
const { image, media, title, description, url } = usePostData();

return (
<Modal
Expand Down Expand Up @@ -63,85 +49,4 @@ const SocialPreviewsModal = function SocialPreviewsModal( {
);
};

export default withSelect( select => {
const { getMedia } = select( 'core' );
const { getEditedPostAttribute } = select( 'core/editor' );

const featuredImageId = getEditedPostAttribute( 'featured_media' );

// Use the featured image by default, if it's available.
let image = featuredImageId ? getMediaSourceUrl( getMedia( featuredImageId ) ) : '';

const sigSettings = getImageGeneratorPostSettings();

const sigImageUrl = sigSettings.enabled ? getSigImageUrl( sigSettings.token ) : '';

const attachedMedia = getAttachedMedia();

// If we have a SIG token, use it to generate the image URL.
if ( sigImageUrl ) {
image = sigImageUrl;
} else if ( attachedMedia?.[ 0 ]?.id ) {
// If we don't have a SIG image, use the first image in the attached media.
const [ firstMedia ] = attachedMedia;
const isImage = firstMedia.id
? getMedia( firstMedia.id )?.mime_type?.startsWith( 'image/' )
: false;

if ( isImage && firstMedia.url ) {
image = firstMedia.url;
}
}

const media = [];

// Attach media only if "Share as a social post" option is enabled.
if ( shouldUploadAttachedMedia() ) {
if ( sigImageUrl ) {
media.push( {
type: 'image/jpeg',
url: sigImageUrl,
alt: '',
} );
} else {
const getMediaDetails = id => {
const mediaItem = getMedia( id );
if ( ! mediaItem ) {
return null;
}
return {
type: mediaItem.mime_type,
url: getMediaSourceUrl( mediaItem ),
alt: mediaItem.alt_text,
};
};

for ( const { id } of attachedMedia ) {
const mediaDetails = getMediaDetails( id );
if ( mediaDetails ) {
media.push( mediaDetails );
}
}
if ( 0 === media.length && featuredImageId ) {
const mediaDetails = getMediaDetails( featuredImageId );
if ( mediaDetails ) {
media.push( mediaDetails );
}
}
}
}

return {
title:
getEditedPostAttribute( 'meta' )?.jetpack_seo_html_title || getEditedPostAttribute( 'title' ),
description:
getEditedPostAttribute( 'meta' )?.advanced_seo_description ||
getEditedPostAttribute( 'excerpt' ) ||
getEditedPostAttribute( 'content' ).split( '<!--more' )[ 0 ] ||
__( 'Visit the post for more.', 'jetpack' ),
url: getEditedPostAttribute( 'link' ),
image,
media,
initialTabName: null,
};
} )( SocialPreviewsModal );
export default SocialPreviewsModal;
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import { Button } from '@wordpress/components';
import { __, _x } from '@wordpress/i18n';
import { useAvailableSerivces } from './useAvailableServices';
import { useAvailableSerivces } from './use-available-services';
import './panel.scss';

const SocialPreviewsPanel = ( { openModal } ) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { TwitterPreviews } from '@automattic/social-previews';
import { useSelect } from '@wordpress/data';
import React from 'react';
import { SOCIAL_STORE_ID, CONNECTION_SERVICE_TWITTER } from '../../social-store';
import { getShareMessage } from '../../utils';
import { usePostMeta } from '../../utils';

/**
* The twitter tab component.
Expand All @@ -16,6 +16,8 @@ import { getShareMessage } from '../../utils';
* @returns {React.ReactNode} The twitter tab component.
*/
function Twitter( { title, description, image, url, media } ) {
const { shareMessage } = usePostMeta();

const tweets = useSelect(
select => {
const {
Expand All @@ -29,7 +31,7 @@ function Twitter( { title, description, image, url, media } ) {
name,
profileImage,
screenName,
text: getShareMessage() + ( media.length ? ` ${ url }` : '' ),
text: shareMessage + ( media.length ? ` ${ url }` : '' ),
cardType: image ? 'summary_large_image' : 'summary',
title,
description,
Expand All @@ -39,7 +41,7 @@ function Twitter( { title, description, image, url, media } ) {
},
];
},
[ title, image, description, media, url ]
[ title, image, description, media, url, shareMessage ]
);

return <TwitterPreviews tweets={ tweets } hidePostPreview />;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { useSelect } from '@wordpress/data';
import { __ } from '@wordpress/i18n';
import { usePostMeta } from '../../utils';
import { getSigImageUrl } from '../generated-image-preview/utils';
import { getMediaSourceUrl } from './utils';

/**
* Returns the post data.
*
* @returns {object} The post data.
*/
export function usePostData() {
const { attachedMedia, imageGeneratorSettings, shouldUploadAttachedMedia } = usePostMeta();

return useSelect(
select => {
const { getMedia } = select( 'core' );
const { getEditedPostAttribute } = select( 'core/editor' );

const featuredImageId = getEditedPostAttribute( 'featured_media' );

// Use the featured image by default, if it's available.
let image = featuredImageId ? getMediaSourceUrl( getMedia( featuredImageId ) ) : '';

const sigImageUrl = imageGeneratorSettings.enabled
? getSigImageUrl( imageGeneratorSettings.token )
: '';
// If we have a SIG token, use it to generate the image URL.
if ( sigImageUrl ) {
image = sigImageUrl;
} else if ( attachedMedia?.[ 0 ]?.id ) {
// If we don't have a SIG image, use the first image in the attached media.
const [ firstMedia ] = attachedMedia;
const isImage = firstMedia.id
? getMedia( firstMedia.id )?.mime_type?.startsWith( 'image/' )
: false;

if ( isImage && firstMedia.url ) {
image = firstMedia.url;
}
}

const media = [];

// Attach media only if "Share as a social post" option is enabled.
if ( shouldUploadAttachedMedia ) {
if ( sigImageUrl ) {
media.push( {
type: 'image/jpeg',
url: sigImageUrl,
alt: '',
} );
} else {
const getMediaDetails = id => {
const mediaItem = getMedia( id );
if ( ! mediaItem ) {
return null;
}
return {
type: mediaItem.mime_type,
url: getMediaSourceUrl( mediaItem ),
alt: mediaItem.alt_text,
};
};

for ( const { id } of attachedMedia ) {
const mediaDetails = getMediaDetails( id );
if ( mediaDetails ) {
media.push( mediaDetails );
}
}
if ( 0 === media.length && featuredImageId ) {
const mediaDetails = getMediaDetails( featuredImageId );
if ( mediaDetails ) {
media.push( mediaDetails );
}
}
}
}
return {
title:
getEditedPostAttribute( 'meta' )?.jetpack_seo_html_title ||
getEditedPostAttribute( 'title' ),
description:
getEditedPostAttribute( 'meta' )?.advanced_seo_description ||
getEditedPostAttribute( 'excerpt' ) ||
getEditedPostAttribute( 'content' ).split( '<!--more' )[ 0 ] ||
__( 'Visit the post for more.', 'jetpack' ),
url: getEditedPostAttribute( 'link' ),
image,
media,
initialTabName: null,
};
},
[ shouldUploadAttachedMedia, attachedMedia, imageGeneratorSettings ]
);
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import { useDispatch } from '@wordpress/data';
import { store as editorStore } from '@wordpress/editor';
import { useCallback } from '@wordpress/element';
import { getAttachedMedia, getJetpackSocialOptions, shouldUploadAttachedMedia } from '../../utils';
import { usePostMeta } from '../../utils';

/**
* @typedef {object} AttachedMediaHook
Expand All @@ -17,22 +14,11 @@ import { getAttachedMedia, getJetpackSocialOptions, shouldUploadAttachedMedia }
* @returns {AttachedMediaHook} - An object with the attached media hook properties set.
*/
export default function useAttachedMedia() {
const { editPost } = useDispatch( editorStore );

const updateJetpackSocialOptions = useCallback(
( key, value ) => {
editPost( {
meta: {
jetpack_social_options: { ...getJetpackSocialOptions(), [ key ]: value },
},
} );
},
[ editPost ]
);
const { attachedMedia, shouldUploadAttachedMedia, updateJetpackSocialOptions } = usePostMeta();

return {
attachedMedia: getAttachedMedia(),
shouldUploadAttachedMedia: shouldUploadAttachedMedia(),
attachedMedia,
shouldUploadAttachedMedia,
updateAttachedMedia: media => updateJetpackSocialOptions( 'attached_media', media ),
updateShouldUploadAttachedMedia: option =>
updateJetpackSocialOptions( 'should_upload_attached_media', option ),
Expand Down
Loading

0 comments on commit d790023

Please sign in to comment.