diff --git a/projects/plugins/jetpack/_inc/lib/core-api/wpcom-fields/post-fields-publicize-connections.php b/projects/plugins/jetpack/_inc/lib/core-api/wpcom-fields/post-fields-publicize-connections.php
index f4bd54ddd8593..8e4b282dac89c 100644
--- a/projects/plugins/jetpack/_inc/lib/core-api/wpcom-fields/post-fields-publicize-connections.php
+++ b/projects/plugins/jetpack/_inc/lib/core-api/wpcom-fields/post-fields-publicize-connections.php
@@ -6,12 +6,13 @@
* { # Post Object
* ...
* jetpack_publicize_connections: { # Defined below in this file. See schema for more detail.
- * id: (string) Connection unique_id
- * service_name: (string) Service slug
- * display_name: (string) User name/display name of user/connection on Service
- * enabled: (boolean) Is this connection slated to be shared to? context=edit only
- * done: (boolean) Is this post (or connection) done sharing? context=edit only
- * toggleable: (boolean) Can the current user change the `enabled` setting for this Connection+Post? context=edit only
+ * id: (string) Connection unique_id
+ * service_name: (string) Service slug
+ * display_name: (string) User name/display name of user/connection on Service
+ * profile_picture: (string) Profile picture of user/connection on Service
+ * enabled: (boolean) Is this connection slated to be shared to? context=edit only
+ * done: (boolean) Is this post (or connection) done sharing? context=edit only
+ * toggleable: (boolean) Can the current user change the `enabled` setting for this Connection+Post? context=edit only
* }
* ...
* meta: { # Not defined in this file. Handled in modules/publicize/publicize.php via `register_meta()`
@@ -71,36 +72,42 @@ private function post_connection_schema() {
'title' => 'jetpack-publicize-post-connection',
'type' => 'object',
'properties' => array(
- 'id' => array(
+ 'id' => array(
'description' => __( 'Unique identifier for the Publicize Connection', 'jetpack' ),
'type' => 'string',
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
- 'service_name' => array(
+ 'service_name' => array(
'description' => __( 'Alphanumeric identifier for the Publicize Service', 'jetpack' ),
'type' => 'string',
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
- 'display_name' => array(
+ 'display_name' => array(
'description' => __( 'Username of the connected account', 'jetpack' ),
'type' => 'string',
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
- 'enabled' => array(
+ 'profile_picture' => array(
+ 'description' => __( 'Profile picture of the connected account', 'jetpack' ),
+ 'type' => 'string',
+ 'context' => array( 'view', 'edit' ),
+ 'readonly' => true,
+ ),
+ 'enabled' => array(
'description' => __( 'Whether to share to this connection', 'jetpack' ),
'type' => 'boolean',
'context' => array( 'edit' ),
),
- 'done' => array(
+ 'done' => array(
'description' => __( 'Whether Publicize has already finished sharing for this post', 'jetpack' ),
'type' => 'boolean',
'context' => array( 'edit' ),
'readonly' => true,
),
- 'toggleable' => array(
+ 'toggleable' => array(
'description' => __( 'Whether `enable` can be changed for this post/connection', 'jetpack' ),
'type' => 'boolean',
'context' => array( 'edit' ),
diff --git a/projects/plugins/jetpack/changelog/add-re-publicize-icon-component b/projects/plugins/jetpack/changelog/add-re-publicize-icon-component
new file mode 100644
index 0000000000000..1e312c57daec3
--- /dev/null
+++ b/projects/plugins/jetpack/changelog/add-re-publicize-icon-component
@@ -0,0 +1,4 @@
+Significance: minor
+Type: enhancement
+
+Add the user's profile picture and new styling to the Publicize toggle.
diff --git a/projects/plugins/jetpack/extensions/plugins/publicize/components/connection-icon/index.jsx b/projects/plugins/jetpack/extensions/plugins/publicize/components/connection-icon/index.jsx
new file mode 100644
index 0000000000000..477e3018ab701
--- /dev/null
+++ b/projects/plugins/jetpack/extensions/plugins/publicize/components/connection-icon/index.jsx
@@ -0,0 +1,40 @@
+/**
+ * External dependencies
+ */
+import PropTypes from 'prop-types';
+
+/**
+ * Internal dependencies
+ */
+import { SocialServiceIcon } from '../../../../shared/icons';
+
+/**
+ * Style dependencies
+ */
+import './style.scss';
+
+const ConnectionIcon = props => {
+ const { id, serviceName, label, profilePicture } = props;
+
+ return (
+
+ );
+};
+
+ConnectionIcon.propTypes = {
+ id: PropTypes.string.isRequired,
+ serviceName: PropTypes.string,
+ label: PropTypes.string,
+ profilePicture: PropTypes.string,
+};
+
+export default ConnectionIcon;
diff --git a/projects/plugins/jetpack/extensions/plugins/publicize/components/connection-icon/style.scss b/projects/plugins/jetpack/extensions/plugins/publicize/components/connection-icon/style.scss
new file mode 100644
index 0000000000000..d4917399c4401
--- /dev/null
+++ b/projects/plugins/jetpack/extensions/plugins/publicize/components/connection-icon/style.scss
@@ -0,0 +1,36 @@
+.jetpack-publicize-connection-label {
+ display: flex;
+ align-items: center;
+
+ // Icon and picture.
+ .components-connection-icon__picture {
+ display: grid;
+
+ img,
+ .placeholder {
+ border-radius: 2px;
+ width: 24px;
+ height: 24px;
+ grid-area: 1 / 1 / 2 / 2;
+ }
+
+ .placeholder {
+ display: block;
+ background-color: #a8bece;
+ }
+
+ svg {
+ width: 15px;
+ height: 15px;
+ grid-area: 1 / 1 / 2 / 2;
+ margin-top: 14px;
+ margin-left: 14px;
+ border-radius: 2px;
+ background-color: white;
+
+ &.is-facebook {
+ border-radius: 50%;
+ }
+ }
+ }
+}
diff --git a/projects/plugins/jetpack/extensions/plugins/publicize/components/connection-toggle/index.jsx b/projects/plugins/jetpack/extensions/plugins/publicize/components/connection-toggle/index.jsx
new file mode 100644
index 0000000000000..408780f81457b
--- /dev/null
+++ b/projects/plugins/jetpack/extensions/plugins/publicize/components/connection-toggle/index.jsx
@@ -0,0 +1,60 @@
+/**
+ * External dependencies
+ */
+import classnames from 'classnames';
+import PropTypes from 'prop-types';
+
+/**
+ * WordPress dependencies
+ */
+import { FormToggle } from '@wordpress/components';
+
+/**
+ * Internal dependencies
+ */
+import ConnectionIcon from '../connection-icon';
+
+/**
+ * Style dependencies
+ */
+import './style.scss';
+
+const ConnectionToggle = props => {
+ const { className, checked, id, disabled, onChange, serviceName, label, profilePicture } = props;
+
+ const wrapperClasses = classnames( 'components-connection-toggle', {
+ 'is-not-checked': ! checked,
+ 'is-disabled': disabled,
+ } );
+
+ return (
+
+
+
+
+ );
+};
+
+ConnectionToggle.propTypes = {
+ className: PropTypes.string,
+ checked: PropTypes.bool,
+ id: PropTypes.string.isRequired,
+ disabled: PropTypes.bool,
+ onChange: PropTypes.func,
+ serviceName: PropTypes.string,
+ label: PropTypes.string,
+ profilePicture: PropTypes.string,
+};
+
+export default ConnectionToggle;
diff --git a/projects/plugins/jetpack/extensions/plugins/publicize/components/connection-toggle/style.scss b/projects/plugins/jetpack/extensions/plugins/publicize/components/connection-toggle/style.scss
new file mode 100644
index 0000000000000..ea43164623b88
--- /dev/null
+++ b/projects/plugins/jetpack/extensions/plugins/publicize/components/connection-toggle/style.scss
@@ -0,0 +1,19 @@
+@import '../../../../shared/styles/gutenberg-base-styles.scss';
+
+.components-connection-toggle {
+ position: relative;
+ display: flex;
+ align-items: center;
+ width: 100%;
+
+ // Unchecked state.
+ &.is-not-checked .jetpack-gutenberg-social-icon {
+ fill: $gray-300;
+ }
+
+ // Disabled state:
+ &.is-disabled,
+ .components-disabled & {
+ opacity: 0.5;
+ }
+}
diff --git a/projects/plugins/jetpack/extensions/plugins/publicize/components/connection/index.js b/projects/plugins/jetpack/extensions/plugins/publicize/components/connection/index.js
index a106c86d0a0d8..908cd68052bd8 100644
--- a/projects/plugins/jetpack/extensions/plugins/publicize/components/connection/index.js
+++ b/projects/plugins/jetpack/extensions/plugins/publicize/components/connection/index.js
@@ -10,7 +10,7 @@
*/
import { __ } from '@wordpress/i18n';
import { Component } from '@wordpress/element';
-import { Disabled, FormToggle, Notice, ExternalLink } from '@wordpress/components';
+import { Disabled, Notice, ExternalLink } from '@wordpress/components';
import { withSelect } from '@wordpress/data';
import { includes } from 'lodash';
@@ -18,7 +18,7 @@ import { includes } from 'lodash';
* Internal dependencies
*/
import getSiteFragment from '../../../../shared/get-site-fragment';
-import { SocialServiceIcon } from '../../../../shared/icons';
+import ConnectionToggle from '../connection-toggle';
class PublicizeConnection extends Component {
/**
@@ -61,17 +61,21 @@ class PublicizeConnection extends Component {
}
render() {
- const { disabled, enabled, id, label, name } = this.props;
+ const { disabled, enabled, id, label, name, profilePicture } = this.props;
const fieldId = 'connection-' + name + '-' + id;
// Genericon names are dash separated
const serviceName = name.replace( '_', '-' );
let toggle = (
-
);
@@ -82,16 +86,7 @@ class PublicizeConnection extends Component {
return (
{ this.maybeDisplayLinkedInNotice() }
-
-
- { toggle }
-
+ { toggle }
);
}
diff --git a/projects/plugins/jetpack/extensions/plugins/publicize/components/form/index.js b/projects/plugins/jetpack/extensions/plugins/publicize/components/form/index.js
index f469890c438c6..298ca9fec2040 100644
--- a/projects/plugins/jetpack/extensions/plugins/publicize/components/form/index.js
+++ b/projects/plugins/jetpack/extensions/plugins/publicize/components/form/index.js
@@ -45,17 +45,20 @@ export default function PublicizeForm( {
{ hasConnections && (
- { connections.map( ( { display_name, enabled, id, service_name, toggleable } ) => (
-
- ) ) }
+ { connections.map(
+ ( { display_name, enabled, id, service_name, toggleable, profile_picture } ) => (
+
+ )
+ ) }
) }
diff --git a/projects/plugins/jetpack/extensions/plugins/publicize/editor.scss b/projects/plugins/jetpack/extensions/plugins/publicize/editor.scss
index 1e3af16c0c2a4..2e9c133fca408 100644
--- a/projects/plugins/jetpack/extensions/plugins/publicize/editor.scss
+++ b/projects/plugins/jetpack/extensions/plugins/publicize/editor.scss
@@ -13,6 +13,10 @@
.publicize-jetpack-connection-container {
display: flex;
+
+ .components-disabled {
+ width: 100%;
+ }
}
.jetpack-publicize-gutenberg-social-icon {
diff --git a/projects/plugins/jetpack/extensions/plugins/publicize/store/effects.js b/projects/plugins/jetpack/extensions/plugins/publicize/store/effects.js
index 51d66e5fb4f99..5aa7069086469 100644
--- a/projects/plugins/jetpack/extensions/plugins/publicize/store/effects.js
+++ b/projects/plugins/jetpack/extensions/plugins/publicize/store/effects.js
@@ -53,14 +53,10 @@ export async function refreshConnectionTestResults() {
done: false,
enabled: true,
toggleable: true,
+ profile_picture: freshConnection.profile_picture,
};
}
- // Populate the connection with extra fresh data.
- if ( freshConnection.profile_picture ) {
- connection.profile_picture = freshConnection.profile_picture;
- }
-
connections.push( connection );
}
diff --git a/projects/plugins/jetpack/extensions/shared/icons.js b/projects/plugins/jetpack/extensions/shared/icons.js
index e72a1201d5a1e..7ba7694f6446b 100644
--- a/projects/plugins/jetpack/extensions/shared/icons.js
+++ b/projects/plugins/jetpack/extensions/shared/icons.js
@@ -209,7 +209,10 @@ const FacebookIcon = (
);
@@ -217,7 +220,16 @@ const TwitterIcon = (
);
diff --git a/projects/plugins/jetpack/modules/publicize/publicize-jetpack.php b/projects/plugins/jetpack/modules/publicize/publicize-jetpack.php
index 358ddc0ecb01c..6f618c62e0604 100644
--- a/projects/plugins/jetpack/modules/publicize/publicize-jetpack.php
+++ b/projects/plugins/jetpack/modules/publicize/publicize-jetpack.php
@@ -5,6 +5,8 @@
class Publicize extends Publicize_Base {
+ const CONNECTION_REFRESH_WAIT_TRANSIENT = 'jetpack_publicize_connection_refresh_wait';
+
function __construct() {
parent::__construct();
@@ -37,6 +39,8 @@ function __construct() {
add_filter( 'jetpack_sharing_twitter_via', array( $this, 'get_publicized_twitter_account' ), 10, 2 );
+ add_action( 'updating_jetpack_version', array( $this, 'init_refresh_transient' ) );
+
include_once( JETPACK__PLUGIN_DIR . 'modules/publicize/enhanced-open-graph.php' );
jetpack_require_lib( 'class.jetpack-keyring-service-helper' );
@@ -118,6 +122,7 @@ function register_update_publicize_connections_xmlrpc_method( $methods ) {
}
function get_all_connections() {
+ $this->refresh_connections();
$connections = Jetpack_Options::get_option( 'publicize_connections' );
if ( isset( $connections['google_plus'] ) ) {
unset( $connections['google_plus'] );
@@ -272,6 +277,51 @@ function unglobalize_connection( $connection_id ) {
}
}
+ /**
+ * As Jetpack updates set the refresh transient to a random amount
+ * in order to spread out updates to the connection data.
+ *
+ * @param string $version The Jetpack version being updated to.
+ */
+ public function init_refresh_transient( $version ) {
+ if ( version_compare( $version, '10.2.1', '>=' ) && ! get_transient( self::CONNECTION_REFRESH_WAIT_TRANSIENT ) ) {
+ $this->set_refresh_wait_transient( wp_rand( 10, HOUR_IN_SECONDS * 24 ) );
+ }
+ }
+
+ /**
+ * Grabs a fresh copy of the publicize connections data.
+ * Only refreshes once every 12 hours or retries after an hour with an error.
+ */
+ public function refresh_connections() {
+ if ( get_transient( self::CONNECTION_REFRESH_WAIT_TRANSIENT ) ) {
+ return;
+ }
+ $xml = new Jetpack_IXR_Client();
+ $xml->query( 'jetpack.fetchPublicizeConnections' );
+ $wait_time = HOUR_IN_SECONDS * 24;
+
+ if ( ! $xml->isError() ) {
+ $response = $xml->getResponse();
+ $this->receive_updated_publicize_connections( $response );
+ } else {
+ // Retry a bit quicker, but still wait.
+ $wait_time = HOUR_IN_SECONDS;
+ }
+
+ $this->set_refresh_wait_transient( $wait_time );
+ }
+
+ /**
+ * Sets the transient to expire at the specified time in seconds.
+ * This prevents us from attempting to refresh the data too often.
+ *
+ * @param int $wait_time The number of seconds before the transient should expire.
+ */
+ public function set_refresh_wait_transient( $wait_time ) {
+ set_transient( self::CONNECTION_REFRESH_WAIT_TRANSIENT, microtime( true ), $wait_time );
+ }
+
function connect_url( $service_name, $for = 'publicize' ) {
return Jetpack_Keyring_Service_Helper::connect_url( $service_name, $for );
}
diff --git a/projects/plugins/jetpack/modules/publicize/publicize.php b/projects/plugins/jetpack/modules/publicize/publicize.php
index 44feb1f9586ab..32d43d092a232 100644
--- a/projects/plugins/jetpack/modules/publicize/publicize.php
+++ b/projects/plugins/jetpack/modules/publicize/publicize.php
@@ -400,6 +400,22 @@ function get_display_name( $service_name, $connection ) {
}
}
+ /**
+ * Returns a profile picture for the Connection
+ *
+ * @param object|array $connection The Connection object (WordPress.com) or array (Jetpack).
+ * @return string
+ */
+ private function get_profile_picture( $connection ) {
+ $cmeta = $this->get_connection_meta( $connection );
+
+ if ( isset( $cmeta['profile_picture'] ) ) {
+ return $cmeta['profile_picture'];
+ }
+
+ return '';
+ }
+
/**
* Whether the user needs to select additional options after connecting
*
@@ -590,14 +606,15 @@ abstract function test_connection( $service_name, $connection );
* @return array {
* Array of UI setup data for connection list form.
*
- * @type string 'unique_id' ID string representing connection
- * @type string 'service_name' Slug of the connection's service (facebook, twitter, ...)
- * @type string 'service_label' Service Label (Facebook, Twitter, ...)
- * @type string 'display_name' Connection's human-readable Username: "@jetpack"
- * @type bool 'enabled' Default value for the connection (e.g., for a checkbox).
- * @type bool 'done' Has this connection already been publicized to?
- * @type bool 'toggleable' Is the user allowed to change the value for the connection?
- * @type bool 'global' Is this connection a global one?
+ * @type string 'unique_id' ID string representing connection
+ * @type string 'service_name' Slug of the connection's service (facebook, twitter, ...)
+ * @type string 'service_label' Service Label (Facebook, Twitter, ...)
+ * @type string 'display_name' Connection's human-readable Username: "@jetpack"
+ * @type string 'profile_picture' Connection profile picture.
+ * @type bool 'enabled' Default value for the connection (e.g., for a checkbox).
+ * @type bool 'done' Has this connection already been publicized to?
+ * @type bool 'toggleable' Is the user allowed to change the value for the connection?
+ * @type bool 'global' Is this connection a global one?
* }
*/
public function get_filtered_connection_data( $selected_post_id = null ) {
@@ -720,15 +737,16 @@ public function get_filtered_connection_data( $selected_post_id = null ) {
}
$connection_list[] = array(
- 'unique_id' => $unique_id,
- 'service_name' => $service_name,
- 'service_label' => $this->get_service_label( $service_name ),
- 'display_name' => $this->get_display_name( $service_name, $connection ),
-
- 'enabled' => $enabled,
- 'done' => $done,
- 'toggleable' => $toggleable,
- 'global' => 0 == $connection_data['user_id'],
+ 'unique_id' => $unique_id,
+ 'service_name' => $service_name,
+ 'service_label' => $this->get_service_label( $service_name ),
+ 'display_name' => $this->get_display_name( $service_name, $connection ),
+ 'profile_picture' => $this->get_profile_picture( $connection ),
+
+ 'enabled' => $enabled,
+ 'done' => $done,
+ 'toggleable' => $toggleable,
+ 'global' => 0 == $connection_data['user_id'], // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison -- Other types can be used at times.
);
}
}