Skip to:
Content

BuddyPress.org

Ticket #8519: 8519.patch

File 8519.patch, 28.4 KB (added by imath, 4 years ago)
  • Gruntfile.js

    diff --git Gruntfile.js Gruntfile.js
    index 16635088d..bb010cd0c 100644
    module.exports = function( grunt ) { 
    3939                        '!bp-groups/css/blocks/group.css',
    4040                        '!bp-members/css/blocks/members.css',
    4141                        '!bp-groups/css/blocks/groups.css',
    42                         '!bp-core/css/blocks/login-form.css'
     42                        '!bp-core/css/blocks/login-form.css',
     43                        '!bp-activity/css/blocks/latest-activities.css'
    4344                ],
    4445
    4546                autoprefixer = require('autoprefixer');
    module.exports = function( grunt ) { 
    158159                                flatten: true,
    159160                                src: ['bp-core/sass/blocks/*.scss'],
    160161                                dest: SOURCE_DIR + 'bp-core/css/blocks/'
     162                        },
     163                        activity_blocks: {
     164                                cwd: SOURCE_DIR,
     165                                extDot: 'last',
     166                                expand: true,
     167                                ext: '.css',
     168                                flatten: true,
     169                                src: ['bp-activity/sass/blocks/*.scss'],
     170                                dest: SOURCE_DIR + 'bp-activity/css/blocks/'
    161171                        }
    162172                },
    163173                rtlcss: {
  • src/bp-activity/bp-activity-blocks.php

    diff --git src/bp-activity/bp-activity-blocks.php src/bp-activity/bp-activity-blocks.php
    index 116badd6a..fcaf9d4c1 100644
     
    1111if ( ! defined( 'ABSPATH' ) ) {
    1212        exit;
    1313}
     14
     15/**
     16 * Callback function to render the Latest Activities Block.
     17 *
     18 * @since 9.0.0
     19 *
     20 * @param array $attributes The block attributes.
     21 * @return string           HTML output.
     22 */
     23function bp_activity_render_latest_activities_block( $attributes = array() ) {
     24        $block_args = wp_parse_args(
     25                $attributes,
     26                array(
     27                        'title'         => __( 'Latest updates', 'buddypress' ),
     28                        'maxActivities' => 5,
     29                        'type'          => array( 'activity_update' ),
     30                        'postId'        => 0,
     31                )
     32        );
     33
     34        $max_activities = (int) $block_args['maxActivities'];
     35
     36        // Should we get a specific member's activities?
     37        $member_id = 0;
     38        if ( $block_args['postId'] ) {
     39                $member_id = (int) get_post_field( 'post_author', $block_args['postId'] );
     40        } else {
     41                $member_id = bp_displayed_user_id();
     42        }
     43
     44        // Set the widget's wrapper attributes.
     45        $types              = (array) $block_args['type'];
     46        $classnames         = array_map( 'sanitize_html_class', array_merge( $types, array( 'bp-latest-activities', 'buddypress', 'widget' ) ) );
     47        $wrapper_attributes = get_block_wrapper_attributes( array( 'class' => implode( ' ', $classnames ) ) );
     48
     49        // Set the Block's title.
     50        $widget_content = sprintf( '<h2 class="widget-title">%s</h2>', esc_html( $block_args['title'] ) );
     51
     52        // Avoid conflicts with other activity loops.
     53        $reset_activities_template = null;
     54        if ( ! empty( $GLOBALS['activities_template'] ) ) {
     55                $reset_activities_template = $GLOBALS['activities_template'];
     56        }
     57
     58        $widget_args = array(
     59                'max'          => $max_activities,
     60                'scope'        => 'all',
     61                'user_id'      => $member_id,
     62                'object'       => false,
     63                'action'       => implode( ',', $types ),
     64                'primary_id'   => 0,
     65                'secondary_id' => 0,
     66        );
     67
     68        // Build the activity loop.
     69        if ( 'nouveau' === bp_get_theme_compat_id() ) {
     70                $bp_nouveau = bp_nouveau();
     71
     72                // Globalize the activity widget arguments.
     73                $bp_nouveau->activity->widget_args = $widget_args;
     74
     75                ob_start();
     76                bp_get_template_part( 'activity/widget' );
     77                $widget_content .= ob_get_clean();
     78
     79                // Reset the global.
     80                $bp_nouveau->activity->widget_args = array();
     81        } else {
     82                $activity_loop = sprintf( '<div class="widget-error"><p>%s</p></div>', esc_html__( 'Sorry, there was no activity found. Please try a different filter.', 'buddypress' ) );
     83
     84                if ( bp_has_activities( $widget_args ) ) {
     85                        $activity_loop = '';
     86
     87                        while ( bp_activities() ) {
     88                                bp_the_activity();
     89
     90                                $activity_footer  = '';
     91                                $activity_classes = 'activity-item';
     92                                if ( bp_activity_has_content() ) {
     93                                        $activity_content = bp_get_activity_content_body();
     94                                        $activity_footer  = sprintf(
     95                                                '<footer>
     96                                                        <cite>
     97                                                                <a href="%1$s" class="bp-tooltip" data-bp-tooltip="%2$s">
     98                                                                        %3$s
     99                                                                </a>
     100                                                        </cite>
     101                                                        %4$s
     102                                                </footer>',
     103                                                bp_get_activity_user_link(),
     104                                                bp_get_activity_member_display_name(),
     105                                                bp_get_activity_avatar(
     106                                                        array(
     107                                                                'type'   => 'thumb',
     108                                                                'width'  => '40',
     109                                                                'height' => '40',
     110                                                        )
     111                                                ),
     112                                                bp_insert_activity_meta()
     113                                        );
     114                                } else {
     115                                        $activity_classes .= ' mini';
     116                                        $activity_content  = bp_get_activity_action();
     117                                }
     118
     119                                $activity_loop .= sprintf(
     120                                        '<blockquote>
     121                                                <div class="%1$s">%2$s</div>
     122                                                %3$s
     123                                        </blockquote>',
     124                                        $activity_classes,
     125                                        $activity_content,
     126                                        $activity_footer
     127                                );
     128                        }
     129                }
     130
     131                $widget_content .= sprintf(
     132                        '<div class="activity-list item-list">
     133                                %1$s
     134                        </div>',
     135                        $activity_loop
     136                );
     137        }
     138
     139        // Adds a container to make sure the block is styled even when used into the Columns parent block.
     140        $widget_content = sprintf( '<div class="bp-latest-activities-block">%s</div>', "\n" . $widget_content . "\n" );
     141
     142        // Reset the global template loop.
     143        $GLOBALS['activities_template'] = $reset_activities_template;
     144
     145        // Only add a block wrapper if not loaded into a Widgets sidebar.
     146        if ( ! did_action( 'dynamic_sidebar_before' ) ) {
     147                return sprintf(
     148                        '<div %1$s>%2$s</div>',
     149                        $wrapper_attributes,
     150                        $widget_content
     151                );
     152        }
     153
     154        return $widget_content;
     155}
  • src/bp-activity/classes/class-bp-activity-component.php

    diff --git src/bp-activity/classes/class-bp-activity-component.php src/bp-activity/classes/class-bp-activity-component.php
    index 398550378..d54966b49 100644
    class BP_Activity_Component extends BP_Component { 
    207207                        'search_string'         => __( 'Search Activity...', 'buddypress' ),
    208208                        'global_tables'         => $global_tables,
    209209                        'meta_tables'           => $meta_tables,
     210                        'block_globals'         => array(
     211                                'bp/latest-activities' => array(
     212                                        'widget_classnames' => array( 'wp-block-bp-latest-activities', 'buddypress' ),
     213                                )
     214                        ),
    210215                );
    211216
    212217                parent::setup_globals( $args );
    class BP_Activity_Component extends BP_Component { 
    483488         *                      description.
    484489         */
    485490        public function blocks_init( $blocks = array() ) {
    486                 parent::blocks_init(
    487                         array(
    488                                 'bp/embed-activity' => array(
    489                                         'name'               => 'bp/embed-activity',
    490                                         'editor_script'      => 'bp-embed-activity-block',
    491                                         'editor_script_url'  => plugins_url( 'js/blocks/embed-activity.js', dirname(  __FILE__ ) ),
    492                                         'editor_script_deps' => array(
    493                                                 'wp-blocks',
    494                                                 'wp-element',
    495                                                 'wp-i18n',
    496                                                 'wp-components',
    497                                                 'wp-block-editor',
    498                                                 'wp-data',
    499                                                 'wp-compose',
    500                                                 'bp-block-data',
     491                $blocks = array(
     492                        'bp/latest-activities' => array(
     493                                'name'               => 'bp/latest-activities',
     494                                'editor_script'      => 'bp-latest-activities-block',
     495                                'editor_script_url'  => plugins_url( 'js/blocks/latest-activities.js', dirname(  __FILE__ ) ),
     496                                'editor_script_deps' => array(
     497                                        'wp-blocks',
     498                                        'wp-element',
     499                                        'wp-components',
     500                                        'wp-i18n',
     501                                        'wp-block-editor',
     502                                        'bp-block-data',
     503                                        'bp-block-components',
     504                                ),
     505                                'style'              => 'bp-latest-activities-block',
     506                                'style_url'          => plugins_url( 'css/blocks/latest-activities.css', dirname(  __FILE__ ) ),
     507                                'attributes'         => array(
     508                                        'title'         => array(
     509                                                'type'    => 'string',
     510                                                'default' => __( 'Latest updates', 'buddypress' ),
     511                                        ),
     512                                        'maxActivities' => array(
     513                                                'type'    => 'number',
     514                                                'default' => 5,
     515                                        ),
     516                                        'type'          => array(
     517                                                'type'    => 'array',
     518                                                'default' => array( 'activity_update' ),
     519                                        ),
     520                                        'postId'        => array(
     521                                                'type'    => 'number',
     522                                                'default' => 0,
    501523                                        ),
    502524                                ),
    503                         )
     525                                'render_callback'    => 'bp_activity_render_latest_activities_block',
     526                        ),
    504527                );
     528
     529                if ( bp_is_active( $this->id, 'embeds' ) ) {
     530                        $blocks['bp/embed-activity'] = array(
     531                                'name'               => 'bp/embed-activity',
     532                                'editor_script'      => 'bp-embed-activity-block',
     533                                'editor_script_url'  => plugins_url( 'js/blocks/embed-activity.js', dirname(  __FILE__ ) ),
     534                                'editor_script_deps' => array(
     535                                        'wp-blocks',
     536                                        'wp-element',
     537                                        'wp-i18n',
     538                                        'wp-components',
     539                                        'wp-block-editor',
     540                                        'wp-data',
     541                                        'wp-compose',
     542                                        'bp-block-data',
     543                                ),
     544                        );
     545                }
     546
     547                parent::blocks_init( $blocks );
    505548        }
    506549}
  • new file src/bp-activity/css/blocks/latest-activities-rtl.css

    diff --git src/bp-activity/css/blocks/latest-activities-rtl.css src/bp-activity/css/blocks/latest-activities-rtl.css
    new file mode 100644
    index 000000000..7eaa9c840
    - +  
     1.bp-latest-activities .components-flex.components-select-control select[multiple] {
     2        height: auto;
     3        padding: 0 8px;
     4}
     5
     6.bp-latest-activities .components-flex.components-select-control select[multiple] + .components-input-control__suffix svg {
     7        display: none;
     8}
     9
     10.bp-latest-activities-block a,
     11.entry .entry-content .bp-latest-activities-block a {
     12        border: none;
     13        text-decoration: none;
     14}
     15
     16.bp-latest-activities-block .activity-list.item-list blockquote {
     17        padding: 0;
     18        border: none;
     19}
     20
     21.bp-latest-activities-block .activity-list.item-list blockquote .activity-item:not(.mini) {
     22        position: relative;
     23        box-shadow: -1px 0 4px rgba(0, 0, 0, 0.15);
     24        padding: 0 1em;
     25}
     26
     27.bp-latest-activities-block .activity-list.item-list blockquote .activity-item:not(.mini):after, .bp-latest-activities-block .activity-list.item-list blockquote .activity-item:not(.mini):before {
     28        position: absolute;
     29        right: 15px;
     30        display: block;
     31        width: 0;
     32        height: 0;
     33        border-style: solid;
     34        border-color: transparent;
     35        content: "";
     36}
     37
     38.bp-latest-activities-block .activity-list.item-list blockquote .activity-item:not(.mini):before {
     39        bottom: -18px;
     40        border-top-color: rgba(0, 0, 0, 0.15);
     41        border-width: 9px;
     42        right: 14px;
     43}
     44
     45.bp-latest-activities-block .activity-list.item-list blockquote .activity-item:not(.mini):after {
     46        bottom: -16px;
     47        border-top-color: #fff;
     48        border-width: 8px;
     49}
     50
     51.bp-latest-activities-block .activity-list.item-list blockquote .activity-item.mini .avatar {
     52        display: inline-block;
     53        width: 20px;
     54        height: 20px;
     55        vertical-align: middle;
     56        margin-left: 2px;
     57}
     58
     59.bp-latest-activities-block .activity-list.item-list footer {
     60        display: flex;
     61        align-items: center;
     62}
     63
     64.bp-latest-activities-block .activity-list.item-list footer img.avatar {
     65        display: inline-block;
     66        border: none;
     67        margin-left: 0.5em;
     68}
     69
     70.bp-latest-activities-block .activity-list.item-list footer .activity-time-since {
     71        font-size: 90%;
     72}
     73
     74.bp-latest-activities-block .widget-error {
     75        border-right: solid 4px #0b80a4;
     76        box-shadow: -1px 0 4px rgba(0, 0, 0, 0.15);
     77}
     78
     79.bp-latest-activities-block .widget-error p {
     80        padding: 0 1em;
     81}
  • new file src/bp-activity/css/blocks/latest-activities.css

    diff --git src/bp-activity/css/blocks/latest-activities.css src/bp-activity/css/blocks/latest-activities.css
    new file mode 100644
    index 000000000..63759731c
    - +  
     1.bp-latest-activities .components-flex.components-select-control select[multiple] {
     2        height: auto;
     3        padding: 0 8px;
     4}
     5
     6.bp-latest-activities .components-flex.components-select-control select[multiple] + .components-input-control__suffix svg {
     7        display: none;
     8}
     9
     10.bp-latest-activities-block a,
     11.entry .entry-content .bp-latest-activities-block a {
     12        border: none;
     13        text-decoration: none;
     14}
     15
     16.bp-latest-activities-block .activity-list.item-list blockquote {
     17        padding: 0;
     18        border: none;
     19}
     20
     21.bp-latest-activities-block .activity-list.item-list blockquote .activity-item:not(.mini) {
     22        position: relative;
     23        box-shadow: 1px 0 4px rgba(0, 0, 0, 0.15);
     24        padding: 0 1em;
     25}
     26
     27.bp-latest-activities-block .activity-list.item-list blockquote .activity-item:not(.mini):after, .bp-latest-activities-block .activity-list.item-list blockquote .activity-item:not(.mini):before {
     28        position: absolute;
     29        left: 15px;
     30        display: block;
     31        width: 0;
     32        height: 0;
     33        border-style: solid;
     34        border-color: transparent;
     35        content: "";
     36}
     37
     38.bp-latest-activities-block .activity-list.item-list blockquote .activity-item:not(.mini):before {
     39        bottom: -18px;
     40        border-top-color: rgba(0, 0, 0, 0.15);
     41        border-width: 9px;
     42        left: 14px;
     43}
     44
     45.bp-latest-activities-block .activity-list.item-list blockquote .activity-item:not(.mini):after {
     46        bottom: -16px;
     47        border-top-color: #fff;
     48        border-width: 8px;
     49}
     50
     51.bp-latest-activities-block .activity-list.item-list blockquote .activity-item.mini .avatar {
     52        display: inline-block;
     53        width: 20px;
     54        height: 20px;
     55        vertical-align: middle;
     56        margin-right: 2px;
     57}
     58
     59.bp-latest-activities-block .activity-list.item-list footer {
     60        display: flex;
     61        align-items: center;
     62}
     63
     64.bp-latest-activities-block .activity-list.item-list footer img.avatar {
     65        display: inline-block;
     66        border: none;
     67        margin-right: 0.5em;
     68}
     69
     70.bp-latest-activities-block .activity-list.item-list footer .activity-time-since {
     71        font-size: 90%;
     72}
     73
     74.bp-latest-activities-block .widget-error {
     75        border-left: solid 4px #0b80a4;
     76        box-shadow: 1px 0 4px rgba(0, 0, 0, 0.15);
     77}
     78
     79.bp-latest-activities-block .widget-error p {
     80        padding: 0 1em;
     81}
  • new file src/bp-activity/js/blocks/latest-activities.js

    diff --git src/bp-activity/js/blocks/latest-activities.js src/bp-activity/js/blocks/latest-activities.js
    new file mode 100644
    index 000000000..614751c24
    - +  
     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})({"DIzr":[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    SelectControl = _wp$components.SelectControl,
     138    TextControl = _wp$components.TextControl,
     139    _wp$element = _wp.element,
     140    Fragment = _wp$element.Fragment,
     141    createElement = _wp$element.createElement,
     142    __ = _wp.i18n.__;
     143/**
     144 * BuddyPress dependencies.
     145 */
     146
     147var _bp = bp,
     148    ServerSideRender = _bp.blockComponents.ServerSideRender,
     149    _bp$blockData = _bp.blockData,
     150    currentPostId = _bp$blockData.currentPostId,
     151    activityTypes = _bp$blockData.activityTypes;
     152
     153var editDynamicActivitiesBlock = function editDynamicActivitiesBlock(_ref) {
     154  var attributes = _ref.attributes,
     155      setAttributes = _ref.setAttributes;
     156  var postId = attributes.postId,
     157      maxActivities = attributes.maxActivities,
     158      type = attributes.type,
     159      title = attributes.title;
     160  var post = currentPostId();
     161  var types = activityTypes();
     162
     163  if (!postId && post) {
     164    setAttributes({
     165      postId: post
     166    });
     167  }
     168
     169  return createElement(Fragment, null, createElement(InspectorControls, null, createElement(PanelBody, {
     170    title: __('Settings', 'buddypress'),
     171    initialOpen: true,
     172    className: "bp-latest-activities"
     173  }, createElement(TextControl, {
     174    label: __('Title', 'buddypress'),
     175    value: title,
     176    onChange: function onChange(text) {
     177      setAttributes({
     178        title: text
     179      });
     180    }
     181  }), createElement(RangeControl, {
     182    label: __('Maximum amount to display', 'buddypress'),
     183    value: maxActivities,
     184    onChange: function onChange(value) {
     185      return setAttributes({
     186        maxActivities: value
     187      });
     188    },
     189    min: 1,
     190    max: 10,
     191    required: true
     192  }), createElement(SelectControl, {
     193    multiple: true,
     194    label: __('Type', 'buddypress'),
     195    value: type,
     196    options: types,
     197    onChange: function onChange(option) {
     198      setAttributes({
     199        type: option
     200      });
     201    }
     202  }))), createElement(Disabled, null, createElement(ServerSideRender, {
     203    block: "bp/latest-activities",
     204    attributes: attributes
     205  })));
     206};
     207
     208var _default = editDynamicActivitiesBlock;
     209exports.default = _default;
     210},{}],"yqpU":[function(require,module,exports) {
     211"use strict";
     212
     213Object.defineProperty(exports, "__esModule", {
     214  value: true
     215});
     216exports.default = void 0;
     217
     218/**
     219 * WordPress dependencies.
     220 */
     221var _wp = wp,
     222    createBlock = _wp.blocks.createBlock;
     223/**
     224 * Transforms Nouveau Activity Widget to Activity Block.
     225 *
     226 * @type {Object}
     227 */
     228
     229var transforms = {
     230  from: [{
     231    type: 'block',
     232    blocks: ['core/legacy-widget'],
     233    isMatch: function isMatch(_ref) {
     234      var idBase = _ref.idBase,
     235          instance = _ref.instance;
     236
     237      if (!(instance !== null && instance !== void 0 && instance.raw)) {
     238        return false;
     239      }
     240
     241      return idBase === 'bp_latest_activities';
     242    },
     243    transform: function transform(_ref2) {
     244      var instance = _ref2.instance;
     245      var regex = /i:\d*;s:\d*:"(.*?)";/gmi;
     246      var types = [];
     247      var matches;
     248
     249      while ((matches = regex.exec(instance.raw.type)) !== null) {
     250        if (matches.index === regex.lastIndex) {
     251          regex.lastIndex++;
     252        }
     253
     254        matches.forEach(function (match, groupIndex) {
     255          if (1 === groupIndex) {
     256            types.push(match);
     257          }
     258        });
     259      }
     260
     261      return createBlock('bp/latest-activities', {
     262        title: instance.raw.title,
     263        maxActivities: parseInt(instance.raw.max, 10),
     264        type: types
     265      });
     266    }
     267  }]
     268};
     269var _default = transforms;
     270exports.default = _default;
     271},{}],"q3eE":[function(require,module,exports) {
     272"use strict";
     273
     274var _edit = _interopRequireDefault(require("./latest-activities/edit"));
     275
     276var _transforms = _interopRequireDefault(require("./latest-activities/transforms"));
     277
     278function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
     279
     280/**
     281 * WordPress dependencies.
     282 */
     283var _wp = wp,
     284    registerBlockType = _wp.blocks.registerBlockType,
     285    __ = _wp.i18n.__;
     286/**
     287 * Internal dependencies.
     288 */
     289
     290registerBlockType('bp/latest-activities', {
     291  title: __('Latest Activities', 'buddypress'),
     292  description: __('Display the latest updates of the post author (when used into a page or post), of the displayed user (when viewing their profile) or of your community.', 'buddypress'),
     293  icon: {
     294    background: '#fff',
     295    foreground: '#d84800',
     296    src: 'buddicons-activity'
     297  },
     298  category: 'buddypress',
     299  attributes: {
     300    title: {
     301      type: 'string',
     302      default: __('Latest updates', 'buddypress')
     303    },
     304    maxActivities: {
     305      type: 'number',
     306      default: 5
     307    },
     308    type: {
     309      type: 'array',
     310      default: ['activity_update']
     311    },
     312    postId: {
     313      type: 'number',
     314      default: 0
     315    }
     316  },
     317  edit: _edit.default,
     318  transforms: _transforms.default
     319});
     320},{"./latest-activities/edit":"DIzr","./latest-activities/transforms":"yqpU"}]},{},["q3eE"], null)
     321 No newline at end of file
  • new file src/bp-activity/sass/blocks/latest-activities.scss

    diff --git src/bp-activity/sass/blocks/latest-activities.scss src/bp-activity/sass/blocks/latest-activities.scss
    new file mode 100644
    index 000000000..345258ee6
    - +  
     1.bp-latest-activities {
     2
     3        .components-flex.components-select-control {
     4
     5                select[multiple] {
     6                        height: auto;
     7                        padding: 0 8px;
     8
     9                        + .components-input-control__suffix svg {
     10                                display: none;
     11                        }
     12                }
     13        }
     14}
     15
     16.bp-latest-activities-block {
     17
     18        a,
     19        .entry .entry-content & a {
     20                border: none;
     21                text-decoration: none;
     22        }
     23
     24        .activity-list.item-list {
     25
     26                blockquote {
     27                        padding: 0;
     28                        border: none;
     29
     30                        .activity-item {
     31
     32                                &:not(.mini) {
     33                                        position: relative;
     34                                        box-shadow: 1px 0 4px rgba(0, 0, 0, 0.15);
     35                                        padding: 0 1em;
     36
     37                                        &:after,
     38                                        &:before {
     39                                                position: absolute;
     40                                                left: 15px;
     41                                                display: block;
     42                                                width: 0;
     43                                                height: 0;
     44                                                border-style: solid;
     45                                                border-color: transparent;
     46                                                content: "";
     47                                        }
     48
     49                                        &:before {
     50                                                bottom: -18px;
     51                                                border-top-color: rgba(0, 0, 0, 0.15);
     52                                                border-width: 9px;
     53                                                left: 14px;
     54                                        }
     55
     56                                        &:after {
     57                                                bottom: -16px;
     58                                                border-top-color: #fff;
     59                                                border-width: 8px;
     60                                        }
     61                                }
     62
     63                                &.mini {
     64
     65                                        .avatar {
     66                                                display: inline-block;
     67                                                width: 20px;
     68                                                height: 20px;
     69                                                vertical-align: middle;
     70                                                margin-right: 2px;
     71                                        }
     72                                }
     73                        }
     74                }
     75
     76                footer {
     77                        display: flex;
     78                        align-items: center;
     79
     80                        img.avatar {
     81                                display: inline-block;
     82                                border: none;
     83                                margin-right: 0.5em;
     84                        }
     85
     86                        .activity-time-since {
     87                                font-size: 90%;
     88                        }
     89                }
     90        }
     91
     92        .widget-error {
     93                border-left: solid 4px #0b80a4;
     94                box-shadow: 1px 0 4px rgba(0, 0, 0, 0.15);
     95
     96                p {
     97                        padding: 0 1em;
     98                }
     99        }
     100}
  • new file src/js/bp-activity/js/blocks/latest-activities.js

    diff --git src/js/bp-activity/js/blocks/latest-activities.js src/js/bp-activity/js/blocks/latest-activities.js
    new file mode 100644
    index 000000000..11c440455
    - +  
     1/**
     2 * WordPress dependencies.
     3 */
     4const {
     5        blocks: {
     6                registerBlockType,
     7        },
     8        i18n: {
     9                __,
     10        },
     11} = wp;
     12
     13/**
     14 * Internal dependencies.
     15 */
     16import editDynamicActivitiesBlock from './latest-activities/edit';
     17import transforms from './latest-activities/transforms';
     18
     19registerBlockType( 'bp/latest-activities', {
     20        title: __( 'Latest Activities', 'buddypress' ),
     21        description: __( 'Display the latest updates of the post author (when used into a page or post), of the displayed user (when viewing their profile) or of your community.', 'buddypress' ),
     22        icon: {
     23                background: '#fff',
     24                foreground: '#d84800',
     25                src: 'buddicons-activity',
     26        },
     27        category: 'buddypress',
     28        attributes: {
     29                title: {
     30                        type: 'string',
     31                        default: __( 'Latest updates', 'buddypress' ),
     32                },
     33                maxActivities: {
     34                        type: 'number',
     35                        default: 5
     36                },
     37                type: {
     38                        type: 'array',
     39                        default: ['activity_update'],
     40                },
     41                postId: {
     42                        type: 'number',
     43                        default: 0,
     44                },
     45        },
     46        edit: editDynamicActivitiesBlock,
     47        transforms: transforms,
     48} );
  • new file src/js/bp-activity/js/blocks/latest-activities/edit.js

    diff --git src/js/bp-activity/js/blocks/latest-activities/edit.js src/js/bp-activity/js/blocks/latest-activities/edit.js
    new file mode 100644
    index 000000000..942874abe
    - +  
     1/**
     2 * WordPress dependencies.
     3 */
     4const {
     5        blockEditor: {
     6                InspectorControls,
     7        },
     8        components: {
     9                Disabled,
     10                PanelBody,
     11                RangeControl,
     12                SelectControl,
     13                TextControl,
     14        },
     15        element: {
     16                Fragment,
     17                createElement,
     18        },
     19        i18n: {
     20                __,
     21        },
     22} = wp;
     23
     24/**
     25 * BuddyPress dependencies.
     26 */
     27const {
     28        blockComponents: {
     29                ServerSideRender,
     30        },
     31        blockData: {
     32                currentPostId,
     33                activityTypes,
     34        }
     35} = bp;
     36
     37const editDynamicActivitiesBlock = ( { attributes, setAttributes } ) => {
     38        const { postId, maxActivities, type, title } = attributes;
     39        const post = currentPostId();
     40        const types = activityTypes();
     41
     42        if ( ! postId && post ) {
     43                setAttributes( { postId: post } );
     44        }
     45
     46        return (
     47                <Fragment>
     48                        <InspectorControls>
     49                                <PanelBody title={ __( 'Settings', 'buddypress' ) } initialOpen={ true } className="bp-latest-activities">
     50                                        <TextControl
     51                                                label={ __( 'Title', 'buddypress' ) }
     52                                                value={ title }
     53                                                onChange={ ( text ) => {
     54                                                        setAttributes( { title: text } );
     55                                                } }
     56                                        />
     57                                        <RangeControl
     58                                                label={ __( 'Maximum amount to display', 'buddypress' ) }
     59                                                value={ maxActivities }
     60                                                onChange={ ( value ) =>
     61                                                        setAttributes( { maxActivities: value } )
     62                                                }
     63                                                min={ 1 }
     64                                                max={ 10 }
     65                                                required
     66                                        />
     67                                        <SelectControl
     68                                                multiple
     69                                                label={ __( 'Type', 'buddypress' ) }
     70                                                value={ type }
     71                                                options={ types }
     72                                                onChange={ ( option ) => {
     73                                                        setAttributes( { type: option } );
     74                                                } }
     75                                        />
     76                                </PanelBody>
     77                        </InspectorControls>
     78                        <Disabled>
     79                                <ServerSideRender block="bp/latest-activities" attributes={ attributes } />
     80                        </Disabled>
     81                </Fragment>
     82        );
     83};
     84
     85export default editDynamicActivitiesBlock;
  • new file src/js/bp-activity/js/blocks/latest-activities/transforms.js

    diff --git src/js/bp-activity/js/blocks/latest-activities/transforms.js src/js/bp-activity/js/blocks/latest-activities/transforms.js
    new file mode 100644
    index 000000000..e7f060625
    - +  
     1/**
     2 * WordPress dependencies.
     3 */
     4const {
     5        blocks: {
     6                createBlock,
     7        },
     8} = wp;
     9
     10/**
     11 * Transforms Nouveau Activity Widget to Activity 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_latest_activities';
     26                        },
     27                        transform: ( { instance } ) => {
     28                                const regex = /i:\d*;s:\d*:"(.*?)";/gmi;
     29                                let types = [];
     30                                let matches;
     31
     32                                while ( ( matches = regex.exec( instance.raw.type ) ) !== null ) {
     33                                        if ( matches.index === regex.lastIndex ) {
     34                                                regex.lastIndex++;
     35                                        }
     36
     37                                        matches.forEach( ( match, groupIndex ) => {
     38                                                if ( 1 === groupIndex ) {
     39                                                        types.push( match );
     40                                                }
     41                                        } );
     42                                }
     43
     44                                return createBlock( 'bp/latest-activities', {
     45                                        title: instance.raw.title,
     46                                        maxActivities: parseInt( instance.raw.max, 10 ),
     47                                        type: types,
     48                                } );
     49                        },
     50                },
     51        ],
     52};
     53
     54export default transforms;