Visual Portfolio, Photo Gallery & Post Grid - Version 2.10.2

Version Description

Download this release

Release Info

Developer nko
Plugin Icon 128x128 Visual Portfolio, Photo Gallery & Post Grid
Version 2.10.2
Comparing to
See all releases

Code changes from version 2.10.1 to 2.10.2

assets/admin/js/elementor.js CHANGED
@@ -2,7 +2,7 @@
2
  * Additional js for Elementor
3
  *
4
  * Name : Visual Portfolio
5
- * Version : 2.10.1
6
  * Author : nK https://nkdev.info
7
  */
8
  import { throttle } from 'throttle-debounce';
2
  * Additional js for Elementor
3
  *
4
  * Name : Visual Portfolio
5
+ * Version : 2.10.2
6
  * Author : nK https://nkdev.info
7
  */
8
  import { throttle } from 'throttle-debounce';
assets/admin/js/mce-dropdown.js CHANGED
@@ -1,6 +1,6 @@
1
  /*!
2
  * Name : Visual Portfolio
3
- * Version : 2.10.1
4
  * Author : nK https://nkdev.info
5
  */
6
  const {
1
  /*!
2
  * Name : Visual Portfolio
3
+ * Version : 2.10.2
4
  * Author : nK https://nkdev.info
5
  */
6
  const {
assets/admin/js/script.js CHANGED
@@ -1,6 +1,6 @@
1
  /*!
2
  * Name : Visual Portfolio
3
- * Version : 2.10.1
4
  * Author : nK https://nkdev.info
5
  */
6
  import { debounce } from 'throttle-debounce';
1
  /*!
2
  * Name : Visual Portfolio
3
+ * Version : 2.10.2
4
  * Author : nK https://nkdev.info
5
  */
6
  import { debounce } from 'throttle-debounce';
assets/admin/js/vc-frontend.js CHANGED
@@ -2,7 +2,7 @@
2
  * Additional js for frontend VC
3
  *
4
  * Name : Visual Portfolio
5
- * Version : 2.10.1
6
  * Author : nK https://nkdev.info
7
  */
8
  const {
2
  * Additional js for frontend VC
3
  *
4
  * Name : Visual Portfolio
5
+ * Version : 2.10.2
6
  * Author : nK https://nkdev.info
7
  */
8
  const {
assets/js/lazyload.js CHANGED
@@ -25,6 +25,11 @@ if ( 'undefined' !== typeof objectFitImages ) {
25
  } );
26
  }
27
 
 
 
 
 
 
28
  // Lazyloaded - remove preloader images placeholder effect.
29
  $doc.on( 'lazybeforeunveil', ( e ) => {
30
  const $img = $( e.target );
25
  } );
26
  }
27
 
28
+ // recalculate image size if parent is <picture>
29
+ $doc.on( 'lazybeforesizes', ( e ) => {
30
+ e.detail.width = $( e.target ).parents( ':not(picture)' ).innerWidth() || e.detail.width;
31
+ } );
32
+
33
  // Lazyloaded - remove preloader images placeholder effect.
34
  $doc.on( 'lazybeforeunveil', ( e ) => {
35
  const $img = $( e.target );
assets/js/lazyload.min.js CHANGED
@@ -1 +1 @@
1
- !function(o){var e={};function t(n){if(e[n])return e[n].exports;var r=e[n]={i:n,l:!1,exports:{}};return o[n].call(r.exports,r,r.exports,t),r.l=!0,r.exports}t.m=o,t.c=e,t.d=function(o,e,n){t.o(o,e)||Object.defineProperty(o,e,{enumerable:!0,get:n})},t.r=function(o){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(o,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(o,"__esModule",{value:!0})},t.t=function(o,e){if(1&e&&(o=t(o)),8&e)return o;if(4&e&&"object"==typeof o&&o&&o.__esModule)return o;var n=Object.create(null);if(t.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:o}),2&e&&"string"!=typeof o)for(var r in o)t.d(n,r,function(e){return o[e]}.bind(null,r));return n},t.n=function(o){var e=o&&o.__esModule?function(){return o.default}:function(){return o};return t.d(e,"a",e),e},t.o=function(o,e){return Object.prototype.hasOwnProperty.call(o,e)},t.p="",t(t.s=233)}({233:function(o,e,t){o.exports=t(234)},234:function(o,e){var t=window,n=t.jQuery,r=t.objectFitImages,i=n(document);void 0!==r&&(r(".vp-portfolio img:not(.vp-lazyload)"),i.on("lazybeforeunveil",(function(o){var e=n(o.target);e.closest(".vp-portfolio").length&&e.one("load",(function(){r(e[0])}))}))),i.on("lazybeforeunveil",(function(o){var e=n(o.target);e.closest(".vp-portfolio__item-img").addClass("vp-portfolio__item-img-lazyloading"),e.closest(".vp-portfolio__thumbnail-img").addClass("vp-portfolio__thumbnail-img-lazyloading"),e.prev("noscript").remove()})),i.on("lazyloaded",(function(o){var e=n(o.target);e.closest(".vp-portfolio__item-img-lazyloading").removeClass("vp-portfolio__item-img-lazyloading"),e.closest(".vp-portfolio__thumbnail-img-lazyloading").removeClass("vp-portfolio__thumbnail-img-lazyloading")}))}});
1
+ !function(o){var t={};function e(n){if(t[n])return t[n].exports;var r=t[n]={i:n,l:!1,exports:{}};return o[n].call(r.exports,r,r.exports,e),r.l=!0,r.exports}e.m=o,e.c=t,e.d=function(o,t,n){e.o(o,t)||Object.defineProperty(o,t,{enumerable:!0,get:n})},e.r=function(o){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(o,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(o,"__esModule",{value:!0})},e.t=function(o,t){if(1&t&&(o=e(o)),8&t)return o;if(4&t&&"object"==typeof o&&o&&o.__esModule)return o;var n=Object.create(null);if(e.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:o}),2&t&&"string"!=typeof o)for(var r in o)e.d(n,r,function(t){return o[t]}.bind(null,r));return n},e.n=function(o){var t=o&&o.__esModule?function(){return o.default}:function(){return o};return e.d(t,"a",t),t},e.o=function(o,t){return Object.prototype.hasOwnProperty.call(o,t)},e.p="",e(e.s=233)}({233:function(o,t,e){o.exports=e(234)},234:function(o,t){var e=window,n=e.jQuery,r=e.objectFitImages,i=n(document);void 0!==r&&(r(".vp-portfolio img:not(.vp-lazyload)"),i.on("lazybeforeunveil",(function(o){var t=n(o.target);t.closest(".vp-portfolio").length&&t.one("load",(function(){r(t[0])}))}))),i.on("lazybeforesizes",(function(o){o.detail.width=n(o.target).parents(":not(picture)").innerWidth()||o.detail.width})),i.on("lazybeforeunveil",(function(o){var t=n(o.target);t.closest(".vp-portfolio__item-img").addClass("vp-portfolio__item-img-lazyloading"),t.closest(".vp-portfolio__thumbnail-img").addClass("vp-portfolio__thumbnail-img-lazyloading"),t.prev("noscript").remove()})),i.on("lazyloaded",(function(o){var t=n(o.target);t.closest(".vp-portfolio__item-img-lazyloading").removeClass("vp-portfolio__item-img-lazyloading"),t.closest(".vp-portfolio__thumbnail-img-lazyloading").removeClass("vp-portfolio__thumbnail-img-lazyloading")}))}});
assets/js/preview.js CHANGED
@@ -1,6 +1,6 @@
1
  /*!
2
  * Name : Visual Portfolio
3
- * Version : 2.10.1
4
  * Author : nK https://nkdev.info
5
  */
6
  const $ = window.jQuery;
1
  /*!
2
  * Name : Visual Portfolio
3
+ * Version : 2.10.2
4
  * Author : nK https://nkdev.info
5
  */
6
  const $ = window.jQuery;
class-visual-portfolio.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Plugin Name: Visual Portfolio, Posts & Image Gallery
4
  * Description: Modern gallery and portfolio plugin with advanced layouts editor. Clean and powerful gallery styles with enormous settings in the Gutenberg block.
5
- * Version: 2.10.1
6
  * Author: nK
7
  * Author URI: https://nkdev.info
8
  * License: GPLv2 or later
@@ -143,11 +143,14 @@ class Visual_Portfolio {
143
  require_once $this->plugin_path . 'classes/class-custom-post-meta.php';
144
  require_once $this->plugin_path . 'classes/class-admin.php';
145
  require_once $this->plugin_path . 'classes/class-controls.php';
146
- require_once $this->plugin_path . 'classes/class-tinymce.php';
147
- require_once $this->plugin_path . 'classes/class-vc.php';
148
- require_once $this->plugin_path . 'classes/class-elementor.php';
149
  require_once $this->plugin_path . 'classes/class-supported-themes.php';
150
- require_once $this->plugin_path . 'classes/class-wpml.php';
 
 
 
 
 
 
151
 
152
  // Migration run after all features.
153
  require_once $this->plugin_path . 'classes/class-migration.php';
2
  /**
3
  * Plugin Name: Visual Portfolio, Posts & Image Gallery
4
  * Description: Modern gallery and portfolio plugin with advanced layouts editor. Clean and powerful gallery styles with enormous settings in the Gutenberg block.
5
+ * Version: 2.10.2
6
  * Author: nK
7
  * Author URI: https://nkdev.info
8
  * License: GPLv2 or later
143
  require_once $this->plugin_path . 'classes/class-custom-post-meta.php';
144
  require_once $this->plugin_path . 'classes/class-admin.php';
145
  require_once $this->plugin_path . 'classes/class-controls.php';
 
 
 
146
  require_once $this->plugin_path . 'classes/class-supported-themes.php';
147
+
148
+ // 3rd code integration.
149
+ require_once $this->plugin_path . 'classes/3rd/class-tinymce.php';
150
+ require_once $this->plugin_path . 'classes/3rd/class-vc.php';
151
+ require_once $this->plugin_path . 'classes/3rd/class-elementor.php';
152
+ require_once $this->plugin_path . 'classes/3rd/class-imagify.php';
153
+ require_once $this->plugin_path . 'classes/3rd/class-wpml.php';
154
 
155
  // Migration run after all features.
156
  require_once $this->plugin_path . 'classes/class-migration.php';
classes/{class-elementor-widget.php → 3rd/class-elementor-widget.php} RENAMED
@@ -10,11 +10,11 @@ if ( ! defined( 'ABSPATH' ) ) {
10
  }
11
 
12
  /**
13
- * Class Visual_Portfolio_Elementor_Widget
14
  */
15
- class Visual_Portfolio_Elementor_Widget extends \Elementor\Widget_Base {
16
  /**
17
- * Constructor of Visual_Portfolio_Elementor_Widget class.
18
  *
19
  * @param array $data default widget data.
20
  * @param null|array $args default widget args.
@@ -33,9 +33,9 @@ class Visual_Portfolio_Elementor_Widget extends \Elementor\Widget_Base {
33
 
34
  if ( $this->is_preview_mode() ) {
35
  wp_register_script( 'iframe-resizer', visual_portfolio()->plugin_url . 'assets/vendor/iframe-resizer/js/iframeResizer.min.js', '', '4.2.11', true );
36
- wp_register_script( 'visual-portfolio-elementor', visual_portfolio()->plugin_url . 'assets/admin/js/elementor.min.js', array( 'elementor-frontend', 'iframe-resizer', 'jquery' ), '2.10.1', true );
37
 
38
- wp_register_style( 'visual-portfolio-elementor', visual_portfolio()->plugin_url . 'assets/admin/css/elementor.min.css', array(), '2.10.1' );
39
  wp_style_add_data( 'visual-portfolio-elementor', 'rtl', 'replace' );
40
  wp_style_add_data( 'visual-portfolio-elementor', 'suffix', '.min' );
41
  }
10
  }
11
 
12
  /**
13
+ * Class Visual_Portfolio_3rd_Elementor_Widget
14
  */
15
+ class Visual_Portfolio_3rd_Elementor_Widget extends \Elementor\Widget_Base {
16
  /**
17
+ * Constructor of Visual_Portfolio_3rd_Elementor_Widget class.
18
  *
19
  * @param array $data default widget data.
20
  * @param null|array $args default widget args.
33
 
34
  if ( $this->is_preview_mode() ) {
35
  wp_register_script( 'iframe-resizer', visual_portfolio()->plugin_url . 'assets/vendor/iframe-resizer/js/iframeResizer.min.js', '', '4.2.11', true );
36
+ wp_register_script( 'visual-portfolio-elementor', visual_portfolio()->plugin_url . 'assets/admin/js/elementor.min.js', array( 'elementor-frontend', 'iframe-resizer', 'jquery' ), '2.10.2', true );
37
 
38
+ wp_register_style( 'visual-portfolio-elementor', visual_portfolio()->plugin_url . 'assets/admin/css/elementor.min.css', array(), '2.10.2' );
39
  wp_style_add_data( 'visual-portfolio-elementor', 'rtl', 'replace' );
40
  wp_style_add_data( 'visual-portfolio-elementor', 'suffix', '.min' );
41
  }
classes/{class-elementor.php → 3rd/class-elementor.php} RENAMED
@@ -10,11 +10,11 @@ if ( ! defined( 'ABSPATH' ) ) {
10
  }
11
 
12
  /**
13
- * Class Visual_Portfolio_Elementor
14
  */
15
- class Visual_Portfolio_Elementor {
16
  /**
17
- * Visual_Portfolio_Elementor constructor.
18
  */
19
  public function __construct() {
20
  add_action( 'elementor/widgets/widgets_registered', array( $this, 'widgets_registered' ) );
@@ -26,8 +26,8 @@ class Visual_Portfolio_Elementor {
26
  public function widgets_registered() {
27
  require_once visual_portfolio()->plugin_path . 'classes/class-elementor-widget.php';
28
 
29
- \Elementor\Plugin::instance()->widgets_manager->register_widget_type( new Visual_Portfolio_Elementor_Widget() );
30
  }
31
  }
32
 
33
- new Visual_Portfolio_Elementor();
10
  }
11
 
12
  /**
13
+ * Class Visual_Portfolio_3rd_Elementor
14
  */
15
+ class Visual_Portfolio_3rd_Elementor {
16
  /**
17
+ * Visual_Portfolio_3rd_Elementor constructor.
18
  */
19
  public function __construct() {
20
  add_action( 'elementor/widgets/widgets_registered', array( $this, 'widgets_registered' ) );
26
  public function widgets_registered() {
27
  require_once visual_portfolio()->plugin_path . 'classes/class-elementor-widget.php';
28
 
29
+ \Elementor\Plugin::instance()->widgets_manager->register_widget_type( new Visual_Portfolio_3rd_Elementor_Widget() );
30
  }
31
  }
32
 
33
+ new Visual_Portfolio_3rd_Elementor();
classes/3rd/class-imagify.php ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Imagify Plugin.
4
+ *
5
+ * @package visual-portfolio
6
+ */
7
+
8
+ if ( ! defined( 'ABSPATH' ) ) {
9
+ exit;
10
+ }
11
+
12
+ /**
13
+ * Class Visual_Portfolio_3rd_Imagify
14
+ */
15
+ class Visual_Portfolio_3rd_Imagify {
16
+ /**
17
+ * Visual_Portfolio_3rd_Imagify constructor.
18
+ */
19
+ public function __construct() {
20
+ // Fix lazyload attributes.
21
+ //
22
+ // Thanks to:
23
+ // - https://wordpress.org/support/topic/all-images-are-grey/
24
+ // - https://wordpress.org/support/topic/all-images-are-grey-again/.
25
+ add_filter( 'imagify_picture_attributes', array( $this, 'imagify_picture_attributes' ) );
26
+ add_filter( 'imagify_picture_img_attributes', array( $this, 'imagify_picture_img_attributes' ), 10, 2 );
27
+ }
28
+
29
+ /**
30
+ * Remove lazyload class from the picture tag.
31
+ *
32
+ * @param array $attributes image tag attributes.
33
+ *
34
+ * @return array
35
+ */
36
+ public function imagify_picture_attributes( $attributes ) {
37
+ if ( isset( $attributes['class'] ) && strpos( $attributes['class'], 'vp-lazyload' ) !== false ) {
38
+ $attributes['class'] = str_replace( 'vp-lazyload', '', $attributes['class'] );
39
+ }
40
+
41
+ return $attributes;
42
+ }
43
+
44
+ /**
45
+ * Restore lazyload class to the img tag.
46
+ *
47
+ * @param array $attributes image tag attributes.
48
+ * @param array $image image data.
49
+ *
50
+ * @return array
51
+ */
52
+ public function imagify_picture_img_attributes( $attributes, $image ) {
53
+ if ( isset( $image['attributes']['class'] ) && strpos( $image['attributes']['class'], 'vp-lazyload' ) !== false ) {
54
+ if ( isset( $attributes['class'] ) ) {
55
+ $attributes['class'] .= ' ';
56
+ } else {
57
+ $attributes['class'] = '';
58
+ }
59
+
60
+ $attributes['class'] .= 'vp-lazyload';
61
+ }
62
+
63
+ return $attributes;
64
+ }
65
+ }
66
+
67
+ new Visual_Portfolio_3rd_Imagify();
classes/{class-tinymce.php → 3rd/class-tinymce.php} RENAMED
@@ -10,11 +10,11 @@ if ( ! defined( 'ABSPATH' ) ) {
10
  }
11
 
12
  /**
13
- * Class Visual_Portfolio_TinyMCE
14
  */
15
- class Visual_Portfolio_TinyMCE {
16
  /**
17
- * Visual_Portfolio_TinyMCE constructor.
18
  */
19
  public function __construct() {
20
  $this->init_hooks();
@@ -70,7 +70,7 @@ class Visual_Portfolio_TinyMCE {
70
  return;
71
  }
72
 
73
- wp_enqueue_script( 'visual-portfolio-tinymce-localize', visual_portfolio()->plugin_url . 'assets/admin/js/mce-localize.min.js', array(), '2.10.1', true );
74
  wp_localize_script( 'visual-portfolio-tinymce-localize', 'VPTinyMCEOptions', $data_tiny_mce );
75
  }
76
  }
@@ -100,4 +100,4 @@ class Visual_Portfolio_TinyMCE {
100
  }
101
  }
102
 
103
- new Visual_Portfolio_TinyMCE();
10
  }
11
 
12
  /**
13
+ * Class Visual_Portfolio_3rd_TinyMCE
14
  */
15
+ class Visual_Portfolio_3rd_TinyMCE {
16
  /**
17
+ * Visual_Portfolio_3rd_TinyMCE constructor.
18
  */
19
  public function __construct() {
20
  $this->init_hooks();
70
  return;
71
  }
72
 
73
+ wp_enqueue_script( 'visual-portfolio-tinymce-localize', visual_portfolio()->plugin_url . 'assets/admin/js/mce-localize.min.js', array(), '2.10.2', true );
74
  wp_localize_script( 'visual-portfolio-tinymce-localize', 'VPTinyMCEOptions', $data_tiny_mce );
75
  }
76
  }
100
  }
101
  }
102
 
103
+ new Visual_Portfolio_3rd_TinyMCE();
classes/{class-vc.php → 3rd/class-vc.php} RENAMED
@@ -10,11 +10,11 @@ if ( ! defined( 'ABSPATH' ) ) {
10
  }
11
 
12
  /**
13
- * Class Visual_Portfolio_VC
14
  */
15
- class Visual_Portfolio_VC {
16
  /**
17
- * Visual_Portfolio_VC constructor.
18
  */
19
  public function __construct() {
20
  $this->init_hooks();
@@ -35,7 +35,7 @@ class Visual_Portfolio_VC {
35
  */
36
  public function admin_enqueue_scripts( $page ) {
37
  if ( 'post.php' === $page || 'post-new.php' === $page ) {
38
- wp_enqueue_script( 'visual-portfolio-vc-frontend', visual_portfolio()->plugin_url . 'assets/admin/js/vc-frontend.min.js', array( 'jquery' ), '2.10.1', true );
39
  }
40
  }
41
 
@@ -95,4 +95,4 @@ class Visual_Portfolio_VC {
95
  }
96
  }
97
 
98
- new Visual_Portfolio_VC();
10
  }
11
 
12
  /**
13
+ * Class Visual_Portfolio_3rd_VC
14
  */
15
+ class Visual_Portfolio_3rd_VC {
16
  /**
17
+ * Visual_Portfolio_3rd_VC constructor.
18
  */
19
  public function __construct() {
20
  $this->init_hooks();
35
  */
36
  public function admin_enqueue_scripts( $page ) {
37
  if ( 'post.php' === $page || 'post-new.php' === $page ) {
38
+ wp_enqueue_script( 'visual-portfolio-vc-frontend', visual_portfolio()->plugin_url . 'assets/admin/js/vc-frontend.min.js', array( 'jquery' ), '2.10.2', true );
39
  }
40
  }
41
 
95
  }
96
  }
97
 
98
+ new Visual_Portfolio_3rd_VC();
classes/{class-wpml.php → 3rd/class-wpml.php} RENAMED
@@ -12,11 +12,11 @@ if ( ! defined( 'ABSPATH' ) ) {
12
  // phpcs:disable WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
13
 
14
  /**
15
- * Class Visual_Portfolio_WPML
16
  */
17
- class Visual_Portfolio_WPML {
18
  /**
19
- * Visual_Portfolio_WPML constructor.
20
  */
21
  public function __construct() {
22
  global $iclTranslationManagement;
@@ -90,4 +90,4 @@ class Visual_Portfolio_WPML {
90
  }
91
  }
92
 
93
- new Visual_Portfolio_WPML();
12
  // phpcs:disable WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
13
 
14
  /**
15
+ * Class Visual_Portfolio_3rd_WPML
16
  */
17
+ class Visual_Portfolio_3rd_WPML {
18
  /**
19
+ * Visual_Portfolio_3rd_WPML constructor.
20
  */
21
  public function __construct() {
22
  global $iclTranslationManagement;
90
  }
91
  }
92
 
93
+ new Visual_Portfolio_3rd_WPML();
classes/class-admin.php CHANGED
@@ -42,9 +42,9 @@ class Visual_Portfolio_Admin {
42
  'nonce' => wp_create_nonce( 'vp-ajax-nonce' ),
43
  );
44
 
45
- wp_enqueue_script( 'visual-portfolio-admin', visual_portfolio()->plugin_url . 'assets/admin/js/script.min.js', array( 'jquery', 'wp-data' ), '2.10.1', true );
46
  wp_localize_script( 'visual-portfolio-admin', 'VPAdminVariables', $data_init );
47
- wp_enqueue_style( 'visual-portfolio-admin', visual_portfolio()->plugin_url . 'assets/admin/css/style.min.css', array(), '2.10.1' );
48
  wp_style_add_data( 'visual-portfolio-admin', 'rtl', 'replace' );
49
  wp_style_add_data( 'visual-portfolio-admin', 'suffix', '.min' );
50
  }
@@ -58,8 +58,8 @@ class Visual_Portfolio_Admin {
58
  );
59
 
60
  if ( 'vp_lists' === get_post_type() ) {
61
- wp_enqueue_script( 'visual-portfolio-saved-layouts', visual_portfolio()->plugin_url . 'gutenberg/layouts-editor.min.js', array( 'jquery' ), '2.10.1', true );
62
- wp_enqueue_style( 'visual-portfolio-saved-layouts', visual_portfolio()->plugin_url . 'gutenberg/layouts-editor.min.css', array(), '2.10.1' );
63
  wp_style_add_data( 'visual-portfolio-saved-layouts', 'rtl', 'replace' );
64
  wp_style_add_data( 'visual-portfolio-saved-layouts', 'suffix', '.min' );
65
 
@@ -105,7 +105,7 @@ class Visual_Portfolio_Admin {
105
  // phpcs:ignore
106
  if ( 'visual_portfolio_go_pro' === $_GET['page'] ) {
107
  // phpcs:ignore
108
- wp_redirect( 'https://visualportfolio.co/pro/?utm_source=freeplugin&utm_medium=link&utm_campaign=admin_page&utm_content=2.10.1' );
109
  exit();
110
  }
111
  }
42
  'nonce' => wp_create_nonce( 'vp-ajax-nonce' ),
43
  );
44
 
45
+ wp_enqueue_script( 'visual-portfolio-admin', visual_portfolio()->plugin_url . 'assets/admin/js/script.min.js', array( 'jquery', 'wp-data' ), '2.10.2', true );
46
  wp_localize_script( 'visual-portfolio-admin', 'VPAdminVariables', $data_init );
47
+ wp_enqueue_style( 'visual-portfolio-admin', visual_portfolio()->plugin_url . 'assets/admin/css/style.min.css', array(), '2.10.2' );
48
  wp_style_add_data( 'visual-portfolio-admin', 'rtl', 'replace' );
49
  wp_style_add_data( 'visual-portfolio-admin', 'suffix', '.min' );
50
  }
58
  );
59
 
60
  if ( 'vp_lists' === get_post_type() ) {
61
+ wp_enqueue_script( 'visual-portfolio-saved-layouts', visual_portfolio()->plugin_url . 'gutenberg/layouts-editor.min.js', array( 'jquery' ), '2.10.2', true );
62
+ wp_enqueue_style( 'visual-portfolio-saved-layouts', visual_portfolio()->plugin_url . 'gutenberg/layouts-editor.min.css', array(), '2.10.2' );
63
  wp_style_add_data( 'visual-portfolio-saved-layouts', 'rtl', 'replace' );
64
  wp_style_add_data( 'visual-portfolio-saved-layouts', 'suffix', '.min' );
65
 
105
  // phpcs:ignore
106
  if ( 'visual_portfolio_go_pro' === $_GET['page'] ) {
107
  // phpcs:ignore
108
+ wp_redirect( 'https://visualportfolio.co/pro/?utm_source=freeplugin&utm_medium=link&utm_campaign=admin_page&utm_content=2.10.2' );
109
  exit();
110
  }
111
  }
classes/class-assets.php CHANGED
@@ -98,11 +98,11 @@ class Visual_Portfolio_Assets {
98
  foreach ( self::$stored_assets[ $type ] as $name => $data ) {
99
  if ( isset( $data['value'] ) && $data['value'] ) {
100
  if ( 'script' === $type ) {
101
- wp_enqueue_script( $name, '', array(), '2.10.1', true );
102
  } elseif ( is_string( $data['value'] ) ) {
103
- visual_portfolio()->include_template_style( $name, $data['value'], array(), '2.10.1' );
104
  } else {
105
- wp_enqueue_style( $name, '', array(), '2.10.1' );
106
  }
107
 
108
  self::$stored_assets[ $type ]['value'] = false;
@@ -259,7 +259,7 @@ class Visual_Portfolio_Assets {
259
  $dynamic_styles = Visual_Portfolio_Controls_Dynamic_CSS::get( $options );
260
  $controls_css_handle = 'vp-dynamic-styles-' . $options['id'];
261
 
262
- wp_register_style( $controls_css_handle, false, array(), '2.10.1' );
263
  wp_enqueue_style( $controls_css_handle );
264
  wp_add_inline_style( $controls_css_handle, $dynamic_styles ? $dynamic_styles : ' ' );
265
 
@@ -359,7 +359,7 @@ class Visual_Portfolio_Assets {
359
  // LazySizes.
360
  if ( apply_filters( 'vpf_enqueue_plugin_lazysizes', true ) ) {
361
  wp_register_script( 'lazysizes-object-fit-cover', visual_portfolio()->plugin_url . 'assets/js/lazysizes-object-fit-cover.min.js', array(), '4.1.0', true );
362
- wp_register_script( 'lazysizes-config', visual_portfolio()->plugin_url . 'assets/js/lazysizes-config.min.js', array(), '2.10.1', true );
363
  wp_register_script( 'lazysizes', visual_portfolio()->plugin_url . 'assets/vendor/lazysizes/lazysizes.min.js', array(), '5.2.2', true );
364
  }
365
 
@@ -407,7 +407,7 @@ class Visual_Portfolio_Assets {
407
  );
408
 
409
  foreach ( $vp_styles as $name => $data ) {
410
- wp_register_style( $name, visual_portfolio()->plugin_url . $data[0], $data[1], '2.10.1' );
411
  wp_style_add_data( $name, 'rtl', 'replace' );
412
  wp_style_add_data( $name, 'suffix', '.min' );
413
  }
@@ -527,7 +527,7 @@ class Visual_Portfolio_Assets {
527
  );
528
 
529
  foreach ( $vp_scripts as $name => $data ) {
530
- wp_register_script( $name, visual_portfolio()->plugin_url . $data[0], $data[1], '2.10.1', true );
531
  }
532
 
533
  do_action( 'vpf_after_assets_register' );
98
  foreach ( self::$stored_assets[ $type ] as $name => $data ) {
99
  if ( isset( $data['value'] ) && $data['value'] ) {
100
  if ( 'script' === $type ) {
101
+ wp_enqueue_script( $name, '', array(), '2.10.2', true );
102
  } elseif ( is_string( $data['value'] ) ) {
103
+ visual_portfolio()->include_template_style( $name, $data['value'], array(), '2.10.2' );
104
  } else {
105
+ wp_enqueue_style( $name, '', array(), '2.10.2' );
106
  }
107
 
108
  self::$stored_assets[ $type ]['value'] = false;
259
  $dynamic_styles = Visual_Portfolio_Controls_Dynamic_CSS::get( $options );
260
  $controls_css_handle = 'vp-dynamic-styles-' . $options['id'];
261
 
262
+ wp_register_style( $controls_css_handle, false, array(), '2.10.2' );
263
  wp_enqueue_style( $controls_css_handle );
264
  wp_add_inline_style( $controls_css_handle, $dynamic_styles ? $dynamic_styles : ' ' );
265
 
359
  // LazySizes.
360
  if ( apply_filters( 'vpf_enqueue_plugin_lazysizes', true ) ) {
361
  wp_register_script( 'lazysizes-object-fit-cover', visual_portfolio()->plugin_url . 'assets/js/lazysizes-object-fit-cover.min.js', array(), '4.1.0', true );
362
+ wp_register_script( 'lazysizes-config', visual_portfolio()->plugin_url . 'assets/js/lazysizes-config.min.js', array(), '2.10.2', true );
363
  wp_register_script( 'lazysizes', visual_portfolio()->plugin_url . 'assets/vendor/lazysizes/lazysizes.min.js', array(), '5.2.2', true );
364
  }
365
 
407
  );
408
 
409
  foreach ( $vp_styles as $name => $data ) {
410
+ wp_register_style( $name, visual_portfolio()->plugin_url . $data[0], $data[1], '2.10.2' );
411
  wp_style_add_data( $name, 'rtl', 'replace' );
412
  wp_style_add_data( $name, 'suffix', '.min' );
413
  }
527
  );
528
 
529
  foreach ( $vp_scripts as $name => $data ) {
530
+ wp_register_script( $name, visual_portfolio()->plugin_url . $data[0], $data[1], '2.10.2', true );
531
  }
532
 
533
  do_action( 'vpf_after_assets_register' );
classes/class-custom-post-type.php CHANGED
@@ -248,7 +248,7 @@ class Visual_Portfolio_Custom_Post_Type {
248
  if ( ! is_blog_installed() ) {
249
  return;
250
  }
251
- if ( get_option( 'visual_portfolio_updated_caps' ) === '2.10.1' ) {
252
  return;
253
  }
254
 
@@ -325,7 +325,7 @@ class Visual_Portfolio_Custom_Post_Type {
325
  $wp_roles->add_cap( 'administrator', $cap );
326
  }
327
 
328
- update_option( 'visual_portfolio_updated_caps', '2.10.1' );
329
  }
330
 
331
  /**
248
  if ( ! is_blog_installed() ) {
249
  return;
250
  }
251
+ if ( get_option( 'visual_portfolio_updated_caps' ) === '2.10.2' ) {
252
  return;
253
  }
254
 
325
  $wp_roles->add_cap( 'administrator', $cap );
326
  }
327
 
328
+ update_option( 'visual_portfolio_updated_caps', '2.10.2' );
329
  }
330
 
331
  /**
classes/class-gutenberg.php CHANGED
@@ -173,14 +173,14 @@ class Visual_Portfolio_Gutenberg_Block {
173
  'visual-portfolio-gutenberg',
174
  plugins_url( '../gutenberg/index.min.js', __FILE__ ),
175
  array( 'wp-editor', 'wp-i18n', 'wp-element', 'wp-components', 'jquery' ),
176
- '2.10.1',
177
  true
178
  );
179
  wp_enqueue_style(
180
  'visual-portfolio-gutenberg',
181
  plugins_url( '../gutenberg/style.min.css', __FILE__ ),
182
  array(),
183
- '2.10.1'
184
  );
185
  wp_style_add_data( 'visual-portfolio-gutenberg', 'rtl', 'replace' );
186
  wp_style_add_data( 'visual-portfolio-gutenberg', 'suffix', '.min' );
@@ -200,7 +200,7 @@ class Visual_Portfolio_Gutenberg_Block {
200
  'visual-portfolio-gutenberg-custom-post-meta',
201
  plugins_url( '../gutenberg/custom-post-meta.min.js', __FILE__ ),
202
  array( 'wp-editor', 'wp-i18n', 'wp-element', 'wp-components', 'wp-plugins', 'jquery' ),
203
- '2.10.1',
204
  true
205
  );
206
 
173
  'visual-portfolio-gutenberg',
174
  plugins_url( '../gutenberg/index.min.js', __FILE__ ),
175
  array( 'wp-editor', 'wp-i18n', 'wp-element', 'wp-components', 'jquery' ),
176
+ '2.10.2',
177
  true
178
  );
179
  wp_enqueue_style(
180
  'visual-portfolio-gutenberg',
181
  plugins_url( '../gutenberg/style.min.css', __FILE__ ),
182
  array(),
183
+ '2.10.2'
184
  );
185
  wp_style_add_data( 'visual-portfolio-gutenberg', 'rtl', 'replace' );
186
  wp_style_add_data( 'visual-portfolio-gutenberg', 'suffix', '.min' );
200
  'visual-portfolio-gutenberg-custom-post-meta',
201
  plugins_url( '../gutenberg/custom-post-meta.min.js', __FILE__ ),
202
  array( 'wp-editor', 'wp-i18n', 'wp-element', 'wp-components', 'wp-plugins', 'jquery' ),
203
+ '2.10.2',
204
  true
205
  );
206
 
classes/class-migration.php CHANGED
@@ -18,7 +18,7 @@ class Visual_Portfolio_Migrations {
18
  *
19
  * @var string
20
  */
21
- protected $version = '2.10.1';
22
 
23
  /**
24
  * Initial version.
18
  *
19
  * @var string
20
  */
21
+ protected $version = '2.10.2';
22
 
23
  /**
24
  * Initial version.
classes/class-preview.php CHANGED
@@ -232,7 +232,7 @@ class Visual_Portfolio_Preview {
232
 
233
  // Enqueue assets.
234
  wp_enqueue_script( 'iframe-resizer-content', visual_portfolio()->plugin_url . 'assets/vendor/iframe-resizer/js/iframeResizer.contentWindow.min.js', array(), '4.2.11', true );
235
- wp_enqueue_script( 'visual-portfolio-preview', visual_portfolio()->plugin_url . 'assets/js/preview.min.js', array( 'jquery', 'iframe-resizer-content' ), '2.10.1', true );
236
 
237
  // Post data for script.
238
  wp_localize_script(
@@ -275,7 +275,7 @@ class Visual_Portfolio_Preview {
275
  Visual_Portfolio_Assets::enqueue( $options );
276
 
277
  // Custom styles.
278
- visual_portfolio()->include_template_style( 'visual-portfolio-preview', 'preview/style', array(), '2.10.1' );
279
 
280
  // Output template.
281
  visual_portfolio()->include_template(
232
 
233
  // Enqueue assets.
234
  wp_enqueue_script( 'iframe-resizer-content', visual_portfolio()->plugin_url . 'assets/vendor/iframe-resizer/js/iframeResizer.contentWindow.min.js', array(), '4.2.11', true );
235
+ wp_enqueue_script( 'visual-portfolio-preview', visual_portfolio()->plugin_url . 'assets/js/preview.min.js', array( 'jquery', 'iframe-resizer-content' ), '2.10.2', true );
236
 
237
  // Post data for script.
238
  wp_localize_script(
275
  Visual_Portfolio_Assets::enqueue( $options );
276
 
277
  // Custom styles.
278
+ visual_portfolio()->include_template_style( 'visual-portfolio-preview', 'preview/style', array(), '2.10.2' );
279
 
280
  // Output template.
281
  visual_portfolio()->include_template(
classes/class-settings.php CHANGED
@@ -486,7 +486,7 @@ class Visual_Portfolio_Settings {
486
  <h3>' . esc_html__( 'PRO Feature', 'visual-portfolio' ) . '</h3>
487
  <div>
488
  <p>' . esc_html__( 'Social feeds such as Instagram, Youtube, Flickr, Twitter, etc...', 'visual-portfolio' ) . '</p>
489
- <a class="vpf-settings-info-pro-button" target="_blank" rel="noopener noreferrer" href="https://visualportfolio.co/pro/?utm_source=freeplugin&utm_medium=link&utm_campaign=plugin_settings&utm_content=2.10.1">' . esc_html__( 'Read More', 'visual-portfolio' ) . '</a>
490
  </div>
491
  </div>
492
  ',
486
  <h3>' . esc_html__( 'PRO Feature', 'visual-portfolio' ) . '</h3>
487
  <div>
488
  <p>' . esc_html__( 'Social feeds such as Instagram, Youtube, Flickr, Twitter, etc...', 'visual-portfolio' ) . '</p>
489
+ <a class="vpf-settings-info-pro-button" target="_blank" rel="noopener noreferrer" href="https://visualportfolio.co/pro/?utm_source=freeplugin&utm_medium=link&utm_campaign=plugin_settings&utm_content=2.10.2">' . esc_html__( 'Read More', 'visual-portfolio' ) . '</a>
490
  </div>
491
  </div>
492
  ',
classes/class-supported-themes.php CHANGED
@@ -74,7 +74,7 @@ class Visual_Portfolio_Supported_Themes {
74
  public function wp_enqueue_scripts() {
75
  $theme_compat = $this->get_theme_compatibility_style();
76
  if ( $theme_compat ) {
77
- wp_enqueue_style( $theme_compat['name'], $theme_compat['url'], array(), '2.10.1' );
78
  wp_style_add_data( $theme_compat['name'], 'rtl', 'replace' );
79
  wp_style_add_data( $theme_compat['name'], 'suffix', '.min' );
80
  }
74
  public function wp_enqueue_scripts() {
75
  $theme_compat = $this->get_theme_compatibility_style();
76
  if ( $theme_compat ) {
77
+ wp_enqueue_style( $theme_compat['name'], $theme_compat['url'], array(), '2.10.2' );
78
  wp_style_add_data( $theme_compat['name'], 'rtl', 'replace' );
79
  wp_style_add_data( $theme_compat['name'], 'suffix', '.min' );
80
  }
gutenberg/components/controls-render/index.js CHANGED
@@ -463,7 +463,7 @@ ControlsRender.Control = function( props ) {
463
  { renderControlHelp ? (
464
  <p>{ renderControlHelp }</p>
465
  ) : '' }
466
- <ProNote.Button target="_blank" rel="noopener noreferrer" href="https://visualportfolio.co/pro/?utm_source=freeplugin&amp;utm_medium=link&amp;utm_campaign=block_settings&amp;utm_content=2.10.1">
467
  { __( 'Read More', 'visual-portfolio' ) }
468
  </ProNote.Button>
469
  </ProNote>
463
  { renderControlHelp ? (
464
  <p>{ renderControlHelp }</p>
465
  ) : '' }
466
+ <ProNote.Button target="_blank" rel="noopener noreferrer" href="https://visualportfolio.co/pro/?utm_source=freeplugin&amp;utm_medium=link&amp;utm_campaign=block_settings&amp;utm_content=2.10.2">
467
  { __( 'Read More', 'visual-portfolio' ) }
468
  </ProNote.Button>
469
  </ProNote>
languages/visual-portfolio.pot CHANGED
@@ -872,7 +872,7 @@ msgctxt "Post Type Singular Name"
872
  msgid "Portfolio Item"
873
  msgstr ""
874
 
875
- #: dist/visual-portfolio/classes/class-custom-post-type.php:72, dist/visual-portfolio/classes/class-custom-post-type.php:166, dist/visual-portfolio/classes/class-custom-post-type.php:511, dist/visual-portfolio/classes/class-elementor-widget.php:68, dist/visual-portfolio/classes/class-vc.php:65
876
  msgid "Visual Portfolio"
877
  msgstr ""
878
 
@@ -1010,14 +1010,6 @@ msgstr ""
1010
  msgid "Documentation"
1011
  msgstr ""
1012
 
1013
- #: dist/visual-portfolio/classes/class-elementor-widget.php:148, dist/visual-portfolio/classes/class-settings.php:131
1014
- msgid "General"
1015
- msgstr ""
1016
-
1017
- #: dist/visual-portfolio/classes/class-elementor-widget.php:156, dist/visual-portfolio/classes/class-vc.php:72
1018
- msgid "Select Layout"
1019
- msgstr ""
1020
-
1021
  #: dist/visual-portfolio/classes/class-get-portfolio.php:1788
1022
  msgid "Default sorting"
1023
  msgstr ""
@@ -1075,6 +1067,10 @@ msgstr ""
1075
  msgid "Settings"
1076
  msgstr ""
1077
 
 
 
 
 
1078
  #: dist/visual-portfolio/classes/class-settings.php:139, dist/visual-portfolio/classes/class-settings.php:317
1079
  msgid "Popup Gallery"
1080
  msgstr ""
@@ -1297,22 +1293,26 @@ msgstr ""
1297
  msgid "Visual Portfolio Settings"
1298
  msgstr ""
1299
 
1300
- #: dist/visual-portfolio/classes/class-vc.php:80
 
 
 
 
 
 
 
 
1301
  msgid "Custom Classes"
1302
  msgstr ""
1303
 
1304
- #: dist/visual-portfolio/classes/class-vc.php:87
1305
  msgid "CSS"
1306
  msgstr ""
1307
 
1308
- #: dist/visual-portfolio/classes/class-vc.php:89
1309
  msgid "Design Options"
1310
  msgstr ""
1311
 
1312
- #: dist/visual-portfolio/vendors/class-settings-api.php:139
1313
- msgid "This feature available in PRO plugin only"
1314
- msgstr ""
1315
-
1316
  #: dist/visual-portfolio/templates/items-list/wrapper-start.php:34
1317
  msgid "Visual Portfolio, Posts & Image Gallery for WordPress"
1318
  msgstr ""
872
  msgid "Portfolio Item"
873
  msgstr ""
874
 
875
+ #: dist/visual-portfolio/classes/class-custom-post-type.php:72, dist/visual-portfolio/classes/class-custom-post-type.php:166, dist/visual-portfolio/classes/class-custom-post-type.php:511, dist/visual-portfolio/classes/3rd/class-elementor-widget.php:68, dist/visual-portfolio/classes/3rd/class-vc.php:65
876
  msgid "Visual Portfolio"
877
  msgstr ""
878
 
1010
  msgid "Documentation"
1011
  msgstr ""
1012
 
 
 
 
 
 
 
 
 
1013
  #: dist/visual-portfolio/classes/class-get-portfolio.php:1788
1014
  msgid "Default sorting"
1015
  msgstr ""
1067
  msgid "Settings"
1068
  msgstr ""
1069
 
1070
+ #: dist/visual-portfolio/classes/class-settings.php:131, dist/visual-portfolio/classes/3rd/class-elementor-widget.php:148
1071
+ msgid "General"
1072
+ msgstr ""
1073
+
1074
  #: dist/visual-portfolio/classes/class-settings.php:139, dist/visual-portfolio/classes/class-settings.php:317
1075
  msgid "Popup Gallery"
1076
  msgstr ""
1293
  msgid "Visual Portfolio Settings"
1294
  msgstr ""
1295
 
1296
+ #: dist/visual-portfolio/vendors/class-settings-api.php:139
1297
+ msgid "This feature available in PRO plugin only"
1298
+ msgstr ""
1299
+
1300
+ #: dist/visual-portfolio/classes/3rd/class-elementor-widget.php:156, dist/visual-portfolio/classes/3rd/class-vc.php:72
1301
+ msgid "Select Layout"
1302
+ msgstr ""
1303
+
1304
+ #: dist/visual-portfolio/classes/3rd/class-vc.php:80
1305
  msgid "Custom Classes"
1306
  msgstr ""
1307
 
1308
+ #: dist/visual-portfolio/classes/3rd/class-vc.php:87
1309
  msgid "CSS"
1310
  msgstr ""
1311
 
1312
+ #: dist/visual-portfolio/classes/3rd/class-vc.php:89
1313
  msgid "Design Options"
1314
  msgstr ""
1315
 
 
 
 
 
1316
  #: dist/visual-portfolio/templates/items-list/wrapper-start.php:34
1317
  msgid "Visual Portfolio, Posts & Image Gallery for WordPress"
1318
  msgstr ""
readme.md CHANGED
@@ -5,7 +5,7 @@
5
  * Requires at least: 5.4
6
  * Tested up to: 5.6
7
  * Requires PHP: 5.5.9
8
- * Stable tag: 2.10.1
9
  * License: GPLv2 or later
10
  * License URI: <http://www.gnu.org/licenses/gpl-2.0.html>
11
 
@@ -22,7 +22,7 @@ Modern gallery and portfolio plugin with advanced layouts editor. Clean and powe
22
 
23
  Create beautiful, clean, and powerful photo galleries and portfolio layouts using the Visual Portfolio gallery plugin. It is easy for simple photo galleries, but powerful enough for professionals. Whether you're a photographer, agency, or anything in between, **Visual Portfolio will boost your online presence**.
24
 
25
- ### 💯 Visual Gallery Builder ###
26
 
27
  Build your portfolio and gallery blocks with no coding knowledge. Thanks to Gutenberg page builder you are able to create and customize galleries visually.
28
 
@@ -72,7 +72,7 @@ Fine-tune the source of your galleries. Display posts, portfolios, and any other
72
 
73
  ### 🖼️ Photo Galleries ###
74
 
75
- You can also create galleries using image sets right inside block editor. Just drop your images and gallery is ready.
76
 
77
  ### ⚡ Powerful Lightbox ###
78
 
@@ -127,7 +127,7 @@ Visual Portfolio adds a new layer of compatibility for [WPML](https://wpml.org/)
127
 
128
  Visual Portfolio gives you a wide range of filters and actions to customize every part of your gallery. Also, it allows you to overwrite templates and change it in the theme directory. Moreover, you can customize separate portfolio lists using custom CSS and CSS Variables.
129
 
130
- ### 🌟 Visual Portfolio Pro ###
131
 
132
  > The Visual Portfolio plugin is also available in a professional version which includes more features and enhanced performance! [**Learn more about Visual Portfolio Pro**](https://visualportfolio.co/pro/?utm_source=wporg&utm_medium=link&utm_campaign=pro)
133
  >
@@ -170,13 +170,14 @@ Makes URL automatically change when you open popup and you can easily link to a
170
 
171
  [**Find much more portfolio and gallery features of Visual Portfolio Pro today!**](https://visualportfolio.co/pro/?utm_source=wporg&utm_medium=link&utm_campaign=pro)
172
 
173
- ### More Features ###
174
 
175
  * **Lightboxes for Standard WordPress Images**
176
  Image lightbox available for Visual Portfolio galleries as well as for standard WordPress images and galleries in your content.
177
 
178
  * **AJAX Loading and Pagination**
179
- Every dynamic part of the Visual Portfolio plugin is using AJAX to update the gallery content in live mode. To split long portfolio lists we prepared 3 types of pagination:
 
180
  * Infinite Scroll
181
  * Load More button
182
  * Paged pagination
@@ -289,6 +290,10 @@ For more information, feel free to visit [Visual Portfolio official website](htt
289
 
290
  ## Changelog ##
291
 
 
 
 
 
292
  = 2.10.1 =
293
 
294
  * added setting to enable lazy loading for all images on site (not only for Visual Portfolio)
5
  * Requires at least: 5.4
6
  * Tested up to: 5.6
7
  * Requires PHP: 5.5.9
8
+ * Stable tag: 2.10.2
9
  * License: GPLv2 or later
10
  * License URI: <http://www.gnu.org/licenses/gpl-2.0.html>
11
 
22
 
23
  Create beautiful, clean, and powerful photo galleries and portfolio layouts using the Visual Portfolio gallery plugin. It is easy for simple photo galleries, but powerful enough for professionals. Whether you're a photographer, agency, or anything in between, **Visual Portfolio will boost your online presence**.
24
 
25
+ ### 🏆 Visual Gallery Builder ###
26
 
27
  Build your portfolio and gallery blocks with no coding knowledge. Thanks to Gutenberg page builder you are able to create and customize galleries visually.
28
 
72
 
73
  ### 🖼️ Photo Galleries ###
74
 
75
+ Create galleries using image sets right inside block editor, just drop your images and the gallery is ready. You can create unlimited galleries with different styles, there is no limitation.
76
 
77
  ### ⚡ Powerful Lightbox ###
78
 
127
 
128
  Visual Portfolio gives you a wide range of filters and actions to customize every part of your gallery. Also, it allows you to overwrite templates and change it in the theme directory. Moreover, you can customize separate portfolio lists using custom CSS and CSS Variables.
129
 
130
+ ### 🔥 Visual Portfolio Pro ###
131
 
132
  > The Visual Portfolio plugin is also available in a professional version which includes more features and enhanced performance! [**Learn more about Visual Portfolio Pro**](https://visualportfolio.co/pro/?utm_source=wporg&utm_medium=link&utm_campaign=pro)
133
  >
170
 
171
  [**Find much more portfolio and gallery features of Visual Portfolio Pro today!**](https://visualportfolio.co/pro/?utm_source=wporg&utm_medium=link&utm_campaign=pro)
172
 
173
+ ### 🌟 More Features ###
174
 
175
  * **Lightboxes for Standard WordPress Images**
176
  Image lightbox available for Visual Portfolio galleries as well as for standard WordPress images and galleries in your content.
177
 
178
  * **AJAX Loading and Pagination**
179
+ Every dynamic part of the Visual Portfolio plugin is using AJAX to update the gallery content in live mode.
180
+ Organized galleries and portfolio lists will make your website look more professional, easy to navigate and result in a better user experience. We prepared 3 types of paginations for you:
181
  * Infinite Scroll
182
  * Load More button
183
  * Paged pagination
290
 
291
  ## Changelog ##
292
 
293
+ = 2.10.2 =
294
+
295
+ * fixed conflict of lazy loading and Imagify WebP feature (again)
296
+
297
  = 2.10.1 =
298
 
299
  * added setting to enable lazy loading for all images on site (not only for Visual Portfolio)