Skip to content
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
2 changes: 1 addition & 1 deletion readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Contributors: bfintal, gambitph
Tags: image, optimization, compress, convert, webp
Requires at least: 6.7.5
Tested up to: 6.9.4
Tested up to: 7.0
Requires PHP: 8.0
Stable tag: 1.3.1
License: GPLv2 or later
Expand Down
8 changes: 8 additions & 0 deletions src/admin/class-admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,9 @@ public function register_settings() {
],

// Image Optimization settings
'smart_optimization' => [
'type' => 'integer',
],
'webp_quality' => [
'type' => 'integer',
],
Expand Down Expand Up @@ -322,6 +325,11 @@ public function sanitize_options( $options ) {
$sanitized['thumbnail_sizes'] = array_map( 'sanitize_text_field', $options['thumbnail_sizes'] );
}

// Sanitize smart optimization
if ( isset( $options['smart_optimization'] ) ) {
$sanitized['smart_optimization'] = $options['smart_optimization'] ? 1 : 0;
}

// Sanitize webp quality
if ( isset( $options['webp_quality'] ) ) {
$quality = absint( $options['webp_quality'] );
Expand Down
19 changes: 14 additions & 5 deletions src/admin/class-meta-box.php
Original file line number Diff line number Diff line change
Expand Up @@ -185,11 +185,20 @@ function cimo_get_media_type_label( $mimetype ) {

// Converted format
echo '<li class="cimo-converted">';
echo '🏞️ ' . sprintf(
/* translators: %s: converted format */
esc_html__( 'Converted to %s', 'cimo-image-optimizer' ),
'<span class="cimo-value">' . esc_html( $converted_format ) . '</span>'
);
$converted_format_markup = '<span class="cimo-value">' . esc_html( $converted_format ) . '</span>';
if ( ! empty( $cimo['smartOptimized'] ) ) {
echo '🏞️ ' . sprintf(
/* translators: %s: converted format */
esc_html__( 'Smart optimized to %s', 'cimo-image-optimizer' ),
$converted_format_markup
);
} else {
echo '🏞️ ' . sprintf(
/* translators: %s: converted format */
esc_html__( 'Converted to %s', 'cimo-image-optimizer' ),
$converted_format_markup
);
}
echo '</li>';

// Conversion time
Expand Down
7 changes: 7 additions & 0 deletions src/admin/class-metadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public function register_rest_route() {
'convertedFilesize',
'conversionTime',
'compressionSavings',
'smartOptimized',
];
if ( ! is_array( $value ) ) {
// translators: The %s is the parameter name.
Expand Down Expand Up @@ -85,6 +86,7 @@ public function register_rest_route() {
'convertedFilesize',
'conversionTime',
'compressionSavings',
'smartOptimized',
];
$sanitized = [];
if ( is_array( $value ) ) {
Expand All @@ -98,6 +100,8 @@ public function register_rest_route() {
$entry[ $key ] = intval( $item[ $key ] );
} elseif ( in_array( $key, [ 'conversionTime', 'compressionSavings' ], true ) ) {
$entry[ $key ] = floatval( $item[ $key ] );
} elseif ( $key === 'smartOptimized' ) {
$entry[ $key ] = ! empty( $item[ $key ] ) ? 1 : 0;
} else {
$entry[ $key ] = sanitize_text_field( $item[ $key ] );
}
Expand Down Expand Up @@ -137,6 +141,7 @@ public function save_metadata( $request ) {
'convertedFilesize',
'conversionTime',
'compressionSavings',
'smartOptimized',
];
$sanitized_metadata = [];
foreach ( $metadata_array as $item ) {
Expand All @@ -149,6 +154,8 @@ public function save_metadata( $request ) {
$entry[ $key ] = intval( $item[ $key ] );
} elseif ( in_array( $key, [ 'conversionTime', 'compressionSavings' ], true ) ) {
$entry[ $key ] = floatval( $item[ $key ] );
} elseif ( $key === 'smartOptimized' ) {
$entry[ $key ] = ! empty( $item[ $key ] ) ? 1 : 0;
} else {
$entry[ $key ] = sanitize_text_field( $item[ $key ] );
}
Expand Down
3 changes: 3 additions & 0 deletions src/admin/class-script-loader.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ public static function enqueue_cimo_assets() {
'canManageOptions' => current_user_can( 'manage_options' ),
'optimizeAllMedia' => isset( $settings['optimize_all_media'] ) ? (int) $settings['optimize_all_media'] : 0,
'isPremium' => CIMO_BUILD === 'premium',
'smartOptimization' => CIMO_BUILD === 'premium'
? ( isset( $settings['smart_optimization'] ) ? (int) $settings['smart_optimization'] : 1 )
: 0,
'webpQuality' => ! empty( $settings['webp_quality'] ) ? (int) $settings['webp_quality'] : 80,
'maxImageDimension' => ! empty( $settings['max_image_dimension'] ) ? (int) $settings['max_image_dimension'] : 0,
'videoOptimizationEnabled' => isset( $settings['video_optimization_enabled'] ) ? (int) $settings['video_optimization_enabled'] : 1,
Expand Down
20 changes: 20 additions & 0 deletions src/admin/css/admin-page.css
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,26 @@
order: 1;
}

.cimo-smart-optimization-toggle {
order: 2;

~ .cimo-setting-field {
order: 3;
}

~ .cimo-webp-quality-range-control {
order: 1;
}

~ .cimo-reset-button {
order: 10;
}
}

.cimo-is-premium .cimo-smart-optimization-toggle {
order: 1;
}

@keyframes cimo-bulk-optimizer-blink {

0%, 100% { opacity: 1; }
Expand Down
12 changes: 3 additions & 9 deletions src/admin/js/media-manager/drop-zone.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,22 +103,18 @@ function addDropZoneListenerToMediaManager( targetDocument ) {
const progressModal = new ProgressModal( fileConverters, onCancel )
progressModal.open()

let hasError = false

// Process and optimize each media file here,
// e.g. converting to webp, resizing, compressing, etc.
const optimizedResults = await Promise.all(
fileConverters.map( async converter => {
try {
const result = await converter.convert()
const result = await converter.optimize()
if ( result.error ) {
// eslint-disable-next-line no-console
console.warn( result.error )
hasError = true
}
return result
} catch ( error ) {
hasError = true
// eslint-disable-next-line no-console
console.warn( error )
return { file: converter.file, metadata: null }
Expand Down Expand Up @@ -216,10 +212,8 @@ function addDropZoneListenerToMediaManager( targetDocument ) {
}
}

// If there's an error, do not close the progress modal so the user can read the error.
if ( ! hasError ) {
progressModal.close()
}
// Close when optimization finishes, including when we fall back to the original file after an error.
progressModal.close()
}

// Add our custom drop listener
Expand Down
111 changes: 98 additions & 13 deletions src/admin/js/media-manager/progress-modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,34 @@ class ProgressModal {
this.interval = null
this.modal = null
this.progressBars = []
this._setupModal()
this.delayTimeout = null
}

open() {
if ( ! this.modal ) {
return
}
if ( this.converters.length === 0 ) {
return
}
this.modal.style.display = 'flex'
this._startInterval()

const delays = this.converters
.map( c => c?.progressDelay )
.filter( v => typeof v === 'number' && v > 0 )

// Only delay if all converter opt to delay, to allow
// big media files like video to show the progress modal immediately.
const shouldDelay = delays.length === this.converters.length
const delay = shouldDelay ? Math.max( ...delays ) : 0

const start = () => {
this._setupModal()
this.modal.style.display = 'flex'
this._startInterval()
}

if ( delay > 0 ) {
this.delayTimeout = setTimeout( start, delay )
} else {
start()
}
}

_handleCloseClick() {
Expand All @@ -37,6 +53,10 @@ class ProgressModal {
}

close() {
if ( this.delayTimeout ) {
clearTimeout( this.delayTimeout )
this.delayTimeout = null
}
if ( ! this.modal ) {
return
}
Expand Down Expand Up @@ -150,9 +170,43 @@ class ProgressModal {
this.modal.appendChild( wrapper )
document.body.appendChild( this.modal )

this._ensureIndeterminateStyles()
this._renderProgressBars()
}

_ensureIndeterminateStyles() {
if ( document.getElementById( 'cimo-progress-indeterminate-styles' ) ) {
return
}
const style = document.createElement( 'style' )
style.id = 'cimo-progress-indeterminate-styles'
style.textContent = `
.cimo-progress-indeterminate-layer {
display: none;
position: absolute;
inset: 0;
overflow: hidden;
border-radius: inherit;
pointer-events: none;
}
.cimo-progress-indeterminate-bar {
position: absolute;
top: 0;
left: -35%;
width: 35%;
height: 100%;
border-radius: 5px;
background: linear-gradient(90deg, #00d8f0 0%, #2bc566 100%);
animation: cimo-indet-sweep 1.35s ease-in-out infinite;
}
@keyframes cimo-indet-sweep {
from { left: -35%; }
to { left: 100%; }
}
`
document.head.appendChild( style )
}

_renderProgressBars() {
this.progressList.innerHTML = ''
this.progressBars = []
Expand Down Expand Up @@ -259,22 +313,31 @@ class ProgressModal {
height: 8px;
width: 100%;
overflow: hidden;
position: relative;
`
const indeterminateLayer = document.createElement( 'div' )
indeterminateLayer.className = 'cimo-progress-indeterminate-layer'
const indeterminateBar = document.createElement( 'div' )
indeterminateBar.className = 'cimo-progress-indeterminate-bar'
indeterminateLayer.appendChild( indeterminateBar )

const bar = document.createElement( 'div' )
bar.className = 'cimo-progress-bar'
bar.style.cssText = `
background: linear-gradient(90deg, #00d8f0 0%, #2bc566 100%);
width: 0%;
height: 100%;
transition: width 0.5s linear;
transition: width 0.65s cubic-bezier(0.4, 0, 0.2, 1);
border-radius: 5px 0 0 5px;
`

bar.sizeLabelEl = sizeLabel
bar.statusLabelEl = statusLabel
bar.percentageLabelEl = percentageLabel
bar.indeterminateLayer = indeterminateLayer

barBg.appendChild( bar )
barBg.appendChild( indeterminateLayer )
barContainer.appendChild( label )
barContainer.appendChild( sizeLabel )
barContainer.appendChild( progressStatusFlex )
Expand All @@ -300,10 +363,19 @@ class ProgressModal {
}

_updateProgress() {
if ( ! this.modal ) {
return
}

let allDone = true
let hasError = false

this.converters.forEach( ( converter, i ) => {
const barEl = this.progressBars[ i ]
const isIndeterminate = converter.indeterminateProgress === true &&
converter.progress < 1 &&
! converter.errorMessage

let percent = converter.progress * 100

if (
Expand All @@ -325,18 +397,31 @@ class ProgressModal {
this.errorNote.style.display = 'block'
}

if ( this.progressBars[ i ] ) {
this.progressBars[ i ].statusLabelEl.style.cssText = `
if ( barEl ) {
barEl.statusLabelEl.style.cssText = `
color: ${ converter.errorMessage ? '#dc3545' : 'inherit' };
`
this.progressBars[ i ].statusLabelEl.innerText = converter.errorMessage || converter.status
this.progressBars[ i ].style.width = percent + '%'
this.progressBars[ i ].percentageLabelEl.innerText = parseInt( percent ) + '%'
barEl.statusLabelEl.innerText = converter.errorMessage || converter.status

if ( isIndeterminate ) {
barEl.style.display = 'none'
if ( barEl.indeterminateLayer ) {
barEl.indeterminateLayer.style.display = 'block'
}
barEl.percentageLabelEl.innerText = __( '…', 'cimo-image-optimizer' )
} else {
barEl.style.display = ''
if ( barEl.indeterminateLayer ) {
barEl.indeterminateLayer.style.display = 'none'
}
barEl.style.width = percent + '%'
barEl.percentageLabelEl.innerText = parseInt( percent ) + '%'
}
}
} )

// Optional: auto-close when all converters are done (progress 100%)
if ( allDone && this.modal.style.display === 'block' ) {
if ( allDone && this.modal && this.modal.style.display !== 'none' ) {
if ( ! hasError ) {
setTimeout( () => this.close(), 750 )
}
Expand Down
12 changes: 3 additions & 9 deletions src/admin/js/media-manager/select-files.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,22 +82,18 @@ function addSelectFilesListenerToFileUploads( targetDocument ) {
const progressModal = new ProgressModal( fileConverters, onCancel )
progressModal.open()

let hasError = false

// Process and optimize each media file here,
// e.g. converting to webp, resizing, compressing, etc.
const optimizedResults = await Promise.all(
fileConverters.map( async converter => {
try {
const result = await converter.convert()
const result = await converter.optimize()
if ( result.error ) {
// eslint-disable-next-line no-console
console.warn( result.error )
hasError = true
}
return result
} catch ( error ) {
hasError = true
// eslint-disable-next-line no-console
console.warn( error )
return { file: converter.file, metadata: null }
Expand Down Expand Up @@ -127,10 +123,8 @@ function addSelectFilesListenerToFileUploads( targetDocument ) {
changeEvent.__cimo_converted = true // eslint-disable-line camelcase
event.target.dispatchEvent( changeEvent )

// If there's an error, do not close the progress modal so the user can read the error.
if ( ! hasError ) {
progressModal.close()
}
// Close when optimization finishes, including when we fall back to the original file after an error.
progressModal.close()
}

if ( ! targetDocument.body.__cimo_selectfiles_listener_attached ) {
Expand Down
Loading
Loading