Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Jetpack Social pre publish UI #34243

Merged
merged 14 commits into from
Nov 23, 2023
Merged
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