Skip to:
Content

BuddyPress.org

Ticket #5328: 5328.04.diff

File 5328.04.diff, 22.9 KB (added by imath, 7 years ago)
  • bp-activity/bp-activity-classes.php

    diff --git bp-activity/bp-activity-classes.php bp-activity/bp-activity-classes.php
    index 5d5a870..98f40f8 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..0dccbc4 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 * Adds a just-posted class to avoid some mess in activity ajax pagination
     421 *
     422 * @since  BuddyPress (2.0.0)
     423 * @param  string $classes
     424 * @return string $classes
     425 */
     426function bp_activity_newest_class( $classes = '' ) {
     427        $bp = buddypress();
     428       
     429        if ( ! empty( $bp->activity->new_update_id ) && $bp->activity->new_update_id == bp_get_activity_id() )
     430                $classes .= ' new-update';
     431       
     432        $classes .= ' just-posted';
     433        return $classes;
     434}
     435
     436/**
     437 * Uses WordPress Heartbeat API to check for latest activity update in BP Activity Admin screen
     438 *
     439 * @since BuddyPress (2.0.0)
     440 *
     441 * @uses  bp_activity_get_last_updated() to get the recorded date of the last activity
     442 * @param  array  $response
     443 * @param  array  $data
     444 * @return array  $response
     445 */
     446function bp_activity_heartbeat_last_recorded( $response = array(), $data = array() ) {
     447        $bp = buddypress();
     448
     449        if ( empty( $data['bp_activity_last_id'] ) )
     450                return $response;
     451
     452        $activity_latest_args = bp_parse_args(
     453                bp_ajax_querystring( 'activity' ),
     454                array( 'offset' => absint( $data['bp_activity_last_id'] ) ),
     455                'activity_latest_args'
     456        );
     457
     458        $newest_activities = array();
     459        $last_activity_id = 0;
     460
     461        // temporarly adds a just_posted class for these activities
     462        add_filter( 'bp_get_activity_css_class', 'bp_activity_newest_class', 10, 1 );
     463               
     464        ob_start();
     465        if ( bp_has_activities ( $activity_latest_args ) ) {
     466
     467                while ( bp_activities() ) {
     468                        bp_the_activity();
     469
     470                        if( $last_activity_id < bp_get_activity_id() )
     471                                $last_activity_id = bp_get_activity_id();
     472
     473                        bp_get_template_part( 'activity/entry' );
     474                }
     475
     476        }
     477        $newest_activities['activities'] = ob_get_contents();
     478        $newest_activities['last_id']    = $last_activity_id;
     479        ob_end_clean();
     480
     481        // remove the filter
     482        remove_filter( 'bp_get_activity_css_class', 'bp_activity_newest_class', 10, 1 );
     483
     484        if ( ! empty( $newest_activities['last_id'] ) )
     485                $response['bp_activity_newest_activities'] = $newest_activities;
     486
     487        return $response;
     488}
     489add_filter( 'heartbeat_received', 'bp_activity_heartbeat_last_recorded', 10, 2 );
     490add_filter( 'heartbeat_nopriv_received', 'bp_activity_heartbeat_last_recorded', 10, 2 );
     491
     492/**
     493 * Set the strings for WP HeartBeat API where needed
     494 *
     495 * @since  BuddyPress (2.0.0)
     496 *
     497 * @param  array  $strings localized strings
     498 * @return array  $strings
     499 */
     500function bp_activity_heartbeat_strings( $strings = array() ) {
     501
     502        if ( ! bp_activity_do_heartbeat() )
     503                return $strings;
     504
     505        /**
     506         * Get the heartbeat setting to see if a plugin have changed the pulse
     507         * the goal is to avoid adding too much "mess" in this case.
     508         */
     509        $heartbeat_settings = apply_filters( 'heartbeat_settings', array() );
     510
     511        $global_pulse = 0;
     512
     513        if ( ! empty( $heartbeat_settings['interval'] ) ) {
     514                // 'Fast' is 5
     515                $global_pulse = is_numeric( $heartbeat_settings['interval'] ) ? absint( $heartbeat_settings['interval'] ) : 5;
     516        }
     517        /**
     518         * Site Admin can change the pulse using 'bp_activity_heartbeat_pulse' filter
     519         */
     520        $bp_activity_pulse = apply_filters( 'bp_activity_heartbeat_pulse', 15 );
     521
     522        /**
     523         * If this filter is used, then the Site Admin really wants BuddyPress to change
     524         * the heartbeat interval setting for activity refresh.
     525         * If no pulse have been set by other plugins, apply BuddyPress default value.
     526         */
     527        if ( has_filter( 'bp_activity_heartbeat_pulse' ) || empty( $global_pulse ) ) {
     528                $global_pulse = $bp_activity_pulse;     
     529        }
     530
     531        $strings = array_merge( $strings, array(
     532                'newest' => __( 'Load Newest', 'buddypress' ),
     533                'pulse'  => $global_pulse,
     534        ) );
     535
     536        return $strings;
     537}
     538add_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..378fd80 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/**
     1855 * Should we use HeartBeat to refresh activities every 15 s.
     1856 *
     1857 * @since BuddyPress (2.0.0)
     1858 *
     1859 * @uses bp_is_activity_heartbeat_active() to check if heatbeat setting is on
     1860 * @uses bp_is_activity_directory() to check if the current page is the activity 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 is the group activities
     1863 * @uses bp_is_group_home() to check if the current page is a single group home page
     1864 * @return bool True on success, false on failure.
     1865 */
     1866function bp_activity_do_heartbeat() {
     1867        $retval = false;
     1868
     1869        if ( ! bp_is_activity_heartbeat_active() )
     1870                return $retval;
     1871
     1872        if ( bp_is_activity_directory() )
     1873                $retval = true;
     1874
     1875        if ( bp_is_active( 'groups') ) {
     1876                // If no custom front, then activities are loaded in group's home
     1877                $has_custom_front = bp_locate_template( array( 'groups/single/front.php' ), false, true );
     1878
     1879                if ( bp_is_group_activity() || ( ! $has_custom_front && bp_is_group_home() ) )
     1880                        $retval = true;
     1881        }
     1882
     1883        return $retval;
     1884}
  • bp-activity/bp-activity-template.php

    diff --git bp-activity/bp-activity-template.php bp-activity/bp-activity-template.php
    index 64d1ac1..5fe859c 100644
    function bp_has_activities( $args = '' ) { 
    543543                'action'            => false,        // action to filter on e.g. activity_update, new_forum_post, profile_updated
    544544                'primary_id'        => $primary_id,  // object ID to filter on e.g. a group_id or forum_id or blog_id etc.
    545545                'secondary_id'      => false,        // secondary object ID to filter on e.g. a post_id
     546                'offset'            => false,        // activity id to get newer updates
    546547
    547548                'meta_query'        => false,        // filter on activity meta. See WP_Meta_Query for format
    548549
    function bp_has_activities( $args = '' ) { 
    561562                $display_comments = false;
    562563        }
    563564
     565        // reset pagination to get all new activities
     566        if ( ! empty( $offset ) )
     567                $page = 0;
     568
    564569        if ( empty( $search_terms ) && ! empty( $_REQUEST['s'] ) )
    565570                $search_terms = $_REQUEST['s'];
    566571
    function bp_has_activities( $args = '' ) { 
    632637        // into bp-custom.php or your theme's functions.php
    633638        if ( isset( $_GET['afilter'] ) && apply_filters( 'bp_activity_enable_afilter_support', false ) )
    634639                $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 );
     640        else if ( ! empty( $user_id ) || ! empty( $object ) || ! empty( $action ) || ! empty( $primary_id ) || ! empty( $secondary_id ) || ! empty( $offset ) )
     641                $filter = array( 'user_id' => $user_id, 'object' => $object, 'action' => $action, 'primary_id' => $primary_id, 'secondary_id' => $secondary_id, 'offset' => $offset );
    637642        else
    638643                $filter = false;
    639644
    function bp_activity_pagination_links() { 
    767772function bp_activity_has_more_items() {
    768773        global $activities_template;
    769774
    770         $remaining_pages = floor( ( $activities_template->total_activity_count - 1 ) / ( $activities_template->pag_num * $activities_template->pag_page ) );
     775        $remaining_pages = 0;
     776
     777        if ( ! empty( $activities_template->pag_page ) ) {
     778                $remaining_pages = floor( ( $activities_template->total_activity_count - 1 ) / ( $activities_template->pag_num * $activities_template->pag_page ) );
     779        }
     780
    771781        $has_more_items  = (int) $remaining_pages ? true : false;
    772782
    773783        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..fc15c87 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( 'Allow activity stream to be refreshed every 15 seconds', '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..bfa783f 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 * @return array the javascript dependencies.
     1863 */
     1864function bp_core_get_js_dependencies() {
     1865        return apply_filters( 'bp_core_get_js_dependencies', array( 'jquery' ) );
     1866}
     1867
  • 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..e3d9440 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
    483487        $object_search_text = bp_get_search_default_text( $object );
    484488        if ( ! empty( $_POST['search_terms'] ) && $object_search_text != $_POST['search_terms'] && 'false' != $_POST['search_terms'] && 'undefined' != $_POST['search_terms'] )
    485489                $qs[] = 'search_terms=' . $_POST['search_terms'];
    function bp_legacy_theme_activity_template_loader() { 
    611615 * @since BuddyPress (1.2)
    612616 */
    613617function bp_legacy_theme_post_update() {
     618        $bp = buddypress();
     619
    614620        // Bail if not a POST action
    615621        if ( 'POST' !== strtoupper( $_SERVER['REQUEST_METHOD'] ) )
    616622                return;
    function bp_legacy_theme_post_update() { 
    639645        if ( empty( $activity_id ) )
    640646                exit( '-1<div id="message" class="error"><p>' . __( 'There was a problem posting your update, please try again.', 'buddypress' ) . '</p></div>' );
    641647
    642         if ( bp_has_activities ( 'include=' . $activity_id ) ) {
     648        if ( ! empty( $_POST['offset'] ) && $last_id = absint( $_POST['offset'] ) ) {
     649                $activity_args = array( 'offset' => $last_id );
     650                $bp->activity->new_update_id = $activity_id;
     651                add_filter( 'bp_get_activity_css_class', 'bp_activity_newest_class', 10, 1 );
     652        } else {
     653                $activity_args = array( 'include' => $activity_id );
     654        }
     655       
     656        if ( bp_has_activities ( $activity_args ) ) {
    643657                while ( bp_activities() ) {
    644658                        bp_the_activity();
    645659                        bp_get_template_part( 'activity/entry' );
    646660                }
    647661        }
    648662
     663        if ( ! empty( $last_id ) ) {
     664                remove_filter( 'bp_get_activity_css_class', 'bp_activity_newest_class', 10, 1 );
     665        }
     666       
    649667        exit;
    650668}
    651669
  • 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 350193e..34369fc 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                /* If the scope is not all, the activity update can temporarly be displayed
     62                   in the wrong tab which can be annoying with the load newest feature */
     63                if ( jq( '#activity-all' ).length  ) {
     64
     65                        if ( ! jq( '#activity-all' ).hasClass( 'selected' ) ) {
     66                                // reset to everyting
     67                                jq( '#activity-filter-select select' ).val( '-1' );
     68                                jq( '#activity-all 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() { 
    7189
    7290        /* New posts */
    7391        jq("#aw-whats-new-submit").on( 'click', function() {
    74                 var button = jq(this);
     92                var last_displayed_id = 0;
     93                var     button = jq(this);
    7594                var form = button.closest("form#whats-new-form");
    7695
    7796                form.children().each( function() {
    jq(document).ready( function() { 
    89108                var object = '';
    90109                var item_id = jq("#whats-new-post-in").val();
    91110                var content = jq("#whats-new").val();
     111                var firstrow = jq( '#buddypress ul.activity-list li' ).first();
     112
     113                if ( firstrow.hasClass( 'load-newest' ) ) {
     114                        last_displayed_id = firstrow.next().prop( 'id' ) ? firstrow.next().prop( 'id' ).replace( 'activity-','' ) : 0;
     115                } else {
     116                        last_displayed_id = firstrow.prop( 'id' ) ? firstrow.prop( 'id' ).replace( 'activity-','' ) : 0;
     117                }
    92118
    93119                /* Set object for non-profile posts */
    94120                if ( item_id > 0 ) {
    jq(document).ready( function() { 
    102128                        'content': content,
    103129                        'object': object,
    104130                        'item_id': item_id,
     131                        'offset': last_displayed_id,
    105132                        '_bp_as_nonce': jq('#_bp_as_nonce').val() || ''
    106133                },
    107134                function(response) {
    jq(document).ready( function() { 
    123150                                        jq("div.activity").append( '<ul id="activity-stream" class="activity-list item-list">' );
    124151                                }
    125152
     153                                if ( firstrow.hasClass( 'load-newest' ) )
     154                                        firstrow.remove();
     155
    126156                                jq("#activity-stream").prepend(response);
    127                                 jq("#activity-stream li:first").addClass('new-update just-posted');
     157
     158                                if ( ! last_displayed_id )
     159                                        jq("#activity-stream li:first").addClass('new-update just-posted');
    128160
    129161                                if ( 0 != jq("#latest-update").length ) {
    130162                                        var l = jq("#activity-stream li.new-update .activity-content .activity-inner p").html();
    jq(document).ready( function() { 
    147179                                jq("li.new-update").hide().slideDown( 300 );
    148180                                jq("li.new-update").removeClass( 'new-update' );
    149181                                jq("#whats-new").val('');
     182
     183                                // reset vars to get newest activities
     184                                newest_activities = '';
     185                                activity_last_id  = 0;
    150186                        }
    151187
    152188                        jq("#whats-new-options").animate({
    jq(document).ready( function() { 
    285321                                        li.children('#message').hide().fadeIn(300);
    286322                                } else {
    287323                                        li.slideUp(300);
     324
     325                                        // reset vars to get newest activities
     326                                        if ( activity_last_id == id ) {
     327                                                newest_activities = '';
     328                                                activity_last_id  = 0;
     329                                        }
    288330                                }
    289331                        });
    290332
    jq(document).ready( function() { 
    309351                                        li.children( '#message' ).hide().fadeIn(300);
    310352                                } else {
    311353                                        li.slideUp( 300 );
     354                                        // reset vars to get newest activities
     355                                        if ( activity_last_id == id ) {
     356                                                newest_activities = '';
     357                                                activity_last_id  = 0;
     358                                        }
    312359                                }
    313360                        });
    314361
    jq(document).ready( function() { 
    351398
    352399                        return false;
    353400                }
     401
     402                /* Load newest updates at the top of the list */
     403                if ( target.parent().hasClass('load-newest') ) {
     404
     405                        event.preventDefault();
     406
     407                        target.parent().hide();
     408                        jq( '#buddypress ul.activity-list' ).prepend( newest_activities );
     409
     410                        // reset the newest activities now they're displayed
     411                        newest_activities = '';
     412                }
    354413        });
    355414
    356415        // Activity "Read More" links
    jq(document).ready( function() { 
    13451404        /* if js is enabled then replace the no-js class by a js one */
    13461405        if( jq('body').hasClass('no-js') )
    13471406                jq('body').attr('class', jq('body').attr('class').replace( /no-js/,'js' ) );
     1407
     1408
     1409        /** Activity HeartBeat ************************************************/
     1410
     1411        // Set the interval and the namespace event
     1412        if ( typeof wp != 'undefined' && typeof wp.heartbeat != 'undefined' && typeof BP_DTheme.pulse != 'undefined' ) {
     1413
     1414                wp.heartbeat.interval( Number( BP_DTheme.pulse ) );
     1415
     1416                jq.fn.extend({
     1417                        'heartbeat-send': function() {
     1418                        return this.bind( 'heartbeat-send.buddypress' );
     1419                },
     1420            });
     1421
     1422        }
     1423       
     1424        // Set the last id to request after
     1425        jq( document ).on( 'heartbeat-send.buddypress', function( e, data ) {
     1426
     1427                // First row is default latest activity id
     1428                if ( jq( '#buddypress ul.activity-list li' ).first().prop( 'id' ) ) {
     1429                        firstrow = jq( '#buddypress ul.activity-list li' ).first().prop( 'id' ).replace( 'activity-','' );
     1430                } else {
     1431                        firstrow = 0;
     1432                }
     1433
     1434                if ( 0 == activity_last_id || Number( firstrow ) > activity_last_id )
     1435                        activity_last_id = Number( firstrow );
     1436
     1437                data['bp_activity_last_id'] = activity_last_id;
     1438    });
     1439
     1440        // Increment newest_activities and activity_last_id if data has been returned
     1441        jq( document ).on( 'heartbeat-tick', function( e, data ) {
     1442
     1443                // Only proceed if we have newest activities
     1444                if ( ! data['bp_activity_newest_activities'] )
     1445                return;
     1446
     1447        newest_activities = data['bp_activity_newest_activities']['activities'] + newest_activities;
     1448        activity_last_id  = Number( data['bp_activity_newest_activities']['last_id'] );
     1449
     1450        if ( jq( '#buddypress ul.activity-list li' ).first().hasClass( 'load-newest' ) )
     1451                        return;
     1452
     1453        jq( '#buddypress ul.activity-list' ).prepend( '<li class="load-newest"><a href="#newest">' + BP_DTheme.newest + '</a></li>' );
     1454
     1455    });
    13481456               
    13491457});
    13501458