Skip to:
Content

BuddyPress.org

Ticket #8527: 8527.patch

File 8527.patch, 31.8 KB (added by imath, 3 years ago)
  • Gruntfile.js

    diff --git Gruntfile.js Gruntfile.js
    index 663ac7963..e7a348f6d 100644
    module.exports = function( grunt ) { 
    5050                        '!bp-members/css/blocks/dynamic-members.css',
    5151                        '!bp-groups/css/blocks/dynamic-groups.css',
    5252                        '!bp-messages/css/blocks/sitewide-notices.css',
    53                         '!bp-blogs/css/blocks/recent-posts.css'
     53                        '!bp-blogs/css/blocks/recent-posts.css',
     54                        '!bp-members/css/blocks/active-members.css',
     55                        '!bp-members/css/blocks/online-members.css'
    5456                ],
    5557
    5658                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 467c51ff9..ae9cd93bf 100644
    function bp_members_render_dynamic_members_block( $attributes = array() ) { 
    555555
    556556        return $widget_content;
    557557}
     558
     559/**
     560 * Common function to render the Recently Active & Online Members Blocks.
     561 *
     562 * @since 9.0.0
     563 *
     564 * @param array $block_args {
     565 *    Optional. An array of Block arguments.
     566 *
     567 *    @type string $title      The title of the Block.
     568 *    @type int    $maxMembers The maximum number of members to show. Defaults to `0`.
     569 *    @type string $noMembers  The string to output when there are no members to show.
     570 *    @type string $classname  The name of the CSS class to use.
     571 *    @type string $type       The type of filter to perform. Possible values are `online`, `active`,
     572 *                             `newest`, `alphabetical`, `random` or `popular`.
     573 * }
     574 * @return string HTML output.
     575 */
     576function bp_members_render_members_avatars_block( $block_args = array() ) {
     577        $args = bp_parse_args(
     578                $block_args,
     579                array(
     580                        'title'      => '',
     581                        'maxMembers' => 0,
     582                        'noMembers'  => '',
     583                        'classname'  => '',
     584                        'type'       => 'active',
     585                ),
     586                ''
     587        );
     588
     589        $title              = $args['title'];
     590        $max_members        = (int) $args['maxMembers'];
     591        $no_members         = $args['noMembers'];
     592        $classname          = sanitize_key( $args['classname'] );
     593        $wrapper_attributes = get_block_wrapper_attributes(
     594                array(
     595                        'class' => sprintf( '%s buddypress widget', $classname ),
     596                )
     597        );
     598        $type               = sanitize_key( $args['type'] );
     599
     600        if ( $title ) {
     601                $widget_content = sprintf( '<h2 class="widget-title">%s</h2>', esc_html( $title ) );
     602        } else {
     603                $widget_content = '';
     604        }
     605
     606        // Query Users.
     607        $query = bp_core_get_users(
     608                array(
     609                        'user_id'         => 0,
     610                        'type'            => $type,
     611                        'per_page'        => $max_members,
     612                        'max'             => $max_members,
     613                        'populate_extras' => true,
     614                        'search_terms'    => false,
     615                )
     616        );
     617
     618        // Build the output for online members.
     619        if ( isset( $query['total'] ) && 1 <= (int) $query['total'] ) {
     620                $members        = $query['users'];
     621                $member_avatars = array();
     622
     623                foreach ( $members as $member ) {
     624                        $member_avatars[] = sprintf(
     625                                '<div class="item-avatar">
     626                                        <a href="%1$s" class="bp-tooltip" data-bp-tooltip="%2$s">
     627                                                <img loading="lazy" src="%3$s" class="avatar user-%4$s-avatar avatar-50 photo" width="50" height="50" alt="%5$s">
     628                                        </a>
     629                                </div>',
     630                                esc_url( bp_core_get_user_domain( $member->ID, $member->user_nicename, $member->user_login ) ),
     631                                esc_html( $member->display_name ),
     632                                bp_core_fetch_avatar(
     633                                        array(
     634                                                'item_id' => $member->ID,
     635                                                'html'    => false,
     636                                        )
     637                                ),
     638                                esc_attr( $member->ID ),
     639                                esc_html(
     640                                        sprintf(
     641                                                /* translators: %s: member name */
     642                                                __( 'Profile picture of %s', 'buddypress' ),
     643                                                $member->display_name
     644                                        )
     645                                )
     646                        );
     647                }
     648
     649                $widget_content .= sprintf(
     650                        '<div class="avatar-block">
     651                                %s
     652                        </div>',
     653                        implode( "\n", $member_avatars )
     654                );
     655        } else {
     656                $widget_content .= sprintf(
     657                        '<div class="widget-error">
     658                                %s
     659                        </div>',
     660                        esc_html( $no_members )
     661                );
     662        }
     663
     664        // Only add a block wrapper if not loaded into a Widgets sidebar.
     665        if ( ! did_action( 'dynamic_sidebar_before' ) ) {
     666                return sprintf(
     667                        '<div %1$s>%2$s</div>',
     668                        $wrapper_attributes,
     669                        $widget_content
     670                );
     671        }
     672
     673        return $widget_content;
     674}
     675
     676/**
     677 * Callback function to render the Online Members Block.
     678 *
     679 * @since 9.0.0
     680 *
     681 * @param array $attributes The block attributes.
     682 * @return string           HTML output.
     683 */
     684function bp_members_render_online_members_block( $attributes = array() ) {
     685        $block_args = bp_parse_args(
     686                $attributes,
     687                array(
     688                        'title'      => __( 'Who\'s Online', 'buddypress' ),
     689                        'maxMembers' => 15,
     690                        'noMembers'  => __( 'There are no users currently online', 'buddypress' ),
     691                        'classname'  => 'widget_bp_core_whos_online_widget',
     692                ),
     693                'members_widget_settings'
     694        );
     695
     696        $block_args['type'] = 'online';
     697
     698        return bp_members_render_members_avatars_block( $block_args );
     699}
     700
     701/**
     702 * Callback function to render the Recently Active Members Block.
     703 *
     704 * @since 9.0.0
     705 *
     706 * @param array $attributes The block attributes.
     707 * @return string           HTML output.
     708 */
     709function bp_members_render_active_members_block( $attributes = array() ) {
     710        $block_args = bp_parse_args(
     711                $attributes,
     712                array(
     713                        'title'      => __( 'Recently Active Members', 'buddypress' ),
     714                        'maxMembers' => 15,
     715                        'noMembers'  => __( 'There are no recently active members', 'buddypress' ),
     716                        'classname'  => 'widget_bp_core_recently_active_widget',
     717                ),
     718                'recently_active_members_widget_settings'
     719        );
     720
     721        $block_args['type'] = 'active';
     722
     723        return bp_members_render_members_avatars_block( $block_args );
     724}
  • 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 efa93300f..aa27c337b 100644
    class BP_Members_Component extends BP_Component { 
    200200                        'block_globals'         => array(
    201201                                'bp/dynamic-members' => array(
    202202                                        'widget_classnames' => array( 'widget_bp_core_members_widget', 'buddypress' ),
    203                                 )
     203                                ),
     204                                'bp/online-members' => array(
     205                                        'widget_classnames' => array( 'widget_bp_core_whos_online_widget', 'buddypress' ),
     206                                ),
     207                                'bp/active-members' => array(
     208                                        'widget_classnames' => array( 'widget_bp_core_recently_active_widget', 'buddypress' ),
     209                                ),
    204210                        ),
    205211                );
    206212
    class BP_Members_Component extends BP_Component { 
    862868                                        ),
    863869                                        'render_callback'    => 'bp_members_render_dynamic_members_block',
    864870                                ),
     871                                'bp/online-members'  => array(
     872                                        'name'               => 'bp/online-members',
     873                                        'editor_script'      => 'bp-online-members-block',
     874                                        'editor_script_url'  => plugins_url( 'js/blocks/online-members.js', dirname( __FILE__ ) ),
     875                                        'editor_script_deps' => array(
     876                                                'wp-blocks',
     877                                                'wp-element',
     878                                                'wp-components',
     879                                                'wp-i18n',
     880                                                'wp-block-editor',
     881                                                'bp-block-components',
     882                                        ),
     883                                        'editor_style'       => 'bp-online-members-block',
     884                                        'editor_style_url'   => plugins_url( 'css/blocks/online-members.css', dirname( __FILE__ ) ),
     885                                        'attributes'         => array(
     886                                                'title'      => array(
     887                                                        'type'    => 'string',
     888                                                        'default' => __( 'Who\'s Online', 'buddypress' ),
     889                                                ),
     890                                                'maxMembers' => array(
     891                                                        'type'    => 'number',
     892                                                        'default' => 15,
     893                                                ),
     894                                        ),
     895                                        'render_callback'    => 'bp_members_render_online_members_block',
     896                                ),
     897                                'bp/active-members'  => array(
     898                                        'name'               => 'bp/active-members',
     899                                        'editor_script'      => 'bp-active-members-block',
     900                                        'editor_script_url'  => plugins_url( 'js/blocks/active-members.js', dirname( __FILE__ ) ),
     901                                        'editor_script_deps' => array(
     902                                                'wp-blocks',
     903                                                'wp-element',
     904                                                'wp-components',
     905                                                'wp-i18n',
     906                                                'wp-block-editor',
     907                                                'bp-block-components',
     908                                        ),
     909                                        'editor_style'       => 'bp-active-members-block',
     910                                        'editor_style_url'   => plugins_url( 'css/blocks/active-members.css', dirname( __FILE__ ) ),
     911                                        'attributes'         => array(
     912                                                'title'      => array(
     913                                                        'type'    => 'string',
     914                                                        'default' => __( 'Recently Active Members', 'buddypress' ),
     915                                                ),
     916                                                'maxMembers' => array(
     917                                                        'type'    => 'number',
     918                                                        'default' => 15,
     919                                                ),
     920                                        ),
     921                                        'render_callback'    => 'bp_members_render_active_members_block',
     922                                ),
    865923                        )
    866924                );
    867925        }
  • new file src/bp-members/css/blocks/active-members.css

    diff --git src/bp-members/css/blocks/active-members.css src/bp-members/css/blocks/active-members.css
    new file mode 100644
    index 000000000..ccf5bf1b9
    - +  
     1[data-type="bp/active-members"] .avatar-block {
     2        display: flex;
     3        flex-flow: row wrap;
     4}
     5
     6[data-type="bp/active-members"] .avatar-block img {
     7        margin: 0.5em;
     8}
  • new file src/bp-members/css/blocks/online-members.css

    diff --git src/bp-members/css/blocks/online-members.css src/bp-members/css/blocks/online-members.css
    new file mode 100644
    index 000000000..44cc4783e
    - +  
     1[data-type="bp/online-members"] .avatar-block {
     2        display: flex;
     3        flex-flow: row wrap;
     4}
     5
     6[data-type="bp/online-members"] .avatar-block img {
     7        margin: 0.5em;
     8}
  • new file src/bp-members/js/blocks/active-members.js

    diff --git src/bp-members/js/blocks/active-members.js src/bp-members/js/blocks/active-members.js
    new file mode 100644
    index 000000000..1ff2415e1
    - +  
     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
     8parcelRequire = (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})({"TOWc":[function(require,module,exports) {
     121"use strict";
     122
     123Object.defineProperty(exports, "__esModule", {
     124  value: true
     125});
     126exports.default = void 0;
     127
     128/**
     129 * WordPress dependencies.
     130 */
     131var _wp = wp,
     132    InspectorControls = _wp.blockEditor.InspectorControls,
     133    _wp$components = _wp.components,
     134    Disabled = _wp$components.Disabled,
     135    PanelBody = _wp$components.PanelBody,
     136    RangeControl = _wp$components.RangeControl,
     137    TextControl = _wp$components.TextControl,
     138    _wp$element = _wp.element,
     139    Fragment = _wp$element.Fragment,
     140    createElement = _wp$element.createElement,
     141    __ = _wp.i18n.__;
     142/**
     143 * BuddyPress dependencies.
     144 */
     145
     146var _bp = bp,
     147    ServerSideRender = _bp.blockComponents.ServerSideRender;
     148
     149var editActiveMembersBlock = function editActiveMembersBlock(_ref) {
     150  var attributes = _ref.attributes,
     151      setAttributes = _ref.setAttributes;
     152  var title = attributes.title,
     153      maxMembers = attributes.maxMembers;
     154  return createElement(Fragment, null, createElement(InspectorControls, null, createElement(PanelBody, {
     155    title: __('Settings', 'buddypress'),
     156    initialOpen: true
     157  }, createElement(TextControl, {
     158    label: __('Title', 'buddypress'),
     159    value: title,
     160    onChange: function onChange(text) {
     161      setAttributes({
     162        title: text
     163      });
     164    }
     165  }), createElement(RangeControl, {
     166    label: __('Max members to show', 'buddypress'),
     167    value: maxMembers,
     168    onChange: function onChange(value) {
     169      return setAttributes({
     170        maxMembers: value
     171      });
     172    },
     173    min: 1,
     174    max: 15,
     175    required: true
     176  }))), createElement(Disabled, null, createElement(ServerSideRender, {
     177    block: "bp/active-members",
     178    attributes: attributes
     179  })));
     180};
     181
     182var _default = editActiveMembersBlock;
     183exports.default = _default;
     184},{}],"y7A5":[function(require,module,exports) {
     185"use strict";
     186
     187Object.defineProperty(exports, "__esModule", {
     188  value: true
     189});
     190exports.default = void 0;
     191
     192/**
     193 * WordPress dependencies.
     194 */
     195var _wp = wp,
     196    createBlock = _wp.blocks.createBlock;
     197/**
     198 * Transforms Legacy Widget to Active Members Block.
     199 *
     200 * @type {Object}
     201 */
     202
     203var transforms = {
     204  from: [{
     205    type: 'block',
     206    blocks: ['core/legacy-widget'],
     207    isMatch: function isMatch(_ref) {
     208      var idBase = _ref.idBase,
     209          instance = _ref.instance;
     210
     211      if (!(instance !== null && instance !== void 0 && instance.raw)) {
     212        return false;
     213      }
     214
     215      return idBase === 'bp_core_recently_active_widget';
     216    },
     217    transform: function transform(_ref2) {
     218      var instance = _ref2.instance;
     219      return createBlock('bp/active-members', {
     220        title: instance.raw.title,
     221        maxMembers: instance.raw.max_members
     222      });
     223    }
     224  }]
     225};
     226var _default = transforms;
     227exports.default = _default;
     228},{}],"dkrW":[function(require,module,exports) {
     229"use strict";
     230
     231var _edit = _interopRequireDefault(require("./active-members/edit"));
     232
     233var _transforms = _interopRequireDefault(require("./active-members/transforms"));
     234
     235function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
     236
     237/**
     238 * WordPress dependencies.
     239 */
     240var _wp = wp,
     241    registerBlockType = _wp.blocks.registerBlockType,
     242    __ = _wp.i18n.__;
     243/**
     244 * Internal dependencies.
     245 */
     246
     247registerBlockType('bp/active-members', {
     248  title: __('Recently Active Members', 'buddypress'),
     249  description: __('Profile photos of recently active members.', 'buddypress'),
     250  icon: {
     251    background: '#fff',
     252    foreground: '#d84800',
     253    src: 'groups'
     254  },
     255  category: 'buddypress',
     256  attributes: {
     257    title: {
     258      type: 'string',
     259      default: __('Recently Active Members', 'buddypress')
     260    },
     261    maxMembers: {
     262      type: 'number',
     263      default: 15
     264    }
     265  },
     266  edit: _edit.default,
     267  transforms: _transforms.default
     268});
     269},{"./active-members/edit":"TOWc","./active-members/transforms":"y7A5"}]},{},["dkrW"], null)
     270 No newline at end of file
  • new file src/bp-members/js/blocks/online-members.js

    diff --git src/bp-members/js/blocks/online-members.js src/bp-members/js/blocks/online-members.js
    new file mode 100644
    index 000000000..21fbf528f
    - +  
     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
     8parcelRequire = (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})({"l6vy":[function(require,module,exports) {
     121"use strict";
     122
     123Object.defineProperty(exports, "__esModule", {
     124  value: true
     125});
     126exports.default = void 0;
     127
     128/**
     129 * WordPress dependencies.
     130 */
     131var _wp = wp,
     132    InspectorControls = _wp.blockEditor.InspectorControls,
     133    _wp$components = _wp.components,
     134    Disabled = _wp$components.Disabled,
     135    PanelBody = _wp$components.PanelBody,
     136    RangeControl = _wp$components.RangeControl,
     137    TextControl = _wp$components.TextControl,
     138    _wp$element = _wp.element,
     139    Fragment = _wp$element.Fragment,
     140    createElement = _wp$element.createElement,
     141    __ = _wp.i18n.__;
     142/**
     143 * BuddyPress dependencies.
     144 */
     145
     146var _bp = bp,
     147    ServerSideRender = _bp.blockComponents.ServerSideRender;
     148
     149var editOnlineMembersBlock = function editOnlineMembersBlock(_ref) {
     150  var attributes = _ref.attributes,
     151      setAttributes = _ref.setAttributes;
     152  var title = attributes.title,
     153      maxMembers = attributes.maxMembers;
     154  return createElement(Fragment, null, createElement(InspectorControls, null, createElement(PanelBody, {
     155    title: __('Settings', 'buddypress'),
     156    initialOpen: true
     157  }, createElement(TextControl, {
     158    label: __('Title', 'buddypress'),
     159    value: title,
     160    onChange: function onChange(text) {
     161      setAttributes({
     162        title: text
     163      });
     164    }
     165  }), createElement(RangeControl, {
     166    label: __('Max members to show', 'buddypress'),
     167    value: maxMembers,
     168    onChange: function onChange(value) {
     169      return setAttributes({
     170        maxMembers: value
     171      });
     172    },
     173    min: 1,
     174    max: 15,
     175    required: true
     176  }))), createElement(Disabled, null, createElement(ServerSideRender, {
     177    block: "bp/online-members",
     178    attributes: attributes
     179  })));
     180};
     181
     182var _default = editOnlineMembersBlock;
     183exports.default = _default;
     184},{}],"VbKe":[function(require,module,exports) {
     185"use strict";
     186
     187Object.defineProperty(exports, "__esModule", {
     188  value: true
     189});
     190exports.default = void 0;
     191
     192/**
     193 * WordPress dependencies.
     194 */
     195var _wp = wp,
     196    createBlock = _wp.blocks.createBlock;
     197/**
     198 * Transforms Legacy Widget to Online Members Block.
     199 *
     200 * @type {Object}
     201 */
     202
     203var transforms = {
     204  from: [{
     205    type: 'block',
     206    blocks: ['core/legacy-widget'],
     207    isMatch: function isMatch(_ref) {
     208      var idBase = _ref.idBase,
     209          instance = _ref.instance;
     210
     211      if (!(instance !== null && instance !== void 0 && instance.raw)) {
     212        return false;
     213      }
     214
     215      return idBase === 'bp_core_whos_online_widget';
     216    },
     217    transform: function transform(_ref2) {
     218      var instance = _ref2.instance;
     219      return createBlock('bp/online-members', {
     220        title: instance.raw.title,
     221        maxMembers: instance.raw.max_members
     222      });
     223    }
     224  }]
     225};
     226var _default = transforms;
     227exports.default = _default;
     228},{}],"to6R":[function(require,module,exports) {
     229"use strict";
     230
     231var _edit = _interopRequireDefault(require("./online-members/edit"));
     232
     233var _transforms = _interopRequireDefault(require("./online-members/transforms"));
     234
     235function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
     236
     237/**
     238 * WordPress dependencies.
     239 */
     240var _wp = wp,
     241    registerBlockType = _wp.blocks.registerBlockType,
     242    __ = _wp.i18n.__;
     243/**
     244 * Internal dependencies.
     245 */
     246
     247registerBlockType('bp/online-members', {
     248  title: __('Online Members', 'buddypress'),
     249  description: __('Profile photos of online users.', 'buddypress'),
     250  icon: {
     251    background: '#fff',
     252    foreground: '#d84800',
     253    src: 'groups'
     254  },
     255  category: 'buddypress',
     256  attributes: {
     257    title: {
     258      type: 'string',
     259      default: __('Who\'s Online', 'buddypress')
     260    },
     261    maxMembers: {
     262      type: 'number',
     263      default: 15
     264    }
     265  },
     266  edit: _edit.default,
     267  transforms: _transforms.default
     268});
     269},{"./online-members/edit":"l6vy","./online-members/transforms":"VbKe"}]},{},["to6R"], null)
     270 No newline at end of file
  • new file src/bp-members/sass/blocks/active-members.scss

    diff --git src/bp-members/sass/blocks/active-members.scss src/bp-members/sass/blocks/active-members.scss
    new file mode 100644
    index 000000000..f8c031ba9
    - +  
     1// BP Who's online widget
     2[data-type="bp/active-members"] {
     3
     4        .avatar-block {
     5                display: flex;
     6                flex-flow: row wrap;
     7
     8                img {
     9                        margin: 0.5em;
     10                }
     11        }
     12}
  • new file src/bp-members/sass/blocks/online-members.scss

    diff --git src/bp-members/sass/blocks/online-members.scss src/bp-members/sass/blocks/online-members.scss
    new file mode 100644
    index 000000000..913b90c16
    - +  
     1// BP Who's online widget
     2[data-type="bp/online-members"] {
     3
     4        .avatar-block {
     5                display: flex;
     6                flex-flow: row wrap;
     7
     8                img {
     9                        margin: 0.5em;
     10                }
     11        }
     12}
  • new file src/js/bp-members/js/blocks/active-members.js

    diff --git src/js/bp-members/js/blocks/active-members.js src/js/bp-members/js/blocks/active-members.js
    new file mode 100644
    index 000000000..ca63e845a
    - +  
     1/**
     2 * WordPress dependencies.
     3 */
     4const {
     5        blocks: {
     6                registerBlockType,
     7        },
     8        i18n: {
     9                __,
     10        },
     11} = wp;
     12
     13/**
     14 * Internal dependencies.
     15 */
     16import editActiveMembersBlock from './active-members/edit';
     17import transforms from './active-members/transforms';
     18
     19registerBlockType( 'bp/active-members', {
     20        title: __( 'Recently Active Members', 'buddypress' ),
     21        description: __( 'Profile photos of recently active 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: __( 'Recently Active Members', 'buddypress' ),
     32                },
     33                maxMembers: {
     34                        type: 'number',
     35                        default: 15
     36                },
     37        },
     38        edit: editActiveMembersBlock,
     39        transforms: transforms,
     40} );
  • new file src/js/bp-members/js/blocks/active-members/edit.js

    diff --git src/js/bp-members/js/blocks/active-members/edit.js src/js/bp-members/js/blocks/active-members/edit.js
    new file mode 100644
    index 000000000..8b3722b22
    - +  
     1/**
     2 * WordPress dependencies.
     3 */
     4const {
     5        blockEditor: {
     6                InspectorControls,
     7        },
     8        components: {
     9                Disabled,
     10                PanelBody,
     11                RangeControl,
     12                TextControl,
     13        },
     14        element: {
     15                Fragment,
     16                createElement,
     17        },
     18        i18n: {
     19                __,
     20        },
     21} = wp;
     22
     23/**
     24 * BuddyPress dependencies.
     25 */
     26const {
     27        blockComponents: {
     28                ServerSideRender,
     29        },
     30} = bp;
     31
     32const editActiveMembersBlock = ( { attributes, setAttributes } ) => {
     33        const { title, maxMembers } = attributes;
     34
     35        return (
     36                <Fragment>
     37                        <InspectorControls>
     38                                <PanelBody title={ __( 'Settings', 'buddypress' ) } initialOpen={ true }>
     39                                        <TextControl
     40                                                label={ __( 'Title', 'buddypress' ) }
     41                                                value={ title }
     42                                                onChange={ ( text ) => {
     43                                                        setAttributes( { title: text } );
     44                                                } }
     45                                        />
     46                                        <RangeControl
     47                                                label={ __( 'Max members to show', 'buddypress' ) }
     48                                                value={ maxMembers }
     49                                                onChange={ ( value ) =>
     50                                                        setAttributes( { maxMembers: value } )
     51                                                }
     52                                                min={ 1 }
     53                                                max={ 15 }
     54                                                required
     55                                        />
     56                                </PanelBody>
     57                        </InspectorControls>
     58                        <Disabled>
     59                                <ServerSideRender block="bp/active-members" attributes={ attributes } />
     60                        </Disabled>
     61                </Fragment>
     62        );
     63};
     64
     65export default editActiveMembersBlock;
  • new file src/js/bp-members/js/blocks/active-members/transforms.js

    diff --git src/js/bp-members/js/blocks/active-members/transforms.js src/js/bp-members/js/blocks/active-members/transforms.js
    new file mode 100644
    index 000000000..575c6b989
    - +  
     1/**
     2 * WordPress dependencies.
     3 */
     4const {
     5        blocks: {
     6                createBlock,
     7        },
     8} = wp;
     9
     10/**
     11 * Transforms Legacy Widget to Active Members Block.
     12 *
     13 * @type {Object}
     14 */
     15const 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_recently_active_widget';
     26                        },
     27                        transform: ( { instance } ) => {
     28                                return createBlock( 'bp/active-members', {
     29                                        title: instance.raw.title,
     30                                        maxMembers: instance.raw.max_members,
     31                                } );
     32                        },
     33                },
     34        ],
     35};
     36
     37export default transforms;
  • new file src/js/bp-members/js/blocks/online-members.js

    diff --git src/js/bp-members/js/blocks/online-members.js src/js/bp-members/js/blocks/online-members.js
    new file mode 100644
    index 000000000..653f39c1f
    - +  
     1/**
     2 * WordPress dependencies.
     3 */
     4const {
     5        blocks: {
     6                registerBlockType,
     7        },
     8        i18n: {
     9                __,
     10        },
     11} = wp;
     12
     13/**
     14 * Internal dependencies.
     15 */
     16import editOnlineMembersBlock from './online-members/edit';
     17import transforms from './online-members/transforms';
     18
     19registerBlockType( 'bp/online-members', {
     20        title: __( 'Online Members', 'buddypress' ),
     21        description: __( 'Profile photos of online users.', '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: __( 'Who\'s Online', 'buddypress' ),
     32                },
     33                maxMembers: {
     34                        type: 'number',
     35                        default: 15
     36                },
     37        },
     38        edit: editOnlineMembersBlock,
     39        transforms: transforms,
     40} );
  • new file src/js/bp-members/js/blocks/online-members/edit.js

    diff --git src/js/bp-members/js/blocks/online-members/edit.js src/js/bp-members/js/blocks/online-members/edit.js
    new file mode 100644
    index 000000000..d2157a33f
    - +  
     1/**
     2 * WordPress dependencies.
     3 */
     4const {
     5        blockEditor: {
     6                InspectorControls,
     7        },
     8        components: {
     9                Disabled,
     10                PanelBody,
     11                RangeControl,
     12                TextControl,
     13        },
     14        element: {
     15                Fragment,
     16                createElement,
     17        },
     18        i18n: {
     19                __,
     20        },
     21} = wp;
     22
     23/**
     24 * BuddyPress dependencies.
     25 */
     26const {
     27        blockComponents: {
     28                ServerSideRender,
     29        },
     30} = bp;
     31
     32const editOnlineMembersBlock = ( { attributes, setAttributes } ) => {
     33        const { title, maxMembers } = attributes;
     34
     35        return (
     36                <Fragment>
     37                        <InspectorControls>
     38                                <PanelBody title={ __( 'Settings', 'buddypress' ) } initialOpen={ true }>
     39                                        <TextControl
     40                                                label={ __( 'Title', 'buddypress' ) }
     41                                                value={ title }
     42                                                onChange={ ( text ) => {
     43                                                        setAttributes( { title: text } );
     44                                                } }
     45                                        />
     46                                        <RangeControl
     47                                                label={ __( 'Max members to show', 'buddypress' ) }
     48                                                value={ maxMembers }
     49                                                onChange={ ( value ) =>
     50                                                        setAttributes( { maxMembers: value } )
     51                                                }
     52                                                min={ 1 }
     53                                                max={ 15 }
     54                                                required
     55                                        />
     56                                </PanelBody>
     57                        </InspectorControls>
     58                        <Disabled>
     59                                <ServerSideRender block="bp/online-members" attributes={ attributes } />
     60                        </Disabled>
     61                </Fragment>
     62        );
     63};
     64
     65export default editOnlineMembersBlock;
  • new file src/js/bp-members/js/blocks/online-members/transforms.js

    diff --git src/js/bp-members/js/blocks/online-members/transforms.js src/js/bp-members/js/blocks/online-members/transforms.js
    new file mode 100644
    index 000000000..13d9fc1f2
    - +  
     1/**
     2 * WordPress dependencies.
     3 */
     4const {
     5        blocks: {
     6                createBlock,
     7        },
     8} = wp;
     9
     10/**
     11 * Transforms Legacy Widget to Online Members Block.
     12 *
     13 * @type {Object}
     14 */
     15const 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_whos_online_widget';
     26                        },
     27                        transform: ( { instance } ) => {
     28                                return createBlock( 'bp/online-members', {
     29                                        title: instance.raw.title,
     30                                        maxMembers: instance.raw.max_members,
     31                                } );
     32                        },
     33                },
     34        ],
     35};
     36
     37export default transforms;