Ticket #8523: 8523.patch
File 8523.patch, 45.8 KB (added by , 4 years ago) |
---|
-
.jshintignore
diff --git .jshintignore .jshintignore index 185586a70..eeeb21557 100644
src/**/js/block-*/**/*.js 10 10 src/**/js/block-*.js 11 11 src/**/js/friends.js 12 12 src/**/js/dynamic-members.js 13 src/**/js/dynamic-groups.js 13 14 src/**/js/dynamic-widget-block.js -
Gruntfile.js
diff --git Gruntfile.js Gruntfile.js index 5951547f2..7e4ecdae2 100644
module.exports = function( grunt ) { 25 25 '!**/js/block-*.js', 26 26 '!**/js/friends.js', 27 27 '!**/js/dynamic-members.js', 28 '!**/js/dynamic-groups.js', 28 29 '!**/js/dynamic-widget-block.js' 29 30 ], 30 31 … … module.exports = function( grunt ) { 45 46 '!bp-core/css/blocks/login-form.css', 46 47 '!bp-activity/css/blocks/latest-activities.css', 47 48 '!bp-friends/css/blocks/friends.css', 48 '!bp-members/css/blocks/dynamic-members.css' 49 '!bp-members/css/blocks/dynamic-members.css', 50 '!bp-groups/css/blocks/dynamic-groups.css' 49 51 ], 50 52 51 53 autoprefixer = require('autoprefixer'); -
src/bp-friends/bp-friends-blocks.php
diff --git src/bp-friends/bp-friends-blocks.php src/bp-friends/bp-friends-blocks.php index 876bc46d3..3d3b99f07 100644
function bp_friends_render_friends_block( $attributes = array() ) { 182 182 'html' => false, 183 183 ) 184 184 ), 185 'data.avatar_alt' => esc_ html(185 'data.avatar_alt' => esc_attr( 186 186 sprintf( 187 187 /* translators: %s: member name */ 188 188 __( 'Profile picture of %s', 'buddypress' ), -
src/bp-groups/bp-groups-blocks.php
diff --git src/bp-groups/bp-groups-blocks.php src/bp-groups/bp-groups-blocks.php index c3c08fb39..8eed69b46 100644
function bp_groups_render_groups_block( $attributes = array() ) { 310 310 */ 311 311 return apply_filters( 'bp_groups_render_groups_block_output', $output, $block_args, $groups ); 312 312 } 313 314 /** 315 * Adds specific script data for the BP Groups blocks. 316 * 317 * Only used for the BP Dynamic Groups block. 318 * 319 * @since 9.0.0 320 */ 321 function bp_groups_blocks_add_script_data() { 322 $dynamic_groups_blocks = array_filter( buddypress()->groups->block_globals['bp/dynamic-groups']->items ); 323 324 if ( ! $dynamic_groups_blocks ) { 325 return; 326 } 327 328 // Include the common JS template. 329 echo bp_get_dynamic_template_part( 'assets/widgets/dynamic-groups.php' ); 330 331 // List the block specific props. 332 wp_add_inline_script( 333 'bp-dynamic-groups-script', 334 sprintf( 'var bpDynamicGroupsBlocks = %s;', wp_json_encode( array_values( $dynamic_groups_blocks ) ) ), 335 'before' 336 ); 337 } 338 339 /** 340 * Callback function to render the Dynamic Groups Block. 341 * 342 * @since 9.0.0 343 * 344 * @param array $attributes The block attributes. 345 * @return string HTML output. 346 */ 347 function bp_groups_render_dynamic_groups_block( $attributes = array() ) { 348 $block_args = wp_parse_args( 349 $attributes, 350 array( 351 'title' => __( 'Groups', 'buddypress' ), 352 'maxGroups' => 5, 353 'groupDefault' => 'active', 354 'linkTitle' => false, 355 ) 356 ); 357 358 $classnames = 'widget_bp_groups_widget buddypress widget'; 359 $wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $classnames ) ); 360 361 $max_groups = (int) $block_args['maxGroups']; 362 $no_groups = __( 'There are no groups to display.', 'buddypress' ); 363 364 /** This filter is documented in buddypress/src/bp-groups/classes/class-bp-groups-widget.php */ 365 $separator = apply_filters( 'bp_groups_widget_separator', '|' ); 366 367 // Make sure the widget ID is unique. 368 $widget_id = uniqid( 'groups-list-' ); 369 $groups_directory_link = bp_get_groups_directory_permalink(); 370 371 // Set the Block's title. 372 if ( true === $block_args['linkTitle'] ) { 373 $widget_content = sprintf( 374 '<h2 class="widget-title"><a href="%1$s">%2$s</a></h2>', 375 esc_url( $groups_directory_link ), 376 esc_html( $block_args['title'] ) 377 ); 378 } else { 379 $widget_content = sprintf( '<h2 class="widget-title">%s</h2>', esc_html( $block_args['title'] ) ); 380 } 381 382 $item_options = array( 383 'newest' => array( 384 'class' => '', 385 'label' => __( 'Newest', 'buddypress' ), 386 ), 387 'active' => array( 388 'class' => '', 389 'label' => __( 'Active', 'buddypress' ), 390 ), 391 'popular' => array( 392 'class' => '', 393 'label' => __( 'Popular', 'buddypress' ), 394 ), 395 'alphabetical' => array( 396 'class' => '', 397 'label' => __( 'Alphabetical', 'buddypress' ), 398 ), 399 ); 400 401 $item_options_output = array(); 402 $separator_output = sprintf( ' <span class="bp-separator" role="separator">%s</span> ', esc_html( $separator ) ); 403 404 foreach ( $item_options as $item_type => $item_attr ) { 405 if ( $block_args['groupDefault'] === $item_type ) { 406 $item_attr['class'] = ' class="selected"'; 407 } 408 409 $item_options_output[] = sprintf( 410 '<a href="%1$s" data-bp-sort="%2$s"%3$s>%4$s</a>', 411 esc_url( $groups_directory_link ), 412 esc_attr( $item_type ), 413 $item_attr['class'], 414 esc_html( $item_attr['label'] ) 415 ); 416 } 417 418 $preview = ''; 419 $default_args = array( 420 'type' => $block_args['groupDefault'], 421 'per_page' => $max_groups, 422 'populate_extras' => true, 423 ); 424 425 // Previewing the Block inside the editor. 426 if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) { 427 $bp_query = groups_get_groups( $default_args ); 428 $preview = sprintf( '<div class="widget-error">%s</div>', $no_groups ); 429 430 if ( is_array( $bp_query['groups'] ) && 0 < count( $bp_query['groups'] ) ) { 431 $preview = ''; 432 foreach ( $bp_query['groups'] as $group ) { 433 if ( 'newest' === $block_args['groupDefault'] ) { 434 /* translators: %s is time elapsed since the group was created */ 435 $extra = sprintf( __( 'Created %s', 'buddypress' ), bp_get_group_date_created( $group ) ); 436 } elseif ( 'popular' === $block_args['groupDefault'] ) { 437 $count = (int) $group->total_member_count; 438 439 /* translators: %s is the number of Group members */ 440 $extra = sprintf( _n( '%s member', '%s members', $count, 'buddypress' ), bp_core_number_format( $count ) ); 441 } else { 442 /* translators: %s: a human time diff. */ 443 $extra = sprintf( __( 'Active %s', 'buddypress' ), bp_get_group_last_active( $group ) ); 444 } 445 446 $preview .= bp_get_dynamic_template_part( 447 'assets/widgets/dynamic-groups.php', 448 'php', 449 array( 450 'data.link' => bp_get_group_permalink( $group ), 451 'data.name' => bp_get_group_name( $group ), 452 'data.avatar_urls.thumb' => bp_core_fetch_avatar( 453 array( 454 'item_id' => $group->id, 455 'html' => false, 456 'object' => 'group', 457 ) 458 ), 459 'data.avatar_alt' => esc_attr( 460 sprintf( 461 /* Translators: %s is the group's name. */ 462 __( 'Group Profile photo of %s', 'buddypress' ), 463 $group->name 464 ) 465 ), 466 'data.id' => $group->id, 467 'data.extra' => $extra, 468 ) 469 ); 470 } 471 } 472 } else { 473 // Get corresponding members. 474 $path = sprintf( 475 '/%1$s/%2$s/%3$s', 476 bp_rest_namespace(), 477 bp_rest_version(), 478 buddypress()->groups->id 479 ); 480 481 $default_path = add_query_arg( 482 $default_args, 483 $path 484 ); 485 486 $preloaded_groups = array(); 487 if ( bp_is_running_wp( '5.0.0' ) ) { 488 $preloaded_groups = rest_preload_api_request( '', $default_path ); 489 } 490 491 buddypress()->groups->block_globals['bp/dynamic-groups']->items[ $widget_id ] = (object) array( 492 'selector' => $widget_id, 493 'query_args' => $default_args, 494 'preloaded' => reset( $preloaded_groups ), 495 ); 496 497 // Only enqueue common/specific scripts and data once per page load. 498 if ( ! has_action( 'wp_footer', 'bp_groups_blocks_add_script_data', 1 ) ) { 499 wp_set_script_translations( 'bp-dynamic-groups-script', 'buddypress' ); 500 wp_enqueue_script( 'bp-dynamic-groups-script' ); 501 wp_localize_script( 502 'bp-dynamic-groups-script', 503 'bpDynamicGroupsSettings', 504 array( 505 'path' => ltrim( $path, '/' ), 506 'root' => esc_url_raw( get_rest_url() ), 507 'nonce' => wp_create_nonce( 'wp_rest' ), 508 ) 509 ); 510 511 add_action( 'wp_footer', 'bp_groups_blocks_add_script_data', 1 ); 512 } 513 } 514 515 $widget_content .= sprintf( 516 '<div class="item-options"> 517 %1$s 518 </div> 519 <ul id="%2$s" class="item-list" aria-live="polite" aria-relevant="all" aria-atomic="true"> 520 %3$s 521 </ul>', 522 implode( $separator_output, $item_options_output ), 523 esc_attr( $widget_id ), 524 $preview 525 ); 526 527 // Adds a container to make sure the block is styled even when used into the Columns parent block. 528 $widget_content = sprintf( '<div class="bp-dynamic-block-container">%s</div>', "\n" . $widget_content . "\n" ); 529 530 // Only add a block wrapper if not loaded into a Widgets sidebar. 531 if ( ! did_action( 'dynamic_sidebar_before' ) ) { 532 return sprintf( 533 '<div %1$s>%2$s</div>', 534 $wrapper_attributes, 535 $widget_content 536 ); 537 } 538 539 return $widget_content; 540 } -
src/bp-groups/bp-groups-cssjs.php
diff --git src/bp-groups/bp-groups-cssjs.php src/bp-groups/bp-groups-cssjs.php index 4a2221486..99aab5bb6 100644
function bp_groups_get_group_manage_members_script_data( $group_id = 0 ) { 63 63 ), 64 64 ); 65 65 } 66 67 /** 68 * Registers a new script to manage the dynamic part of the Dynamic groups widget/block. 69 * 70 * @since 9.0.0 71 * 72 * @param array $scripts Data about the scripts to register. 73 * @return array Data about the scripts to register. 74 */ 75 function bp_groups_register_widget_block_scripts( $scripts = array() ) { 76 $scripts['bp-dynamic-groups-script'] = array( 77 'file' => plugins_url( 'js/dynamic-groups.js', __FILE__ ), 78 'dependencies' => array( 79 'bp-dynamic-widget-block-script', 80 'wp-i18n', 81 ), 82 'footer' => true, 83 ); 84 85 return $scripts; 86 } 87 add_filter( 'bp_core_register_common_scripts', 'bp_groups_register_widget_block_scripts', 9, 1 ); -
src/bp-groups/classes/class-bp-groups-component.php
diff --git src/bp-groups/classes/class-bp-groups-component.php src/bp-groups/classes/class-bp-groups-component.php index d40a5c7b7..554ebdc94 100644
class BP_Groups_Component extends BP_Component { 261 261 'search_string' => _x( 'Search Groups...', 'Component directory search', 'buddypress' ), 262 262 'global_tables' => $global_tables, 263 263 'meta_tables' => $meta_tables, 264 'block_globals' => array( 265 'bp/dynamic-groups' => array( 266 'widget_classnames' => array( 'widget_bp_groups_widget', 'buddypress' ), 267 ), 268 ), 264 269 ); 265 270 266 271 parent::setup_globals( $args ); … … class BP_Groups_Component extends BP_Component { 1058 1063 ), 1059 1064 'render_callback' => 'bp_groups_render_groups_block', 1060 1065 ), 1066 'bp/dynamic-groups' => array( 1067 'name' => 'bp/dynamic-groups', 1068 'editor_script' => 'bp-dynamic-groups-block', 1069 'editor_script_url' => plugins_url( 'js/blocks/dynamic-groups.js', dirname( __FILE__ ) ), 1070 'editor_script_deps' => array( 1071 'wp-blocks', 1072 'wp-element', 1073 'wp-components', 1074 'wp-i18n', 1075 'wp-block-editor', 1076 'bp-block-components', 1077 ), 1078 'style' => 'bp-dynamic-groups-block', 1079 'style_url' => plugins_url( 'css/blocks/dynamic-groups.css', dirname( __FILE__ ) ), 1080 'attributes' => array( 1081 'title' => array( 1082 'type' => 'string', 1083 'default' => __( 'Groups', 'buddypress' ), 1084 ), 1085 'maxGroups' => array( 1086 'type' => 'number', 1087 'default' => 5, 1088 ), 1089 'groupDefault' => array( 1090 'type' => 'string', 1091 'default' => 'active', 1092 ), 1093 'linkTitle' => array( 1094 'type' => 'boolean', 1095 'default' => false, 1096 ), 1097 ), 1098 'render_callback' => 'bp_groups_render_dynamic_groups_block', 1099 ), 1061 1100 ) 1062 1101 ); 1063 1102 } -
new file src/bp-groups/css/blocks/dynamic-groups-rtl.css
diff --git src/bp-groups/css/blocks/dynamic-groups-rtl.css src/bp-groups/css/blocks/dynamic-groups-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-groups/css/blocks/dynamic-groups.css
diff --git src/bp-groups/css/blocks/dynamic-groups.css src/bp-groups/css/blocks/dynamic-groups.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-groups/js/blocks/dynamic-groups.js
diff --git src/bp-groups/js/blocks/dynamic-groups.js src/bp-groups/js/blocks/dynamic-groups.js new file mode 100644 index 000000000..ed9e2a31e
- + 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 })({"Ra3s":[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 * Groups 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 label: __('Alphabetical', 'buddypress'), 150 value: 'alphabetical' 151 }]; 152 exports.TYPES = TYPES; 153 },{}],"l8fw":[function(require,module,exports) { 154 "use strict"; 155 156 Object.defineProperty(exports, "__esModule", { 157 value: true 158 }); 159 exports.default = void 0; 160 161 var _constants = require("./constants"); 162 163 /** 164 * WordPress dependencies. 165 */ 166 var _wp = wp, 167 InspectorControls = _wp.blockEditor.InspectorControls, 168 _wp$components = _wp.components, 169 Disabled = _wp$components.Disabled, 170 PanelBody = _wp$components.PanelBody, 171 RangeControl = _wp$components.RangeControl, 172 SelectControl = _wp$components.SelectControl, 173 TextControl = _wp$components.TextControl, 174 ToggleControl = _wp$components.ToggleControl, 175 _wp$element = _wp.element, 176 Fragment = _wp$element.Fragment, 177 createElement = _wp$element.createElement, 178 __ = _wp.i18n.__; 179 /** 180 * BuddyPress dependencies. 181 */ 182 183 var _bp = bp, 184 ServerSideRender = _bp.blockComponents.ServerSideRender; 185 /** 186 * Internal dependencies. 187 */ 188 189 var editDynamicGroupsBlock = function editDynamicGroupsBlock(_ref) { 190 var attributes = _ref.attributes, 191 setAttributes = _ref.setAttributes; 192 var title = attributes.title, 193 maxGroups = attributes.maxGroups, 194 groupDefault = attributes.groupDefault, 195 linkTitle = attributes.linkTitle; 196 return createElement(Fragment, null, createElement(InspectorControls, null, createElement(PanelBody, { 197 title: __('Settings', 'buddypress'), 198 initialOpen: true 199 }, createElement(TextControl, { 200 label: __('Title', 'buddypress'), 201 value: title, 202 onChange: function onChange(text) { 203 setAttributes({ 204 title: text 205 }); 206 } 207 }), createElement(RangeControl, { 208 label: __('Max groups to show', 'buddypress'), 209 value: maxGroups, 210 onChange: function onChange(value) { 211 return setAttributes({ 212 maxGroups: value 213 }); 214 }, 215 min: 1, 216 max: 10, 217 required: true 218 }), createElement(SelectControl, { 219 label: __('Default groups to show', 'buddypress'), 220 value: groupDefault, 221 options: _constants.TYPES, 222 onChange: function onChange(option) { 223 setAttributes({ 224 groupDefault: option 225 }); 226 } 227 }), createElement(ToggleControl, { 228 label: __('Link block title to Groups directory', 'buddypress'), 229 checked: !!linkTitle, 230 onChange: function onChange() { 231 setAttributes({ 232 linkTitle: !linkTitle 233 }); 234 } 235 }))), createElement(Disabled, null, createElement(ServerSideRender, { 236 block: "bp/dynamic-groups", 237 attributes: attributes 238 }))); 239 }; 240 241 var _default = editDynamicGroupsBlock; 242 exports.default = _default; 243 },{"./constants":"Ra3s"}],"SJlW":[function(require,module,exports) { 244 "use strict"; 245 246 Object.defineProperty(exports, "__esModule", { 247 value: true 248 }); 249 exports.default = void 0; 250 251 /** 252 * WordPress dependencies. 253 */ 254 var _wp = wp, 255 createBlock = _wp.blocks.createBlock; 256 /** 257 * Transforms Legacy Widget to Dynamic Groups Block. 258 * 259 * @type {Object} 260 */ 261 262 var transforms = { 263 from: [{ 264 type: 'block', 265 blocks: ['core/legacy-widget'], 266 isMatch: function isMatch(_ref) { 267 var idBase = _ref.idBase, 268 instance = _ref.instance; 269 270 if (!(instance !== null && instance !== void 0 && instance.raw)) { 271 return false; 272 } 273 274 return idBase === 'bp_groups_widget'; 275 }, 276 transform: function transform(_ref2) { 277 var instance = _ref2.instance; 278 return createBlock('bp/dynamic-groups', { 279 title: instance.raw.title, 280 maxGroups: instance.raw.max_groups, 281 groupDefault: instance.raw.group_default, 282 linkTitle: instance.raw.link_title 283 }); 284 } 285 }] 286 }; 287 var _default = transforms; 288 exports.default = _default; 289 },{}],"lVvR":[function(require,module,exports) { 290 "use strict"; 291 292 var _edit = _interopRequireDefault(require("./dynamic-groups/edit")); 293 294 var _transforms = _interopRequireDefault(require("./dynamic-groups/transforms")); 295 296 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 297 298 /** 299 * WordPress dependencies. 300 */ 301 var _wp = wp, 302 registerBlockType = _wp.blocks.registerBlockType, 303 __ = _wp.i18n.__; 304 /** 305 * Internal dependencies. 306 */ 307 308 registerBlockType('bp/dynamic-groups', { 309 title: __('Dynamic Groups List', 'buddypress'), 310 description: __('A dynamic list of recently active, popular, newest, or alphabetical groups.', 'buddypress'), 311 icon: { 312 background: '#fff', 313 foreground: '#d84800', 314 src: 'buddicons-groups' 315 }, 316 category: 'buddypress', 317 attributes: { 318 title: { 319 type: 'string', 320 default: __('Groups', 'buddypress') 321 }, 322 maxGroups: { 323 type: 'number', 324 default: 5 325 }, 326 groupDefault: { 327 type: 'string', 328 default: 'active' 329 }, 330 linkTitle: { 331 type: 'boolean', 332 default: false 333 } 334 }, 335 edit: _edit.default, 336 transforms: _transforms.default 337 }); 338 },{"./dynamic-groups/edit":"l8fw","./dynamic-groups/transforms":"SJlW"}]},{},["lVvR"], null) 339 No newline at end of file -
new file src/bp-groups/js/dynamic-groups.js
diff --git src/bp-groups/js/dynamic-groups.js src/bp-groups/js/dynamic-groups.js new file mode 100644 index 000000000..4a0839982
- + 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 })({"UOvc":[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 Groups Widget Block class. 162 * 163 * @since 9.0.0 164 */ 165 166 var bpGroupsWidgetBlock = /*#__PURE__*/function (_dynamicWidgetBlock) { 167 _inherits(bpGroupsWidgetBlock, _dynamicWidgetBlock); 168 169 var _super = _createSuper(bpGroupsWidgetBlock); 170 171 function bpGroupsWidgetBlock() { 172 _classCallCheck(this, bpGroupsWidgetBlock); 173 174 return _super.apply(this, arguments); 175 } 176 177 _createClass(bpGroupsWidgetBlock, [{ 178 key: "loop", 179 value: function loop() { 180 var groups = 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(bpGroupsWidgetBlock.prototype), "useTemplate", this).call(this, 'bp-dynamic-groups-item'); 185 186 var selector = document.querySelector('#' + container); 187 var output = ''; 188 189 if (groups && groups.length) { 190 groups.forEach(function (group) { 191 if ('newest' === type && group.created_since) { 192 /* translators: %s is time elapsed since the group was created */ 193 group.extra = sprintf(__('Created %s', 'buddypress'), group.created_since); 194 } else if ('popular' === type && group.total_member_count) { 195 var membersCount = parseInt(group.total_member_count, 10); 196 197 if (0 === membersCount) { 198 group.extra = __('No members', 'buddypress'); 199 } else if (1 === membersCount) { 200 group.extra = __('1 member', 'buddypress'); 201 } else { 202 /* translators: %s is the number of Group members (more than 1). */ 203 group.extra = sprintf(__('%s members', 'buddypress'), group.total_member_count); 204 } 205 } else { 206 /* translators: %s: a human time diff. */ 207 group.extra = sprintf(__('Active %s', 'buddypress'), group.last_activity_diff); 208 } 209 /* Translators: %s is the group's name. */ 210 211 212 group.avatar_alt = sprintf(__('Group Profile photo of %s', 'buddypress'), group.name); 213 output += tmpl(group); 214 }); 215 } else { 216 output = '<div class="widget-error">' + __('There are no groups to display.', '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 groups. 230 231 _get(_getPrototypeOf(bpGroupsWidgetBlock.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(bpGroupsWidgetBlock.prototype), "getItems", _this).call(_this, newType, i); 244 } 245 }); 246 }); 247 }); 248 } 249 }]); 250 251 return bpGroupsWidgetBlock; 252 }(dynamicWidgetBlock); 253 254 var settings = window.bpDynamicGroupsSettings || {}; 255 var blocks = window.bpDynamicGroupsBlocks || []; 256 var bpDynamicGroups = new bpGroupsWidgetBlock(settings, blocks); 257 258 if ('loading' === document.readyState) { 259 document.addEventListener('DOMContentLoaded', bpDynamicGroups.start()); 260 } else { 261 bpDynamicGroups.start(); 262 } 263 },{}]},{},["UOvc"], null) 264 No newline at end of file -
new file src/bp-groups/sass/blocks/dynamic-groups.scss
diff --git src/bp-groups/sass/blocks/dynamic-groups.scss src/bp-groups/sass/blocks/dynamic-groups.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 } -
src/bp-members/bp-members-blocks.php
diff --git src/bp-members/bp-members-blocks.php src/bp-members/bp-members-blocks.php index 06310ecf0..467c51ff9 100644
function bp_members_render_dynamic_members_block( $attributes = array() ) { 473 473 'html' => false, 474 474 ) 475 475 ), 476 'data.avatar_alt' => esc_ html(476 'data.avatar_alt' => esc_attr( 477 477 sprintf( 478 478 /* translators: %s: member name */ 479 479 __( 'Profile picture of %s', 'buddypress' ), -
new file src/bp-templates/bp-legacy/buddypress/assets/widgets/dynamic-groups.php
diff --git src/bp-templates/bp-legacy/buddypress/assets/widgets/dynamic-groups.php src/bp-templates/bp-legacy/buddypress/assets/widgets/dynamic-groups.php new file mode 100644 index 000000000..0fa900c52
- + 1 <?php 2 /** 3 * Dynamic Groups 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-groups-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 group-{{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-groups.php
diff --git src/bp-templates/bp-nouveau/buddypress/assets/widgets/dynamic-groups.php src/bp-templates/bp-nouveau/buddypress/assets/widgets/dynamic-groups.php new file mode 100644 index 000000000..4047d8a2d
- + 1 <?php 2 /** 3 * Dynamic Groups 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-groups-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 group-{{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-groups/js/blocks/dynamic-groups.js
diff --git src/js/bp-groups/js/blocks/dynamic-groups.js src/js/bp-groups/js/blocks/dynamic-groups.js new file mode 100644 index 000000000..408884d40
- + 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 editDynamicGroupsBlock from './dynamic-groups/edit'; 17 import transforms from './dynamic-groups/transforms'; 18 19 registerBlockType( 'bp/dynamic-groups', { 20 title: __( 'Dynamic Groups List', 'buddypress' ), 21 description: __( 'A dynamic list of recently active, popular, newest, or alphabetical groups.', 'buddypress' ), 22 icon: { 23 background: '#fff', 24 foreground: '#d84800', 25 src: 'buddicons-groups', 26 }, 27 category: 'buddypress', 28 attributes: { 29 title: { 30 type: 'string', 31 default: __( 'Groups', 'buddypress' ), 32 }, 33 maxGroups: { 34 type: 'number', 35 default: 5 36 }, 37 groupDefault: { 38 type: 'string', 39 default: 'active', 40 }, 41 linkTitle: { 42 type: 'boolean', 43 default: false, 44 }, 45 }, 46 edit: editDynamicGroupsBlock, 47 transforms: transforms, 48 } ); -
new file src/js/bp-groups/js/blocks/dynamic-groups/constants.js
diff --git src/js/bp-groups/js/blocks/dynamic-groups/constants.js src/js/bp-groups/js/blocks/dynamic-groups/constants.js new file mode 100644 index 000000000..e3e5ebe3e
- + 1 /** 2 * WordPress dependencies. 3 */ 4 const { 5 i18n: { 6 __, 7 }, 8 } = wp; 9 10 /** 11 * Groups 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 { 29 label: __('Alphabetical', 'buddypress' ), 30 value: 'alphabetical', 31 }, 32 ]; -
new file src/js/bp-groups/js/blocks/dynamic-groups/edit.js
diff --git src/js/bp-groups/js/blocks/dynamic-groups/edit.js src/js/bp-groups/js/blocks/dynamic-groups/edit.js new file mode 100644 index 000000000..b1be4d5b5
- + 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 } = bp; 33 34 /** 35 * Internal dependencies. 36 */ 37 import { TYPES } from './constants'; 38 39 const editDynamicGroupsBlock = ( { attributes, setAttributes } ) => { 40 const { title, maxGroups, groupDefault, linkTitle } = attributes; 41 42 return ( 43 <Fragment> 44 <InspectorControls> 45 <PanelBody title={ __( 'Settings', 'buddypress' ) } initialOpen={ true }> 46 <TextControl 47 label={ __( 'Title', 'buddypress' ) } 48 value={ title } 49 onChange={ ( text ) => { 50 setAttributes( { title: text } ); 51 } } 52 /> 53 <RangeControl 54 label={ __( 'Max groups to show', 'buddypress' ) } 55 value={ maxGroups } 56 onChange={ ( value ) => 57 setAttributes( { maxGroups: value } ) 58 } 59 min={ 1 } 60 max={ 10 } 61 required 62 /> 63 <SelectControl 64 label={ __( 'Default groups to show', 'buddypress' ) } 65 value={ groupDefault } 66 options={ TYPES } 67 onChange={ ( option ) => { 68 setAttributes( { groupDefault: option } ); 69 } } 70 /> 71 <ToggleControl 72 label={ __( 'Link block title to Groups directory', 'buddypress' ) } 73 checked={ !! linkTitle } 74 onChange={ () => { 75 setAttributes( { linkTitle: ! linkTitle } ); 76 } } 77 /> 78 </PanelBody> 79 </InspectorControls> 80 <Disabled> 81 <ServerSideRender block="bp/dynamic-groups" attributes={ attributes } /> 82 </Disabled> 83 </Fragment> 84 ); 85 }; 86 87 export default editDynamicGroupsBlock; -
new file src/js/bp-groups/js/blocks/dynamic-groups/transforms.js
diff --git src/js/bp-groups/js/blocks/dynamic-groups/transforms.js src/js/bp-groups/js/blocks/dynamic-groups/transforms.js new file mode 100644 index 000000000..b4ced716a
- + 1 /** 2 * WordPress dependencies. 3 */ 4 const { 5 blocks: { 6 createBlock, 7 }, 8 } = wp; 9 10 /** 11 * Transforms Legacy Widget to Dynamic Groups 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_groups_widget'; 26 }, 27 transform: ( { instance } ) => { 28 return createBlock( 'bp/dynamic-groups', { 29 title: instance.raw.title, 30 maxGroups: instance.raw.max_groups, 31 groupDefault: instance.raw.group_default, 32 linkTitle: instance.raw.link_title, 33 } ); 34 }, 35 }, 36 ], 37 }; 38 39 export default transforms; -
new file src/js/bp-groups/js/dynamic-groups.js
diff --git src/js/bp-groups/js/dynamic-groups.js src/js/bp-groups/js/dynamic-groups.js new file mode 100644 index 000000000..17a732113
- + 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 Groups Widget Block class. 20 * 21 * @since 9.0.0 22 */ 23 class bpGroupsWidgetBlock extends dynamicWidgetBlock { 24 loop( groups = [], container = '', type = 'active' ) { 25 const tmpl = super.useTemplate( 'bp-dynamic-groups-item' ); 26 const selector = document.querySelector( '#' + container ); 27 let output = ''; 28 29 if ( groups && groups.length ) { 30 groups.forEach( ( group ) => { 31 if ( 'newest' === type && group.created_since ) { 32 /* translators: %s is time elapsed since the group was created */ 33 group.extra = sprintf( __( 'Created %s', 'buddypress' ), group.created_since ); 34 } else if ( 'popular' === type && group.total_member_count ) { 35 const membersCount = parseInt( group.total_member_count, 10 ); 36 37 if ( 0 === membersCount ) { 38 group.extra = __( 'No members', 'buddypress' ); 39 } else if ( 1 === membersCount ) { 40 group.extra = __( '1 member', 'buddypress' ); 41 } else { 42 /* translators: %s is the number of Group members (more than 1). */ 43 group.extra = sprintf( __( '%s members', 'buddypress' ), group.total_member_count ); 44 } 45 } else { 46 /* translators: %s: a human time diff. */ 47 group.extra = sprintf( __( 'Active %s', 'buddypress' ), group.last_activity_diff ); 48 } 49 50 /* Translators: %s is the group's name. */ 51 group.avatar_alt = sprintf( __( 'Group Profile photo of %s', 'buddypress' ), group.name ); 52 53 output += tmpl( group ); 54 } ); 55 } else { 56 output = '<div class="widget-error">' + __( 'There are no groups to display.', '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 groups. 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.bpDynamicGroupsSettings || {}; 92 const blocks = window.bpDynamicGroupsBlocks || []; 93 const bpDynamicGroups = new bpGroupsWidgetBlock( settings, blocks ); 94 95 if ( 'loading' === document.readyState ) { 96 document.addEventListener( 'DOMContentLoaded', bpDynamicGroups.start() ); 97 } else { 98 bpDynamicGroups.start(); 99 }