diff --git a/.eslintrc b/.eslintrc
index ebd30d933..7745aad3b 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -11,7 +11,7 @@
"ecmaVersion": 2021,
"sourceType": "module"
},
- "ignorePatterns": [ "node_modules", "assets/js" ],
+ "ignorePatterns": [ "node_modules", "assets/js", "**/*.d.ts" ],
"rules": {
"camelcase" : "off",
"indent": [
diff --git a/assets/src/dashboard/parts/components/GroupSettingsContainer.js b/assets/src/dashboard/parts/components/GroupSettingsContainer.js
new file mode 100644
index 000000000..1e95fda86
--- /dev/null
+++ b/assets/src/dashboard/parts/components/GroupSettingsContainer.js
@@ -0,0 +1,25 @@
+import classNames from 'classnames';
+
+export const GroupSettingsContainer = ({ children, className = '' }) => {
+ return (
+
+ { children }
+
+ );
+};
+
+export const GroupSettingsTitle = ({ children, className = '' }) => {
+ return (
+
+ { children }
+
+ );
+};
+
+export const GroupSettingsOption = ({ children, className = '' }) => {
+ return (
+
+ { children }
+
+ );
+};
diff --git a/assets/src/dashboard/parts/components/Miscellaneous.js b/assets/src/dashboard/parts/components/Miscellaneous.js
new file mode 100644
index 000000000..e515ebc3e
--- /dev/null
+++ b/assets/src/dashboard/parts/components/Miscellaneous.js
@@ -0,0 +1,37 @@
+import classNames from 'classnames';
+
+export const TextWithWarningBadge = ({ text, badgeLabel }) => {
+ return (
+ <>
+ {text}
+
+ {badgeLabel}
+
+ >
+ );
+};
+
+const DescriptionTag = ({ text, showAsDisabled }) => (
+
+ {text}
+
+);
+
+export const DescriptionWithTags = ({ text, tags }) => (
+ <>
+ {text}
+
+ {tags.map( ({ text, disabled }) => (
+
+ ) )}
+
+ >
+);
diff --git a/assets/src/dashboard/parts/components/RadioBoxes.js b/assets/src/dashboard/parts/components/RadioBoxes.js
index 5e78d301f..3aa2c62db 100644
--- a/assets/src/dashboard/parts/components/RadioBoxes.js
+++ b/assets/src/dashboard/parts/components/RadioBoxes.js
@@ -43,6 +43,8 @@ export default function RadioBoxes({ options, value, onChange, label, disabled =
type="radio"
name="label"
value={buttonValue}
+ checked={isActive}
+ onChange={() => {}} // Add empty onChange to satisfy React's controlled input requirements
id={buttonValue}
className="!opacity-0 !w-0 !h-0 !overflow-hidden !absolute !pointer-events-none"
disabled={disabled}
diff --git a/assets/src/dashboard/parts/connected/settings/General.js b/assets/src/dashboard/parts/connected/settings/General.js
index bf5e0bf6d..6feb91c2d 100644
--- a/assets/src/dashboard/parts/connected/settings/General.js
+++ b/assets/src/dashboard/parts/connected/settings/General.js
@@ -77,21 +77,6 @@ const General = ({
- }
- checked={ isLazyloadEnabled }
- disabled={ ! isReplacerEnabled || isLoading }
- className={ classnames(
- {
- 'is-disabled': ! isReplacerEnabled || isLoading
- }
- ) }
- onChange={ value => updateOption( 'lazyload', value ) }
- />
-
-
-
{ isUserActive && <>
{
- const { isLoading } = useSelect( select => {
+const Lazyload = ({ settings, setSettings, setCanSave }) => {
+ const { isLoading } = useSelect( ( select ) => {
const { isLoading } = select( 'optimole' );
return {
@@ -35,236 +57,457 @@ const Lazyload = ({
};
});
- const isLazyloadPlaceholderEnabled = 'disabled' !== settings[ 'lazyload_placeholder' ];
- const isNativeLazyloadEnabled = 'disabled' !== settings[ 'native_lazyload' ];
- const isBGReplacerEnabled = 'disabled' !== settings[ 'bg_replacer' ];
- const isVideoLazyloadEnabled = 'disabled' !== settings[ 'video_lazyload' ];
- const isNoScriptEnabled = 'disabled' !== settings[ 'no_script' ];
- const placeholderColor = settings[ 'placeholder_color' ];
+ const isLazyLoadPlaceholderEnabled = useMemo(
+ () => 'disabled' !== settings['lazyload_placeholder'],
+ [ settings ]
+ );
+ const isNativeLazyLoadEnabled = useMemo(
+ () => 'disabled' !== settings['native_lazyload'],
+ [ settings ]
+ );
+ const isBGReplacerEnabled = useMemo(
+ () => 'disabled' !== settings['bg_replacer'],
+ [ settings ]
+ );
+ const isVideoLazyLoadEnabled = useMemo(
+ () => 'disabled' !== settings['video_lazyload'],
+ [ settings ]
+ );
+ const isNoScriptEnabled = useMemo(
+ () => 'disabled' !== settings['no_script'],
+ [ settings ]
+ );
+ const placeholderColor = useMemo(
+ () => settings['placeholder_color'],
+ [ settings.placeholder_color ]
+ );
+ const isScaleEnabled = useMemo(
+ () => 'disabled' === settings.scale,
+ [ settings.scale ]
+ );
+ const isLazyLoadEnabled = useMemo(
+ () => 'disabled' !== settings.lazyload,
+ [ settings.lazyload ]
+ );
+ const isViewPortLoadingEnabled = useMemo(
+ () => settings['lazyload_type']?.includes( 'viewport' ),
+ [ settings?.lazyload_type ]
+ );
+ const isFixedSkipLazyEnabled = useMemo(
+ () => settings['lazyload_type']?.includes( 'fixed' ),
+ [ settings?.lazyload_type ]
+ );
const [ phPicker, setPhPicker ] = useState( false );
+ const [ showModal, setShowModal ] = useState( false );
+
+ const supportPrefilledContactFormUrl = useMemo( () => {
+ const contactUrl = new URL( window.optimoleDashboardApp.report_issue_url );
+ const { contact_support } = window.optimoleDashboardApp.strings;
- const updateOption = ( option, value ) => {
- setCanSave( true );
- const data = { ...settings };
- data[ option ] = value ? 'enabled' : 'disabled';
- setSettings( data );
- };
+ let subject = contact_support.disable_lazy_load_scaling;
+ if ( DISABLE_OPTION_MODAL_TYPE.scale === showModal ) {
+ subject = contact_support.disable_image_scaling;
+ } else if ( DISABLE_OPTION_MODAL_TYPE.javascriptLoading === showModal ) {
+ subject = contact_support.enable_native_lazy_load;
+ }
- const updateValue = ( option, value ) => {
- setCanSave( true );
- const data = { ...settings };
- data[ option ] = value;
- setSettings( data );
- };
+ contactUrl.searchParams.set(
+ 'contact_subject',
+ sprintf( contact_support.title_prefix, subject )
+ );
- const setColor = ( value ) => {
- updateValue( 'placeholder_color', value );
- };
+ return contactUrl;
+ }, [ showModal ]);
+
+ const toggleOption = useCallback(
+ ( option, value ) => {
+ setCanSave( true );
+ const data = { ...settings };
+ data[option] = value ? 'enabled' : 'disabled';
+ setSettings( data );
+ },
+ [ setCanSave, settings, setSettings ]
+ );
+
+ const updateValue = useCallback(
+ ( option, value ) => {
+ setCanSave( true );
+ setSettings( ( prevSettings ) => ({
+ ...prevSettings,
+ [option]: value
+ }) );
+ },
+ [ setCanSave, setSettings ]
+ );
+
+ const setColor = useCallback(
+ ( value ) => {
+ updateValue( 'placeholder_color', value );
+ },
+ [ updateValue ]
+ );
+
+ const toggleLoadingBehavior = useCallback(
+ ( value, slug ) => {
+ const setting = new Set(
+ ( settings?.lazyload_type ?? '' )
+ ?.split( '|' )
+ .filter( ( i ) => 'viewport' === i || 'fixed' === i ) ?? []
+ );
+ if ( value ) {
+ setting.add( slug );
+ } else {
+ setting.delete( slug );
+ }
+ updateValue( 'lazyload_type', Array.from( setting ).toSorted().join( '|' ) );
+ },
+ [ settings?.lazyload_type ]
+ );
+
+ if ( ! isLazyLoadEnabled ) {
+ return (
+ <>
+ }
+ checked={isLazyLoadEnabled}
+ disabled={isLoading}
+ className={classnames({
+ 'is-disabled': isLoading
+ })}
+ onChange={( value ) => toggleOption( 'lazyload', value )}
+ />
+ >
+ );
+ }
return (
<>
-
-
-
-
-
}
+ checked={isLazyLoadEnabled}
+ disabled={isLoading}
+ className={classnames({
+ 'is-disabled': isLoading
+ })}
+ onChange={() => setShowModal( DISABLE_OPTION_MODAL_TYPE.lazyLoad )}
+ />
+ {showModal && (
+ setShowModal( false )}
+ onConfirm={() => {
+ window?.formbricks?.track( 'disable_lazy_load_feature', {
+ hiddenFields: {
+ feature: `${showModal}`
+ }
+ });
+
+ if ( DISABLE_OPTION_MODAL_TYPE.javascriptLoading === showModal ) {
+ toggleOption( 'native_lazyload', true );
+ } else if ( DISABLE_OPTION_MODAL_TYPE.scale === showModal ) {
+ toggleOption( 'scale', true );
+ } else if ( DISABLE_OPTION_MODAL_TYPE.lazyLoad === showModal ) {
+ toggleOption( 'lazyload', false );
+ }
+
+ setShowModal( false );
+ }}
+ onSecondaryAction={() => {
+ window.open( supportPrefilledContactFormUrl, '_blank' );
+ setShowModal( false );
+ }}
+ />
+ )}
+
+
+
+
- {optimoleDashboardApp.strings.options_strings.lazyload_behaviour_fixed.replace( '[N]', settings['skip_lazyload_images'])}
- {'fixed' === settings['lazyload_type'] && (
- <>
-
- {optimoleDashboardApp.strings.options_strings.lazyload_behaviour_fixed_desc}
-
-
- updateValue( 'skip_lazyload_images', value )}
- />
-
- >
- )}
-
+ title: options_strings.smart_loading_title,
+ description: (
+
),
- value: 'fixed'
+ value: 'disabled'
},
{
- label: (
-
-
{optimoleDashboardApp.strings.options_strings.lazyload_behaviour_viewport}
- {'viewport' === settings['lazyload_type'] && (
-
- {optimoleDashboardApp.strings.options_strings.lazyload_behaviour_viewport_desc}
-
- )}
-
+ title: (
+
),
- value: 'viewport'
- },
- {
- label: (
-
-
{optimoleDashboardApp.strings.options_strings.lazyload_behaviour_all}
- {'all' === settings['lazyload_type'] && (
-
- {optimoleDashboardApp.strings.options_strings.lazyload_behaviour_all_desc}
-
- )}
-
+ description: (
+
),
- value: 'all'
+ value: 'enabled'
+ }
+ ]}
+ value={isNativeLazyLoadEnabled ? 'enabled' : 'disabled'}
+ onChange={( value ) => {
+ if ( 'disabled' === value ) {
+ toggleOption( 'native_lazyload', false );
+ } else {
+ setShowModal( DISABLE_OPTION_MODAL_TYPE.javascriptLoading );
}
- ] }
- onChange={value => updateValue( 'lazyload_type', value )}
+ }}
/>
-
-
-
-
-
- }
- checked={ isLazyloadPlaceholderEnabled }
- disabled={ isLoading }
- className={ classnames(
- {
- 'is-disabled': isLoading
- }
- ) }
- onChange={ value => updateOption( 'lazyload_placeholder', value ) }
- />
- { isLazyloadPlaceholderEnabled &&
-
-
-
- { phPicker &&
-
setPhPicker( false )}
- >
-
+
+ {options_strings.lazyload_behaviour_title} (
+ {options_strings.global_option})
+
+
+ {
+ toggleLoadingBehavior( value, 'fixed' );
+ }}
+ disabled={false}
+ __nextHasNoMarginBottom={true}
+ />
+
+
+ updateValue( 'skip_lazyload_images', value )
+ }
+ __nextHasNoMarginBottom={true}
/>
-
-
- }
-
- }
-
-
-
+
+
+
+ {
+ toggleLoadingBehavior( value, 'viewport' );
+ }}
+ disabled={false}
+ __nextHasNoMarginBottom={true}
+ />
+
+ {isFixedSkipLazyEnabled && isViewPortLoadingEnabled && (
+
+ )}
+
- }
- checked={ isNativeLazyloadEnabled }
- disabled={ isLoading }
- className={ classnames(
- {
- 'is-disabled': isLoading
- }
- ) }
- onChange={ value => updateOption( 'native_lazyload', value ) }
- />
+
+
+ {options_strings.visual_settings}
+
+
+
+
+ toggleOption( 'lazyload_placeholder', value )
+ }
+ disabled={isLoading}
+ __nextHasNoMarginBottom={true}
+ />
+
-
+ {isLazyLoadPlaceholderEnabled && (
+
+
+ {phPicker && (
+
setPhPicker( false )}
+ >
+
+
+
+ )}
+
+ )}
+
+
+ <noscript>
+ }
+ )}
+ onChange={( value ) => toggleOption( 'no_script', value )}
+ disabled={isLoading}
+ __nextHasNoMarginBottom={true}
+ />
+
+
+
+
- }
- checked={ isVideoLazyloadEnabled }
- disabled={ isLoading }
- className={ classnames(
- {
- 'is-disabled': isLoading
- }
- ) }
- onChange={ value => updateOption( 'video_lazyload', value ) }
- />
+ {isNativeLazyLoadEnabled && (
+
+ )}
-
+
}
- checked={ isNoScriptEnabled }
- disabled={ isLoading }
- className={ classnames(
- {
- 'is-disabled': isLoading
+ label={options_strings.toggle_scale}
+ help={options_strings.scale_desc}
+ checked={isScaleEnabled}
+ disabled={isLoading}
+ className={classnames({
+ 'is-disabled': isLoading
+ })}
+ onChange={( value ) => {
+ if ( value ) {
+ toggleOption( 'scale', ! value );
+ } else {
+ setShowModal( DISABLE_OPTION_MODAL_TYPE.scale );
}
- ) }
- onChange={ value => updateOption( 'no_script', value ) }
+ }}
/>
-
- }
- checked={ isBGReplacerEnabled }
- disabled={ isLoading }
- className={ classnames(
- {
- 'is-disabled': isLoading
- }
- ) }
- onChange={ value => updateOption( 'bg_replacer', value ) }
- />
- { isBGReplacerEnabled && (
- <>
-
-
-
+
+
+ {options_strings.extended_features}
+
+ (
+ )}
+ checked={isBGReplacerEnabled}
+ disabled={isLoading}
+ className={classnames( 'text-sm', {
+ 'is-disabled': isLoading
+ })}
+ onChange={( value ) => toggleOption( 'bg_replacer', value )}
+ />
+ {isBGReplacerEnabled && (
+ <>
updateValue( 'watchers', value ) }
+ placeholder={
+ options_strings.watch_placeholder_lazyload +
+ '\n' +
+ options_strings.watch_placeholder_lazyload_example
+ }
+ value={settings.watchers}
+ onChange={( value ) => updateValue( 'watchers', value )}
+ help={options_strings.watch_desc_lazyload}
/>
-
- >
- ) }
+ >
+ )}
+
+ (
+
+ )}
+ checked={isVideoLazyLoadEnabled}
+ disabled={isLoading}
+ className={classnames( 'mt-8', {
+ 'is-disabled': isLoading
+ })}
+ onChange={( value ) => toggleOption( 'video_lazyload', value )}
+ __nextHasNoMarginBottom={true}
+ />
+
>
);
};
diff --git a/assets/src/dashboard/parts/connected/settings/Menu.js b/assets/src/dashboard/parts/connected/settings/Menu.js
index 90ebf8b3c..8be80542f 100644
--- a/assets/src/dashboard/parts/connected/settings/Menu.js
+++ b/assets/src/dashboard/parts/connected/settings/Menu.js
@@ -59,16 +59,12 @@ const menuItems = [
const SubMenu = ({
children,
tab,
- settings,
setTab
}) => {
return (
{children.map( item => {
const { value, label } = item;
- if ( 'lazyload' === item.value && 'disabled' === settings.lazyload ) {
- return;
- }
const classes = classnames(
{
'bg-light-blue hover:text-purple-gray': tab === value,
diff --git a/assets/src/dashboard/parts/connected/settings/Resize.js b/assets/src/dashboard/parts/connected/settings/Resize.js
index b5800878a..62989e665 100644
--- a/assets/src/dashboard/parts/connected/settings/Resize.js
+++ b/assets/src/dashboard/parts/connected/settings/Resize.js
@@ -17,7 +17,6 @@ import {
import { useSelect } from '@wordpress/data';
import { useState } from '@wordpress/element';
-import Notice from '../../components/Notice';
const Resize = ({
settings,
@@ -38,8 +37,6 @@ const Resize = ({
const isSmartResizeEnabled = 'disabled' !== settings[ 'resize_smart' ];
const isLimitDimensionsEnabled = 'disabled' !== settings[ 'limit_dimensions' ];
- const isLazyloadEnabled = 'disabled' !== settings.lazyload;
- const isScaleEnabled = 'disabled' === settings.scale;
const updateOption = ( option, value ) => {
setCanSave( true );
const data = { ...settings };
@@ -109,25 +106,6 @@ const Resize = ({
-
- {isLazyloadEnabled && (
- <>
- }
- checked={ isScaleEnabled }
- disabled={ isLoading }
- className={ classnames(
- {
- 'is-disabled': isLoading
- }
- ) }
- onChange={ value => updateOption( 'scale', ! value ) }
- />
-
>
- ) }
-
-
}
diff --git a/assets/src/dashboard/style.scss b/assets/src/dashboard/style.scss
index 5367f897c..69ac06e46 100644
--- a/assets/src/dashboard/style.scss
+++ b/assets/src/dashboard/style.scss
@@ -459,3 +459,14 @@ $mango-yellow: #FBBF24;
@apply text-xs rounded-sm bg-gray-100/50;
}
}
+
+
+textarea#optml-css-watchers {
+ border-color: rgb(229 231 235);
+ border-radius: 0.25rem;
+ color: gray;
+
+ &::placeholder {
+ color: #6B7280;
+ }
+}
diff --git a/assets/src/global.d.ts b/assets/src/global.d.ts
new file mode 100644
index 000000000..5bdf096e1
--- /dev/null
+++ b/assets/src/global.d.ts
@@ -0,0 +1,701 @@
+
+export {};
+
+declare global {
+ var optimoleDashboardApp: IOptimoleDashboardApp;
+}
+
+// @see https://transform.tools/json-to-typescript
+export interface IOptimoleDashboardApp {
+ strings: Strings
+ assets_url: string
+ dam_url: string
+ connection_status: string
+ has_application: string
+ user_status: string
+ available_apps: AvailableApp[]
+ api_key: string
+ routes: Routes
+ language: string
+ nonce: string
+ user_data: UserData
+ remove_latest_images: string
+ current_user: CurrentUser
+ site_settings: SiteSettings
+ offload_limit: string
+ home_url: string
+ optimoleHome: string
+ optimoleDashHome: string
+ optimoleDashBilling: string
+ days_since_install: string
+ is_offload_media_available: string
+ auto_connect: string
+ cron_disabled: string
+ submenu_links: SubmenuLink[]
+ bf_notices: any[]
+ spc_banner: SpcBanner
+ show_exceed_plan_quota_notice: string
+ report_issue_url: string
+}
+
+export interface Strings {
+ optimole: string
+ version: string
+ terms_menu: string
+ privacy_menu: string
+ testdrive_menu: string
+ service_details: string
+ dashboard_title: string
+ banner_title: string
+ banner_description: string
+ quick_action_title: string
+ connect_btn: string
+ disconnect_btn: string
+ select: string
+ your_domain: string
+ add_api: string
+ your_api_key: string
+ looking_for_api_key: string
+ refresh_stats_cta: string
+ updating_stats_cta: string
+ api_key_placeholder: string
+ account_needed_heading: string
+ account_needed_sub_heading: string
+ account_needed_trust_badge: string
+ account_needed_setup_time: string
+ invalid_key: string
+ keep_connected: string
+ cloud_library: string
+ image_storage: string
+ disconnect_title: string
+ disconnect_desc: string
+ email_address_label: string
+ steps_connect_api_title: string
+ register_btn: string
+ secure_connection: string
+ step_one_api_title: string
+ optml_dashboard: string
+ steps_connect_api_desc: string
+ api_exists: string
+ back_to_register: string
+ back_to_connect: string
+ error_register: string
+ invalid_email: string
+ connected: string
+ connecting: string
+ not_connected: string
+ usage: string
+ quota: string
+ logged_in_as: string
+ private_cdn_url: string
+ existing_user: string
+ notification_message_register: string
+ premium_support: string
+ account_needed_title: string
+ account_needed_subtitle_1: string
+ account_needed_subtitle_3: string
+ account_needed_subtitle_2: string
+ account_needed_subtitle_4: string
+ account_needed_footer: string
+ account_connecting_title: string
+ account_connecting_subtitle: string
+ notice_just_activated: string
+ notice_api_not_working: string
+ notice_disabled_account: string
+ signup_terms: string
+ dashboard_menu_item: string
+ settings_menu_item: string
+ help_menu_item: string
+ settings_exclusions_menu_item: string
+ settings_resize_menu_item: string
+ settings_compression_menu_item: string
+ advanced_settings_menu_item: string
+ general_settings_menu_item: string
+ lazyload_settings_menu_item: string
+ watermarks_menu_item: string
+ conflicts_menu_item: string
+ conflicts: Conflicts
+ upgrade: Upgrade
+ neve: Neve
+ metrics: Metrics
+ quick_actions: QuickActions
+ options_strings: OptionsStrings
+ help: Help
+ watermarks: Watermarks
+ latest_images: LatestImages
+ csat: Csat
+ cron_error: string
+ cancel: string
+ optimization_status: OptimizationStatus
+ optimization_tips: string
+ native_lazy_load_warning: string
+ contact_support: {
+ title_prefix: string
+ disable_lazy_load_scaling: string
+ disable_image_scaling: string
+ enable_native_lazy_load: string
+ }
+}
+
+export interface Conflicts {
+ title: string
+ message: string
+ conflict_close: string
+ no_conflicts_found: string
+}
+
+export interface Upgrade {
+ title: string
+ title_long: string
+ reason_1: string
+ reason_2: string
+ reason_3: string
+ reason_4: string
+ cta: string
+}
+
+export interface Neve {
+ is_active: string
+ byline: string
+ reason_1: string
+ reason_2: string
+ reason_3: string
+ reason_4: string
+ reason_5: string
+}
+
+export interface Metrics {
+ metricsTitle1: string
+ metricsSubtitle1: string
+ metricsTitle2: string
+ metricsSubtitle2: string
+ metricsTitle3: string
+ metricsSubtitle3: string
+ metricsTitle4: string
+ metricsSubtitle4: string
+}
+
+export interface QuickActions {
+ speed_test_title: string
+ speed_test_desc: string
+ speed_test_link: string
+ clear_cache_images: string
+ clear_cache: string
+ offload_images: string
+ offload_images_desc: string
+ advance_settings: string
+ configure_settings: string
+}
+
+export interface OptionsStrings {
+ compression_mode: string
+ compression_mode_speed_optimized: string
+ compression_mode_quality_optimized: string
+ compression_mode_custom: string
+ compression_mode_speed_optimized_desc: string
+ compression_mode_quality_optimized_desc: string
+ compression_mode_custom_desc: string
+ best_format_title: string
+ best_format_desc: string
+ add_filter: string
+ add_site: string
+ admin_bar_desc: string
+ auto_q_title: string
+ cache_desc: string
+ cache_title: string
+ clear_cache_notice: string
+ image_size_notice: string
+ clear_cache_images: string
+ clear_cache_assets: string
+ connect_step_0: string
+ connect_step_1: string
+ connect_step_2: string
+ connect_step_3: string
+ disabled: string
+ enable_avif_title: string
+ enable_avif_desc: string
+ enable_bg_lazyload_desc: string
+ enable_bg_lazyload_title: string
+ enable_video_lazyload_desc: string
+ enable_video_lazyload_title: string
+ enable_noscript_desc: string
+ enable_noscript_title: string
+ enable_gif_replace_title: string
+ enable_offload_media_title: string
+ enable_offload_media_desc: string
+ enable_cloud_images_title: string
+ enable_cloud_images_desc: string
+ enable_image_replace: string
+ enable_lazyload_placeholder_desc: string
+ lazyload_behaviour_title: string
+ lazyload_behaviour_desc: string
+ lazyload_behaviour_all: string
+ lazyload_behaviour_all_desc: string
+ lazyload_behaviour_viewport: string
+ lazyload_behaviour_viewport_desc: string
+ lazyload_behaviour_fixed: string
+ lazyload_behaviour_fixed_desc: string
+ enable_lazyload_placeholder_title: string
+ enable_network_opt_desc: string
+ enable_network_opt_title: string
+ enable_resize_smart_desc: string
+ enable_resize_smart_title: string
+ enable_retina_desc: string
+ enable_retina_title: string
+ enable_limit_dimensions_desc: string
+ enable_limit_dimensions_title: string
+ enable_limit_dimensions_notice: string
+ enable_badge_title: string
+ enable_badge_settings: string
+ enable_badge_show_icon: string
+ enable_badge_position: string
+ badge_position_text_1: string
+ badge_position_text_2: string
+ enable_badge_description: string
+ image_sizes_title: string
+ enabled: string
+ exclude_class_desc: string
+ exclude_ext_desc: string
+ exclude_filename_desc: string
+ exclude_desc_optimize: string
+ exclude_title_lazyload: string
+ exclude_desc_lazyload: string
+ exclude_title_optimize: string
+ exclude_url_desc: string
+ name: string
+ cropped: string
+ exclude_url_match_desc: string
+ exclude_first: string
+ images: string
+ exclude_first_images_title: string
+ exclude_first_images_desc: string
+ filter_class: string
+ filter_ext: string
+ filter_filename: string
+ filter_operator_contains: string
+ filter_operator_matches: string
+ filter_operator_is: string
+ filter_url: string
+ filter_helper: string
+ gif_replacer_desc: string
+ height_field: string
+ add_image_size_button: string
+ add_image_size_desc: string
+ here: string
+ hide: string
+ high_q_title: string
+ image_1_label: string
+ image_2_label: string
+ lazyload_desc: string
+ filter_length_error: string
+ scale_desc: string
+ low_q_title: string
+ medium_q_title: string
+ no_images_found: string
+ native_desc: string
+ option_saved: string
+ ml_quality_desc: string
+ quality_desc: string
+ quality_selected_value: string
+ quality_slider_desc: string
+ quality_title: string
+ strip_meta_title: string
+ strip_meta_desc: string
+ replacer_desc: string
+ sample_image_loading: string
+ save_changes: string
+ show: string
+ selected_sites_title: string
+ selected_sites_desc: string
+ selected_all_sites_desc: string
+ select_all_sites_desc: string
+ select_site: string
+ cloud_site_title: string
+ cloud_site_desc: string
+ toggle_ab_item: string
+ toggle_lazyload: string
+ toggle_scale: string
+ toggle_native: string
+ on_toggle: string
+ off_toggle: string
+ view_sample_image: string
+ watch_placeholder_lazyload: string
+ watch_placeholder_lazyload_example: string
+ watch_desc_lazyload: string
+ smart_loading_title: string
+ smart_loading_desc: string
+ browser_native_lazy: string
+ viewport_detection: string
+ placeholders_color: string
+ auto_scaling: string
+ lightweight_native: string
+ watch_title_lazyload: string
+ width_field: string
+ crop: string
+ toggle_cdn: string
+ cdn_desc: string
+ enable_css_minify_title: string
+ css_minify_desc: string
+ enable_js_minify_title: string
+ js_minify_desc: string
+ sync_title: string
+ rollback_title: string
+ sync_desc: string
+ rollback_desc: string
+ sync_media: string
+ rollback_media: string
+ sync_media_progress: string
+ estimated_time: string
+ calculating_estimated_time: string
+ images_processing: string
+ active_optimize_exclusions: string
+ active_lazyload_exclusions: string
+ minutes: string
+ stop: string
+ show_logs: string
+ hide_logs: string
+ view_logs: string
+ rollback_media_progress: string
+ rollback_media_error: string
+ rollback_media_error_desc: string
+ remove_notice: string
+ sync_media_error: string
+ sync_media_link: string
+ rollback_media_link: string
+ sync_media_error_desc: string
+ offload_disable_warning_title: string
+ offload_disable_warning_desc: string
+ offload_enable_info_desc: string
+ offload_conflicts_part_1: string
+ offload_conflicts_part_2: string
+ offloading_success: string
+ rollback_success: string
+ offloading_radio_legend: string
+ offload_radio_option_rollback_title: string
+ offload_radio_option_rollback_desc: string
+ offload_radio_option_offload_title: string
+ offload_radio_option_offload_desc: string
+ offload_limit_reached: string
+ select: string
+ yes: string
+ no: string
+ lazyload_placeholder_color: string
+ clear: string
+ settings_saved: string
+ settings_saved_error: string
+ cache_cleared: string
+ cache_cleared_error: string
+ offloading_start_title: string
+ offloading_start_description: string
+ offloading_start_action: string
+ offloading_stop_title: string
+ offloading_stop_description: string
+ offloading_stop_action: string
+ rollback_start_title: string
+ rollback_start_description: string
+ rollback_start_action: string
+ rollback_stop_title: string
+ rollback_stop_description: string
+ rollback_stop_action: string
+ cloud_library_btn_text: string
+ cloud_library_btn_link: string
+ exceed_plan_quota_notice_title: string
+ exceed_plan_quota_notice_description: string
+ exceed_plan_quota_notice_start_action: string
+ exceed_plan_quota_notice_secondary_action: string
+ visual_settings: string
+ extended_features: string
+ global_option: string
+ not_recommended: string
+ viewport_skip_images_notice: string
+}
+
+export interface Help {
+ section_one_title: string
+ section_two_title: string
+ section_two_sub: string
+ get_support_title: string
+ get_support_desc: string
+ get_support_cta: string
+ feat_request_title: string
+ feat_request_desc: string
+ feat_request_cta: string
+ feedback_title: string
+ feedback_desc: string
+ feedback_cta: string
+ account_title: string
+ account_item_one: string
+ account_item_two: string
+ account_item_three: string
+ image_processing_title: string
+ image_processing_item_one: string
+ image_processing_item_two: string
+ image_processing_item_three: string
+ api_title: string
+ api_item_one: string
+ api_item_two: string
+ api_item_three: string
+}
+
+export interface Watermarks {
+ image: string
+ loading_remove_watermark: string
+ max_allowed: string
+ list_header: string
+ settings_header: string
+ no_images_found: string
+ id: string
+ name: string
+ type: string
+ action: string
+ upload: string
+ add_desc: string
+ wm_title: string
+ wm_desc: string
+ opacity_field: string
+ opacity_title: string
+ opacity_desc: string
+ position_title: string
+ position_desc: string
+ pos_nowe_title: string
+ pos_no_title: string
+ pos_noea_title: string
+ pos_we_title: string
+ pos_ce_title: string
+ pos_ea_title: string
+ pos_sowe_title: string
+ pos_so_title: string
+ pos_soea_title: string
+ offset_x_field: string
+ offset_y_field: string
+ offset_title: string
+ offset_desc: string
+ scale_field: string
+ scale_title: string
+ scale_desc: string
+ save_changes: string
+}
+
+export interface LatestImages {
+ image: string
+ no_images_found: string
+ compression: string
+ loading_latest_images: string
+ last: string
+ saved: string
+ smaller: string
+ optimized_images: string
+ same_size: string
+ small_optimization: string
+ medium_optimization: string
+ big_optimization: string
+}
+
+export interface Csat {
+ title: string
+ close: string
+ heading_one: string
+ heading_two: string
+ heading_three: string
+ low: string
+ high: string
+ feedback_placeholder: string
+ skip: string
+ submit: string
+ thank_you: string
+}
+
+export interface OptimizationStatus {
+ title: string
+ statusTitle1: string
+ statusSubTitle1: string
+ statusTitle2: string
+ statusSubTitle2: string
+ statusTitle3: string
+ statusSubTitle3: string
+}
+
+export interface AvailableApp {
+ key: string
+ status: string
+ domain: string
+ is_cname_assigned: string
+ cf_ssl_registered: string
+ certificate_arn: string
+ limit_wl_sites: number
+}
+
+export interface Routes {
+ update_option: string
+ request_update: string
+ check_redirects: string
+ connect: string
+ select_application: string
+ register_service: string
+ disconnect: string
+ poll_optimized_images: string
+ get_sample_rate: string
+ upload_onboard_images: string
+ number_of_images_and_pages: string
+ clear_offload_errors: string
+ get_offload_conflicts: string
+ move_image: string
+ poll_conflicts: string
+ dismiss_conflict: string
+ clear_cache_request: string
+ insert_images: string
+ dismiss_notice: string
+ optimizations: string
+}
+
+export interface UserData {
+ id: number
+ display_name: string
+ user_email: string
+ picture: string
+ validated: string
+ cdn_key: string
+ cdn_secret: string
+ whitelist: string[]
+ plan: string
+ status: string
+ visitors: number
+ visitors_limit: number
+ visitors_left: number
+ visitors_pretty: string
+ visitors_limit_pretty: string
+ visitors_left_pretty: string
+ app_count: number
+ available_apps: AvailableApp2[]
+ traffic: number
+ images_number: number
+ offload_limit: number
+ offloaded_images: number
+ compression_percentage: number
+ saved_size: number
+ domain: string
+ is_cname_assigned: string
+ extra_visits: boolean
+ renews_on: number
+}
+
+export interface AvailableApp2 {
+ key: string
+ status: string
+ domain: string
+ is_cname_assigned: string
+ cf_ssl_registered: string
+ certificate_arn: string
+ limit_wl_sites: number
+}
+
+export interface CurrentUser {
+ email: string
+}
+
+export interface SiteSettings {
+ quality: string
+ admin_bar_item: string
+ lazyload: string
+ network_optimization: string
+ retina_images: string
+ limit_dimensions: string
+ limit_height: number
+ limit_width: number
+ lazyload_placeholder: string
+ skip_lazyload_images: number
+ bg_replacer: string
+ video_lazyload: string
+ resize_smart: string
+ no_script: string
+ lazyload_type: string
+ compression_mode: string
+ image_replacer: string
+ cdn: string
+ filters: Filters
+ cloud_sites: CloudSites
+ defined_image_sizes: any[]
+ watchers: string
+ watermark: Watermark
+ img_to_video: string
+ scale: string
+ css_minify: string
+ js_minify: string
+ native_lazyload: string
+ avif: string
+ autoquality: string
+ offload_media: string
+ cloud_images: string
+ strip_metadata: string
+ whitelist_domains: string[]
+ banner_frontend: string
+ offloading_status: string
+ rollback_status: string
+ best_format: string
+ offload_limit_reached: string
+ placeholder_color: string
+ show_offload_finish_notice: string
+ show_badge_icon: string
+ badge_position: string
+}
+
+export interface Filters {
+ lazyload: Lazyload
+ optimize: Optimize
+}
+
+export interface Lazyload {
+ extension: any[]
+ filename: any[]
+ page_url: any[]
+ page_url_match: any[]
+ class: any[]
+}
+
+export interface Optimize {
+ extension: any[]
+ filename: any[]
+ page_url: any[]
+ page_url_match: any[]
+ class: any[]
+}
+
+export interface CloudSites {
+ all: string
+ "localhost:10038": string
+}
+
+export interface Watermark {
+ id: number
+ opacity: number
+ position: string
+ x_offset: number
+ y_offset: number
+ scale: number
+}
+
+export interface SubmenuLink {
+ href: string
+ text: string
+ hash: string
+}
+
+export interface SpcBanner {
+ activate_url: string
+ status: string
+ banner_dismiss_key: string
+ i18n: I18n
+}
+
+export interface I18n {
+ dismiss: string
+ title: string
+ byline: string
+ features: string[]
+ cta: string
+ activate: string
+ installing: string
+ activating: string
+ activated: string
+ error: string
+}
diff --git a/inc/admin.php b/inc/admin.php
index 06451c60c..b5cabe68a 100755
--- a/inc/admin.php
+++ b/inc/admin.php
@@ -1345,6 +1345,13 @@ private function localize_dashboard_app() {
];
$lang_code = isset( $available_languages[ $language ] ) ? 'de' : 'en';
+ $site_settings = $this->settings->get_site_settings();
+ // Migrate settings if needed.
+ if ( isset( $site_settings['lazyload_type'] ) && 'all' === $site_settings['lazyload_type'] ) {
+ $site_settings['lazyload_type'] = 'fixed';
+ $site_settings['skip_lazyload_images'] = 0;
+ }
+
return [
'strings' => $this->get_dashboard_strings(),
'assets_url' => OPTML_URL . 'assets/',
@@ -1362,7 +1369,7 @@ private function localize_dashboard_app() {
'current_user' => [
'email' => $user->user_email,
],
- 'site_settings' => $this->settings->get_site_settings(),
+ 'site_settings' => $site_settings,
'offload_limit' => $this->settings->get( 'offload_limit' ),
'home_url' => home_url(),
'optimoleHome' => tsdk_translate_link( 'https://optimole.com/' ),
@@ -1382,6 +1389,15 @@ 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(),
+ 'report_issue_url' => add_query_arg(
+ [
+ 'utm_source' => 'plugin',
+ 'utm_medium' => 'wp_dashboard',
+ 'utm_campaign' => 'report_issue',
+ 'contact_website' => home_url(),
+ ],
+ tsdk_translate_link( 'https://optimole.com/contact/' )
+ ),
];
}
@@ -1791,27 +1807,18 @@ private function get_dashboard_strings() {
'',
''
),
- 'enable_bg_lazyload_desc' => sprintf(
- /* translators: 1 is the starting anchor tag, 2 is the ending anchor tag */
- __( 'Enable this to lazy-load images set as CSS backgrounds. If Optimole misses any, you can directly target specific CSS selectors to ensure all background images are optimized. %1$sLearn more%2$s', 'optimole-wp' ),
- '',
- ''
- ),
+ 'enable_bg_lazyload_desc' => __( 'Apply lazy loading to CSS background images. The toggle below enables it globally. The selector list is optional and only needed to extend coverage if certain elements are missed.', 'optimole-wp' ),
'enable_bg_lazyload_title' => __( 'CSS Background Lazy Load', 'optimole-wp' ),
- 'enable_video_lazyload_desc' => sprintf(
- /* translators: 1 is the starting anchor tag, 2 is the ending anchor tag */
- __( 'By default, lazy loading does not work for embedded videos and iframes. Enable this option to activate the lazy-load on these elements. %1$sLearn more%2$s', 'optimole-wp' ),
- '',
- ''
- ),
- 'enable_video_lazyload_title' => __( 'Lazy Loading for Embedded Videos and Iframes', 'optimole-wp' ),
+ 'enable_video_lazyload_desc' => __( 'Lazy load embedded videos and iframe content', 'optimole-wp' ),
+ 'enable_video_lazyload_title' => __( 'Video & iframes', 'optimole-wp' ),
'enable_noscript_desc' => sprintf(
/* translators: 1 is the starting anchor tag, 2 is the ending anchor tag */
__( 'Enables fallback images for browsers that can\'t handle JavaScript-based lazy loading or related features. Disabling it may resolve conflicts with other plugins or configurations and decrease HTML page size. %1$sLearn more%2$s', 'optimole-wp' ),
'',
''
),
- 'enable_noscript_title' => __( 'Noscript Tag', 'optimole-wp' ),
+ // translators: %s is the name of the html tag (e.g: