diff --git a/.github/workflows/diff-translations.yml b/.github/workflows/diff-translations.yml new file mode 100644 index 000000000..f0ce5a58d --- /dev/null +++ b/.github/workflows/diff-translations.yml @@ -0,0 +1,53 @@ +name: Translations Diff + +on: + pull_request_review: + pull_request: + types: [opened, edited, synchronize, ready_for_review] + branches: + - development + - master + +jobs: + translation: + runs-on: ubuntu-latest + steps: + - name: Checkout Base Branch + uses: actions/checkout@v4 + with: + ref: ${{ github.base_ref }} + path: optimole-base + - name: Setup node 16 + uses: actions/setup-node@v4 + with: + node-version: 16.x + - name: Build POT for Base Branch + run: | + cd optimole-base + composer install --no-dev --prefer-dist --no-progress --no-suggest + npm ci + npm run build + # TODO: when is merged to master, switch to npm run make-pot + docker run --user root --rm --volume $(pwd):/var/www/html/optimole-wp wordpress:cli bash -c 'php -d memory_limit=512M $(which wp) --version --allow-root && wp i18n make-pot optimole-wp ./optimole-wp/languages/optimole-wp.pot --include=inc,assets/src --allow-root --domain=optimole-wp' + ls languages/ + - name: Checkout PR Branch (Head) + uses: actions/checkout@v4 + with: + path: optimole-head + - name: Build POT for PR Branch + run: | + cd optimole-head + composer install --no-dev --prefer-dist --no-progress --no-suggest + npm ci + npm run build + npm run make-pot + ls languages/ + - name: Compare POT files + uses: Codeinwp/action-i18n-string-reviewer@main + with: + fail-on-changes: 'true' + openrouter-key: ${{ secrets.OPEN_ROUTER_API_KEY }} + openrouter-model: 'google/gemini-2.5-flash' + base-pot-file: 'optimole-base/languages/optimole-wp.pot' + target-pot-file: 'optimole-head/languages/optimole-wp.pot' + github-token: ${{ secrets.BOT_TOKEN }} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 98897f479..2a3d29e16 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ assets/build test-results tests/assets/filestash coverage +languages \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 336b0ce6b..b0b3541d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -992,7 +992,7 @@ Fix edge cases for auto allowing domain on site migration. **Documentation** -* improve readme description of the OptiMole service ([e020300](https://github.com/Codeinwp/optimole-wp/commit/e020300)) +* improve readme description of the Optimole service ([e020300](https://github.com/Codeinwp/optimole-wp/commit/e020300)) diff --git a/README.md b/README.md index d442af2c0..a7b791f19 100644 --- a/README.md +++ b/README.md @@ -260,12 +260,12 @@ Discover how to make the most of Optimole with our detailed and user-friendly [d ## Installation ## -The following are the steps to install the OptiMole plugin +The following are the steps to install the Optimole plugin 1. In your WordPress Administration Panels, click on Add New option under Plugins from the menu. Click on upload at the top. -2. Browse the location and select the OptiMole Plugin and click install now. -3. Go to Media -> OptiMole and follow in the instructions on how to enable the service. +2. Browse the location and select the Optimole Plugin and click install now. +3. Go to Media -> Optimole and follow in the instructions on how to enable the service. ## Frequently Asked Questions ## diff --git a/assets/src/dashboard/parts/connected/dashboard/LastImages.js b/assets/src/dashboard/parts/connected/dashboard/LastImages.js index 83ac67730..82e6d845d 100644 --- a/assets/src/dashboard/parts/connected/dashboard/LastImages.js +++ b/assets/src/dashboard/parts/connected/dashboard/LastImages.js @@ -55,7 +55,7 @@ const Image = ({ } } ref={ squareRef } /> -

{ getSize() }% { optimoleDashboardApp.strings.latest_images.saved }

+

{ optimoleDashboardApp.strings.latest_images.percentage_saved.replace( '{ratio}', getSize() ) }

); }; @@ -136,7 +136,7 @@ const LastImages = () => { return (
-

{ optimoleDashboardApp.strings.latest_images.last } { optimoleDashboardApp.strings.latest_images.optimized_images }

+

{ optimoleDashboardApp.strings.latest_images.last_optimized_images }

{ ( isInitialLoading && ! isLoaded ) && (
diff --git a/assets/src/dashboard/parts/connected/settings/Compression.js b/assets/src/dashboard/parts/connected/settings/Compression.js index a55ac8998..b44dc63c0 100644 --- a/assets/src/dashboard/parts/connected/settings/Compression.js +++ b/assets/src/dashboard/parts/connected/settings/Compression.js @@ -352,7 +352,7 @@ const Compression = ({ { ( sampleImages.id && 0 < sampleImages.original_size ) && (
{ 0 < getCompressionRatio() ? ( -

{ 100 - getCompressionRatio() }% { optimoleDashboardApp.strings.latest_images.smaller }

+

{ optimoleDashboardApp.strings.latest_images.percentage_smaller.replace( '{ratio}', 100 - getCompressionRatio() ) }

) : (

{ optimoleDashboardApp.strings.latest_images.same_size }

) } diff --git a/assets/src/dashboard/utils/api.js b/assets/src/dashboard/utils/api.js index e89332259..63f7dfd86 100644 --- a/assets/src/dashboard/utils/api.js +++ b/assets/src/dashboard/utils/api.js @@ -153,7 +153,7 @@ export const connectAccount = ( data, callback = () => {}) => { sendOnboardingImages(); toggleDashboardSidebarSubmenu( true ); - console.log( '%c OptiMole API connection successful.', 'color: #59B278' ); + console.log( '%c Optimole API connection successful.', 'color: #59B278' ); } else { setHasValidKey( false ); @@ -195,7 +195,7 @@ export const disconnectAccount = () => { sethasDashboardLoaded( false ); setShowDisconnect( false ); toggleDashboardSidebarSubmenu( false ); - console.log( '%c Disconnected from OptiMole API.', 'color: #59B278' ); + console.log( '%c Disconnected from Optimole API.', 'color: #59B278' ); } else { console.error( response ); } @@ -221,7 +221,7 @@ export const selectDomain = ( data, callback = () => {}) => { setAPIKey( response.data.api_key ); setUserData( response.data ); setAvailableApps( response.data ); - console.log( '%c OptiMole API connection successful.', 'color: #59B278' ); + console.log( '%c Optimole API connection successful.', 'color: #59B278' ); } else { setHasValidKey( false ); console.log( '%c Invalid API Key.', 'color: #E7602A' ); @@ -271,7 +271,7 @@ export const requestStatsUpdate = () => { if ( 'disconnected' === response.code ) { setIsConnected( false ); sethasDashboardLoaded( false ); - console.log( '%c Disconnected from OptiMole API.', 'color: #59B278' ); + console.log( '%c Disconnected from Optimole API.', 'color: #59B278' ); } }); }; diff --git a/assets/src/global.d.ts b/assets/src/global.d.ts index df811f82d..541e9aeac 100644 --- a/assets/src/global.d.ts +++ b/assets/src/global.d.ts @@ -481,10 +481,9 @@ export interface LatestImages { no_images_found: string compression: string loading_latest_images: string - last: string - saved: string - smaller: string - optimized_images: string + last_optimized_images: string + percentage_saved: string + percentage_smaller: string same_size: string small_optimization: string medium_optimization: string diff --git a/assets/src/widget/components/WidgetFooter.js b/assets/src/widget/components/WidgetFooter.js index 14753ee13..b399fd020 100644 --- a/assets/src/widget/components/WidgetFooter.js +++ b/assets/src/widget/components/WidgetFooter.js @@ -1,7 +1,7 @@ import { Icon, external } from '@wordpress/icons'; export default function WidgetFooter() { - const { i18n, dashboardURL, adminPageURL } = optimoleDashboardWidget; + const { i18n, dashboardURL, dashboardMetricsURL } = optimoleDashboardWidget; return (
@@ -10,8 +10,9 @@ export default function WidgetFooter() { Optimole - + { i18n.viewAllStats } +
); diff --git a/inc/admin.php b/inc/admin.php index 0b5b705c1..1ca0dd712 100755 --- a/inc/admin.php +++ b/inc/admin.php @@ -635,22 +635,17 @@ public function add_notice_upgrade() { } ?>
+ style="background-color: #577BF9; color:white; border: none !important; display: flex; align-items: center;">
- '> + '>
-
+

', - number_format_i18n( 2000 ), - '', - '', - '', - '

' + /* translators: 1 - visits limit */ + __( 'You\'re nearing your %1$s-visit monthly cap on Optimole. If you exceed it, we\'ll serve original (unoptimized) images - expect slower pages.', 'optimole-wp' ), + '' . number_format_i18n( 2000 ) . '' ); ?>

@@ -864,7 +859,7 @@ public function add_notice() {

+ class="button button-primary button-hero"> @@ -2286,10 +2281,11 @@ private function get_dashboard_strings() { 'no_images_found' => sprintf( /* translators: 1 is the starting anchor tag, 2 is the ending anchor tag */ __( 'We are currently optimizing your images. Meanwhile you can visit your %1$shomepage%2$s and check how our plugin performs.', 'optimole-wp' ), '', '' ), 'compression' => __( 'Optimization', 'optimole-wp' ), 'loading_latest_images' => __( 'Loading your optimized images...', 'optimole-wp' ), - 'last' => __( 'Last', 'optimole-wp' ), - 'saved' => __( 'Saved', 'optimole-wp' ), - 'smaller' => __( 'smaller', 'optimole-wp' ), - 'optimized_images' => __( 'optimized images', 'optimole-wp' ), + 'last_optimized_images' => __( 'Last optimized images', 'optimole-wp' ), + // translators: %s is the percentage (e.g. 10%). + 'percentage_saved' => sprintf( __( '%s Saved', 'optimole-wp' ), '{ratio}%' ), + // translators: %s is the percentage (e.g. 10%). + 'percentage_smaller' => sprintf( __( '%s smaller', 'optimole-wp' ), '{ratio}%' ), 'same_size' => __( '🙉 We couldn\'t do better, this image is already optimized at maximum.', 'optimole-wp' ), 'small_optimization' => __( '😬 Not that much, just {ratio} smaller.', 'optimole-wp' ), 'medium_optimization' => __( '🤓 We are on the right track, {ratio} squeezed.', 'optimole-wp' ), diff --git a/inc/cli/cli_setting.php b/inc/cli/cli_setting.php index 2ef670ffa..743d7dd6f 100644 --- a/inc/cli/cli_setting.php +++ b/inc/cli/cli_setting.php @@ -32,12 +32,11 @@ public function connect( $args ) { if ( $data === false || is_wp_error( $data ) ) { $extra = ''; if ( is_wp_error( $data ) ) { - /** - * Error from api. - * - * @var WP_Error $data Error object. - */ - $extra = sprintf( /* translators: errors details */ __( '. ERROR details: %s', 'optimole-wp' ), $data->get_error_message() ); + $extra = sprintf( + /* translators: Error details */ + __( '. ERROR details: %s', 'optimole-wp' ), + $data->get_error_message() + ); } return \WP_CLI::error( __( 'Can not connect to Optimole service', 'optimole-wp' ) . $extra ); diff --git a/inc/dashboard_widget.php b/inc/dashboard_widget.php index d804717ae..2c7756ad1 100644 --- a/inc/dashboard_widget.php +++ b/inc/dashboard_widget.php @@ -114,7 +114,7 @@ private function get_script_localization() { 'billingURL' => tsdk_translate_link( 'https://dashboard.optimole.com/settings/billing', 'query' ), 'serviceData' => $this->get_service_data(), 'assetsURL' => OPTML_URL . 'assets/', - 'adminPageURL' => esc_url( admin_url( 'admin.php?page=optimole' ) ), + 'dashboardMetricsURL' => esc_url( 'https://dashboard.optimole.com/metrics' ), 'dashboardURL' => esc_url( tsdk_translate_link( 'https://dashboard.optimole.com' ) ), ]; } diff --git a/optimole-wp.php b/optimole-wp.php index 748d7a22b..dadeda968 100644 --- a/optimole-wp.php +++ b/optimole-wp.php @@ -58,14 +58,12 @@ function optml_php_notice() { ', '7.4', '', '', - '', - '', '', '', '

' diff --git a/package.json b/package.json index da3cd8aec..38351e254 100755 --- a/package.json +++ b/package.json @@ -45,7 +45,8 @@ "release": "semantic-release --debug", "e2e:open": "playwright test --ui", "e2e:run": "playwright test", - "dist": "./bin/dist.sh" + "dist": "./bin/dist.sh", + "make-pot": "docker run --user root --rm --volume $(pwd):/var/www/html/optimole-wp wordpress:cli bash -c 'php -d memory_limit=512M $(which wp) --version --allow-root && wp i18n make-pot optimole-wp ./optimole-wp/languages/optimole-wp.pot --include=inc,assets/src --allow-root --domain=optimole-wp'" }, "devDependencies": { "@playwright/test": "^1.50.1", diff --git a/readme.txt b/readme.txt index 882c19599..2811ba1ca 100755 --- a/readme.txt +++ b/readme.txt @@ -70,8 +70,7 @@ Optimize your entire media library with a single click. Optimole processes your #### 🚀 One-Click Image Offloading [PRO] -Free up valuable server space by offloading your entire media library to Optimole's secure cloud storage. All your images are safely stored and delivered from our optimized CDN, reducing your hosting costs and server load. Need your images back on your server? Our seamless one-click restoration process makes it easy to transfer everything back -whenever you want, giving you complete flexibility and control over your media assets. +Free up valuable server space by offloading your entire media library to Optimole's secure cloud storage. All your images are safely stored and delivered from our optimized CDN, reducing your hosting costs and server load. Need your images back on your server? Our seamless one-click restoration process makes it easy to transfer everything back whenever you want, giving you complete flexibility and control over your media assets. #### 🌎 CDN @@ -260,12 +259,12 @@ Discover how to make the most of Optimole with our detailed and user-friendly [d == Installation == -The following are the steps to install the OptiMole plugin +The following are the steps to install the Optimole plugin -1. In your WordPress Administration Panels, click on Add New option under Plugins from the menu. +1. In your WordPress Dashboard, click on Add New option under Plugins from the menu. Click on upload at the top. -2. Browse the location and select the OptiMole Plugin and click install now. -3. Go to Media -> OptiMole and follow in the instructions on how to enable the service. +2. Browse the location, select the Optimole plugin and click "Install now". +3. Go to Media -> Optimole and follow in the instructions on how to enable the service. == Frequently Asked Questions == @@ -305,7 +304,7 @@ We use your original images as sources when deliver the optimized images. Unless A higher compression might result in a small loss of image quality. Selecting the auto level will let Optimole choose the minimum size with no loss in the quality of your picture. -= I used Kraken, Shortpixel, Optimus, EWWW or WP Smush, Imagify will Optimole further optimize my images? = += I used Kraken, Shortpixel, Optimus, EWWW or WP Smush, Imagify. Will Optimole further optimize my images? = Yes, Optimole will also take care of serving your image at the RIGHT size for your visitors and optimize them to the best possible format for their browser.