From da8e09868b832054451c46ed2b9594ca3c02c736 Mon Sep 17 00:00:00 2001 From: "Soare Robert Daniel (Mac 2023)" Date: Fri, 13 Oct 2023 17:18:40 +0300 Subject: [PATCH 01/11] fix: use only postMessages for OtterMemory --- src/blocks/helpers/block-utility.js | 69 +++++++++++++++++++++++++---- 1 file changed, 60 insertions(+), 9 deletions(-) diff --git a/src/blocks/helpers/block-utility.js b/src/blocks/helpers/block-utility.js index 9002de069..6222a98f1 100644 --- a/src/blocks/helpers/block-utility.js +++ b/src/blocks/helpers/block-utility.js @@ -526,12 +526,27 @@ export class GlobalStateMemory { */ handleMessage( event ) { if ( 'object' === typeof event.data && null !== event.data && 'otterMemoryState' in event.data ) { - const { key, value, location } = event.data.otterMemoryState; - if ( this.states[location] === undefined ) { - this.states[location] = {}; + const { key, value, location, action } = event.data.otterMemoryState; + + if ( 'set' === action ) { + if ( this.states[location] === undefined ) { + this.states[location] = {}; + } + + this.states[location][key] = value; } - this.states[location][key] = value; + if ( 'get' === action ) { + ( window.parent !== undefined ? window?.parent : window ) + .postMessage?.({ + otterMemoryState: { + key, + location, + value: this.getState( location, key ), + action: 'value' + } + }); + } } } @@ -558,20 +573,56 @@ export class GlobalStateMemory { */ export function useTabSwitch( key, defaultValue ) { const location = 'tab'; - const [ tab, setTab ] = useState( ( window?.parent ?? window ).otterStateMemory.getState( location, key ) ?? defaultValue ); + const [ tab, setTab ] = useState( defaultValue ); useEffect( () => { + + /** + * Retrieve the initial state from the parent via bi-directional communication. + */ + const listener = ( event ) => { + if ( 'object' === typeof event.data && null !== event.data && 'otterMemoryState' in event.data ) { + const { key: componentKey, value, location, action } = event.data.otterMemoryState; + if ( 'tab' === location && key === componentKey && 'value' === action ) { + setTab( value ?? defaultValue ); + } + } + }; + window.addEventListener( 'message', listener ); + + + // Request the state from the parent. ( window.parent !== undefined ? window?.parent : window ) - .postMessage?.({ + .postMessage({ otterMemoryState: { key, location, - value: tab + action: 'get' } }); - }, [ tab ]); - return [ tab, setTab ]; + + return () => { + window.removeEventListener( 'message', listener ); + }; + }, []); + + return [ tab, ( value ) => { + + /** + * Update the state in the parent. + */ + ( window.parent !== undefined ? window?.parent : window ) + .postMessage?.({ + otterMemoryState: { + key, + location, + value: value, + action: 'set' + } + }); + setTab( value ); + } ]; } From b6949cc8b58bedc893e2dea839dd5ecbbce273fa Mon Sep 17 00:00:00 2001 From: "Soare Robert Daniel (Mac 2023)" Date: Tue, 30 Jan 2024 15:50:32 +0200 Subject: [PATCH 02/11] feat: use black friday data from sdk --- inc/plugins/class-limited-offers.php | 137 +++++++++------------------ src/dashboard/components/Main.js | 2 +- 2 files changed, 44 insertions(+), 95 deletions(-) diff --git a/inc/plugins/class-limited-offers.php b/inc/plugins/class-limited-offers.php index c402743c5..86459792f 100644 --- a/inc/plugins/class-limited-offers.php +++ b/inc/plugins/class-limited-offers.php @@ -35,27 +35,41 @@ class LimitedOffers { * * @var array */ - public $offer_metadata = array(); + public $assets = array(); /** * Timeline for the offers. * * @var array[] */ - public $timelines = array( - 'bf' => array( - 'start' => '2023-11-20 00:00:00', - 'end' => '2023-11-27 23:59:00', - ), - ); + public $announcements = array(); /** * LimitedOffers constructor. */ public function __construct() { + $this->announcements = apply_filters( 'themeisle_sdk_announcements', array() ); + + if ( empty( $this->announcements ) || ! is_array( $this->announcements ) ) { + return; + } + try { - if ( $this->is_deal_active( 'bf' ) ) { - $this->activate_bff(); + foreach ( $this->announcements as $announcement => $event_data ) { + if ( false !== strpos( $announcement, 'black_friday' ) ) { + if ( + empty( $event_data ) || + ! is_array( $event_data ) || + empty( $event_data['active'] ) || + empty( $event_data['otter_dashboard_url'] ) || + ! isset( $event_data['urgency_text'] ) + ) { + continue; + } + + $this->active = $announcement; + $this->prepare_black_friday_assets( $event_data ); + } } } catch ( Exception $e ) { if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { @@ -70,6 +84,11 @@ public function __construct() { * @return void */ public function load_dashboard_hooks() { + + if ( empty( $this->assets['globalNoticeUrl'] ) ) { + return; + } + add_filter( 'themeisle_products_deal_priority', array( $this, 'add_priority' ) ); add_action( 'admin_notices', array( $this, 'render_notice' ) ); add_action( 'wp_ajax_dismiss_themeisle_event_notice_otter', array( $this, 'disable_notification_ajax' ) ); @@ -87,16 +106,19 @@ public function is_active() { /** * Activate the Black Friday deal. * + * @param array $data Event data. + * * @return void */ - public function activate_bff() { - $this->active = 'bf'; - - $this->offer_metadata = array( - 'bannerUrl' => OTTER_BLOCKS_URL . 'assets/images/black-friday-banner.png', - 'bannerAlt' => 'Otter Black Friday Sale', - 'linkDashboard' => tsdk_utmify( 'https://themeisle.com/plugins/otter-blocks/blackfriday/', 'blackfridayltd23', 'dashboard' ), - 'linkGlobal' => tsdk_utmify( 'https://themeisle.com/plugins/otter-blocks/blackfriday/', 'blackfridayltd23', 'globalnotice' ), + public function prepare_black_friday_assets( $data ) { + $this->assets = array_merge( + $this->assets, + array( + 'bannerUrl' => OTTER_BLOCKS_URL . 'assets/images/black-friday-banner.png', + 'bannerAlt' => 'Otter Black Friday Sale', + 'linkDashboard' => esc_url_raw( $data['otter_dashboard_url'] ), + 'urgencyText' => esc_html( $data['urgency_text'] ), + ) ); } @@ -109,77 +131,6 @@ public function get_active_deal() { return $this->active; } - /** - * Check if the deal is active with the given slug. - * - * @param string $slug Slug of the deal. - * - * @throws Exception When date is invalid. - */ - public function is_deal_active( $slug ) { - - if ( empty( $slug ) || ! array_key_exists( $slug, $this->timelines ) ) { - return false; - } - - return $this->check_date_range( $this->timelines[ $slug ]['start'], $this->timelines[ $slug ]['end'] ); - } - - /** - * Get the remaining time for the deal in a human readable format. - * - * @param string $slug Slug of the deal. - * @return string Remaining time for the deal. - */ - public function get_remaining_time_for_deal( $slug ) { - if ( empty( $slug ) || ! array_key_exists( $slug, $this->timelines ) ) { - return ''; - } - - try { - $end_date = new DateTime( $this->timelines[ $slug ]['end'], new DateTimeZone( 'GMT' ) ); - $current_date = new DateTime( 'now', new DateTimeZone( 'GMT' ) ); - $diff = $end_date->diff( $current_date ); - - if ( 0 < $diff->days ) { - return 1 === $diff->days ? $diff->format( '%a day' ) : $diff->format( '%a days' ); - } - - if ( 0 < $diff->h ) { - return 1 === $diff->h ? $diff->format( '%h hour' ) : $diff->format( '%h hours' ); - } - - if ( 0 < $diff->i ) { - return 1 === $diff->i ? $diff->format( '%i minute' ) : $diff->format( '%i minutes' ); - } - - return 1 === $diff->s ? $diff->format( '%s second' ) : $diff->format( '%s seconds' ); - } catch ( Exception $e ) { - if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { - error_log( $e->getMessage() ); // phpcs:ignore - } - } - - return ''; - } - - /** - * Check if the current date is in the range of the offer. - * - * @param string $start Start date. - * @param string $end End date. - * - * @throws Exception When date is invalid. - */ - public function check_date_range( $start, $end ) { - - $start_date = new DateTime( $start, new DateTimeZone( 'GMT' ) ); - $end_date = new DateTime( $end, new DateTimeZone( 'GMT' ) ); - $current_date = new DateTime( 'now', new DateTimeZone( 'GMT' ) ); - - return $start_date <= $current_date && $current_date <= $end_date; - } - /** * Get the localized data for the plugin. * @@ -188,12 +139,10 @@ public function check_date_range( $start, $end ) { public function get_localized_data() { return array_merge( array( - 'active' => $this->is_active(), - 'dealSlug' => $this->get_active_deal(), - 'remainingTime' => $this->get_remaining_time_for_deal( $this->get_active_deal() ), - 'urgencyText' => 'Hurry Up! Only ' . $this->get_remaining_time_for_deal( $this->get_active_deal() ) . ' left', + 'active' => $this->is_active(), + 'dealSlug' => $this->get_active_deal(), ), - $this->offer_metadata + $this->assets ); } @@ -262,7 +211,7 @@ public function render_notice() { - + diff --git a/src/dashboard/components/Main.js b/src/dashboard/components/Main.js index 888ded122..7c3a3a707 100644 --- a/src/dashboard/components/Main.js +++ b/src/dashboard/components/Main.js @@ -84,7 +84,7 @@ const Main = ({ return ( { - window.otterObj.deal.active && ( + ( window.otterObj?.deal?.active && window.otterObj.deal?.linkDashboard ) && ( Date: Tue, 30 Jan 2024 16:51:21 +0200 Subject: [PATCH 03/11] refactor: assets name --- inc/plugins/class-limited-offers.php | 8 ++++---- src/dashboard/components/Main.js | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/inc/plugins/class-limited-offers.php b/inc/plugins/class-limited-offers.php index 86459792f..8922929d7 100644 --- a/inc/plugins/class-limited-offers.php +++ b/inc/plugins/class-limited-offers.php @@ -114,10 +114,10 @@ public function prepare_black_friday_assets( $data ) { $this->assets = array_merge( $this->assets, array( - 'bannerUrl' => OTTER_BLOCKS_URL . 'assets/images/black-friday-banner.png', - 'bannerAlt' => 'Otter Black Friday Sale', - 'linkDashboard' => esc_url_raw( $data['otter_dashboard_url'] ), - 'urgencyText' => esc_html( $data['urgency_text'] ), + 'bannerUrl' => OTTER_BLOCKS_URL . 'assets/images/black-friday-banner.png', + 'bannerAlt' => 'Otter Black Friday Sale', + 'bannerStoreUrl' => esc_url_raw( $data['otter_dashboard_url'] ), + 'urgencyText' => esc_html( $data['urgency_text'] ), ) ); } diff --git a/src/dashboard/components/Main.js b/src/dashboard/components/Main.js index 7c3a3a707..6471f8e6b 100644 --- a/src/dashboard/components/Main.js +++ b/src/dashboard/components/Main.js @@ -84,9 +84,9 @@ const Main = ({ return ( { - ( window.otterObj?.deal?.active && window.otterObj.deal?.linkDashboard ) && ( + ( window.otterObj?.deal?.active && window.otterObj.deal?.bannerStoreUrl ) && ( Date: Wed, 7 Feb 2024 12:11:07 +0200 Subject: [PATCH 04/11] chore: update phpdocs --- inc/plugins/class-limited-offers.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/inc/plugins/class-limited-offers.php b/inc/plugins/class-limited-offers.php index 8922929d7..527e27f19 100644 --- a/inc/plugins/class-limited-offers.php +++ b/inc/plugins/class-limited-offers.php @@ -31,16 +31,16 @@ class LimitedOffers { public $wp_option_dismiss_notification_key_base = 'dismiss_themeisle_notice_event_'; /** - * Offer Links + * Metadata for announcements. * - * @var array + * @var array */ public $assets = array(); /** * Timeline for the offers. * - * @var array[] + * @var array */ public $announcements = array(); From 7956017162fe3ac7414b90d4136796a0f708703e Mon Sep 17 00:00:00 2001 From: Hardeep Asrani Date: Fri, 16 Feb 2024 20:20:52 +0530 Subject: [PATCH 05/11] fix: improvements to onboarding loading --- src/onboarding/components/Main.js | 15 ++++++++++++++- src/onboarding/components/Sidebar.js | 15 ++++++++++++++- src/onboarding/hooks/index.js | 7 ++++++- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/onboarding/components/Main.js b/src/onboarding/components/Main.js index 46fd9c81e..c8a78b0d0 100644 --- a/src/onboarding/components/Main.js +++ b/src/onboarding/components/Main.js @@ -7,6 +7,11 @@ import { Spinner } from '@wordpress/components'; import { useSelect } from '@wordpress/data'; +import { + useEffect, + useState +} from '@wordpress/element'; + /** * Internal dependencies. */ @@ -21,9 +26,17 @@ const Main = ({ isEditorLoading }) => { }; }); + const [ isLoading, setIsLoading ] = useState( true ); + const Controls = STEP_DATA[ currentStep ]?.content || null; - if ( isEditorLoading ) { + useEffect( () => { + if ( ! isEditorLoading ) { + setIsLoading( false ); + } + }, [ isEditorLoading ]); + + if ( isLoading ) { return (
diff --git a/src/onboarding/components/Sidebar.js b/src/onboarding/components/Sidebar.js index 16b967a10..9d74f82f6 100644 --- a/src/onboarding/components/Sidebar.js +++ b/src/onboarding/components/Sidebar.js @@ -14,6 +14,11 @@ import { useSelect } from '@wordpress/data'; +import { + useEffect, + useState +} from '@wordpress/element'; + /** * Internal dependencies. */ @@ -56,15 +61,23 @@ const Sidebar = ({ isEditorLoading }) => { onContinue } = useDispatch( 'otter/onboarding' ); + const [ isLoading, setIsLoading ] = useState( true ); + const Controls = STEP_DATA[ currentStep ]?.controls || null; + useEffect( () => { + if ( ! isEditorLoading ) { + setIsLoading( false ); + } + }, [ isEditorLoading ]); + const onExit = () => { window.open( siteURL, '_self' ); }; return (
- { ( isEditorLoading || isSaving ) && ( + { ( isLoading || isSaving ) && (
diff --git a/src/onboarding/hooks/index.js b/src/onboarding/hooks/index.js index 5ac46813e..022b98be2 100644 --- a/src/onboarding/hooks/index.js +++ b/src/onboarding/hooks/index.js @@ -1,8 +1,13 @@ /** * WordPress dependencies */ -import { useEffect, useState } from '@wordpress/element'; +import { + useEffect, + useState +} from '@wordpress/element'; + import { useSelect } from '@wordpress/data'; + import { decodeEntities } from '@wordpress/html-entities'; const MAX_LOADING_TIME = 10000; // 10 seconds From ca4b4cbfc114509c17273f178d108e014f51c459 Mon Sep 17 00:00:00 2001 From: Hardeep Asrani Date: Fri, 16 Feb 2024 20:48:35 +0530 Subject: [PATCH 06/11] fix: mention plan name in Search extension --- src/blocks/plugins/live-search/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blocks/plugins/live-search/index.js b/src/blocks/plugins/live-search/index.js index dc5078335..fc6f19df2 100644 --- a/src/blocks/plugins/live-search/index.js +++ b/src/blocks/plugins/live-search/index.js @@ -45,7 +45,7 @@ const liveSearchUpsell = createHigherOrderComponent( BlockEdit => { /> { __( 'Unlock this with Otter Pro.', 'otter-blocks' ) } } + notice={ { __( 'Unlock this with Otter Pro\'s Agency Plan.', 'otter-blocks' ) } } variant="upsell" />