Skip to content

Commit 8950a11

Browse files
fix: file conflicts
2 parents 8af5483 + 00b10f2 commit 8950a11

File tree

5 files changed

+274
-3
lines changed

5 files changed

+274
-3
lines changed
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
import { useState, useEffect } from '@wordpress/element';
2+
import { close, check } from '@wordpress/icons';
3+
import { Button, Icon } from '@wordpress/components';
4+
import classNames from 'classnames';
5+
6+
7+
import { installPlugin, activatePlugin } from '../../utils/plugin-install';
8+
import { dismissNotice } from '../../utils/api';
9+
10+
const STATUSES = {
11+
IDLE: 'idle',
12+
INSTALLING: 'installing',
13+
ACTIVATING: 'activating',
14+
ACTIVE: 'active',
15+
ERROR: 'error'
16+
};
17+
18+
const SPC_SLUG = 'wp-cloudflare-page-cache';
19+
20+
const SPCRecommendation = () => {
21+
const {
22+
i18n,
23+
activate_url: spcActivateURL,
24+
banner_dismiss_key: bannerDismissKey,
25+
status: initialStatus
26+
} = optimoleDashboardApp.spc_banner;
27+
28+
const [ status, setStatus ] = useState( 'installed' === initialStatus ? STATUSES.INSTALLED : STATUSES.IDLE );
29+
const [ isVisible, setIsVisible ] = useState( true );
30+
const [ shouldRender, setShouldRender ] = useState( true );
31+
32+
const isLoading = status === STATUSES.INSTALLING || status === STATUSES.ACTIVATING;
33+
34+
const installActivePlugin = ( e ) => {
35+
e.preventDefault();
36+
37+
if ( status === STATUSES.INSTALLED ) {
38+
setStatus( STATUSES.ACTIVATING );
39+
activatePlugin( spcActivateURL ).then( ( response ) => {
40+
if ( response.success ) {
41+
setStatus( STATUSES.ACTIVE );
42+
} else {
43+
setStatus( STATUSES.ERROR );
44+
}
45+
});
46+
return;
47+
}
48+
49+
setStatus( STATUSES.INSTALLING );
50+
51+
installPlugin( SPC_SLUG ).then( ( response ) => {
52+
if ( response.success ) {
53+
setStatus( STATUSES.ACTIVATING );
54+
55+
activatePlugin( spcActivateURL ).then( ( response ) => {
56+
if ( response.success ) {
57+
setStatus( STATUSES.ACTIVE );
58+
} else {
59+
setStatus( STATUSES.ERROR );
60+
}
61+
});
62+
} else {
63+
setStatus( STATUSES.ERROR );
64+
}
65+
});
66+
};
67+
68+
69+
const onDismiss = () => {
70+
dismissNotice( bannerDismissKey, () => {
71+
setIsVisible( false );
72+
});
73+
};
74+
75+
useEffect( () => {
76+
if ( ! isVisible ) {
77+
const timer = setTimeout( () => {
78+
setShouldRender( false );
79+
}, 300 );
80+
return () => clearTimeout( timer );
81+
}
82+
}, [ isVisible ]);
83+
84+
if ( ! shouldRender ) {
85+
return null;
86+
}
87+
88+
const wrapClasses = classNames(
89+
'bg-white flex flex-col text-gray-700 border-0 rounded-lg overflow-hidden shadow-md relative transition-opacity duration-300',
90+
{
91+
'opacity-0': ! isVisible,
92+
'opacity-100': isVisible
93+
}
94+
);
95+
96+
return (
97+
<div className={ wrapClasses }>
98+
<button onClick={ onDismiss } className="absolute top-2 right-2 p-1 bg-transparent border-0 text-red z-10 cursor-pointer rounded-full flex items-center justify-center hover:opacity-75 transition-opacity text-gray-500 hover:text-info">
99+
<span className="sr-only">{i18n.dismiss}</span>
100+
<Icon icon={ close } className="fill-current" size={ 18 } />
101+
</button>
102+
<div className="p-8 flex flex-col gap-2">
103+
<h3 className="text-gray-800 text-lg font-bold m-0">{ i18n.title }</h3>
104+
<p className="text-gray-600 m-0">{ i18n.byline }</p>
105+
<ul className="grid gap-2">
106+
{ i18n.features.map( ( feature, index ) => (
107+
<li className="flex items-center gap-2" key={ index }>
108+
<Icon icon={ check } className="fill-info bg-info/20 rounded-full" size={ 20 } />
109+
<span className="text-gray-700 font-normal">{ feature }</span>
110+
</li>
111+
) ) }
112+
</ul>
113+
{ ! [ STATUSES.ACTIVE, STATUSES.ERROR ].includes( status ) && (
114+
<Button
115+
variant="primary"
116+
onClick={installActivePlugin}
117+
className="flex w-full justify-center font-bold rounded hover:opacity-90 transition-opacity"
118+
disabled={ isLoading }
119+
isBusy={ isLoading }
120+
>
121+
{ status === STATUSES.IDLE && i18n.cta }
122+
{ status === STATUSES.INSTALLED && i18n.activate }
123+
{ status === STATUSES.INSTALLING && i18n.installing }
124+
{ status === STATUSES.ACTIVATING && i18n.activating }
125+
</Button>
126+
) }
127+
128+
{ status === STATUSES.ACTIVE && (
129+
<div className="flex items-center justify-center gap-3 py-3 px-4 rounded-md bg-emerald-100 border border-solid border-emerald-200">
130+
<span className="font-medium text-sm text-emerald-700">{ i18n.activated }</span>
131+
</div>
132+
) }
133+
134+
{ status === STATUSES.ERROR && (
135+
<div className="text-center py-3 px-4 rounded-md bg-red-100 border border-solid border-red-200">
136+
<span className="font-medium text-sm text-red-700">{ i18n.error }</span>
137+
</div>
138+
) }
139+
</div>
140+
</div>
141+
);
142+
};
143+
144+
export default SPCRecommendation;

assets/src/dashboard/parts/connected/Sidebar.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { useSelect } from '@wordpress/data';
1212

1313
import { addQueryArgs } from '@wordpress/url';
1414

15+
import SPCRecommendation from './SPCRecommendation';
1516
const reasons = [
1617
optimoleDashboardApp.strings.upgrade.reason_1,
1718
optimoleDashboardApp.strings.upgrade.reason_2,
@@ -62,6 +63,8 @@ const Sidebar = () => {
6263
};
6364
});
6465

66+
const showSPCRecommendation = null !== optimoleDashboardApp.spc_banner;
67+
6568
return (
6669
<div className="grid md:grid-cols-2 xl:flex xl:flex-col xl:mt-8 xl:mb-5 p-0 transition-all ease-in-out duration-700 gap-5 shrink-0 xl:w-[350px]">
6770
<div className="bg-white gap-5 flex flex-col text-gray-700 border-0 rounded-lg shadow-md p-8">
@@ -173,6 +176,9 @@ const Sidebar = () => {
173176
/>
174177
</div>
175178
) }
179+
{ showSPCRecommendation && (
180+
<SPCRecommendation />
181+
) }
176182
</div>
177183
);
178184
};

assets/src/dashboard/parts/connecting/index.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,21 @@ const ConnectingLayout = () => {
2424
const [ progress, setProgress ] = useState( 0 );
2525
const [ step, setStep ] = useState( 0 );
2626
const [ timer, setTimer ] = useState( 0 );
27-
const maxTime = 25;
27+
const maxTime = 5;
2828

2929
const { sethasDashboardLoaded } = useDispatch( 'optimole' );
3030

3131
useEffect( () => {
3232
if ( timer <= maxTime ) {
33-
setTimeout( () => {
33+
const timeout = setTimeout( () => {
3434
updateProgress();
3535
}, 1000 );
36+
37+
return () => {
38+
if ( timeout ) {
39+
clearTimeout( timeout );
40+
}
41+
};
3642
}
3743
}, [ timer ]);
3844

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
const installPlugin = ( slug ) => {
2+
return new Promise( ( resolve ) => {
3+
wp.updates.ajax( 'install-plugin', {
4+
slug,
5+
success: () => {
6+
resolve({ success: true });
7+
},
8+
error: ( err ) => {
9+
resolve({ success: false, code: err.errorCode });
10+
}
11+
});
12+
});
13+
};
14+
15+
const activatePlugin = ( url ) => {
16+
return new Promise( ( resolve ) => {
17+
fetch( url )
18+
.then( () => {
19+
resolve({ success: true });
20+
})
21+
.catch( () => {
22+
resolve({ success: false });
23+
});
24+
});
25+
};
26+
27+
export { installPlugin, activatePlugin };

inc/admin.php

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ class Optml_Admin {
2222
const IMAGE_DATA_COLLECTED_BATCH = 100;
2323

2424
const BF_PROMO_DISMISS_KEY = 'optml_bf24_notice_dismiss';
25+
26+
const SPC_BANNER_DISMISS_KEY = 'optml_spc_banner_dismiss';
27+
2528
/**
2629
* Hold the settings object.
2730
*
@@ -1243,7 +1246,7 @@ public function enqueue() {
12431246
wp_register_script(
12441247
OPTML_NAMESPACE . '-admin',
12451248
OPTML_URL . 'assets/build/dashboard/index.js',
1246-
$asset_file['dependencies'],
1249+
array_merge( $asset_file['dependencies'], [ 'updates' ] ),
12471250
$asset_file['version'],
12481251
true
12491252
);
@@ -1340,9 +1343,94 @@ private function localize_dashboard_app() {
13401343
],
13411344
],
13421345
'bf_notices' => $this->get_bf_notices(),
1346+
'spc_banner' => $this->get_spc_banner(),
1347+
];
1348+
}
1349+
1350+
/**
1351+
* Get the SPC banner data.
1352+
*
1353+
* @return array|null
1354+
*/
1355+
private function get_spc_banner() {
1356+
// User can't dismiss notice or install plugins.
1357+
if ( ! current_user_can( 'manage_options' ) || ! current_user_can( 'install_plugins' ) ) {
1358+
return null;
1359+
}
1360+
1361+
// User has dismissed the notice.
1362+
if ( get_option( self::SPC_BANNER_DISMISS_KEY ) === 'yes' ) {
1363+
return null;
1364+
}
1365+
1366+
// User has installed the pro plugin.
1367+
if ( defined( 'SPC_PRO_PATH' ) ) {
1368+
return null;
1369+
}
1370+
1371+
// User has installed the plugin.
1372+
if ( defined( 'SPC_PATH' ) ) {
1373+
return null;
1374+
}
1375+
1376+
return [
1377+
'activate_url' => $this->get_spc_activate_url(),
1378+
'status' => $this->get_spc_status(),
1379+
'banner_dismiss_key' => self::SPC_BANNER_DISMISS_KEY,
1380+
'i18n' => [
1381+
'dismiss' => __( 'Dismiss', 'optimole-wp' ),
1382+
'title' => __( 'Pair Optimole with Super Page Cache', 'optimole-wp' ),
1383+
'byline' => __( 'Improve your Core Web Vitals with our recommended caching solution', 'optimole-wp' ),
1384+
'features' => [
1385+
__( 'Edge Caching (with Cloudflare free plan)', 'optimole-wp' ),
1386+
__( 'Works with Optimole optimization', 'optimole-wp' ),
1387+
__( 'Lightning Speed Disk Caching', 'optimole-wp' ),
1388+
],
1389+
'cta' => __( 'Get Super Page Cache', 'optimole-wp' ),
1390+
'activate' => __( 'Activate Super Page Cache', 'optimole-wp' ),
1391+
'installing' => __( 'Installing Super Page Cache...', 'optimole-wp' ),
1392+
'activating' => __( 'Activating Super Page Cache...', 'optimole-wp' ),
1393+
'activated' => __( 'Super Page Cache is active!', 'optimole-wp' ),
1394+
'error' => __( 'Something went wrong. Please refresh the page and try again.', 'optimole-wp' ),
1395+
],
13431396
];
13441397
}
13451398

1399+
/**
1400+
* Get the SPC activate URL.
1401+
*
1402+
* @return string
1403+
*/
1404+
private function get_spc_activate_url() {
1405+
return add_query_arg(
1406+
[
1407+
'plugin_status' => 'all',
1408+
'paged' => 1,
1409+
'action' => 'activate',
1410+
'plugin' => rawurlencode( 'wp-cloudflare-page-cache/wp-cloudflare-super-page-cache.php' ),
1411+
'_wpnonce' => wp_create_nonce( 'activate-plugin_wp-cloudflare-page-cache/wp-cloudflare-super-page-cache.php' ),
1412+
],
1413+
admin_url( 'plugins.php' )
1414+
);
1415+
}
1416+
1417+
/**
1418+
* Get the SPC status.
1419+
*
1420+
* @return string
1421+
*/
1422+
private function get_spc_status() {
1423+
if ( is_plugin_active( 'wp-cloudflare-page-cache/wp-cloudflare-super-page-cache.php' ) ) {
1424+
return 'active';
1425+
}
1426+
1427+
if ( file_exists( WP_PLUGIN_DIR . '/wp-cloudflare-page-cache/wp-cloudflare-super-page-cache.php' ) ) {
1428+
return 'installed';
1429+
}
1430+
1431+
return 'not-installed';
1432+
}
1433+
13461434
/**
13471435
* Get the black friday notices.
13481436
*

0 commit comments

Comments
 (0)