Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Image Optimization: Bulk Image Optimization #35

Open
wants to merge 7 commits into
base: enhance/PRESS7-76-lazy-load-images
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions build/bulk-optimizer.min.asset.php
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<?php return array('dependencies' => array(), 'version' => 'd69f4bfea2649c9caaee');
1 change: 1 addition & 0 deletions build/bulk-optimizer.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

230 changes: 150 additions & 80 deletions components/imageOptimizationSettings/index.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
// WordPress
import { useState, useEffect } from '@wordpress/element';
import {
Alert,
Container,
ToggleField,
Button,
} from '@newfold/ui-component-library';

// Components
import { Alert, Container, ToggleField } from '@newfold/ui-component-library';

// Classes and functions
import defaultText from '../performance/defaultText';

const ImageOptimizationSettings = ( { methods } ) => {
const [ settings, setSettings ] = useState( null ); // Local state for settings
const [ settings, setSettings ] = useState( null );
const [ isError, setIsError ] = useState( false );
const [ isLoading, setIsLoading ] = useState( true );

Expand All @@ -19,6 +20,7 @@ const ImageOptimizationSettings = ( { methods } ) => {
const fetchSettings = async () => {
setIsLoading( true );
setIsError( false );

try {
const fetchedSettings = await methods.apiFetch( { path: apiUrl } );
setSettings( fetchedSettings.nfd_image_optimization || {} );
Expand All @@ -29,7 +31,7 @@ const ImageOptimizationSettings = ( { methods } ) => {
}
};

// Update settings via the REST API
// Update settings via REST API
const updateSettings = async ( newSettings ) => {
setIsError( false );
try {
Expand All @@ -39,6 +41,7 @@ const ImageOptimizationSettings = ( { methods } ) => {
data: { nfd_image_optimization: newSettings },
} );
setSettings( updatedSettings.nfd_image_optimization || {} );

notify.push( 'image-optimization-updated', {
title: defaultText.imageOptimizationUpdatedTitle,
description: defaultText.imageOptimizationUpdatedDescription,
Expand All @@ -47,39 +50,62 @@ const ImageOptimizationSettings = ( { methods } ) => {
} );
} catch ( error ) {
setIsError( true );
notify.push( 'image-optimization-update-error', {
title: defaultText.imageOptimizationUpdateErrorTitle,
description: defaultText.imageOptimizationGenericErrorMessage,
variant: 'error',
autoDismiss: 8000,
} );
}
};

// Handle toggle changes
// Handle Toggle Changes
const handleToggleChange = ( field, value ) => {
const updatedSettings = { ...settings };

if ( field === 'enabled' ) {
updatedSettings.enabled = value;

// Automatically enable/disable dependent settings
updatedSettings.auto_optimized_uploaded_images = {
enabled: value,
auto_delete_original_image: value,
};
updatedSettings.lazy_loading = { enabled: value };
} else if ( field === 'autoOptimizeEnabled' ) {
updatedSettings.auto_optimized_uploaded_images.enabled = value;
if ( ! value ) {
updatedSettings.auto_optimized_uploaded_images.auto_delete_original_image = false;
}
} else if ( field === 'autoDeleteOriginalImage' ) {
updatedSettings.auto_optimized_uploaded_images.auto_delete_original_image =
value;
} else if ( field === 'lazyLoading' ) {
updatedSettings.lazy_loading.enabled = value;
switch ( field ) {
case 'enabled':
updatedSettings.enabled = value;
updatedSettings.auto_optimized_uploaded_images.enabled = value;
updatedSettings.bulk_optimization = value;
updatedSettings.lazy_loading.enabled = value;
break;

case 'autoOptimizeEnabled':
updatedSettings.auto_optimized_uploaded_images.enabled = value;
break;

case 'bulkOptimize':
updatedSettings.bulk_optimization = value;
break;

case 'lazyLoading':
updatedSettings.lazy_loading.enabled = value;
break;

case 'autoDeleteOriginalImage':
updatedSettings.auto_optimized_uploaded_images.auto_delete_original_image =
value;
break;

default:
break;
}

// Auto-disable Auto Delete Original Image if both options are off
if (
field !== 'autoDeleteOriginalImage' &&
! updatedSettings.bulk_optimization &&
! updatedSettings.auto_optimized_uploaded_images.enabled
) {
updatedSettings.auto_optimized_uploaded_images.auto_delete_original_image = false;
}

setSettings( updatedSettings );
updateSettings( updatedSettings );
};

// Fetch settings on component mount
// Fetch settings on mount
useEffect( () => {
fetchSettings();
}, [] );
Expand Down Expand Up @@ -107,11 +133,11 @@ const ImageOptimizationSettings = ( { methods } ) => {
);
}

// Destructure settings with camel case for internal use
const {
enabled,
auto_optimized_uploaded_images: autoOptimizedUploadedImages,
lazy_loading: lazyLoading = { enabled: true },
bulk_optimization: bulkOptimization = false,
} = settings || {};

const {
Expand All @@ -136,61 +162,105 @@ const ImageOptimizationSettings = ( { methods } ) => {
handleToggleChange( 'enabled', ! enabled )
}
/>
<div className="nfd-flex nfd-flex-col nfd-gap-6">
<ToggleField
id="auto-optimize-images"
label={ defaultText.imageOptimizationAutoOptimizeLabel }
description={
defaultText.imageOptimizationAutoOptimizeDescription
}
checked={ autoOptimizeEnabled }
onChange={ () =>
handleToggleChange(
'autoOptimizeEnabled',
! autoOptimizeEnabled
)
}
disabled={ ! enabled }
/>
<div className="nfd-flex nfd-flex-col nfd-gap-6">
<ToggleField
id="auto-delete-original"
label={
defaultText.imageOptimizationAutoDeleteLabel
}
description={

<ToggleField
id="auto-optimize-images"
label={ defaultText.imageOptimizationAutoOptimizeLabel }
description={
defaultText.imageOptimizationAutoOptimizeDescription
}
checked={ autoOptimizeEnabled }
onChange={ () =>
handleToggleChange(
'autoOptimizeEnabled',
! autoOptimizeEnabled
)
}
disabled={ ! enabled }
/>

<ToggleField
id="auto-delete-original"
label={ defaultText.imageOptimizationAutoDeleteLabel }
description={
<>
{
defaultText.imageOptimizationAutoDeleteDescription
}
checked={ autoDeleteOriginalImage }
onChange={ () =>
handleToggleChange(
'autoDeleteOriginalImage',
! autoDeleteOriginalImage
)
}
disabled={ ! enabled || ! autoOptimizeEnabled }
/>
</div>
<div className="nfd-flex nfd-flex-col nfd-gap-6">
<ToggleField
id="lazy-loading-enabled"
label={
defaultText.imageOptimizationLazyLoadingLabel
}
description={
defaultText.imageOptimizationLazyLoadingDescription
}
checked={ lazyLoading.enabled }
onChange={ () =>
handleToggleChange(
'lazyLoading',
! lazyLoading.enabled
)
<p
style={ {
color: 'red',
marginTop: '8px',
} }
>
{
defaultText.imageOptimizationAutoDeleteCaution
}
</p>
</>
}
checked={ autoDeleteOriginalImage }
onChange={ () =>
handleToggleChange(
'autoDeleteOriginalImage',
! autoDeleteOriginalImage
)
}
disabled={
! enabled ||
( ! autoOptimizeEnabled && ! bulkOptimization )
}
/>

<ToggleField
id="lazy-loading-enabled"
label={ defaultText.imageOptimizationLazyLoadingLabel }
description={
defaultText.imageOptimizationLazyLoadingDescription
}
checked={ lazyLoading.enabled }
onChange={ () =>
handleToggleChange(
'lazyLoading',
! lazyLoading.enabled
)
}
disabled={ ! enabled }
/>

<ToggleField
id="bulk-optimize-images"
label={ defaultText.imageOptimizationBulkOptimizeLabel }
description={
defaultText.imageOptimizationBulkOptimizeDescription
}
checked={ bulkOptimization }
onChange={ () =>
handleToggleChange( 'bulkOptimize', ! bulkOptimization )
}
disabled={ ! enabled }
/>

{ bulkOptimization && (
<div className="nfd-flex nfd-justify-end">
<Button
variant="primary"
size="small"
onClick={ () => {
const basePath =
window.location.pathname.split(
'/wp-admin'
)[ 0 ];
const adminUrl = `${ window.location.origin }${ basePath }/wp-admin/upload.php`;
window.open( adminUrl, '_blank' );
} }
>
{
defaultText.imageOptimizationBulkOptimizeButtonLabel
}
disabled={ ! enabled }
/>
</Button>
</div>
</div>
) }
</div>
</Container.SettingsField>
);
Expand Down
26 changes: 25 additions & 1 deletion components/performance/defaultText.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,17 @@ const defaultText = {
'wp-module-performance'
),
imageOptimizationAutoDeleteLabel: __(
'Auto Delete Original Image (Recommended)',
'Auto Delete Original Image',
'wp-module-performance'
),
imageOptimizationAutoDeleteDescription: __(
'When enabled, the original uploaded image is deleted and replaced with the optimized version, helping to save storage space. If disabled, the optimized image is saved as a separate file, retaining the original.',
'wp-module-performance'
),
imageOptimizationAutoDeleteCaution: __(
'Caution: If the original image is being referenced elsewhere (e.g., in posts, pages, or custom templates), those references will break. You will need to manually update those references to use the optimized image.',
'wp-module-performance'
),
imageOptimizationNoSettings: __(
'No settings available.',
'wp-module-performance'
Expand Down Expand Up @@ -136,6 +140,26 @@ const defaultText = {
'Oops! There was an error updating the lazy loading settings.',
'wp-module-performance'
),
imageOptimizationBulkOptimizeLabel: __(
'Enable Bulk Optimization of Images',
'wp-module-performance'
),
imageOptimizationBulkOptimizeDescription: __(
'When enabled, allows bulk optimization of images in the media library.',
'wp-module-performance'
),
imageOptimizationBulkOptimizeButtonLabel: __(
'Go to Media Library',
'wp-module-performance'
),
imageOptimizationUpdateErrorTitle: __(
'Error Updating Settings',
'wp-module-performance'
),
imageOptimizationGenericErrorMessage: __(
'Something went wrong while updating the settings. Please try again.',
'wp-module-performance'
),
linkPrefetchDescription: __(
'Asks the browser to download and cache links on the page ahead of them being clicked on, so that when they are clicked they load almost instantly. ',
'wp-module-performance'
Expand Down
Loading
Loading