Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions assets/src/dashboard/parts/components/Modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { close } from '@wordpress/icons';
import { useViewportMatch } from '@wordpress/compose';
import { Button, Icon, Modal as CoreModal } from '@wordpress/components';

export default function Modal({ icon, labels = {}, onRequestClose = () => {}, onConfirm = () => {}, variant = 'default', onSecondaryAction = () => {} }) {
export default function Modal({ icon, labels = {}, onRequestClose = () => {}, onConfirm = () => {}, variant = 'default', onSecondaryAction = () => {}, afterContentChildren = null }) {

const isMobileViewport = useViewportMatch( 'small', '<' );

Expand Down Expand Up @@ -53,7 +53,8 @@ export default function Modal({ icon, labels = {}, onRequestClose = () => {}, on
className="text-center mx-0 my-4 text-gray-700"
dangerouslySetInnerHTML={ { __html: labels.description } }
/>
<div class="flex gap-4">
{ afterContentChildren }
<div className="flex gap-4">
<Button variant="primary" className={ actionButtonClasses } onClick={ onConfirm }>
{ labels.action }
</Button>
Expand Down
53 changes: 42 additions & 11 deletions assets/src/dashboard/parts/connected/settings/OffloadMedia.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* global optimoleDashboardApp */

import classnames from 'classnames';
import { useEffect, useState } from '@wordpress/element';
import { useEffect, useState, useMemo } from '@wordpress/element';
import { useDispatch, useSelect } from '@wordpress/data';
import { Icon } from '@wordpress/icons';

Expand Down Expand Up @@ -37,7 +37,9 @@ const OffloadMedia = ({ settings, canSave, setSettings, setCanSave }) => {
processedImages,
offloadFinishNotice,
offloadLimitReached,
offloadLimit
offloadLimit,
canUseMediaOffloadingFlag,
canShowFreeUserWithOffloadNoticeFlag
} = useSelect( select => {
const {
getOffloadConflicts,
Expand All @@ -51,9 +53,13 @@ const OffloadMedia = ({ settings, canSave, setSettings, setCanSave }) => {
getQueryArgs,
isLoading,
getSiteSettings,
getOffloadLimit
getOffloadLimit,
getUserData,
canShowFreeUserWithOffloadNotice
} = select( 'optimole' );

const userData = getUserData();

return {
offloadConflicts: getOffloadConflicts(),
errorMedia: getErrorMedia(),
Expand All @@ -67,7 +73,9 @@ const OffloadMedia = ({ settings, canSave, setSettings, setCanSave }) => {
processedImages: getProcessedImages(),
offloadFinishNotice: getSiteSettings( 'show_offload_finish_notice' ),
offloadLimitReached: 'enabled' === getSiteSettings( 'offload_limit_reached' ),
offloadLimit: getOffloadLimit()
offloadLimit: getOffloadLimit(),
canUseMediaOffloadingFlag: Boolean( userData?.can_use_offloading ),
canShowFreeUserWithOffloadNoticeFlag: canShowFreeUserWithOffloadNotice()
};
}, []);

Expand All @@ -85,6 +93,9 @@ const OffloadMedia = ({ settings, canSave, setSettings, setCanSave }) => {
const isOffloadingInProgress = 'disabled' !== settings['offloading_status'];
const isRollbackInProgress = 'disabled' !== settings['rollback_status'];

const showDisabledOffloadingNotice = useMemo( () => {
return 'enabled' === settings?.['offload_media'] && ! canUseMediaOffloadingFlag && canShowFreeUserWithOffloadNoticeFlag;
}, [ settings, canUseMediaOffloadingFlag, canShowFreeUserWithOffloadNoticeFlag ]);

useEffect( () => {
if ( isOffloadingInProgress ) {
Expand Down Expand Up @@ -187,18 +198,28 @@ const OffloadMedia = ({ settings, canSave, setSettings, setCanSave }) => {
[MODAL_STATE_OFFLOAD]: {
icon: offload,
onConfirm: () => {
nextSettings['offload_media'] = 'offload' === optionValue ? 'enabled' : 'disabled';
setSettings( nextSettings );
setCanSave( true );

onOffloadMedia();
if ( canUseMediaOffloadingFlag ) {
nextSettings['offload_media'] = 'offload' === optionValue ? 'enabled' : 'disabled';
setSettings( nextSettings );
setCanSave( true );

onOffloadMedia();
} else {
window.open( optimoleDashboardApp?.offload_upgrade_url, '_blank' );
}
setModal( null );
},
labels: {
title: options_strings.offloading_start_title,
description: options_strings.offloading_start_description,
action: options_strings.offloading_start_action
}
action: canUseMediaOffloadingFlag ? options_strings.offloading_start_action : optimoleDashboardApp.strings.upgrade.title_long
},
afterContentChildren: ! canUseMediaOffloadingFlag && (
<Notice
type="warning"
text={options_strings.upgrade_to_use_offloading_notice_desc}
/>
)
},
[MODAL_STATE_ROLLBACK]: {
icon: rollbackIcon,
Expand Down Expand Up @@ -322,6 +343,16 @@ const OffloadMedia = ({ settings, canSave, setSettings, setCanSave }) => {
<h1 className="text-xl font-bold">{options_strings.enable_offload_media_title}</h1>
<p dangerouslySetInnerHTML={{ __html: options_strings.enable_offload_media_desc }}/>

{
showDisabledOffloadingNotice && (
<Notice
type="warning"
title={options_strings.plan_update_notice_title}
text={options_strings.plan_update_notice_desc}
/>
)
}

{offloadFinishNotice && (
<Notice
title={'offload' === offloadFinishNotice ? options_strings.offloading_success : options_strings.rollback_success }
Expand Down
3 changes: 2 additions & 1 deletion assets/src/dashboard/store/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ const DEFAULT_STATE = {
logs: {
offload: '',
rollback: ''
}
},
canShowFreeUserWithOffloadNotice: 'yes' === optimoleDashboardApp?.show_free_user_with_offload_notice
};

const reducer = ( state = DEFAULT_STATE, action ) => {
Expand Down
3 changes: 3 additions & 0 deletions assets/src/dashboard/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ const selectors = {
},
isSubApiKey( state ) {
return state.apiKey && state.apiKey.startsWith( 'optml-s' );
},
canShowFreeUserWithOffloadNotice( state ) {
return Boolean( state?.canShowFreeUserWithOffloadNotice );
}
};

Expand Down
37 changes: 35 additions & 2 deletions inc/admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ public function __construct() {
}

add_filter( 'themeisle-sdk/survey/' . OPTML_PRODUCT_SLUG, [ $this, 'get_survey_metadata' ], 10, 2 );
add_action( 'admin_init', [ $this, 'mark_user_with_offload' ] );
}

/**
Expand Down Expand Up @@ -1070,8 +1071,16 @@ public function daily_sync() {
if ( isset( $data['extra_visits'] ) ) {
$this->settings->update_frontend_banner_from_remote( $data['extra_visits'] );
}

// Here the account got deactivated, in this case we check if the user is using offloaded images and we roll them back.
if ( isset( $data['status'] ) && $data['status'] === 'inactive' ) {
$should_revert_offloading = isset( $data['status'] ) && $data['status'] === 'inactive';

// The user is now on a plan without offloading and the grace period is over.
if ( isset( $data['should_revert_offload'] ) && (bool) $data['should_revert_offload'] ) {
$should_revert_offloading = true;
}

if ( $should_revert_offloading ) {
// We check if the user has images offloaded.
if ( $this->settings->get( 'offload_media' ) === 'disabled' ) {
return;
Expand Down Expand Up @@ -1375,6 +1384,7 @@ private function localize_dashboard_app() {
'optimoleHome' => tsdk_translate_link( 'https://optimole.com/' ),
'optimoleDashHome' => tsdk_translate_link( 'https://dashboard.optimole.com/', 'query' ),
'optimoleDashBilling' => tsdk_translate_link( 'https://dashboard.optimole.com/settings/billing', 'query' ),
'offload_upgrade_url' => tsdk_translate_link( tsdk_utmify( 'https://optimole.com/pricing/', 'offload' ) ),
'days_since_install' => round( ( time() - get_option( 'optimole_wp_install', 0 ) ) / DAY_IN_SECONDS ),
'is_offload_media_available' => $is_offload_media_available,
'auto_connect' => $auto_connect,
Expand All @@ -1389,6 +1399,7 @@ private function localize_dashboard_app() {
'bf_notices' => $this->get_bf_notices(),
'spc_banner' => $this->get_spc_banner(),
'show_exceed_plan_quota_notice' => $this->should_show_exceed_quota_warning(),
'show_free_user_with_offload_notice' => get_option( 'optml_has_offloading_enabled_on_upgrade', 'no' ),
'report_issue_url' => add_query_arg(
[
'utm_source' => 'plugin',
Expand Down Expand Up @@ -1626,7 +1637,7 @@ private function get_dashboard_strings() {
' <a href="' . esc_url( tsdk_translate_link( 'https://dashboard.optimole.com/register', 'query' ) ) . '" target="_blank">optimole.com</a>'
),
'account_needed_subtitle_1' => sprintf(
/* translators: 1 is starting bold tag, 2 is ending bold tag, 3 is the starting bold tag, 4 is the limit number, 5 is ending bold tag, 6 is the starting anchor tag for the docs link on how we count visits, 7 is the ending anchor tag. */
/* translators: 1 is the starting bold tag, 2 is the ending bold tag, 3 is the starting bold tag, 4 is the limit number, 5 is ending bold tag, 6 is the starting anchor tag for the docs link on how we count visits, 7 is the ending anchor tag. */
__( '%1$sOptimize unlimited images%2$s for up to %3$s monthly %4$svisitors%5$s - completely FREE.', 'optimole-wp' ),
'<strong>',
'</strong>',
Expand Down Expand Up @@ -2085,6 +2096,9 @@ private function get_dashboard_strings() {
'exceed_plan_quota_notice_description' => sprintf( /* translators: 1 is the starting anchor tag, 2 is the ending anchor tag */ __( 'Based on this trend, you are likely to exceed your free quota before the month ends. To avoid any disruption in service, we strongly recommend %1$supgrading%2$s your plan or waiting until your traffic stabilizes before offloading your images. Do you still wish to proceed?', 'optimole-wp' ), '<a style="white-space: nowrap;" target=”_blank” href="https://dashboard.optimole.com/settings/billing/">', '</a>' ),
'exceed_plan_quota_notice_start_action' => __( 'Yes, Transfer to Optimole Cloud', 'optimole-wp' ),
'exceed_plan_quota_notice_secondary_action' => __( 'No, keep images on my website', 'optimole-wp' ),
'plan_update_notice_title' => __( 'Plan Update', 'optimole-wp' ),
'plan_update_notice_desc' => __( 'We\'ve changed how plans work. Users on the Optimole Free plan cannot offload new images. Existing images that are already offloaded will remain offloaded.', 'optimole-wp' ),
'upgrade_to_use_offloading_notice_desc' => __( 'Offloading images is a PRO feature. Please upgrade your plan to enable image transfer to Optimole Cloud.', 'optimole-wp' ),
'visual_settings' => __( 'Visual Settings', 'optimole-wp' ),
'extended_features' => __( 'Extended Features', 'optimole-wp' ),
// translators: mark that the options are aplied globally.
Expand Down Expand Up @@ -2376,4 +2390,23 @@ private function get_active_notices_count() {

return $conflicts_count - count( $dismissed_notices );
}

/**
* Mark if the user had offloading enabled on first run.
*
* If it is an old free user that had offloading enabled, we will use the mark to show a notice about the plan changes.
*
* @return void
*/
public function mark_user_with_offload() {
if ( ! $this->settings->is_connected() ) {
return;
}

if ( false !== get_option( 'optml_has_offloading_enabled_on_upgrade', false ) ) {
return;
}

update_option( 'optml_has_offloading_enabled_on_upgrade', $this->settings->is_offload_enabled() ? 'yes' : 'no' );
}
}
2 changes: 1 addition & 1 deletion inc/main.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ final class Optml_Main {
/**
* Optml_Main The single instance of Starter_Plugin.
*
* @var object
* @var Optml_Main|null
* @access private
* @since 1.0.0
*/
Expand Down
Loading