Skip to:
Content

BuddyPress.org

Ticket #5328: 5328.05.diff

File 5328.05.diff, 24.6 KB (added by boonebgorges, 11 years ago)
  • bp-activity/bp-activity-classes.php

    diff --git bp-activity/bp-activity-classes.php bp-activity/bp-activity-classes.php
    index 5d5a870..f16e53a 100644
    class BP_Activity_Activity { 
    11451145                                $filter_sql[] = $sid_sql;
    11461146                }
    11471147
     1148                if ( ! empty( $filter_array['offset'] ) ) {
     1149                        $sid_sql = absint( $filter_array['offset'] );
     1150                        $filter_sql[] = "a.id >= {$sid_sql}";
     1151                }
     1152
    11481153                if ( empty( $filter_sql ) )
    11491154                        return false;
    11501155
  • bp-activity/bp-activity-filters.php

    diff --git bp-activity/bp-activity-filters.php bp-activity/bp-activity-filters.php
    index 2afbc34..73624e6 100644
    function bp_activity_truncate_entry( $text ) { 
    396396
    397397        return apply_filters( 'bp_activity_truncate_entry', $excerpt, $text, $append_text );
    398398}
     399
     400/**
     401 * Include extra javascript dependencies for activity component.
     402 *
     403 * @since BuddyPress (2.0.0)
     404 *
     405 * @uses bp_activity_do_heartbeat() to check if heartbeat is required.
     406 *
     407 * @param array $js_handles The original dependencies.
     408 * @return array $js_handles The new dependencies.
     409 */
     410function bp_activity_get_js_dependencies( $js_handles = array() ) {
     411        if ( bp_activity_do_heartbeat() ) {
     412                $js_handles[] = 'heartbeat';
     413        }
     414
     415        return $js_handles;
     416}
     417add_filter( 'bp_core_get_js_dependencies', 'bp_activity_get_js_dependencies', 10, 1 );
     418
     419/**
     420 * Add a just-posted class to avoid some mess in activity ajax pagination
     421 *
     422 * @since BuddyPress (2.0.0)
     423 *
     424 * @param string $classes
     425 * @return string $classes
     426 */
     427function bp_activity_newest_class( $classes = '' ) {
     428        $bp = buddypress();
     429
     430        if ( ! empty( $bp->activity->new_update_id ) && $bp->activity->new_update_id == bp_get_activity_id() ) {
     431                $classes .= ' new-update';
     432        }
     433
     434        $classes .= ' just-posted';
     435        return $classes;
     436}
     437
     438/**
     439 * Use WordPress Heartbeat API to check for latest activity update.
     440 *
     441 * @since BuddyPress (2.0.0)
     442 *
     443 * @uses bp_activity_get_last_updated() to get the recorded date of the last activity
     444
     445 * @param array $response
     446 * @param array $data
     447 * @return array $response
     448 */
     449function bp_activity_heartbeat_last_recorded( $response = array(), $data = array() ) {
     450        $bp = buddypress();
     451
     452        if ( empty( $data['bp_activity_last_id'] ) ) {
     453                return $response;
     454        }
     455
     456        $activity_latest_args = bp_parse_args(
     457                bp_ajax_querystring( 'activity' ),
     458                array( 'offset' => absint( $data['bp_activity_last_id'] ) + 1 ),
     459                'activity_latest_args'
     460        );
     461
     462        $newest_activities = array();
     463        $last_activity_id = 0;
     464
     465        // temporarly adds a just_posted class for these activities
     466        add_filter( 'bp_get_activity_css_class', 'bp_activity_newest_class', 10, 1 );
     467
     468        ob_start();
     469        if ( bp_has_activities ( $activity_latest_args ) ) {
     470
     471                while ( bp_activities() ) {
     472                        bp_the_activity();
     473
     474                        if ( $last_activity_id < bp_get_activity_id() ) {
     475                                $last_activity_id = bp_get_activity_id();
     476                        }
     477
     478                        bp_get_template_part( 'activity/entry' );
     479                }
     480
     481        }
     482        $newest_activities['activities'] = ob_get_contents();
     483        $newest_activities['last_id']    = $last_activity_id;
     484        ob_end_clean();
     485
     486        // remove the filter
     487        remove_filter( 'bp_get_activity_css_class', 'bp_activity_newest_class', 10, 1 );
     488
     489        if ( ! empty( $newest_activities['last_id'] ) ) {
     490                $response['bp_activity_newest_activities'] = $newest_activities;
     491        }
     492
     493        return $response;
     494}
     495add_filter( 'heartbeat_received', 'bp_activity_heartbeat_last_recorded', 10, 2 );
     496add_filter( 'heartbeat_nopriv_received', 'bp_activity_heartbeat_last_recorded', 10, 2 );
     497
     498/**
     499 * Set the strings for WP HeartBeat API where needed.
     500 *
     501 * @since BuddyPress (2.0.0)
     502 *
     503 * @param array $strings localized strings
     504 * @return array $strings
     505 */
     506function bp_activity_heartbeat_strings( $strings = array() ) {
     507
     508        if ( ! bp_activity_do_heartbeat() ) {
     509                return $strings;
     510        }
     511
     512        // Check whether the global heartbeat settings already exist.
     513        $heartbeat_settings = apply_filters( 'heartbeat_settings', array() );
     514
     515        $global_pulse = 0;
     516
     517        if ( ! empty( $heartbeat_settings['interval'] ) ) {
     518                // 'Fast' is 5
     519                $global_pulse = is_numeric( $heartbeat_settings['interval'] ) ? absint( $heartbeat_settings['interval'] ) : 5;
     520        }
     521
     522        // Filter here to specify a BP-specific pulse frequency
     523        $bp_activity_pulse = apply_filters( 'bp_activity_heartbeat_pulse', 15 );
     524
     525        /**
     526         * Use the global pulse value unless:
     527         * a. it doesn't exist, or
     528         * b. the BP-specific value has been specifically filtered
     529         */
     530        if ( has_filter( 'bp_activity_heartbeat_pulse' ) || empty( $global_pulse ) ) {
     531                $pulse = $bp_activity_pulse;
     532        } else {
     533                $pulse = $global_pulse;
     534        }
     535
     536        $strings = array_merge( $strings, array(
     537                'newest' => __( 'Load Newest', 'buddypress' ),
     538                'pulse'  => $pulse,
     539        ) );
     540
     541        return $strings;
     542}
     543add_filter( 'bp_core_get_js_strings', 'bp_activity_heartbeat_strings', 10, 1 );
  • bp-activity/bp-activity-functions.php

    diff --git bp-activity/bp-activity-functions.php bp-activity/bp-activity-functions.php
    index 12016cd..6cbf3b4 100644
    function bp_embed_activity_cache( $cache, $id, $cachekey ) { 
    18491849function bp_embed_activity_save_cache( $cache, $cachekey, $id ) {
    18501850        bp_activity_update_meta( $id, $cachekey, $cache );
    18511851}
     1852
     1853/**
     1854 * Should we use Heartbeat to refresh activities?
     1855 *
     1856 * @since BuddyPress (2.0.0)
     1857 *
     1858 * @uses bp_is_activity_heartbeat_active() to check if heatbeat setting is on.
     1859 * @uses bp_is_activity_directory() to check if the current page is the activity
     1860 *       directory.
     1861 * @uses bp_is_active() to check if the group component is active.
     1862 * @uses bp_is_group_activity() to check if on a single group, the current page
     1863 *       is the group activities.
     1864 * @uses bp_is_group_home() to check if the current page is a single group home
     1865 *       page.
     1866 *
     1867 * @return bool True if activity heartbeat is enabled, otherwise false.
     1868 */
     1869function bp_activity_do_heartbeat() {
     1870        $retval = false;
     1871
     1872        if ( ! bp_is_activity_heartbeat_active() ) {
     1873                return $retval;
     1874        }
     1875
     1876        if ( bp_is_activity_directory() ) {
     1877                $retval = true;
     1878        }
     1879
     1880        if ( bp_is_active( 'groups') ) {
     1881                // If no custom front, then activities are loaded in group's home
     1882                $has_custom_front = bp_locate_template( array( 'groups/single/front.php' ), false, true );
     1883
     1884                if ( bp_is_group_activity() || ( ! $has_custom_front && bp_is_group_home() ) ) {
     1885                        $retval = true;
     1886                }
     1887        }
     1888
     1889        return $retval;
     1890}
  • bp-activity/bp-activity-template.php

    diff --git bp-activity/bp-activity-template.php bp-activity/bp-activity-template.php
    index 64d1ac1..b416e3a 100644
    class BP_Activity_Template { 
    454454 *           column in the database. The meaning of 'secondary_id' differs
    455455 *           between components/types. Accepts a single ID, or an array of
    456456 *           multiple IDs. Defaults to false.
     457 *     @type int $offset Return only activity items with an ID greater than or
     458 *           equal to this one. Note that providing an offset will disable
     459 *           pagination. Default: false.
    457460 *     @type string|bool $display_comments How to handle activity comments.
    458461 *           Possible values:
    459462 *             - 'threaded' - comments appear in a threaded tree, under their
    function bp_has_activities( $args = '' ) { 
    543546                'action'            => false,        // action to filter on e.g. activity_update, new_forum_post, profile_updated
    544547                'primary_id'        => $primary_id,  // object ID to filter on e.g. a group_id or forum_id or blog_id etc.
    545548                'secondary_id'      => false,        // secondary object ID to filter on e.g. a post_id
     549                'offset'            => false,        // return only items >= this ID
    546550
    547551                'meta_query'        => false,        // filter on activity meta. See WP_Meta_Query for format
    548552
    function bp_has_activities( $args = '' ) { 
    561565                $display_comments = false;
    562566        }
    563567
     568        // Ignore pagination if an offset is passed
     569        if ( ! empty( $offset ) ) {
     570                $page = 0;
     571        }
     572
    564573        if ( empty( $search_terms ) && ! empty( $_REQUEST['s'] ) )
    565574                $search_terms = $_REQUEST['s'];
    566575
    function bp_has_activities( $args = '' ) { 
    632641        // into bp-custom.php or your theme's functions.php
    633642        if ( isset( $_GET['afilter'] ) && apply_filters( 'bp_activity_enable_afilter_support', false ) )
    634643                $filter = array( 'object' => $_GET['afilter'] );
    635         else if ( !empty( $user_id ) || !empty( $object ) || !empty( $action ) || !empty( $primary_id ) || !empty( $secondary_id ) )
    636                 $filter = array( 'user_id' => $user_id, 'object' => $object, 'action' => $action, 'primary_id' => $primary_id, 'secondary_id' => $secondary_id );
     644        else if ( ! empty( $user_id ) || ! empty( $object ) || ! empty( $action ) || ! empty( $primary_id ) || ! empty( $secondary_id ) || ! empty( $offset ) )
     645                $filter = array( 'user_id' => $user_id, 'object' => $object, 'action' => $action, 'primary_id' => $primary_id, 'secondary_id' => $secondary_id, 'offset' => $offset );
    637646        else
    638647                $filter = false;
    639648
    function bp_activity_pagination_links() { 
    767776function bp_activity_has_more_items() {
    768777        global $activities_template;
    769778
    770         $remaining_pages = floor( ( $activities_template->total_activity_count - 1 ) / ( $activities_template->pag_num * $activities_template->pag_page ) );
     779        $remaining_pages = 0;
     780
     781        if ( ! empty( $activities_template->pag_page ) ) {
     782                $remaining_pages = floor( ( $activities_template->total_activity_count - 1 ) / ( $activities_template->pag_num * $activities_template->pag_page ) );
     783        }
     784
    771785        $has_more_items  = (int) $remaining_pages ? true : false;
    772786
    773787        return apply_filters( 'bp_activity_has_more_items', $has_more_items );
  • bp-core/admin/bp-core-settings.php

    diff --git bp-core/admin/bp-core-settings.php bp-core/admin/bp-core-settings.php
    index 01ed8c5..a836b08 100644
    function bp_admin_setting_callback_blogforum_comments() { 
    104104}
    105105
    106106/**
     107 * Allow Heartbeat to refresh activity stream.
     108 *
     109 * @since BuddyPress (2.0.0)
     110 */
     111function bp_admin_setting_callback_heartbeat() {
     112?>
     113
     114        <input id="_bp_enable_heartbeat_refresh" name="_bp_enable_heartbeat_refresh" type="checkbox" value="1" <?php checked( bp_is_activity_heartbeat_active( true ) ); ?> />
     115        <label for="_bp_enable_heartbeat_refresh"><?php _e( 'Query automatically for new items when viewing the activity stream', 'buddypress' ); ?></label>
     116
     117<?php
     118}
     119
     120/**
    107121 * Sanitization for _bp_force_buddyvar
    108122 *
    109123 * If upgraded to 1.6 and you chose to keep the BuddyBar, a checkbox asks if you want to switch to
  • bp-core/bp-core-admin.php

    diff --git bp-core/bp-core-admin.php bp-core/bp-core-admin.php
    index 9e45be9..4020355 100644
    class BP_Admin { 
    330330                        add_settings_field( 'bp-disable-blogforum-comments', __( 'Blog &amp; Forum Comments', 'buddypress' ), 'bp_admin_setting_callback_blogforum_comments', 'buddypress', 'bp_activity' );
    331331                        register_setting( 'buddypress', 'bp-disable-blogforum-comments', 'bp_admin_sanitize_callback_blogforum_comments' );
    332332
     333                        // Activity Heartbeat refresh
     334                        add_settings_field( '_bp_enable_heartbeat_refresh', __( 'Activity auto-refresh', 'buddypress' ), 'bp_admin_setting_callback_heartbeat', 'buddypress', 'bp_activity' );
     335                        register_setting( 'buddypress', '_bp_enable_heartbeat_refresh', 'intval' );
     336
    333337                        // Allow activity akismet
    334338                        if ( is_plugin_active( 'akismet/akismet.php' ) && defined( 'AKISMET_VERSION' ) ) {
    335339                                add_settings_field( '_bp_enable_akismet', __( 'Akismet',          'buddypress' ), 'bp_admin_setting_callback_activity_akismet', 'buddypress', 'bp_activity' );
  • bp-core/bp-core-functions.php

    diff --git bp-core/bp-core-functions.php bp-core/bp-core-functions.php
    index ccea74b..c054987 100644
    function bp_nav_menu_get_item_url( $slug ) { 
    18521852
    18531853        return $nav_item_url;
    18541854}
     1855
     1856/**
     1857 * Get the javascript dependencies for buddypress.js.
     1858 *
     1859 * @since BuddyPress (2.0.0)
     1860 *
     1861 * @uses apply_filters() to allow other component to load extra dependencies
     1862 *
     1863 * @return array The javascript dependencies.
     1864 */
     1865function bp_core_get_js_dependencies() {
     1866        return apply_filters( 'bp_core_get_js_dependencies', array( 'jquery' ) );
     1867}
     1868
  • bp-core/bp-core-options.php

    diff --git bp-core/bp-core-options.php bp-core/bp-core-options.php
    index f76c5be..07edc8c 100644
    function bp_get_default_options() { 
    7676                // Users from all sites can post
    7777                '_bp_enable_akismet'              => true,
    7878
     79                /** Activity HeartBeat ************************************************/
     80
     81                // HeartBeat is on to refresh activities
     82                '_bp_enable_heartbeat_refresh'    => true,
     83
    7984                /** BuddyBar **********************************************************/
    8085
    8186                // Force the BuddyBar
    function bp_is_akismet_active( $default = true ) { 
    586591}
    587592
    588593/**
     594 * Check whether Activity Heartbeat refresh is enabled.
     595 *
     596 * @since BuddyPress (2.0.0)
     597 *
     598 * @uses bp_get_option() To get the Heartbeat option.
     599 *
     600 * @param bool $default Optional. Fallback value if not found in the database.
     601 *        Default: true.
     602 * @return bool True if Heartbeat refresh is enabled, otherwise false.
     603 */
     604function bp_is_activity_heartbeat_active( $default = true ) {
     605        return (bool) apply_filters( 'bp_is_activity_heartbeat_active', (bool) bp_get_option( '_bp_enable_heartbeat_refresh', $default ) );
     606}
     607
     608/**
    589609 * Get the current theme package ID.
    590610 *
    591611 * @since BuddyPress (1.7.0)
  • bp-templates/bp-legacy/buddypress-functions.php

    diff --git bp-templates/bp-legacy/buddypress-functions.php bp-templates/bp-legacy/buddypress-functions.php
    index 0cb3153..6b7c230 100644
    class BP_Legacy extends BP_Theme_Compat { 
    223223                // Enqueue the global JS, if found - AJAX will not work
    224224                // without it
    225225                if ( isset( $asset['location'], $asset['handle'] ) ) {
    226                         wp_enqueue_script( $asset['handle'], $asset['location'], array( 'jquery' ), $this->version );
     226                        wp_enqueue_script( $asset['handle'], $asset['location'], bp_core_get_js_dependencies(), $this->version );
    227227                }
    228228
    229229                // Add words that we need to use in JS to the end of the page
    230230                // so they can be translated and still used.
    231                 $params = array(
     231                $params = apply_filters( 'bp_core_get_js_strings', array(
    232232                        'accepted'            => __( 'Accepted', 'buddypress' ),
    233233                        'close'               => __( 'Close', 'buddypress' ),
    234234                        'comments'            => __( 'comments', 'buddypress' ),
    class BP_Legacy extends BP_Theme_Compat { 
    242242                        'show_x_comments'     => __( 'Show all %d comments', 'buddypress' ),
    243243                        'unsaved_changes'     => __( 'Your profile has unsaved changes. If you leave the page, the changes will be lost.', 'buddypress' ),
    244244                        'view'                => __( 'View', 'buddypress' ),
    245                 );
     245                ) );
    246246                wp_localize_script( $asset['handle'], 'BP_DTheme', $params );
    247247
    248248                // Maybe enqueue comment reply JS
    function bp_legacy_theme_ajax_querystring( $query_string, $object ) { 
    480480                $qs[] = 'exclude=' . implode( ',', $just_posted );
    481481        }
    482482
     483        // to get newest activities
     484        if ( ! empty( $_POST['offset'] ) ) {
     485                $qs[] = 'offset=' . intval( $_POST['offset'] );
     486        }
     487
    483488        $object_search_text = bp_get_search_default_text( $object );
    484489        if ( ! empty( $_POST['search_terms'] ) && $object_search_text != $_POST['search_terms'] && 'false' != $_POST['search_terms'] && 'undefined' != $_POST['search_terms'] )
    485490                $qs[] = 'search_terms=' . $_POST['search_terms'];
    function bp_legacy_theme_activity_template_loader() { 
    611616 * @since BuddyPress (1.2)
    612617 */
    613618function bp_legacy_theme_post_update() {
     619        $bp = buddypress();
     620
    614621        // Bail if not a POST action
    615622        if ( 'POST' !== strtoupper( $_SERVER['REQUEST_METHOD'] ) )
    616623                return;
    function bp_legacy_theme_post_update() { 
    639646        if ( empty( $activity_id ) )
    640647                exit( '-1<div id="message" class="error"><p>' . __( 'There was a problem posting your update, please try again.', 'buddypress' ) . '</p></div>' );
    641648
    642         if ( bp_has_activities ( 'include=' . $activity_id ) ) {
     649        if ( ! empty( $_POST['offset'] ) && $last_id = absint( $_POST['offset'] ) ) {
     650                $activity_args = array( 'offset' => $last_id );
     651                $bp->activity->new_update_id = $activity_id;
     652                add_filter( 'bp_get_activity_css_class', 'bp_activity_newest_class', 10, 1 );
     653        } else {
     654                $activity_args = array( 'include' => $activity_id );
     655        }
     656
     657        if ( bp_has_activities ( $activity_args ) ) {
    643658                while ( bp_activities() ) {
    644659                        bp_the_activity();
    645660                        bp_get_template_part( 'activity/entry' );
    646661                }
    647662        }
    648663
     664        if ( ! empty( $last_id ) ) {
     665                remove_filter( 'bp_get_activity_css_class', 'bp_activity_newest_class', 10, 1 );
     666        }
     667
    649668        exit;
    650669}
    651670
  • bp-templates/bp-legacy/css/buddypress.css

    diff --git bp-templates/bp-legacy/css/buddypress.css bp-templates/bp-legacy/css/buddypress.css
    index 81dd03f..e343077 100644
    body.activity-permalink #buddypress .activity-content blockquote { 
    290290        margin-left: 1em;
    291291        white-space: nowrap;
    292292}
    293 #buddypress .activity-list li.load-more {
     293#buddypress .activity-list li.load-more,
     294#buddypress .activity-list li.load-newest {
    294295        background: #f0f0f0;
    295296        font-size: 110%;
    296297        margin: 15px 0;
    297298        padding: 10px 15px;
    298299        text-align: center;
    299300}
    300 #buddypress .activity-list li.load-more a {
     301#buddypress .activity-list li.load-more a,
     302#buddypress .activity-list li.load-newest a {
    301303        color: #4D4D4D;
    302304}
    303305
  • bp-templates/bp-legacy/js/buddypress.js

    diff --git bp-templates/bp-legacy/js/buddypress.js bp-templates/bp-legacy/js/buddypress.js
    index 100375e..a22b09c 100644
    var jq = jQuery; 
    44// Global variable to prevent multiple AJAX requests
    55var bp_ajax_request = null;
    66
     7// Global variables to temporarly store newest activities
     8var newest_activities = '';
     9var activity_last_id  = 0;
     10
    711jq(document).ready( function() {
    812        /**** Page Load Actions *******************************************************/
    913
    jq(document).ready( function() { 
    5357                if ( $whats_new_form.hasClass("submitted") ) {
    5458                        $whats_new_form.removeClass("submitted");       
    5559                }
     60
     61                // Return to the 'All Members' tab and 'Everything' filter,
     62                // to avoid inconsistencies with the heartbeat integration
     63                var $activity_all = jq( '#activity-all' );
     64                if ( $activity_all.length  ) {
     65                        if ( ! $activity_all.hasClass( 'selected' ) ) {
     66                                // reset to everyting
     67                                jq( '#activity-filter-select select' ).val( '-1' );
     68                                $activity_all.children( 'a' ).trigger( "click" );
     69                        } else if ( '-1' != jq( '#activity-filter-select select' ).val() ) {
     70                                jq( '#activity-filter-select select' ).val( '-1' );
     71                                jq( '#activity-filter-select select' ).trigger( 'change' );
     72                        }
     73                }
    5674        });
    5775
    5876        /* On blur, shrink if it's empty */
    jq(document).ready( function() { 
    7391
    7492        /* New posts */
    7593        jq("#aw-whats-new-submit").on( 'click', function() {
     94                var last_displayed_id = 0;
    7695                var button = jq(this);
    7796                var form = button.closest("form#whats-new-form");
    7897
    jq(document).ready( function() { 
    91110                var object = '';
    92111                var item_id = jq("#whats-new-post-in").val();
    93112                var content = jq("#whats-new").val();
     113                var firstrow = jq( '#buddypress ul.activity-list li' ).first();
     114
     115                if ( firstrow.hasClass( 'load-newest' ) ) {
     116                        last_displayed_id = firstrow.next().prop( 'id' ) ? firstrow.next().prop( 'id' ).replace( 'activity-','' ) : 0;
     117                } else {
     118                        last_displayed_id = firstrow.prop( 'id' ) ? firstrow.prop( 'id' ).replace( 'activity-','' ) : 0;
     119                }
    94120
    95121                /* Set object for non-profile posts */
    96122                if ( item_id > 0 ) {
    jq(document).ready( function() { 
    104130                        'content': content,
    105131                        'object': object,
    106132                        'item_id': item_id,
     133                        'offset': last_displayed_id,
    107134                        '_bp_as_nonce': jq('#_bp_as_nonce').val() || ''
    108135                },
    109136                function(response) {
    jq(document).ready( function() { 
    125152                                        jq("div.activity").append( '<ul id="activity-stream" class="activity-list item-list">' );
    126153                                }
    127154
     155                                if ( firstrow.hasClass( 'load-newest' ) )
     156                                        firstrow.remove();
     157
    128158                                jq("#activity-stream").prepend(response);
    129                                 jq("#activity-stream li:first").addClass('new-update just-posted');
     159
     160                                if ( ! last_displayed_id )
     161                                        jq("#activity-stream li:first").addClass('new-update just-posted');
    130162
    131163                                if ( 0 != jq("#latest-update").length ) {
    132164                                        var l = jq("#activity-stream li.new-update .activity-content .activity-inner p").html();
    jq(document).ready( function() { 
    149181                                jq("li.new-update").hide().slideDown( 300 );
    150182                                jq("li.new-update").removeClass( 'new-update' );
    151183                                jq("#whats-new").val('');
     184
     185                                // reset vars to get newest activities
     186                                newest_activities = '';
     187                                activity_last_id  = 0;
    152188                        }
    153189
    154190                        jq("#whats-new-options").animate({
    jq(document).ready( function() { 
    287323                                        li.children('#message').hide().fadeIn(300);
    288324                                } else {
    289325                                        li.slideUp(300);
     326
     327                                        // reset vars to get newest activities
     328                                        if ( activity_last_id == id ) {
     329                                                newest_activities = '';
     330                                                activity_last_id  = 0;
     331                                        }
    290332                                }
    291333                        });
    292334
    jq(document).ready( function() { 
    311353                                        li.children( '#message' ).hide().fadeIn(300);
    312354                                } else {
    313355                                        li.slideUp( 300 );
     356                                        // reset vars to get newest activities
     357                                        if ( activity_last_id == id ) {
     358                                                newest_activities = '';
     359                                                activity_last_id  = 0;
     360                                        }
    314361                                }
    315362                        });
    316363
    jq(document).ready( function() { 
    353400
    354401                        return false;
    355402                }
     403
     404                /* Load newest updates at the top of the list */
     405                if ( target.parent().hasClass('load-newest') ) {
     406
     407                        event.preventDefault();
     408
     409                        target.parent().hide();
     410                        jq( '#buddypress ul.activity-list' ).prepend( newest_activities );
     411
     412                        // reset the newest activities now they're displayed
     413                        newest_activities = '';
     414                }
    356415        });
    357416
    358417        // Activity "Read More" links
    jq(document).ready( function() { 
    13471406        /* if js is enabled then replace the no-js class by a js one */
    13481407        if( jq('body').hasClass('no-js') )
    13491408                jq('body').attr('class', jq('body').attr('class').replace( /no-js/,'js' ) );
    1350                
     1409
     1410
     1411        /** Activity HeartBeat ************************************************/
     1412
     1413        // Set the interval and the namespace event
     1414        if ( typeof wp != 'undefined' && typeof wp.heartbeat != 'undefined' && typeof BP_DTheme.pulse != 'undefined' ) {
     1415
     1416                wp.heartbeat.interval( Number( BP_DTheme.pulse ) );
     1417
     1418                jq.fn.extend({
     1419                        'heartbeat-send': function() {
     1420                        return this.bind( 'heartbeat-send.buddypress' );
     1421                },
     1422            });
     1423
     1424        }
     1425
     1426        // Set the last id to request after
     1427        jq( document ).on( 'heartbeat-send.buddypress', function( e, data ) {
     1428
     1429                // First row is default latest activity id
     1430                if ( jq( '#buddypress ul.activity-list li' ).first().prop( 'id' ) ) {
     1431                        firstrow = jq( '#buddypress ul.activity-list li' ).first().prop( 'id' ).replace( 'activity-','' );
     1432                } else {
     1433                        firstrow = 0;
     1434                }
     1435
     1436                if ( 0 == activity_last_id || Number( firstrow ) > activity_last_id )
     1437                        activity_last_id = Number( firstrow );
     1438
     1439                data['bp_activity_last_id'] = activity_last_id;
     1440        });
     1441
     1442        // Increment newest_activities and activity_last_id if data has been returned
     1443        jq( document ).on( 'heartbeat-tick', function( e, data ) {
     1444
     1445                // Only proceed if we have newest activities
     1446                if ( ! data['bp_activity_newest_activities'] ) {
     1447                        return;
     1448                }
     1449
     1450                newest_activities = data['bp_activity_newest_activities']['activities'] + newest_activities;
     1451                activity_last_id  = Number( data['bp_activity_newest_activities']['last_id'] );
     1452
     1453                if ( jq( '#buddypress ul.activity-list li' ).first().hasClass( 'load-newest' ) )
     1454                        return;
     1455
     1456                jq( '#buddypress ul.activity-list' ).prepend( '<li class="load-newest"><a href="#newest">' + BP_DTheme.newest + '</a></li>' );
     1457        });
    13511458});
    13521459
    13531460/* Setup activity scope and filter based on the current cookie settings. */
  • tests/testcases/activity/class.BP_Activity_Activity.php

    diff --git tests/testcases/activity/class.BP_Activity_Activity.php tests/testcases/activity/class.BP_Activity_Activity.php
    index 4754644..f969380 100644
    class BP_Tests_Activity_Class extends BP_UnitTestCase { 
    257257        }
    258258
    259259        /**
     260         * @group get
     261         */
     262        public function test_get_with_offset() {
     263                $now = time();
     264                $a1 = $this->factory->activity->create( array(
     265                        'content' => 'Life Rules',
     266                        'recorded_time' => date( 'Y-m-d H:i:s', $now - 100 ),
     267                ) );
     268                $a2 = $this->factory->activity->create( array(
     269                        'content' => 'Life Drools',
     270                        'recorded_time' => date( 'Y-m-d H:i:s', $now - 50 ),
     271                ) );
     272                $a3 = $this->factory->activity->create( array(
     273                        'content' => 'Life Drools',
     274                        'recorded_time' => date( 'Y-m-d H:i:s', $now - 10 ),
     275                ) );
     276
     277                $activity = BP_Activity_Activity::get( array(
     278                        'filter' => array(
     279                                'offset' => $a2,
     280                        ),
     281                ) );
     282                $ids = wp_list_pluck( $activity['activities'], 'id' );
     283                $this->assertEquals( array( $a3, $a2 ), $ids );
     284        }
     285        /**
    260286         * @group get_id
    261287         */
    262288        public function test_get_id_with_item_id() {