From 7dde62024ca0e6ade16e634b15db497c060f473d Mon Sep 17 00:00:00 2001 From: Siddharth Thevaril Date: Mon, 5 Sep 2022 22:29:37 +0530 Subject: [PATCH 01/94] add img element --- src/js/AutoshareForTwitterPrePublishPanel.js | 26 +++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/js/AutoshareForTwitterPrePublishPanel.js b/src/js/AutoshareForTwitterPrePublishPanel.js index 13c35312..14fcb605 100644 --- a/src/js/AutoshareForTwitterPrePublishPanel.js +++ b/src/js/AutoshareForTwitterPrePublishPanel.js @@ -15,7 +15,7 @@ class AutoshareForTwitterPrePublishPanel extends Component { // Although these values are delivered as props, we copy them into state so that we can check for changes // and save data when they update. - this.state = { autoshareEnabled: null, tweetText: null }; + this.state = { autoshareEnabled: null, tweetText: null, featuredImageUrl: null }; this.saveData = debounce( this.saveData.bind( this ), 250 ); } @@ -27,11 +27,11 @@ class AutoshareForTwitterPrePublishPanel extends Component { } componentDidUpdate() { - const { autoshareEnabled, tweetText } = this.props; + const { autoshareEnabled, tweetText, featuredImageUrl } = this.props; // Update if either of these values has changed in the data store. if ( autoshareEnabled !== this.state.autoshareEnabled || tweetText !== this.state.tweetText ) { - this.setState( { autoshareEnabled, tweetText }, () => { + this.setState( { autoshareEnabled, tweetText, featuredImageUrl }, () => { this.props.setSaving( true ); this.saveData(); } ); @@ -80,6 +80,7 @@ class AutoshareForTwitterPrePublishPanel extends Component { setOverriding, setTweetText, tweetText, + featuredImageUrl, } = this.props; const overrideLengthClass = () => { @@ -135,7 +136,16 @@ class AutoshareForTwitterPrePublishPanel extends Component { ) } - + { featuredImageUrl && ( + <> + + + + ) }
{ errorMessage }
); @@ -156,6 +166,13 @@ const permalinkLength = ( select ) => { return siteUrl.length; }; +const featuredImageUrl = ( select ) => { + const imageId = select( 'core/editor' ).getEditedPostAttribute( 'featured_media' ); + const imageUrl = select( 'core' ).getMedia( imageId ); + + return imageUrl ? imageUrl.source_url : false; +}; + export default compose( withSelect( ( select ) => ( { autoshareEnabled: select( STORE ).getAutoshareEnabled(), @@ -164,6 +181,7 @@ export default compose( permalinkLength: permalinkLength( select ), saving: select( STORE ).getSaving(), tweetText: select( STORE ).getTweetText(), + featuredImageUrl: featuredImageUrl( select ), } ) ), withDispatch( ( dispatch ) => ( { setAutoshareEnabled: dispatch( STORE ).setAutoshareEnabled, From f703893f1dec19890599696cda8d6a6bd569a3fb Mon Sep 17 00:00:00 2001 From: Siddharth Thevaril Date: Tue, 6 Sep 2022 16:12:52 +0530 Subject: [PATCH 02/94] update rest route --- includes/admin/assets.php | 2 ++ includes/admin/post-meta.php | 2 ++ includes/rest.php | 7 +++++++ 3 files changed, 11 insertions(+) diff --git a/includes/admin/assets.php b/includes/admin/assets.php index f447aee6..a5fe23f8 100644 --- a/includes/admin/assets.php +++ b/includes/admin/assets.php @@ -16,6 +16,7 @@ use const TenUp\AutoshareForTwitter\Core\Post_Meta\ENABLE_AUTOSHARE_FOR_TWITTER_KEY; use const TenUp\AutoshareForTwitter\Core\Post_Meta\TWEET_BODY_KEY; use const TenUp\AutoshareForTwitter\Core\Post_Meta\TWITTER_STATUS_KEY; +use const TenUp\AutoshareForTwitter\Core\Post_Meta\TWEET_ALLOW_IMAGE; /** * The handle used in registering plugin assets. @@ -201,6 +202,7 @@ function localize_data( $handle = SCRIPT_HANDLE ) { 'status' => $status_meta && is_array( $status_meta ) ? $status_meta : null, 'unknownErrorText' => __( 'An unknown error occurred', 'autoshare-for-twitter' ), 'siteUrl' => home_url(), + 'tweetImageUrl' => TWEET_ALLOW_IMAGE, ]; wp_localize_script( $handle, 'adminAutoshareForTwitter', $localization ); diff --git a/includes/admin/post-meta.php b/includes/admin/post-meta.php index fec044a3..f057c400 100644 --- a/includes/admin/post-meta.php +++ b/includes/admin/post-meta.php @@ -38,6 +38,8 @@ */ const TWITTER_STATUS_KEY = 'status'; +const TWEET_ALLOW_IMAGE = 'tweet-allow-image'; + /** * The setup function * diff --git a/includes/rest.php b/includes/rest.php index fbef3881..c6673d46 100644 --- a/includes/rest.php +++ b/includes/rest.php @@ -12,6 +12,7 @@ use WP_REST_Server; use const TenUp\AutoshareForTwitter\Core\Post_Meta\TWEET_BODY_KEY; use const TenUp\AutoshareForTwitter\Core\Post_Meta\ENABLE_AUTOSHARE_FOR_TWITTER_KEY; +use const TenUp\AutoshareForTwitter\Core\Post_Meta\TWEET_ALLOW_IMAGE; use const TenUp\AutoshareForTwitter\Core\POST_TYPE_SUPPORT_FEATURE; use function TenUp\AutoshareForTwitter\Core\Post_Meta\get_tweet_status_message; @@ -84,6 +85,12 @@ function register_post_autoshare_for_twitter_meta_rest_route() { 'type' => 'boolean', 'validate_callback' => 'rest_validate_request_arg', ], + TWEET_ALLOW_IMAGE => [ + 'description' => __( 'Whether the tweet has an image.', 'autoshare-for-twitter' ), + 'required' => true, + 'type' => array( 'string', 'boolean' ), + 'validate_callback' => 'rest_validate_request_arg', + ], ], ] ); From d6b90ab86209a43e5e80227c1f5b071ef1ca4fd0 Mon Sep 17 00:00:00 2001 From: Siddharth Thevaril Date: Tue, 6 Sep 2022 16:58:18 +0530 Subject: [PATCH 03/94] submit form data --- includes/admin/assets.php | 2 +- includes/rest.php | 2 +- src/js/AutoshareForTwitterPrePublishPanel.js | 28 ++++++++++++++------ src/js/store/actions.js | 6 +++++ src/js/store/constants.js | 1 + src/js/store/reducer.js | 9 +++++++ src/js/store/selectors.js | 2 ++ 7 files changed, 40 insertions(+), 10 deletions(-) diff --git a/includes/admin/assets.php b/includes/admin/assets.php index a5fe23f8..77848021 100644 --- a/includes/admin/assets.php +++ b/includes/admin/assets.php @@ -202,7 +202,7 @@ function localize_data( $handle = SCRIPT_HANDLE ) { 'status' => $status_meta && is_array( $status_meta ) ? $status_meta : null, 'unknownErrorText' => __( 'An unknown error occurred', 'autoshare-for-twitter' ), 'siteUrl' => home_url(), - 'tweetImageUrl' => TWEET_ALLOW_IMAGE, + 'allowTweetImageKey' => TWEET_ALLOW_IMAGE, ]; wp_localize_script( $handle, 'adminAutoshareForTwitter', $localization ); diff --git a/includes/rest.php b/includes/rest.php index c6673d46..85842478 100644 --- a/includes/rest.php +++ b/includes/rest.php @@ -88,7 +88,7 @@ function register_post_autoshare_for_twitter_meta_rest_route() { TWEET_ALLOW_IMAGE => [ 'description' => __( 'Whether the tweet has an image.', 'autoshare-for-twitter' ), 'required' => true, - 'type' => array( 'string', 'boolean' ), + 'type' => 'boolean', 'validate_callback' => 'rest_validate_request_arg', ], ], diff --git a/src/js/AutoshareForTwitterPrePublishPanel.js b/src/js/AutoshareForTwitterPrePublishPanel.js index 14fcb605..e68610a1 100644 --- a/src/js/AutoshareForTwitterPrePublishPanel.js +++ b/src/js/AutoshareForTwitterPrePublishPanel.js @@ -4,7 +4,7 @@ import { withDispatch, withSelect } from '@wordpress/data'; import { compose } from '@wordpress/compose'; import { Component } from '@wordpress/element'; import { debounce } from 'lodash'; -import { enableAutoshareKey, errorText, restUrl, siteUrl, tweetBodyKey } from 'admin-autoshare-for-twitter'; +import { enableAutoshareKey, errorText, restUrl, siteUrl, tweetBodyKey, allowTweetImageKey } from 'admin-autoshare-for-twitter'; import { __ } from '@wordpress/i18n'; import { STORE } from './store'; @@ -15,23 +15,27 @@ class AutoshareForTwitterPrePublishPanel extends Component { // Although these values are delivered as props, we copy them into state so that we can check for changes // and save data when they update. - this.state = { autoshareEnabled: null, tweetText: null, featuredImageUrl: null }; + this.state = { autoshareEnabled: null, tweetText: null, featuredImageUrl: null, allowTweetImage: true }; this.saveData = debounce( this.saveData.bind( this ), 250 ); } componentDidMount() { - const { autoshareEnabled, tweetText } = this.props; + const { autoshareEnabled, tweetText, allowTweetImage } = this.props; - this.setState( { autoshareEnabled, tweetText } ); + this.setState( { autoshareEnabled, tweetText, allowTweetImage } ); } componentDidUpdate() { - const { autoshareEnabled, tweetText, featuredImageUrl } = this.props; + const { autoshareEnabled, tweetText, featuredImageUrl, allowTweetImage } = this.props; // Update if either of these values has changed in the data store. - if ( autoshareEnabled !== this.state.autoshareEnabled || tweetText !== this.state.tweetText ) { - this.setState( { autoshareEnabled, tweetText, featuredImageUrl }, () => { + if ( + autoshareEnabled !== this.state.autoshareEnabled || + tweetText !== this.state.tweetText || + allowTweetImage !== this.state.allowTweetImage + ) { + this.setState( { autoshareEnabled, tweetText, featuredImageUrl, allowTweetImage }, () => { this.props.setSaving( true ); this.saveData(); } ); @@ -39,11 +43,12 @@ class AutoshareForTwitterPrePublishPanel extends Component { } async saveData() { - const { autoshareEnabled, setErrorMessage, setSaving, tweetText } = this.props; + const { autoshareEnabled, setErrorMessage, setSaving, tweetText, allowTweetImage } = this.props; const body = {}; body[ enableAutoshareKey ] = autoshareEnabled; body[ tweetBodyKey ] = tweetText; + body[ allowTweetImageKey ] = allowTweetImage; try { const response = await apiFetch( { @@ -76,9 +81,11 @@ class AutoshareForTwitterPrePublishPanel extends Component { errorMessage, overriding, permalinkLength, + allowTweetImage, setAutoshareEnabled, setOverriding, setTweetText, + setAllowTweetImage, tweetText, featuredImageUrl, } = this.props; @@ -141,6 +148,9 @@ class AutoshareForTwitterPrePublishPanel extends Component { @@ -182,6 +192,7 @@ export default compose( saving: select( STORE ).getSaving(), tweetText: select( STORE ).getTweetText(), featuredImageUrl: featuredImageUrl( select ), + allowTweetImage: select( STORE ).getAllowTweetImage(), } ) ), withDispatch( ( dispatch ) => ( { setAutoshareEnabled: dispatch( STORE ).setAutoshareEnabled, @@ -197,5 +208,6 @@ export default compose( } }, setTweetText: dispatch( STORE ).setTweetText, + setAllowTweetImage: dispatch( STORE ).setAllowTweetImage, } ) ), )( AutoshareForTwitterPrePublishPanel ); diff --git a/src/js/store/actions.js b/src/js/store/actions.js index 1084ef32..d0cb9cdc 100644 --- a/src/js/store/actions.js +++ b/src/js/store/actions.js @@ -5,6 +5,7 @@ import { SET_SAVING, SET_LOADED, SET_OVERRIDING, + SET_ALLOW_TWEET_IMAGE, } from './constants'; export const setAutoshareEnabled = ( autoshareEnabled ) => ( { @@ -35,3 +36,8 @@ export const setTweetText = ( tweetText ) => ( { type: SET_TWEET_TEXT, tweetText, } ); + +export const setAllowTweetImage = ( allowTweetImage ) => ( { + type: SET_ALLOW_TWEET_IMAGE, + allowTweetImage, +} ); diff --git a/src/js/store/constants.js b/src/js/store/constants.js index 34fa28b2..abe66ee3 100644 --- a/src/js/store/constants.js +++ b/src/js/store/constants.js @@ -4,3 +4,4 @@ export const SET_LOADED = 'SET_LOADED'; export const SET_OVERRIDING = 'SET_OVERRIDING'; export const SET_SAVING = 'SET_SAVING'; export const SET_TWEET_TEXT = 'SET_TWEET_TEXT'; +export const SET_ALLOW_TWEET_IMAGE = 'SET_ALLOW_TWEET_IMAGE'; diff --git a/src/js/store/reducer.js b/src/js/store/reducer.js index 877ef20b..fd14c844 100644 --- a/src/js/store/reducer.js +++ b/src/js/store/reducer.js @@ -7,6 +7,7 @@ import { SET_SAVING, SET_LOADED, SET_OVERRIDING, + SET_ALLOW_TWEET_IMAGE, } from './constants'; export const DEFAULT_STATE = { @@ -16,6 +17,7 @@ export const DEFAULT_STATE = { overriding: false, overrideLength: 0, tweetText: '', + allowTweetImage: false, }; export default function reducer( state = DEFAULT_STATE, action ) { @@ -59,5 +61,12 @@ export default function reducer( state = DEFAULT_STATE, action ) { tweetText: action.tweetText, }; } + + case SET_ALLOW_TWEET_IMAGE: { + return { + ...state, + allowTweetImage: action.allowTweetImage, + }; + } } } diff --git a/src/js/store/selectors.js b/src/js/store/selectors.js index ab59d6c1..d0268c94 100644 --- a/src/js/store/selectors.js +++ b/src/js/store/selectors.js @@ -7,3 +7,5 @@ export const getOverriding = ( state ) => state.overriding; export const getSaving = ( state ) => state.saving; export const getTweetText = ( state ) => state.tweetText; + +export const getAllowTweetImage = ( state ) => state.allowTweetImage; From f33855f1d92d5643cc73afbaa99cdb35db12eeb5 Mon Sep 17 00:00:00 2001 From: Siddharth Thevaril Date: Tue, 6 Sep 2022 21:32:53 +0530 Subject: [PATCH 04/94] add meta to disallow image --- includes/admin/post-meta.php | 9 +++++++++ includes/class-publish-tweet.php | 7 ++++++- src/js/AutoshareForTwitterPrePublishPanel.js | 4 ++-- src/js/store/reducer.js | 2 +- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/includes/admin/post-meta.php b/includes/admin/post-meta.php index f057c400..a10497c9 100644 --- a/includes/admin/post-meta.php +++ b/includes/admin/post-meta.php @@ -163,6 +163,15 @@ function save_autoshare_for_twitter_meta_data( $post_id, $data ) { } else { delete_autoshare_for_twitter_meta( $post_id, TWEET_BODY_KEY ); } + + break; + + case TWEET_ALLOW_IMAGE: + update_autoshare_for_twitter_meta( $post_id, TWEET_ALLOW_IMAGE, $value ? 'yes' : 'no' ); + break; + + default: + break; } } } diff --git a/includes/class-publish-tweet.php b/includes/class-publish-tweet.php index 255058fd..6ab99d1f 100644 --- a/includes/class-publish-tweet.php +++ b/includes/class-publish-tweet.php @@ -9,6 +9,7 @@ use TenUp\AutoshareForTwitter\Utils as Utils; use Abraham\TwitterOAuth\TwitterOAuth as TwitterOAuth; +use const \TenUp\AutoshareForTwitter\Core\Post_Meta\TWEET_ALLOW_IMAGE; /** * Publish tweets to twitter. @@ -98,12 +99,16 @@ public function status_update( $body, $post ) { if ( empty( $body ) ) { return; } + $update_data = array( 'status' => $body, // URL encoding handled by buildHttpQuery vai TwitterOAuth. ); + $is_image_allowed = Utils\get_autoshare_for_twitter_meta( $post->ID, TWEET_ALLOW_IMAGE ); + $media_id = $this->get_upload_data_media_id( $post ); - if ( $media_id ) { + + if ( $media_id && 'no' !== $is_image_allowed ) { $update_data['media_ids'] = [ $media_id ]; } diff --git a/src/js/AutoshareForTwitterPrePublishPanel.js b/src/js/AutoshareForTwitterPrePublishPanel.js index e68610a1..54b6ec54 100644 --- a/src/js/AutoshareForTwitterPrePublishPanel.js +++ b/src/js/AutoshareForTwitterPrePublishPanel.js @@ -145,14 +145,14 @@ class AutoshareForTwitterPrePublishPanel extends Component { ) } { featuredImageUrl && ( <> - + ) } diff --git a/src/js/store/reducer.js b/src/js/store/reducer.js index fd14c844..4de575b8 100644 --- a/src/js/store/reducer.js +++ b/src/js/store/reducer.js @@ -17,7 +17,7 @@ export const DEFAULT_STATE = { overriding: false, overrideLength: 0, tweetText: '', - allowTweetImage: false, + allowTweetImage: true, }; export default function reducer( state = DEFAULT_STATE, action ) { From 77850fb83e5719b59c99459933ca893eaeecf6ce Mon Sep 17 00:00:00 2001 From: Siddharth Thevaril Date: Thu, 8 Sep 2022 21:01:41 +0530 Subject: [PATCH 05/94] replace button link with form toggle --- includes/rest.php | 2 +- src/js/AutoshareForTwitterPrePublishPanel.js | 44 ++++++++++---------- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/includes/rest.php b/includes/rest.php index 85842478..5ab3b1e1 100644 --- a/includes/rest.php +++ b/includes/rest.php @@ -85,7 +85,7 @@ function register_post_autoshare_for_twitter_meta_rest_route() { 'type' => 'boolean', 'validate_callback' => 'rest_validate_request_arg', ], - TWEET_ALLOW_IMAGE => [ + TWEET_ALLOW_IMAGE => [ 'description' => __( 'Whether the tweet has an image.', 'autoshare-for-twitter' ), 'required' => true, 'type' => 'boolean', diff --git a/src/js/AutoshareForTwitterPrePublishPanel.js b/src/js/AutoshareForTwitterPrePublishPanel.js index 54b6ec54..d80bc9b1 100644 --- a/src/js/AutoshareForTwitterPrePublishPanel.js +++ b/src/js/AutoshareForTwitterPrePublishPanel.js @@ -15,7 +15,7 @@ class AutoshareForTwitterPrePublishPanel extends Component { // Although these values are delivered as props, we copy them into state so that we can check for changes // and save data when they update. - this.state = { autoshareEnabled: null, tweetText: null, featuredImageUrl: null, allowTweetImage: true }; + this.state = { autoshareEnabled: null, tweetText: null, hasFeaturedImage: null, allowTweetImage: true }; this.saveData = debounce( this.saveData.bind( this ), 250 ); } @@ -27,7 +27,7 @@ class AutoshareForTwitterPrePublishPanel extends Component { } componentDidUpdate() { - const { autoshareEnabled, tweetText, featuredImageUrl, allowTweetImage } = this.props; + const { autoshareEnabled, tweetText, hasFeaturedImage, allowTweetImage } = this.props; // Update if either of these values has changed in the data store. if ( @@ -35,7 +35,7 @@ class AutoshareForTwitterPrePublishPanel extends Component { tweetText !== this.state.tweetText || allowTweetImage !== this.state.allowTweetImage ) { - this.setState( { autoshareEnabled, tweetText, featuredImageUrl, allowTweetImage }, () => { + this.setState( { autoshareEnabled, tweetText, hasFeaturedImage, allowTweetImage }, () => { this.props.setSaving( true ); this.saveData(); } ); @@ -87,7 +87,7 @@ class AutoshareForTwitterPrePublishPanel extends Component { setTweetText, setAllowTweetImage, tweetText, - featuredImageUrl, + hasFeaturedImage, } = this.props; const overrideLengthClass = () => { @@ -114,6 +114,17 @@ class AutoshareForTwitterPrePublishPanel extends Component { className="autoshare-for-twitter-toggle-control" /> + { hasFeaturedImage && ( + { + setAllowTweetImage( ! allowTweetImage ); + } } + className="autoshare-for-twitter-toggle-control" + /> + ) } + { autoshareEnabled && (
{ overriding && ( @@ -143,19 +154,6 @@ class AutoshareForTwitterPrePublishPanel extends Component {
) } - { featuredImageUrl && ( - <> - - - - ) }
{ errorMessage }
); @@ -176,11 +174,15 @@ const permalinkLength = ( select ) => { return siteUrl.length; }; -const featuredImageUrl = ( select ) => { +/** + * Returns true if the post has a featured image, false otherwise. + * @param {Function} select Data store selector function. + * @returns {boolean} + */ +const hasFeaturedImage = ( select ) => { const imageId = select( 'core/editor' ).getEditedPostAttribute( 'featured_media' ); - const imageUrl = select( 'core' ).getMedia( imageId ); - return imageUrl ? imageUrl.source_url : false; + return imageId > 0; }; export default compose( @@ -191,7 +193,7 @@ export default compose( permalinkLength: permalinkLength( select ), saving: select( STORE ).getSaving(), tweetText: select( STORE ).getTweetText(), - featuredImageUrl: featuredImageUrl( select ), + hasFeaturedImage: hasFeaturedImage( select ), allowTweetImage: select( STORE ).getAllowTweetImage(), } ) ), withDispatch( ( dispatch ) => ( { From b4d5af03170feb50718a0d96153a6b140798849f Mon Sep 17 00:00:00 2001 From: Siddharth Thevaril Date: Sat, 17 Sep 2022 17:45:44 +0530 Subject: [PATCH 06/94] merge develop --- includes/admin/post-meta.php | 2 +- src/js/AutoshareForTwitterPostStatusInfo.js | 5 +- src/js/AutoshareForTwitterPrePublishPanel.js | 54 ++--------------- src/js/components/TweetTextField.js | 61 ++++++++++++++++++++ 4 files changed, 72 insertions(+), 50 deletions(-) create mode 100644 src/js/components/TweetTextField.js diff --git a/includes/admin/post-meta.php b/includes/admin/post-meta.php index a10497c9..144b9418 100644 --- a/includes/admin/post-meta.php +++ b/includes/admin/post-meta.php @@ -312,7 +312,7 @@ function markup_published( $status_meta ) { return sprintf( '%s %s (%s)

', - esc_html__( 'Tweeted on', 'autoshare-for-twitter' ), + esc_html__( 'Tweetedd on', 'autoshare-for-twitter' ), esc_html( $date ), esc_url( $twitter_url ), esc_html__( 'View', 'autoshare-for-twitter' ) diff --git a/src/js/AutoshareForTwitterPostStatusInfo.js b/src/js/AutoshareForTwitterPostStatusInfo.js index d29d4109..a30f0749 100644 --- a/src/js/AutoshareForTwitterPostStatusInfo.js +++ b/src/js/AutoshareForTwitterPostStatusInfo.js @@ -3,7 +3,7 @@ import { compose } from '@wordpress/compose'; import { withSelect } from '@wordpress/data'; import { Dashicon } from '@wordpress/components'; -export function AutoshareForTwitterPostStatusInfo( { statusMessage } ) { +export function AutoshareForTwitterPostStatusInfo( { statusMessage, allowRetweet } ) { return ( statusMessage.message && (
@@ -18,6 +18,9 @@ export function AutoshareForTwitterPostStatusInfo( { statusMessage } ) { { ')' } ) } + { allowRetweet && ( +
Hello, you
+ ) }
) ); diff --git a/src/js/AutoshareForTwitterPrePublishPanel.js b/src/js/AutoshareForTwitterPrePublishPanel.js index d80bc9b1..6be121d0 100644 --- a/src/js/AutoshareForTwitterPrePublishPanel.js +++ b/src/js/AutoshareForTwitterPrePublishPanel.js @@ -1,12 +1,13 @@ import apiFetch from '@wordpress/api-fetch'; -import { Button, TextareaControl, ToggleControl } from '@wordpress/components'; +import { Button, ToggleControl } from '@wordpress/components'; import { withDispatch, withSelect } from '@wordpress/data'; import { compose } from '@wordpress/compose'; import { Component } from '@wordpress/element'; import { debounce } from 'lodash'; -import { enableAutoshareKey, errorText, restUrl, siteUrl, tweetBodyKey, allowTweetImageKey } from 'admin-autoshare-for-twitter'; +import { enableAutoshareKey, errorText, restUrl, tweetBodyKey, allowTweetImageKey } from 'admin-autoshare-for-twitter'; import { __ } from '@wordpress/i18n'; +import { TweetTextField } from './components/TweetTextField'; import { STORE } from './store'; class AutoshareForTwitterPrePublishPanel extends Component { @@ -80,28 +81,13 @@ class AutoshareForTwitterPrePublishPanel extends Component { autoshareEnabled, errorMessage, overriding, - permalinkLength, allowTweetImage, setAutoshareEnabled, setOverriding, - setTweetText, setAllowTweetImage, - tweetText, hasFeaturedImage, } = this.props; - const overrideLengthClass = () => { - if ( 280 <= permalinkLength + tweetText.length ) { - return 'over-limit'; - } - - if ( 240 <= permalinkLength + tweetText.length ) { - return 'near-limit'; - } - - return null; - }; - return ( <> { overriding && ( - { - setTweetText( value ); - } } - label={ - - { __( 'Custom message:', 'autoshare-for-twitter' ) }  - - { tweetText.length } - - - } - /> + ) } - - ) } -
{ errorMessage }
- - ); - } + > + { overriding ? __( 'Hide', 'autoshare-for-twitter' ) : __( 'Edit', 'autoshare-for-twitter' ) } + + + ) } +
{ errorMessage }
+ + ); } - -/** - * Returns true if the post has a featured image, false otherwise. - * - * @param {Function} select Data store selector function. - * @return {boolean} Returns true if post has featured image. - */ -const hasFeaturedImage = ( select ) => { - const imageId = select( 'core/editor' ).getEditedPostAttribute( 'featured_media' ); - - return imageId > 0; -}; - -export default compose( - withSelect( ( select ) => ( { - autoshareEnabled: select( STORE ).getAutoshareEnabled(), - errorMessage: select( STORE ).getErrorMessage(), - overriding: select( STORE ).getOverriding(), - saving: select( STORE ).getSaving(), - tweetText: select( STORE ).getTweetText(), - hasFeaturedImage: hasFeaturedImage( select ), - allowTweetImage: select( STORE ).getAllowTweetImage(), - } ) ), - withDispatch( ( dispatch ) => ( { - setAutoshareEnabled: dispatch( STORE ).setAutoshareEnabled, - setErrorMessage: dispatch( STORE ).setErrorMessage, - setOverriding: dispatch( STORE ).setOverriding, - setSaving: ( saving ) => { - dispatch( STORE ).setSaving( saving ); - - if ( saving ) { - dispatch( 'core/editor' ).lockPostSaving(); - } else { - dispatch( 'core/editor' ).unlockPostSaving(); - } - }, - setAllowTweetImage: dispatch( STORE ).setAllowTweetImage, - } ) ), -)( AutoshareForTwitterPrePublishPanel ); diff --git a/src/js/components/TweetTextField.js b/src/js/components/TweetTextField.js index 6aeabb42..ec9d6b35 100644 --- a/src/js/components/TweetTextField.js +++ b/src/js/components/TweetTextField.js @@ -1,8 +1,8 @@ import { TextareaControl } from '@wordpress/components'; -import { useSelect, useDispatch } from '@wordpress/data'; +import { useSelect } from '@wordpress/data'; import { siteUrl } from 'admin-autoshare-for-twitter'; import { __ } from '@wordpress/i18n'; -import { STORE } from '../store'; +import { useTweetText } from '../hooks'; export function TweetTextField() { const getPermalinkLength = ( select ) => { @@ -33,14 +33,13 @@ export function TweetTextField() { return null; }; - const { permalinkLength, tweetText } = useSelect( ( select ) => { + const { permalinkLength } = useSelect( ( select ) => { return { permalinkLength: getPermalinkLength( select ), - tweetText: select( STORE ).getTweetText(), }; } ); - const { setTweetText } = useDispatch( STORE ); + const [ tweetText, setTweetText ] = useTweetText(); return ( { + return { + tweetText: select( STORE ).getTweetText(), + }; + } ); + + const { setTweetText } = useDispatch( STORE ); + + return [ tweetText, setTweetText ]; +} + +export function useTwitterAutoshareEnabled() { + const { autoshareEnabled } = useSelect( ( select ) => { + return { + autoshareEnabled: select( STORE ).getAutoshareEnabled(), + }; + } ); + + const { setAutoshareEnabled } = useDispatch( STORE ); + + return [ autoshareEnabled, setAutoshareEnabled ]; +} + +export function useTwitterTextOverriding() { + const { overriding } = useSelect( ( select ) => { + return { + overriding: select( STORE ).getOverriding(), + }; + } ); + + const { setOverriding } = useDispatch( STORE ); + + return [ overriding, setOverriding ]; +} + +export function useSavingTweetData() { + function setSaving( saving ) { + dispatch( STORE ).setSaving( saving ); + + if ( saving ) { + dispatch( 'core/editor' ).lockPostSaving(); + } else { + dispatch( 'core/editor' ).unlockPostSaving(); + } + } + + const { saving } = useSelect( ( select ) => { + return { + saving: select( STORE ).getSaving(), + }; + } ); + + return [ saving, setSaving ]; +} + +export function useAllowTweetImage() { + const { allowTweetImage } = useSelect( ( select ) => { + return { + allowTweetImage: select( STORE ).getAllowTweetImage(), + }; + } ); + + const { setAllowTweetImage } = useDispatch( STORE ); + + return [ allowTweetImage, setAllowTweetImage ]; +} + +export function useTwitterAutoshareErrorMessage() { + const { errorMessage } = useSelect( ( select ) => { + return { + errorMessage: select( STORE ).getErrorMessage(), + }; + } ); + + const { setErrorMessage } = useDispatch( STORE ); + + return [ errorMessage, setErrorMessage ]; +} + +export function useSaveTwitterData() { + const [ autoshareEnabled ] = useTwitterAutoshareEnabled(); + const [ allowTweetImage ] = useAllowTweetImage(); + const [ tweetText ] = useTweetText(); + const [ , setErrorMessage ] = useTwitterAutoshareErrorMessage(); + const [ , setSaving ] = useSavingTweetData(); + + const { hasFeaturedImage } = useSelect( ( select ) => { + const imageId = select( 'core/editor' ).getEditedPostAttribute( 'featured_media' ); + + return { + hasFeaturedImage: imageId > 0, + }; + } ); + + async function saveData( autoshareEnabledArg, tweetTextArg, allowTweetImageArg ) { + const body = {}; + body[ enableAutoshareKey ] = autoshareEnabledArg; + body[ tweetBodyKey ] = tweetTextArg; + body[ allowTweetImageKey ] = allowTweetImageArg; + + try { + const response = await apiFetch( { + url: restUrl, + data: body, + method: 'POST', + parse: false, // We'll check the response for errors. + } ); + + if ( ! response.ok ) { + throw response; + } + + await response.json(); + + setErrorMessage( '' ); + setSaving( false ); + } catch ( e ) { + setErrorMessage( + e.statusText ? `${ errorText } ${ e.status }: ${ e.statusText }` : __( 'An error occurred.', 'autoshare-for-twitter' ), + ); + + setSaving( false ); + } + } + + const saveDataDebounced = useCallback( debounce( saveData, 250 ), [] ); + + useEffect( () => { + saveDataDebounced( autoshareEnabled, tweetText, allowTweetImage ); + }, [ autoshareEnabled, tweetText, hasFeaturedImage, allowTweetImage ] ); +} From 2dd22f036a6f29ebb26de80452b9984b20fcba55 Mon Sep 17 00:00:00 2001 From: Siddharth Thevaril Date: Tue, 27 Sep 2022 22:38:04 +0530 Subject: [PATCH 08/94] add retweet capability --- includes/admin/assets.php | 1 + includes/admin/post-meta.php | 86 ++++++++++------ includes/admin/post-transition.php | 49 ++++++++- src/js/AutoshareForTwitterPostStatusInfo.js | 103 ++++++++++++++----- src/js/AutoshareForTwitterPrePublishPanel.js | 11 +- src/js/hooks/index.js | 12 +++ 6 files changed, 196 insertions(+), 66 deletions(-) diff --git a/includes/admin/assets.php b/includes/admin/assets.php index 77848021..9896d9aa 100644 --- a/includes/admin/assets.php +++ b/includes/admin/assets.php @@ -203,6 +203,7 @@ function localize_data( $handle = SCRIPT_HANDLE ) { 'unknownErrorText' => __( 'An unknown error occurred', 'autoshare-for-twitter' ), 'siteUrl' => home_url(), 'allowTweetImageKey' => TWEET_ALLOW_IMAGE, + 'retweetAction' => 'tenup_autoshare_retweet', ]; wp_localize_script( $handle, 'adminAutoshareForTwitter', $localization ); diff --git a/includes/admin/post-meta.php b/includes/admin/post-meta.php index 144b9418..e13f88bd 100644 --- a/includes/admin/post-meta.php +++ b/includes/admin/post-meta.php @@ -253,47 +253,67 @@ function render_tweet_submitbox( $post ) { * @return array Associative array containing a message and a URL if the post was tweeted. */ function get_tweet_status_message( $post ) { - $post = get_post( $post ); - $post_status = get_post_status( $post ); + $post = get_post( $post ); + $post_status = get_post_status( $post ); + $response_array = array(); if ( 'publish' === $post_status ) { - $twitter_status = Utils\get_autoshare_for_twitter_meta( $post->ID, TWITTER_STATUS_KEY ); - $status = isset( $twitter_status['status'] ) ? $twitter_status['status'] : ''; - - switch ( $status ) { - case 'published': - $date = Utils\date_from_twitter( $twitter_status['created_at'] ); - $twitter_url = Utils\link_from_twitter( $twitter_status['twitter_id'] ); - - return [ - // Translators: Placeholder is a date. - 'message' => sprintf( __( 'Tweeted on %s', 'autoshare-for-twitter' ), $date ), - 'url' => $twitter_url, - 'status' => $status, - ]; + $tweet_metas = Utils\get_autoshare_for_twitter_meta( $post->ID, TWITTER_STATUS_KEY ); - case 'error': - return [ - 'message' => __( 'Failed to tweet: ', 'autoshare-for-twitter' ) . $twitter_status['message'], - 'status' => $status, - ]; - - case 'unknown': - return [ - 'message' => $twitter_status['message'], - 'status' => $status, - ]; + if ( empty( $tweet_metas ) || isset( $tweet_metas['twitter_id'] ) ) { + $tweet_metas = array( + array( + 'status' => $tweet_metas['status'], + 'created_at' => $tweet_metas['created_at'], + 'twitter_id' => $tweet_metas['twitter_id'], + ), + ); + } - default: - return [ - 'message' => __( 'This post was not tweeted.', 'autoshare-for-twitter' ), - 'status' => $status, - ]; + foreach ( $tweet_metas as $tweet_meta ) { + $status = $tweet_meta['status']; + + switch ( $status ) { + case 'published': + $date = Utils\date_from_twitter( $tweet_meta['created_at'] ); + $twitter_url = Utils\link_from_twitter( $tweet_meta['twitter_id'] ); + + $response_array[] = [ + // Translators: Placeholder is a date. + 'message' => sprintf( __( 'Tweeted on %s', 'autoshare-for-twitter' ), $date ), + 'url' => $twitter_url, + 'status' => $status, + ]; + + break; + + case 'error': + $response_array[] = [ + 'message' => __( 'Failed to tweet: ', 'autoshare-for-twitter' ) . $tweet_meta['message'], + 'status' => $status, + ]; + + break; + + case 'unknown': + $response_array[] = [ + 'message' => $tweet_meta['message'], + 'status' => $status, + ]; + + break; + + default: + $response_array[] = [ + 'message' => __( 'This post was not tweeted.', 'autoshare-for-twitter' ), + 'status' => $status, + ]; + } } } - return [ 'message' => '' ]; + return [ 'message' => $response_array ]; } diff --git a/includes/admin/post-transition.php b/includes/admin/post-transition.php index b842636a..df909011 100644 --- a/includes/admin/post-transition.php +++ b/includes/admin/post-transition.php @@ -11,9 +11,12 @@ use TenUp\AutoshareForTwitter\Core\AST_Staging\AST_Staging; use TenUp\AutoshareForTwitter\Core\Post_Meta as Meta; use TenUp\AutoshareForTwitter\Utils as Utils; + +use function TenUp\AutoshareForTwitter\Core\Post_Meta\get_tweet_status_message; use function TenUp\AutoshareForTwitter\Utils\delete_autoshare_for_twitter_meta; use function TenUp\AutoshareForTwitter\Utils\update_autoshare_for_twitter_meta; use function TenUp\AutoshareForTwitter\Core\Post_Meta\save_tweet_meta; +use function TenUp\AutoshareForTwitter\Utils\get_autoshare_for_twitter_meta; /** * Setup function. @@ -22,6 +25,7 @@ */ function setup() { add_action( 'transition_post_status', __NAMESPACE__ . '\maybe_publish_tweet', 10, 3 ); + add_action( 'wp_ajax_tenup_autoshare_retweet', __NAMESPACE__ . '\retweet', 10, 3 ); } /** @@ -128,6 +132,8 @@ function publish_tweet( $post_id ) { */ do_action( 'autoshare_for_twitter_success' ); + return true; + } else { // something here about it failing so do not allow republishing just in case. update_autoshare_for_twitter_meta_from_response( $post->ID, $response ); @@ -136,8 +142,31 @@ function publish_tweet( $post_id ) { * Fires if the response back from Twitter was an error. */ do_action( 'autoshare_for_twitter_failed' ); + + return false; } } + + return false; +} + +/** + * Handles Re-tweeting. + */ +function retweet() { + if ( isset( $_POST['nonce'] ) && ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'wp_rest' ) ) { + wp_send_json_error( __( 'Nonce verification failed.', 'autoshare-for-twitter' ) ); + } + + $post_id = isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : 0; + $is_retweeted = publish_tweet( $post_id ); + + if ( $is_retweeted ) { + $message = get_tweet_status_message( $post_id ); + wp_send_json_success( $message ); + } else { + wp_send_json_error(); + } } /** @@ -204,11 +233,29 @@ function update_autoshare_for_twitter_meta_from_response( $post_id, $data ) { */ $response = apply_filters( 'autoshare_for_twitter_post_status_meta', $response ); + $tweet_meta = get_autoshare_for_twitter_meta( $post_id, Meta\TWITTER_STATUS_KEY ); + + if ( '' === $tweet_meta ) { + $tweet_meta = array(); + } + + /** + * Handles meta for multiple tweets. + */ + if ( isset( $tweet_meta['twitter_id'] ) ) { + $tweet_meta = array( + $tweet_meta, + $response, + ); + } else { + $tweet_meta[] = $response; + } + /** * Update the post meta entry that stores the response * and remove the "Autoshare this post" value as a double-check. */ - update_autoshare_for_twitter_meta( $post_id, Meta\TWITTER_STATUS_KEY, $response ); + update_autoshare_for_twitter_meta( $post_id, Meta\TWITTER_STATUS_KEY, $tweet_meta ); delete_autoshare_for_twitter_meta( $post_id, Meta\ENABLE_AUTOSHARE_FOR_TWITTER_KEY ); /** diff --git a/src/js/AutoshareForTwitterPostStatusInfo.js b/src/js/AutoshareForTwitterPostStatusInfo.js index 05226e6c..c88effad 100644 --- a/src/js/AutoshareForTwitterPostStatusInfo.js +++ b/src/js/AutoshareForTwitterPostStatusInfo.js @@ -1,39 +1,96 @@ import { __ } from '@wordpress/i18n'; import { compose } from '@wordpress/compose'; +import { useState } from '@wordpress/element'; import { withSelect, useSelect } from '@wordpress/data'; -import { Dashicon, Button } from '@wordpress/components'; +import { Button, ToggleControl } from '@wordpress/components'; import { TweetTextField } from './components/TweetTextField'; +import { useHasFeaturedImage, useAllowTweetImage, useSaveTwitterData } from './hooks'; export function AutoshareForTwitterPostStatusInfo() { - const { statusMessage } = useSelect( ( select ) => { + const hasFeaturedImage = useHasFeaturedImage(); + const [ allowTweetImage, setAllowTweetImage ] = useAllowTweetImage(); + const [ reTweet, setReTweet ] = useState( false ); + const { messages } = useSelect( ( select ) => { return { - statusMessage: select( 'core/editor' ).getCurrentPostAttribute( 'autoshare_for_twitter_status' ), + messages: select( 'core/editor' ).getCurrentPostAttribute( 'autoshare_for_twitter_status' ), }; } ); + const [ statusMessages, setStatusMessages ] = useState( messages ); + + useSaveTwitterData(); + + const tweetNow = async () => { + setReTweet( true ); + + const postId = await wp.data.select("core/editor").getCurrentPostId(); + const body = new FormData(); + + body.append( 'action', adminAutoshareForTwitter.retweetAction ); + body.append( 'nonce', adminAutoshareForTwitter.nonce ); + body.append( 'post_id', postId ); + + const apiResponse = await fetch( ajaxurl, { + method: 'POST', + body, + } ); + + const { success, data } = await apiResponse.json(); + + if ( success ) { + setStatusMessages( data ); + } + + setReTweet( false ); + }; + + if ( statusMessages && ! statusMessages.message.length ) { + return null; + } + return ( - statusMessage.message && ( -
- - { statusMessage.message } - { statusMessage.url && ( - <> - { ' (' } - - { __( 'View', 'autoshare-for-twitter' ) } - - { ')' } - - ) } -
-
+ ) } + +
- ) + ); } diff --git a/src/js/AutoshareForTwitterPrePublishPanel.js b/src/js/AutoshareForTwitterPrePublishPanel.js index 07720aba..9cb8713a 100644 --- a/src/js/AutoshareForTwitterPrePublishPanel.js +++ b/src/js/AutoshareForTwitterPrePublishPanel.js @@ -1,6 +1,5 @@ import { Button, ToggleControl } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; -import { useSelect } from '@wordpress/data'; import { TweetTextField } from './components/TweetTextField'; import { useTwitterAutoshareEnabled, @@ -8,6 +7,7 @@ import { useAllowTweetImage, useTwitterAutoshareErrorMessage, useSaveTwitterData, + useHasFeaturedImage, } from './hooks'; export default function AutoshareForTwitterPrePublishPanel() { @@ -15,17 +15,10 @@ export default function AutoshareForTwitterPrePublishPanel() { const [ overriding, setOverriding ] = useTwitterTextOverriding(); const [ allowTweetImage, setAllowTweetImage ] = useAllowTweetImage(); const [ errorMessage ] = useTwitterAutoshareErrorMessage(); + const hasFeaturedImage = useHasFeaturedImage(); useSaveTwitterData(); - const { hasFeaturedImage } = useSelect( ( select ) => { - const imageId = select( 'core/editor' ).getEditedPostAttribute( 'featured_media' ); - - return { - hasFeaturedImage: imageId > 0, - }; - } ); - return ( <> { + return { + imageId: select( 'core/editor' ).getEditedPostAttribute( 'featured_media' ), + }; + } ); + + const hasFeaturedImage = imageId > 0; + + return hasFeaturedImage; +} + export function useSaveTwitterData() { const [ autoshareEnabled ] = useTwitterAutoshareEnabled(); const [ allowTweetImage ] = useAllowTweetImage(); From c93f52fe23c3279497959608bb10c26a01d71928 Mon Sep 17 00:00:00 2001 From: Siddharth Thevaril Date: Wed, 28 Sep 2022 15:32:35 +0530 Subject: [PATCH 09/94] add tweet log and touch up --- .eslintrc.json | 5 +- assets/css/admin-autoshare-for-twitter.css | 11 +++ includes/admin/post-meta.php | 2 +- includes/admin/post-transition.php | 4 +- src/js/AutoshareForTwitterPostStatusInfo.js | 84 +++++++++++---------- src/js/components/TweetTextField.js | 2 +- src/js/index.js | 24 +----- src/js/utils.js | 29 +++++++ 8 files changed, 93 insertions(+), 68 deletions(-) create mode 100644 src/js/utils.js diff --git a/.eslintrc.json b/.eslintrc.json index d8ee40e3..83237ed3 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -2,7 +2,10 @@ "globals": { "adminAutoshareForTwitter": "readonly", "jQuery": "readonly", - "wp": "readonly" + "wp": "readonly", + "FormData": "readonly", + "fetch": "readonly", + "ajaxurl": "readonly" }, "extends": "plugin:@wordpress/eslint-plugin/recommended" } diff --git a/assets/css/admin-autoshare-for-twitter.css b/assets/css/admin-autoshare-for-twitter.css index 25106eaa..6c26904b 100644 --- a/assets/css/admin-autoshare-for-twitter.css +++ b/assets/css/admin-autoshare-for-twitter.css @@ -130,3 +130,14 @@ tbody .autoshare-for-twitter-status-logo--disabled::before { width: 24px; height: 24px; } + +.autoshare-for-twitter-log { + display: flex; + align-items: flex-start; + margin-bottom: 4px; +} + +.autoshare-for-twitter-log svg { + max-width: 20px; + height: auto; +} diff --git a/includes/admin/post-meta.php b/includes/admin/post-meta.php index e13f88bd..f539bbba 100644 --- a/includes/admin/post-meta.php +++ b/includes/admin/post-meta.php @@ -332,7 +332,7 @@ function markup_published( $status_meta ) { return sprintf( '%s %s (%s)

', - esc_html__( 'Tweetedd on', 'autoshare-for-twitter' ), + esc_html__( 'Tweeted on', 'autoshare-for-twitter' ), esc_html( $date ), esc_url( $twitter_url ), esc_html__( 'View', 'autoshare-for-twitter' ) diff --git a/includes/admin/post-transition.php b/includes/admin/post-transition.php index df909011..29836c2d 100644 --- a/includes/admin/post-transition.php +++ b/includes/admin/post-transition.php @@ -160,12 +160,12 @@ function retweet() { $post_id = isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : 0; $is_retweeted = publish_tweet( $post_id ); + $message = get_tweet_status_message( $post_id ); if ( $is_retweeted ) { - $message = get_tweet_status_message( $post_id ); wp_send_json_success( $message ); } else { - wp_send_json_error(); + wp_send_json_error( $message ); } } diff --git a/src/js/AutoshareForTwitterPostStatusInfo.js b/src/js/AutoshareForTwitterPostStatusInfo.js index c88effad..7a6a1445 100644 --- a/src/js/AutoshareForTwitterPostStatusInfo.js +++ b/src/js/AutoshareForTwitterPostStatusInfo.js @@ -2,14 +2,17 @@ import { __ } from '@wordpress/i18n'; import { compose } from '@wordpress/compose'; import { useState } from '@wordpress/element'; import { withSelect, useSelect } from '@wordpress/data'; -import { Button, ToggleControl } from '@wordpress/components'; +import { Button, ToggleControl, CardDivider, Icon, ExternalLink } from '@wordpress/components'; import { TweetTextField } from './components/TweetTextField'; import { useHasFeaturedImage, useAllowTweetImage, useSaveTwitterData } from './hooks'; +import { getIconByStatus } from './utils'; + export function AutoshareForTwitterPostStatusInfo() { const hasFeaturedImage = useHasFeaturedImage(); const [ allowTweetImage, setAllowTweetImage ] = useAllowTweetImage(); const [ reTweet, setReTweet ] = useState( false ); + const [ tweetNow, setTweetNow ] = useState( false ); const { messages } = useSelect( ( select ) => { return { messages: select( 'core/editor' ).getCurrentPostAttribute( 'autoshare_for_twitter_status' ), @@ -20,10 +23,10 @@ export function AutoshareForTwitterPostStatusInfo() { useSaveTwitterData(); - const tweetNow = async () => { + const reTweetHandler = async () => { setReTweet( true ); - const postId = await wp.data.select("core/editor").getCurrentPostId(); + const postId = await wp.data.select( 'core/editor' ).getCurrentPostId(); const body = new FormData(); body.append( 'action', adminAutoshareForTwitter.retweetAction ); @@ -35,12 +38,9 @@ export function AutoshareForTwitterPostStatusInfo() { body, } ); - const { success, data } = await apiResponse.json(); - - if ( success ) { - setStatusMessages( data ); - } + const { data } = await apiResponse.json(); + setStatusMessages( data ); setReTweet( false ); }; @@ -48,48 +48,50 @@ export function AutoshareForTwitterPostStatusInfo() { return null; } + const chevronUp =