Ticket #8522: 8522.patch
File 8522.patch, 45.5 KB (added by , 4 years ago) |
---|
-
.jshintignore
diff --git .jshintignore .jshintignore index 06a8e1509..185586a70 100644
src/**/js/block-*/*.js 9 9 src/**/js/block-*/**/*.js 10 10 src/**/js/block-*.js 11 11 src/**/js/friends.js 12 src/**/js/dynamic-members.js 12 13 src/**/js/dynamic-widget-block.js -
Gruntfile.js
diff --git Gruntfile.js Gruntfile.js index 3417b09fd..5951547f2 100644
module.exports = function( grunt ) { 24 24 '!**/js/block-*/**/*.js', 25 25 '!**/js/block-*.js', 26 26 '!**/js/friends.js', 27 '!**/js/dynamic-members.js', 27 28 '!**/js/dynamic-widget-block.js' 28 29 ], 29 30 … … module.exports = function( grunt ) { 43 44 '!bp-groups/css/blocks/groups.css', 44 45 '!bp-core/css/blocks/login-form.css', 45 46 '!bp-activity/css/blocks/latest-activities.css', 46 '!bp-friends/css/blocks/friends.css' 47 '!bp-friends/css/blocks/friends.css', 48 '!bp-members/css/blocks/dynamic-members.css' 47 49 ], 48 50 49 51 autoprefixer = require('autoprefixer'); -
src/bp-members/bp-members-blocks.php
diff --git src/bp-members/bp-members-blocks.php src/bp-members/bp-members-blocks.php index 50b49bc55..06310ecf0 100644
function bp_members_render_members_block( $attributes = array() ) { 331 331 */ 332 332 return apply_filters( 'bp_members_render_members_block_output', $output, $block_args, $members ); 333 333 } 334 335 /** 336 * Adds specific script data for the BP Members blocks. 337 * 338 * Only used for the BP Dynamic Members block. 339 * 340 * @since 9.0.0 341 */ 342 function bp_members_blocks_add_script_data() { 343 $dynamic_members_blocks = array_filter( buddypress()->members->block_globals['bp/dynamic-members']->items ); 344 345 if ( ! $dynamic_members_blocks ) { 346 return; 347 } 348 349 // Include the common JS template. 350 echo bp_get_dynamic_template_part( 'assets/widgets/dynamic-members.php' ); 351 352 // List the block specific props. 353 wp_add_inline_script( 354 'bp-dynamic-members-script', 355 sprintf( 'var bpDynamicMembersBlocks = %s;', wp_json_encode( array_values( $dynamic_members_blocks ) ) ), 356 'before' 357 ); 358 } 359 360 /** 361 * Callback function to render the Dynamic Members Block. 362 * 363 * @since 9.0.0 364 * 365 * @param array $attributes The block attributes. 366 * @return string HTML output. 367 */ 368 function bp_members_render_dynamic_members_block( $attributes = array() ) { 369 $block_args = wp_parse_args( 370 $attributes, 371 array( 372 'title' => __( 'Members', 'buddypress' ), 373 'maxMembers' => 5, 374 'memberDefault' => 'active', 375 'linkTitle' => false, 376 ) 377 ); 378 379 $classnames = 'widget_bp_core_members_widget buddypress widget'; 380 $wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $classnames ) ); 381 382 $max_members = (int) $block_args['maxMembers']; 383 $no_members = __( 'No members found.', 'buddypress' ); 384 385 /** This filter is documented in buddypress/src/bp-members/classes/class-bp-core-members-widget.php */ 386 $separator = apply_filters( 'bp_members_widget_separator', '|' ); 387 388 // Make sure the widget ID is unique. 389 $widget_id = uniqid( 'members-list-' ); 390 $members_directory_link = bp_get_members_directory_permalink(); 391 392 // Set the Block's title. 393 if ( true === $block_args['linkTitle'] ) { 394 $widget_content = sprintf( 395 '<h2 class="widget-title"><a href="%1$s">%2$s</a></h2>', 396 esc_url( $members_directory_link ), 397 esc_html( $block_args['title'] ) 398 ); 399 } else { 400 $widget_content = sprintf( '<h2 class="widget-title">%s</h2>', esc_html( $block_args['title'] ) ); 401 } 402 403 $item_options = array( 404 'newest' => array( 405 'class' => '', 406 'label' => __( 'Newest', 'buddypress' ), 407 ), 408 'active' => array( 409 'class' => '', 410 'label' => __( 'Active', 'buddypress' ), 411 ), 412 ); 413 414 if ( bp_is_active( 'friends' ) ) { 415 $item_options['popular'] = array( 416 'class' => '', 417 'label' => __( 'Popular', 'buddypress' ), 418 ); 419 } 420 421 $item_options_output = array(); 422 $separator_output = sprintf( ' <span class="bp-separator" role="separator">%s</span> ', esc_html( $separator ) ); 423 424 foreach ( $item_options as $item_type => $item_attr ) { 425 if ( $block_args['memberDefault'] === $item_type ) { 426 $item_attr['class'] = ' class="selected"'; 427 } 428 429 $item_options_output[] = sprintf( 430 '<a href="%1$s" data-bp-sort="%2$s"%3$s>%4$s</a>', 431 esc_url( $members_directory_link ), 432 esc_attr( $item_type ), 433 $item_attr['class'], 434 esc_html( $item_attr['label'] ) 435 ); 436 } 437 438 $preview = ''; 439 $default_args = array( 440 'type' => $block_args['memberDefault'], 441 'per_page' => $max_members, 442 'populate_extras' => true, 443 ); 444 445 // Previewing the Block inside the editor. 446 if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) { 447 $bp_query = bp_core_get_users( $default_args ); 448 $preview = sprintf( '<div class="widget-error">%s</div>', $no_members ); 449 450 if ( is_array( $bp_query['users'] ) && 0 < count( $bp_query['users'] ) ) { 451 $preview = ''; 452 foreach ( $bp_query['users'] as $user ) { 453 if ( 'newest' === $block_args['memberDefault'] ) { 454 /* translators: %s is time elapsed since the registration date happened */ 455 $extra = sprintf( _x( 'Registered %s', 'The timestamp when the user registered', 'buddypress' ), bp_core_time_since( $user->user_registered ) ); 456 } elseif ( 'popular' === $block_args['memberDefault'] && isset( $item_options['popular'] ) && isset( $user->total_friend_count ) ) { 457 /* translators: %s: total friend count */ 458 $extra = sprintf( _n( '%s friend', '%s friends', $user->total_friend_count, 'buddypress' ), number_format_i18n( $user->total_friend_count ) ); 459 } else { 460 /* translators: %s: a human time diff. */ 461 $extra = sprintf( __( 'Active %s', 'buddypress' ), bp_core_time_since( $user->last_activity ) ); 462 } 463 464 $preview .= bp_get_dynamic_template_part( 465 'assets/widgets/dynamic-members.php', 466 'php', 467 array( 468 'data.link' => bp_core_get_user_domain( $user->ID, $user->user_nicename, $user->user_login ), 469 'data.name' => $user->display_name, 470 'data.avatar_urls.thumb' => bp_core_fetch_avatar( 471 array( 472 'item_id' => $user->ID, 473 'html' => false, 474 ) 475 ), 476 'data.avatar_alt' => esc_html( 477 sprintf( 478 /* translators: %s: member name */ 479 __( 'Profile picture of %s', 'buddypress' ), 480 $user->display_name 481 ) 482 ), 483 'data.id' => $user->ID, 484 'data.extra' => $extra, 485 ) 486 ); 487 } 488 } 489 } else { 490 // Get corresponding members. 491 $path = sprintf( 492 '/%1$s/%2$s/%3$s', 493 bp_rest_namespace(), 494 bp_rest_version(), 495 buddypress()->members->id 496 ); 497 498 $default_path = add_query_arg( 499 $default_args, 500 $path 501 ); 502 503 $preloaded_members = array(); 504 if ( bp_is_running_wp( '5.0.0' ) ) { 505 $preloaded_members = rest_preload_api_request( '', $default_path ); 506 } 507 508 buddypress()->members->block_globals['bp/dynamic-members']->items[ $widget_id ] = (object) array( 509 'selector' => $widget_id, 510 'query_args' => $default_args, 511 'preloaded' => reset( $preloaded_members ), 512 ); 513 514 // Only enqueue common/specific scripts and data once per page load. 515 if ( ! has_action( 'wp_footer', 'bp_members_blocks_add_script_data', 1 ) ) { 516 wp_set_script_translations( 'bp-dynamic-members-script', 'buddypress' ); 517 wp_enqueue_script( 'bp-dynamic-members-script' ); 518 wp_localize_script( 519 'bp-dynamic-members-script', 520 'bpDynamicMembersSettings', 521 array( 522 'path' => ltrim( $path, '/' ), 523 'root' => esc_url_raw( get_rest_url() ), 524 'nonce' => wp_create_nonce( 'wp_rest' ), 525 ) 526 ); 527 528 add_action( 'wp_footer', 'bp_members_blocks_add_script_data', 1 ); 529 } 530 } 531 532 $widget_content .= sprintf( 533 '<div class="item-options"> 534 %1$s 535 </div> 536 <ul id="%2$s" class="item-list" aria-live="polite" aria-relevant="all" aria-atomic="true"> 537 %3$s 538 </ul>', 539 implode( $separator_output, $item_options_output ), 540 esc_attr( $widget_id ), 541 $preview 542 ); 543 544 // Adds a container to make sure the block is styled even when used into the Columns parent block. 545 $widget_content = sprintf( '<div class="bp-dynamic-block-container">%s</div>', "\n" . $widget_content . "\n" ); 546 547 // Only add a block wrapper if not loaded into a Widgets sidebar. 548 if ( ! did_action( 'dynamic_sidebar_before' ) ) { 549 return sprintf( 550 '<div %1$s>%2$s</div>', 551 $wrapper_attributes, 552 $widget_content 553 ); 554 } 555 556 return $widget_content; 557 } -
new file src/bp-members/bp-members-cssjs.php
diff --git src/bp-members/bp-members-cssjs.php src/bp-members/bp-members-cssjs.php new file mode 100644 index 000000000..61bb70b81
- + 1 <?php 2 /** 3 * BP Members component CSS/JS. 4 * 5 * @package BuddyPress 6 * @subpackage MembersScripts 7 * @since 9.0.0 8 */ 9 10 // Exit if accessed directly. 11 if ( ! defined( 'ABSPATH' ) ) { 12 exit; 13 } 14 15 /** 16 * Registers the script to manage the dynamic part of the Dynamic Members widget/block. 17 * 18 * @since 9.0.0 19 * 20 * @param array $scripts Data about the scripts to register. 21 * @return array Data about the scripts to register. 22 */ 23 function bp_members_register_scripts( $scripts = array() ) { 24 $scripts['bp-dynamic-members-script'] = array( 25 'file' => plugins_url( 'js/dynamic-members.js', __FILE__ ), 26 'dependencies' => array( 27 'bp-dynamic-widget-block-script', 28 'wp-i18n', 29 ), 30 'footer' => true, 31 ); 32 33 return $scripts; 34 } 35 add_filter( 'bp_core_register_common_scripts', 'bp_members_register_scripts', 9, 1 ); -
src/bp-members/classes/class-bp-members-component.php
diff --git src/bp-members/classes/class-bp-members-component.php src/bp-members/classes/class-bp-members-component.php index 280485e33..efa93300f 100644
class BP_Members_Component extends BP_Component { 58 58 59 59 // Always include these files. 60 60 $includes = array( 61 'cssjs', 61 62 'filters', 62 63 'template', 63 64 'adminbar', … … class BP_Members_Component extends BP_Component { 196 197 'table_name_signups' => $wpdb->base_prefix . 'signups', // Signups is a global WordPress table. 197 198 ), 198 199 'notification_callback' => 'members_format_notifications', 200 'block_globals' => array( 201 'bp/dynamic-members' => array( 202 'widget_classnames' => array( 'widget_bp_core_members_widget', 'buddypress' ), 203 ) 204 ), 199 205 ); 200 206 201 207 parent::setup_globals( $args ); … … class BP_Members_Component extends BP_Component { 821 827 ), 822 828 'render_callback' => 'bp_members_render_members_block', 823 829 ), 830 'bp/dynamic-members' => array( 831 'name' => 'bp/dynamic-members', 832 'editor_script' => 'bp-dynamic-members-block', 833 'editor_script_url' => plugins_url( 'js/blocks/dynamic-members.js', dirname( __FILE__ ) ), 834 'editor_script_deps' => array( 835 'wp-blocks', 836 'wp-element', 837 'wp-components', 838 'wp-i18n', 839 'wp-block-editor', 840 'bp-block-data', 841 'bp-block-components', 842 ), 843 'style' => 'bp-dynamic-members-block', 844 'style_url' => plugins_url( 'css/blocks/dynamic-members.css', dirname( __FILE__ ) ), 845 'attributes' => array( 846 'title' => array( 847 'type' => 'string', 848 'default' => __( 'Members', 'buddypress' ), 849 ), 850 'maxMembers' => array( 851 'type' => 'number', 852 'default' => 5, 853 ), 854 'memberDefault' => array( 855 'type' => 'string', 856 'default' => 'active', 857 ), 858 'linkTitle' => array( 859 'type' => 'boolean', 860 'default' => false, 861 ), 862 ), 863 'render_callback' => 'bp_members_render_dynamic_members_block', 864 ), 824 865 ) 825 866 ); 826 867 } -
new file src/bp-members/css/blocks/dynamic-members-rtl.css
diff --git src/bp-members/css/blocks/dynamic-members-rtl.css src/bp-members/css/blocks/dynamic-members-rtl.css new file mode 100644 index 000000000..8aff30506
- + 1 .bp-dynamic-block-container .item-options { 2 font-size: 0.5em; 3 margin: 0 0 1em; 4 padding: 1em 0; 5 } 6 7 .bp-dynamic-block-container .item-options a.selected { 8 font-weight: 600; 9 } 10 11 .bp-dynamic-block-container ul.item-list { 12 list-style: none; 13 margin: 1em 0; 14 } 15 16 .bp-dynamic-block-container ul.item-list li { 17 margin-bottom: 1em; 18 } 19 20 .bp-dynamic-block-container ul.item-list li:before, .bp-dynamic-block-container ul.item-list li:after { 21 content: " "; 22 display: table; 23 } 24 25 .bp-dynamic-block-container ul.item-list li:after { 26 clear: both; 27 } 28 29 .bp-dynamic-block-container ul.item-list li .item-avatar { 30 float: right; 31 width: 60px; 32 } 33 34 .bp-dynamic-block-container ul.item-list li .item { 35 margin-right: 70px; 36 } -
new file src/bp-members/css/blocks/dynamic-members.css
diff --git src/bp-members/css/blocks/dynamic-members.css src/bp-members/css/blocks/dynamic-members.css new file mode 100644 index 000000000..110c8aaa5
- + 1 .bp-dynamic-block-container .item-options { 2 font-size: 0.5em; 3 margin: 0 0 1em; 4 padding: 1em 0; 5 } 6 7 .bp-dynamic-block-container .item-options a.selected { 8 font-weight: 600; 9 } 10 11 .bp-dynamic-block-container ul.item-list { 12 list-style: none; 13 margin: 1em 0; 14 } 15 16 .bp-dynamic-block-container ul.item-list li { 17 margin-bottom: 1em; 18 } 19 20 .bp-dynamic-block-container ul.item-list li:before, .bp-dynamic-block-container ul.item-list li:after { 21 content: " "; 22 display: table; 23 } 24 25 .bp-dynamic-block-container ul.item-list li:after { 26 clear: both; 27 } 28 29 .bp-dynamic-block-container ul.item-list li .item-avatar { 30 float: left; 31 width: 60px; 32 } 33 34 .bp-dynamic-block-container ul.item-list li .item { 35 margin-left: 70px; 36 } -
new file src/bp-members/js/blocks/dynamic-members.js
diff --git src/bp-members/js/blocks/dynamic-members.js src/bp-members/js/blocks/dynamic-members.js new file mode 100644 index 000000000..6f55a264e
- + 1 // modules are defined as an array 2 // [ module function, map of requires ] 3 // 4 // map of requires is short require name -> numeric require 5 // 6 // anything defined in a previous bundle is accessed via the 7 // orig method which is the require for previous bundles 8 parcelRequire = (function (modules, cache, entry, globalName) { 9 // Save the require from previous bundle to this closure if any 10 var previousRequire = typeof parcelRequire === 'function' && parcelRequire; 11 var nodeRequire = typeof require === 'function' && require; 12 13 function newRequire(name, jumped) { 14 if (!cache[name]) { 15 if (!modules[name]) { 16 // if we cannot find the module within our internal map or 17 // cache jump to the current global require ie. the last bundle 18 // that was added to the page. 19 var currentRequire = typeof parcelRequire === 'function' && parcelRequire; 20 if (!jumped && currentRequire) { 21 return currentRequire(name, true); 22 } 23 24 // If there are other bundles on this page the require from the 25 // previous one is saved to 'previousRequire'. Repeat this as 26 // many times as there are bundles until the module is found or 27 // we exhaust the require chain. 28 if (previousRequire) { 29 return previousRequire(name, true); 30 } 31 32 // Try the node require function if it exists. 33 if (nodeRequire && typeof name === 'string') { 34 return nodeRequire(name); 35 } 36 37 var err = new Error('Cannot find module \'' + name + '\''); 38 err.code = 'MODULE_NOT_FOUND'; 39 throw err; 40 } 41 42 localRequire.resolve = resolve; 43 localRequire.cache = {}; 44 45 var module = cache[name] = new newRequire.Module(name); 46 47 modules[name][0].call(module.exports, localRequire, module, module.exports, this); 48 } 49 50 return cache[name].exports; 51 52 function localRequire(x){ 53 return newRequire(localRequire.resolve(x)); 54 } 55 56 function resolve(x){ 57 return modules[name][1][x] || x; 58 } 59 } 60 61 function Module(moduleName) { 62 this.id = moduleName; 63 this.bundle = newRequire; 64 this.exports = {}; 65 } 66 67 newRequire.isParcelRequire = true; 68 newRequire.Module = Module; 69 newRequire.modules = modules; 70 newRequire.cache = cache; 71 newRequire.parent = previousRequire; 72 newRequire.register = function (id, exports) { 73 modules[id] = [function (require, module) { 74 module.exports = exports; 75 }, {}]; 76 }; 77 78 var error; 79 for (var i = 0; i < entry.length; i++) { 80 try { 81 newRequire(entry[i]); 82 } catch (e) { 83 // Save first error but execute all entries 84 if (!error) { 85 error = e; 86 } 87 } 88 } 89 90 if (entry.length) { 91 // Expose entry point to Node, AMD or browser globals 92 // Based on https://github.com/ForbesLindesay/umd/blob/master/template.js 93 var mainExports = newRequire(entry[entry.length - 1]); 94 95 // CommonJS 96 if (typeof exports === "object" && typeof module !== "undefined") { 97 module.exports = mainExports; 98 99 // RequireJS 100 } else if (typeof define === "function" && define.amd) { 101 define(function () { 102 return mainExports; 103 }); 104 105 // <script> 106 } else if (globalName) { 107 this[globalName] = mainExports; 108 } 109 } 110 111 // Override the current require with this new one 112 parcelRequire = newRequire; 113 114 if (error) { 115 // throw error from earlier, _after updating parcelRequire_ 116 throw error; 117 } 118 119 return newRequire; 120 })({"gOka":[function(require,module,exports) { 121 "use strict"; 122 123 Object.defineProperty(exports, "__esModule", { 124 value: true 125 }); 126 exports.TYPES = void 0; 127 128 /** 129 * WordPress dependencies. 130 */ 131 var _wp = wp, 132 __ = _wp.i18n.__; 133 /** 134 * Members ordering types. 135 * 136 * @type {Array} 137 */ 138 139 var TYPES = [{ 140 label: __('Newest', 'buddypress'), 141 value: 'newest' 142 }, { 143 label: __('Active', 'buddypress'), 144 value: 'active' 145 }, { 146 label: __('Popular', 'buddypress'), 147 value: 'popular' 148 }]; 149 exports.TYPES = TYPES; 150 },{}],"z0p7":[function(require,module,exports) { 151 "use strict"; 152 153 Object.defineProperty(exports, "__esModule", { 154 value: true 155 }); 156 exports.default = void 0; 157 158 var _constants = require("./constants"); 159 160 /** 161 * WordPress dependencies. 162 */ 163 var _wp = wp, 164 InspectorControls = _wp.blockEditor.InspectorControls, 165 _wp$components = _wp.components, 166 Disabled = _wp$components.Disabled, 167 PanelBody = _wp$components.PanelBody, 168 RangeControl = _wp$components.RangeControl, 169 SelectControl = _wp$components.SelectControl, 170 TextControl = _wp$components.TextControl, 171 ToggleControl = _wp$components.ToggleControl, 172 _wp$element = _wp.element, 173 Fragment = _wp$element.Fragment, 174 createElement = _wp$element.createElement, 175 __ = _wp.i18n.__; 176 /** 177 * BuddyPress dependencies. 178 */ 179 180 var _bp = bp, 181 ServerSideRender = _bp.blockComponents.ServerSideRender, 182 isActive = _bp.blockData.isActive; 183 /** 184 * Internal dependencies. 185 */ 186 187 var editDynamicMembersBlock = function editDynamicMembersBlock(_ref) { 188 var attributes = _ref.attributes, 189 setAttributes = _ref.setAttributes; 190 var title = attributes.title, 191 maxMembers = attributes.maxMembers, 192 memberDefault = attributes.memberDefault, 193 linkTitle = attributes.linkTitle; 194 var sortTypes = !!isActive('friends') ? _constants.TYPES : _constants.TYPES.filter(function (type) { 195 return 'popular' !== type.value; 196 }); 197 return createElement(Fragment, null, createElement(InspectorControls, null, createElement(PanelBody, { 198 title: __('Settings', 'buddypress'), 199 initialOpen: true 200 }, createElement(TextControl, { 201 label: __('Title', 'buddypress'), 202 value: title, 203 onChange: function onChange(text) { 204 setAttributes({ 205 title: text 206 }); 207 } 208 }), createElement(RangeControl, { 209 label: __('Max members to show', 'buddypress'), 210 value: maxMembers, 211 onChange: function onChange(value) { 212 return setAttributes({ 213 maxMembers: value 214 }); 215 }, 216 min: 1, 217 max: 10, 218 required: true 219 }), createElement(SelectControl, { 220 label: __('Default members to show', 'buddypress'), 221 value: memberDefault, 222 options: sortTypes, 223 onChange: function onChange(option) { 224 setAttributes({ 225 memberDefault: option 226 }); 227 } 228 }), createElement(ToggleControl, { 229 label: __('Link block title to Members directory', 'buddypress'), 230 checked: !!linkTitle, 231 onChange: function onChange() { 232 setAttributes({ 233 linkTitle: !linkTitle 234 }); 235 } 236 }))), createElement(Disabled, null, createElement(ServerSideRender, { 237 block: "bp/dynamic-members", 238 attributes: attributes 239 }))); 240 }; 241 242 var _default = editDynamicMembersBlock; 243 exports.default = _default; 244 },{"./constants":"gOka"}],"qfGr":[function(require,module,exports) { 245 "use strict"; 246 247 Object.defineProperty(exports, "__esModule", { 248 value: true 249 }); 250 exports.default = void 0; 251 252 /** 253 * WordPress dependencies. 254 */ 255 var _wp = wp, 256 createBlock = _wp.blocks.createBlock; 257 /** 258 * Transforms Legacy Widget to Dynamic Members Block. 259 * 260 * @type {Object} 261 */ 262 263 var transforms = { 264 from: [{ 265 type: 'block', 266 blocks: ['core/legacy-widget'], 267 isMatch: function isMatch(_ref) { 268 var idBase = _ref.idBase, 269 instance = _ref.instance; 270 271 if (!(instance !== null && instance !== void 0 && instance.raw)) { 272 return false; 273 } 274 275 return idBase === 'bp_core_members_widget'; 276 }, 277 transform: function transform(_ref2) { 278 var instance = _ref2.instance; 279 return createBlock('bp/dynamic-members', { 280 title: instance.raw.title, 281 maxMembers: instance.raw.max_members, 282 memberDefault: instance.raw.member_default, 283 linkTitle: instance.raw.link_title 284 }); 285 } 286 }] 287 }; 288 var _default = transforms; 289 exports.default = _default; 290 },{}],"Znbi":[function(require,module,exports) { 291 "use strict"; 292 293 var _edit = _interopRequireDefault(require("./dynamic-members/edit")); 294 295 var _transforms = _interopRequireDefault(require("./dynamic-members/transforms")); 296 297 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 298 299 /** 300 * WordPress dependencies. 301 */ 302 var _wp = wp, 303 registerBlockType = _wp.blocks.registerBlockType, 304 __ = _wp.i18n.__; 305 /** 306 * Internal dependencies. 307 */ 308 309 registerBlockType('bp/dynamic-members', { 310 title: __('Dynamic Members List', 'buddypress'), 311 description: __('A dynamic list of recently active, popular, and newest members.', 'buddypress'), 312 icon: { 313 background: '#fff', 314 foreground: '#d84800', 315 src: 'groups' 316 }, 317 category: 'buddypress', 318 attributes: { 319 title: { 320 type: 'string', 321 default: __('Members', 'buddypress') 322 }, 323 maxMembers: { 324 type: 'number', 325 default: 5 326 }, 327 memberDefault: { 328 type: 'string', 329 default: 'active' 330 }, 331 linkTitle: { 332 type: 'boolean', 333 default: false 334 } 335 }, 336 edit: _edit.default, 337 transforms: _transforms.default 338 }); 339 },{"./dynamic-members/edit":"z0p7","./dynamic-members/transforms":"qfGr"}]},{},["Znbi"], null) 340 No newline at end of file -
new file src/bp-members/js/dynamic-members.js
diff --git src/bp-members/js/dynamic-members.js src/bp-members/js/dynamic-members.js new file mode 100644 index 000000000..827f914c5
- + 1 // modules are defined as an array 2 // [ module function, map of requires ] 3 // 4 // map of requires is short require name -> numeric require 5 // 6 // anything defined in a previous bundle is accessed via the 7 // orig method which is the require for previous bundles 8 parcelRequire = (function (modules, cache, entry, globalName) { 9 // Save the require from previous bundle to this closure if any 10 var previousRequire = typeof parcelRequire === 'function' && parcelRequire; 11 var nodeRequire = typeof require === 'function' && require; 12 13 function newRequire(name, jumped) { 14 if (!cache[name]) { 15 if (!modules[name]) { 16 // if we cannot find the module within our internal map or 17 // cache jump to the current global require ie. the last bundle 18 // that was added to the page. 19 var currentRequire = typeof parcelRequire === 'function' && parcelRequire; 20 if (!jumped && currentRequire) { 21 return currentRequire(name, true); 22 } 23 24 // If there are other bundles on this page the require from the 25 // previous one is saved to 'previousRequire'. Repeat this as 26 // many times as there are bundles until the module is found or 27 // we exhaust the require chain. 28 if (previousRequire) { 29 return previousRequire(name, true); 30 } 31 32 // Try the node require function if it exists. 33 if (nodeRequire && typeof name === 'string') { 34 return nodeRequire(name); 35 } 36 37 var err = new Error('Cannot find module \'' + name + '\''); 38 err.code = 'MODULE_NOT_FOUND'; 39 throw err; 40 } 41 42 localRequire.resolve = resolve; 43 localRequire.cache = {}; 44 45 var module = cache[name] = new newRequire.Module(name); 46 47 modules[name][0].call(module.exports, localRequire, module, module.exports, this); 48 } 49 50 return cache[name].exports; 51 52 function localRequire(x){ 53 return newRequire(localRequire.resolve(x)); 54 } 55 56 function resolve(x){ 57 return modules[name][1][x] || x; 58 } 59 } 60 61 function Module(moduleName) { 62 this.id = moduleName; 63 this.bundle = newRequire; 64 this.exports = {}; 65 } 66 67 newRequire.isParcelRequire = true; 68 newRequire.Module = Module; 69 newRequire.modules = modules; 70 newRequire.cache = cache; 71 newRequire.parent = previousRequire; 72 newRequire.register = function (id, exports) { 73 modules[id] = [function (require, module) { 74 module.exports = exports; 75 }, {}]; 76 }; 77 78 var error; 79 for (var i = 0; i < entry.length; i++) { 80 try { 81 newRequire(entry[i]); 82 } catch (e) { 83 // Save first error but execute all entries 84 if (!error) { 85 error = e; 86 } 87 } 88 } 89 90 if (entry.length) { 91 // Expose entry point to Node, AMD or browser globals 92 // Based on https://github.com/ForbesLindesay/umd/blob/master/template.js 93 var mainExports = newRequire(entry[entry.length - 1]); 94 95 // CommonJS 96 if (typeof exports === "object" && typeof module !== "undefined") { 97 module.exports = mainExports; 98 99 // RequireJS 100 } else if (typeof define === "function" && define.amd) { 101 define(function () { 102 return mainExports; 103 }); 104 105 // <script> 106 } else if (globalName) { 107 this[globalName] = mainExports; 108 } 109 } 110 111 // Override the current require with this new one 112 parcelRequire = newRequire; 113 114 if (error) { 115 // throw error from earlier, _after updating parcelRequire_ 116 throw error; 117 } 118 119 return newRequire; 120 })({"k5We":[function(require,module,exports) { 121 function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } 122 123 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 124 125 function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } 126 127 function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 128 129 function _get(target, property, receiver) { if (typeof Reflect !== "undefined" && Reflect.get) { _get = Reflect.get; } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(receiver); } return desc.value; }; } return _get(target, property, receiver || target); } 130 131 function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; } 132 133 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } 134 135 function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } 136 137 function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } 138 139 function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } 140 141 function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } 142 143 function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } 144 145 function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } 146 147 /** 148 * WordPress dependencies. 149 */ 150 var _wp = wp, 151 _wp$i18n = _wp.i18n, 152 __ = _wp$i18n.__, 153 sprintf = _wp$i18n.sprintf; 154 /** 155 * BuddyPress dependencies. 156 */ 157 158 var _bp = bp, 159 dynamicWidgetBlock = _bp.dynamicWidgetBlock; 160 /** 161 * Front-end Dynamic Members Widget Block class. 162 * 163 * @since 9.0.0 164 */ 165 166 var bpMembersWidgetBlock = /*#__PURE__*/function (_dynamicWidgetBlock) { 167 _inherits(bpMembersWidgetBlock, _dynamicWidgetBlock); 168 169 var _super = _createSuper(bpMembersWidgetBlock); 170 171 function bpMembersWidgetBlock() { 172 _classCallCheck(this, bpMembersWidgetBlock); 173 174 return _super.apply(this, arguments); 175 } 176 177 _createClass(bpMembersWidgetBlock, [{ 178 key: "loop", 179 value: function loop() { 180 var members = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 181 var container = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; 182 var type = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'active'; 183 184 var tmpl = _get(_getPrototypeOf(bpMembersWidgetBlock.prototype), "useTemplate", this).call(this, 'bp-dynamic-members-item'); 185 186 var selector = document.querySelector('#' + container); 187 var output = ''; 188 189 if (members && members.length) { 190 members.forEach(function (member) { 191 if ('active' === type && member.last_activity) { 192 /* translators: %s: a human time diff. */ 193 member.extra = sprintf(__('Active %s', 'buddypress'), member.last_activity.timediff); 194 } else if ('popular' === type && member.total_friend_count) { 195 var friendsCount = parseInt(member.total_friend_count, 10); 196 197 if (0 === friendsCount) { 198 member.extra = __('No friends', 'buddypress'); 199 } else if (1 === friendsCount) { 200 member.extra = __('1 friend', 'buddypress'); 201 } else { 202 /* translators: %s: total friend count (more than 1). */ 203 member.extra = sprintf(__('%s friends', 'buddypress'), member.total_friend_count); 204 } 205 } else if ('newest' === type && member.registered_since) { 206 /* translators: %s is time elapsed since the registration date happened */ 207 member.extra = sprintf(__('Registered %s', 'buddypress'), member.registered_since); 208 } 209 /* translators: %s: member name */ 210 211 212 member.avatar_alt = sprintf(__('Profile picture of %s', 'buddypress'), member.name); 213 output += tmpl(member); 214 }); 215 } else { 216 output = '<div class="widget-error">' + __('No members found.', 'buddypress') + '</div>'; 217 } 218 219 selector.innerHTML = output; 220 } 221 }, { 222 key: "start", 223 value: function start() { 224 var _this = this; 225 226 this.blocks.forEach(function (block, i) { 227 var selector = block.selector; 228 var type = block.query_args.type; 229 var list = document.querySelector('#' + selector).closest('.bp-dynamic-block-container'); // Get default Block's type members. 230 231 _get(_getPrototypeOf(bpMembersWidgetBlock.prototype), "getItems", _this).call(_this, type, i); // Listen to Block's Nav item clics 232 233 234 list.querySelectorAll('.item-options a').forEach(function (navItem) { 235 navItem.addEventListener('click', function (event) { 236 event.preventDefault(); // Changes the displayed filter. 237 238 event.target.closest('.item-options').querySelector('.selected').classList.remove('selected'); 239 event.target.classList.add('selected'); 240 var newType = event.target.getAttribute('data-bp-sort'); 241 242 if (newType !== _this.blocks[i].query_args.type) { 243 _get(_getPrototypeOf(bpMembersWidgetBlock.prototype), "getItems", _this).call(_this, newType, i); 244 } 245 }); 246 }); 247 }); 248 } 249 }]); 250 251 return bpMembersWidgetBlock; 252 }(dynamicWidgetBlock); 253 254 var settings = window.bpDynamicMembersSettings || {}; 255 var blocks = window.bpDynamicMembersBlocks || {}; 256 var bpDynamicMembers = new bpMembersWidgetBlock(settings, blocks); 257 258 if ('loading' === document.readyState) { 259 document.addEventListener('DOMContentLoaded', bpDynamicMembers.start()); 260 } else { 261 bpDynamicMembers.start(); 262 } 263 },{}]},{},["k5We"], null) 264 No newline at end of file -
new file src/bp-members/sass/blocks/dynamic-members.scss
diff --git src/bp-members/sass/blocks/dynamic-members.scss src/bp-members/sass/blocks/dynamic-members.scss new file mode 100644 index 000000000..35104d10d
- + 1 .bp-dynamic-block-container { 2 3 .item-options { 4 font-size: 0.5em; 5 margin: 0 0 1em; 6 padding: 1em 0; 7 8 a.selected { 9 font-weight: 600; 10 } 11 } 12 13 ul.item-list { 14 list-style: none; 15 margin: 1em 0; 16 17 li { 18 margin-bottom: 1em; 19 20 &:before, 21 &:after { 22 content: " "; 23 display: table; 24 } 25 26 &:after { 27 clear: both; 28 } 29 30 .item-avatar { 31 float: left; 32 width: 60px; 33 } 34 35 .item { 36 margin-left: 70px; 37 } 38 } 39 } 40 } -
new file src/bp-templates/bp-legacy/buddypress/assets/widgets/dynamic-members.php
diff --git src/bp-templates/bp-legacy/buddypress/assets/widgets/dynamic-members.php src/bp-templates/bp-legacy/buddypress/assets/widgets/dynamic-members.php new file mode 100644 index 000000000..52bf4a0f8
- + 1 <?php 2 /** 3 * Dynamic Members Widget Block template. 4 * 5 * @since 9.0.0 6 * 7 * @package BuddyPress 8 * @subpackage bp-legacy 9 * @version 9.0.0 10 */ 11 ?> 12 <script type="html/template" id="tmpl-bp-dynamic-members-item"> 13 <li class="vcard"> 14 <div class="item-avatar"> 15 <a href="{{{data.link}}}" class="bp-tooltip" data-bp-tooltip="{{data.name}}"> 16 <img loading="lazy" src="{{{data.avatar_urls.thumb}}}" class="avatar user-{{data.id}}-avatar avatar-50 photo" width="50" height="50" alt="{{{data.avatar_alt}}}"> 17 </a> 18 </div> 19 20 <div class="item"> 21 <div class="item-title fn"><a href="{{{data.link}}}">{{data.name}}</a></div> 22 <div class="item-meta"> 23 <span class="activity">{{data.extra}}</span> 24 </div> 25 </div> 26 </li> 27 </script> -
new file src/bp-templates/bp-nouveau/buddypress/assets/widgets/dynamic-members.php
diff --git src/bp-templates/bp-nouveau/buddypress/assets/widgets/dynamic-members.php src/bp-templates/bp-nouveau/buddypress/assets/widgets/dynamic-members.php new file mode 100644 index 000000000..9ca4bdd45
- + 1 <?php 2 /** 3 * Dynamic Members Widget Block template. 4 * 5 * @since 9.0.0 6 * 7 * @package BuddyPress 8 * @subpackage bp-nouveau 9 * @version 9.0.0 10 */ 11 ?> 12 <script type="html/template" id="tmpl-bp-dynamic-members-item"> 13 <li class="vcard"> 14 <div class="item-avatar"> 15 <a href="{{{data.link}}}" class="bp-tooltip" data-bp-tooltip="{{data.name}}"> 16 <img loading="lazy" src="{{{data.avatar_urls.thumb}}}" class="avatar user-{{data.id}}-avatar avatar-50 photo" width="50" height="50" alt="{{{data.avatar_alt}}}"> 17 </a> 18 </div> 19 20 <div class="item"> 21 <div class="item-title fn"><a href="{{{data.link}}}">{{data.name}}</a></div> 22 <div class="item-meta"> 23 <span class="activity">{{data.extra}}</span> 24 </div> 25 </div> 26 </li> 27 </script> -
new file src/js/bp-members/js/blocks/dynamic-members.js
diff --git src/js/bp-members/js/blocks/dynamic-members.js src/js/bp-members/js/blocks/dynamic-members.js new file mode 100644 index 000000000..bddb04dc7
- + 1 /** 2 * WordPress dependencies. 3 */ 4 const { 5 blocks: { 6 registerBlockType, 7 }, 8 i18n: { 9 __, 10 }, 11 } = wp; 12 13 /** 14 * Internal dependencies. 15 */ 16 import editDynamicMembersBlock from './dynamic-members/edit'; 17 import transforms from './dynamic-members/transforms'; 18 19 registerBlockType( 'bp/dynamic-members', { 20 title: __( 'Dynamic Members List', 'buddypress' ), 21 description: __( 'A dynamic list of recently active, popular, and newest members.', 'buddypress' ), 22 icon: { 23 background: '#fff', 24 foreground: '#d84800', 25 src: 'groups', 26 }, 27 category: 'buddypress', 28 attributes: { 29 title: { 30 type: 'string', 31 default: __( 'Members', 'buddypress' ), 32 }, 33 maxMembers: { 34 type: 'number', 35 default: 5 36 }, 37 memberDefault: { 38 type: 'string', 39 default: 'active', 40 }, 41 linkTitle: { 42 type: 'boolean', 43 default: false, 44 }, 45 }, 46 edit: editDynamicMembersBlock, 47 transforms: transforms, 48 } ); -
new file src/js/bp-members/js/blocks/dynamic-members/constants.js
diff --git src/js/bp-members/js/blocks/dynamic-members/constants.js src/js/bp-members/js/blocks/dynamic-members/constants.js new file mode 100644 index 000000000..0f8930622
- + 1 /** 2 * WordPress dependencies. 3 */ 4 const { 5 i18n: { 6 __, 7 }, 8 } = wp; 9 10 /** 11 * Members ordering types. 12 * 13 * @type {Array} 14 */ 15 export const TYPES = [ 16 { 17 label: __( 'Newest', 'buddypress' ), 18 value: 'newest', 19 }, 20 { 21 label: __( 'Active', 'buddypress' ), 22 value: 'active', 23 }, 24 { 25 label: __( 'Popular', 'buddypress' ), 26 value: 'popular', 27 }, 28 ]; -
new file src/js/bp-members/js/blocks/dynamic-members/edit.js
diff --git src/js/bp-members/js/blocks/dynamic-members/edit.js src/js/bp-members/js/blocks/dynamic-members/edit.js new file mode 100644 index 000000000..88b5ee297
- + 1 /** 2 * WordPress dependencies. 3 */ 4 const { 5 blockEditor: { 6 InspectorControls, 7 }, 8 components: { 9 Disabled, 10 PanelBody, 11 RangeControl, 12 SelectControl, 13 TextControl, 14 ToggleControl, 15 }, 16 element: { 17 Fragment, 18 createElement, 19 }, 20 i18n: { 21 __, 22 }, 23 } = wp; 24 25 /** 26 * BuddyPress dependencies. 27 */ 28 const { 29 blockComponents: { 30 ServerSideRender, 31 }, 32 blockData: { 33 isActive, 34 } 35 } = bp; 36 37 /** 38 * Internal dependencies. 39 */ 40 import { TYPES } from './constants'; 41 42 const editDynamicMembersBlock = ( { attributes, setAttributes } ) => { 43 const { title, maxMembers, memberDefault, linkTitle } = attributes; 44 const sortTypes = !! isActive( 'friends' ) ? TYPES : TYPES.filter( ( type ) => 'popular' !== type.value ); 45 46 return ( 47 <Fragment> 48 <InspectorControls> 49 <PanelBody title={ __( 'Settings', 'buddypress' ) } initialOpen={ true }> 50 <TextControl 51 label={ __( 'Title', 'buddypress' ) } 52 value={ title } 53 onChange={ ( text ) => { 54 setAttributes( { title: text } ); 55 } } 56 /> 57 <RangeControl 58 label={ __( 'Max members to show', 'buddypress' ) } 59 value={ maxMembers } 60 onChange={ ( value ) => 61 setAttributes( { maxMembers: value } ) 62 } 63 min={ 1 } 64 max={ 10 } 65 required 66 /> 67 <SelectControl 68 label={ __( 'Default members to show', 'buddypress' ) } 69 value={ memberDefault } 70 options={ sortTypes } 71 onChange={ ( option ) => { 72 setAttributes( { memberDefault: option } ); 73 } } 74 /> 75 <ToggleControl 76 label={ __( 'Link block title to Members directory', 'buddypress' ) } 77 checked={ !! linkTitle } 78 onChange={ () => { 79 setAttributes( { linkTitle: ! linkTitle } ); 80 } } 81 /> 82 </PanelBody> 83 </InspectorControls> 84 <Disabled> 85 <ServerSideRender block="bp/dynamic-members" attributes={ attributes } /> 86 </Disabled> 87 </Fragment> 88 ); 89 }; 90 91 export default editDynamicMembersBlock; -
new file src/js/bp-members/js/blocks/dynamic-members/transforms.js
diff --git src/js/bp-members/js/blocks/dynamic-members/transforms.js src/js/bp-members/js/blocks/dynamic-members/transforms.js new file mode 100644 index 000000000..d5090aee8
- + 1 /** 2 * WordPress dependencies. 3 */ 4 const { 5 blocks: { 6 createBlock, 7 }, 8 } = wp; 9 10 /** 11 * Transforms Legacy Widget to Dynamic Members Block. 12 * 13 * @type {Object} 14 */ 15 const transforms = { 16 from: [ 17 { 18 type: 'block', 19 blocks: [ 'core/legacy-widget' ], 20 isMatch: ( { idBase, instance } ) => { 21 if ( ! instance?.raw ) { 22 return false; 23 } 24 25 return idBase === 'bp_core_members_widget'; 26 }, 27 transform: ( { instance } ) => { 28 return createBlock( 'bp/dynamic-members', { 29 title: instance.raw.title, 30 maxMembers: instance.raw.max_members, 31 memberDefault: instance.raw.member_default, 32 linkTitle: instance.raw.link_title, 33 } ); 34 }, 35 }, 36 ], 37 }; 38 39 export default transforms; -
new file src/js/bp-members/js/dynamic-members.js
diff --git src/js/bp-members/js/dynamic-members.js src/js/bp-members/js/dynamic-members.js new file mode 100644 index 000000000..c1f340a60
- + 1 /** 2 * WordPress dependencies. 3 */ 4 const { 5 i18n: { 6 __, 7 sprintf, 8 }, 9 } = wp; 10 11 /** 12 * BuddyPress dependencies. 13 */ 14 const { 15 dynamicWidgetBlock, 16 } = bp; 17 18 /** 19 * Front-end Dynamic Members Widget Block class. 20 * 21 * @since 9.0.0 22 */ 23 class bpMembersWidgetBlock extends dynamicWidgetBlock { 24 loop( members = [], container = '', type = 'active' ) { 25 const tmpl = super.useTemplate( 'bp-dynamic-members-item' ); 26 const selector = document.querySelector( '#' + container ); 27 let output = ''; 28 29 if ( members && members.length ) { 30 members.forEach( ( member ) => { 31 if ( 'active' === type && member.last_activity ) { 32 /* translators: %s: a human time diff. */ 33 member.extra = sprintf( __( 'Active %s', 'buddypress' ), member.last_activity.timediff ); 34 } else if ( 'popular' === type && member.total_friend_count ) { 35 const friendsCount = parseInt( member.total_friend_count, 10 ); 36 37 if ( 0 === friendsCount ) { 38 member.extra = __( 'No friends', 'buddypress' ); 39 } else if ( 1 === friendsCount ) { 40 member.extra = __( '1 friend', 'buddypress' ); 41 } else { 42 /* translators: %s: total friend count (more than 1). */ 43 member.extra = sprintf( __( '%s friends', 'buddypress' ), member.total_friend_count ); 44 } 45 } else if ( 'newest' === type && member.registered_since ) { 46 /* translators: %s is time elapsed since the registration date happened */ 47 member.extra = sprintf( __( 'Registered %s', 'buddypress' ), member.registered_since ); 48 } 49 50 /* translators: %s: member name */ 51 member.avatar_alt = sprintf( __( 'Profile picture of %s', 'buddypress' ), member.name ); 52 53 output += tmpl( member ); 54 } ); 55 } else { 56 output = '<div class="widget-error">' + __( 'No members found.', 'buddypress' ) + '</div>'; 57 } 58 59 selector.innerHTML = output; 60 } 61 62 start() { 63 this.blocks.forEach( ( block, i ) => { 64 const { selector } = block; 65 const { type } = block.query_args; 66 const list = document.querySelector( '#' + selector ).closest( '.bp-dynamic-block-container' ); 67 68 // Get default Block's type members. 69 super.getItems( type, i ); 70 71 // Listen to Block's Nav item clics 72 list.querySelectorAll( '.item-options a' ).forEach( ( navItem ) => { 73 navItem.addEventListener( 'click', ( event ) => { 74 event.preventDefault(); 75 76 // Changes the displayed filter. 77 event.target.closest( '.item-options' ).querySelector( '.selected' ).classList.remove( 'selected' ); 78 event.target.classList.add( 'selected' ); 79 80 const newType = event.target.getAttribute( 'data-bp-sort' ); 81 82 if ( newType !== this.blocks[ i ].query_args.type ) { 83 super.getItems( newType, i ); 84 } 85 } ); 86 } ); 87 } ); 88 } 89 } 90 91 const settings = window.bpDynamicMembersSettings || {}; 92 const blocks = window.bpDynamicMembersBlocks || {}; 93 const bpDynamicMembers = new bpMembersWidgetBlock( settings, blocks ); 94 95 if ( 'loading' === document.readyState ) { 96 document.addEventListener( 'DOMContentLoaded', bpDynamicMembers.start() ); 97 } else { 98 bpDynamicMembers.start(); 99 }