[ Index ] |
PHP Cross Reference of BuddyPress |
[Summary view] [Print] [Text view]
1 /* jshint browser: true */ 2 /* global BP_Nouveau */ 3 /* @since 3.0.0 */ 4 /* @version 10.0.0 */ 5 window.bp = window.bp || {}; 6 7 ( function( bp, $ ) { 8 9 // Bail if not set 10 if ( typeof BP_Nouveau === 'undefined' ) { 11 return; 12 } 13 14 bp.Nouveau = bp.Nouveau || {}; 15 16 /** 17 * [Activity description] 18 * @type {Object} 19 */ 20 bp.Nouveau.Activity = { 21 22 /** 23 * [start description] 24 * @return {[type]} [description] 25 */ 26 start: function() { 27 this.setupGlobals(); 28 29 // Listen to events ("Add hooks!") 30 this.addListeners(); 31 }, 32 33 /** 34 * [setupGlobals description] 35 * @return {[type]} [description] 36 */ 37 setupGlobals: function() { 38 // Init just posted activities 39 this.just_posted = []; 40 41 // Init current page 42 this.current_page = 1; 43 44 // Init mentions count 45 this.mentions_count = Number( $( bp.Nouveau.objectNavParent + ' [data-bp-scope="mentions"]' ).find( 'a span' ).html() ) || 0; 46 47 // HeartBeat Globals 48 this.heartbeat_data = { 49 newest : '', 50 highlights : {}, 51 last_recorded : 0, 52 first_recorded : 0, 53 document_title : $( document ).prop( 'title' ) 54 }; 55 }, 56 57 /** 58 * [addListeners description] 59 */ 60 addListeners: function() { 61 // HeartBeat listeners 62 $( '#buddypress' ).on( 'bp_heartbeat_send', this.heartbeatSend.bind( this ) ); 63 $( '#buddypress' ).on( 'bp_heartbeat_tick', this.heartbeatTick.bind( this ) ); 64 65 // Inject Activities 66 $( '#buddypress [data-bp-list="activity"]' ).on( 'click', 'li.load-newest, li.load-more', this.injectActivities.bind( this ) ); 67 $( '#buddypress [data-bp-list]' ).on( 'bp_ajax_request', this.updateRssLink ); 68 69 // Hightlight new activities & clean up the stream 70 $( '#buddypress' ).on( 'bp_ajax_request', '[data-bp-list="activity"]', this.scopeLoaded.bind( this ) ); 71 72 // Activity comments effect 73 $( '#buddypress [data-bp-list="activity"]' ).on( 'bp_ajax_append', this.hideComments ); 74 $( '#buddypress [data-bp-list="activity"]' ).on( 'click', '.show-all', this.showComments ); 75 76 // Activity actions 77 $( '#buddypress [data-bp-list="activity"]' ).on( 'click', '.activity-item', bp.Nouveau, this.activityActions ); 78 $( document ).on( 'keydown', this.commentFormAction ); 79 }, 80 81 /** 82 * [heartbeatSend description] 83 * @param {[type]} event [description] 84 * @param {[type]} data [description] 85 * @return {[type]} [description] 86 */ 87 heartbeatSend: function( event, data ) { 88 this.heartbeat_data.first_recorded = $( '#buddypress [data-bp-list] [data-bp-activity-id]' ).first().data( 'bp-timestamp' ) || 0; 89 90 if ( 0 === this.heartbeat_data.last_recorded || this.heartbeat_data.first_recorded > this.heartbeat_data.last_recorded ) { 91 this.heartbeat_data.last_recorded = this.heartbeat_data.first_recorded; 92 } 93 94 data.bp_activity_last_recorded = this.heartbeat_data.last_recorded; 95 96 if ( $( '#buddypress .dir-search input[type=search]' ).length ) { 97 data.bp_activity_last_recorded_search_terms = $( '#buddypress .dir-search input[type=search]' ).val(); 98 } 99 100 $.extend( data, { bp_heartbeat: bp.Nouveau.getStorage( 'bp-activity' ) } ); 101 }, 102 103 /** 104 * [heartbeatTick description] 105 * @param {[type]} event [description] 106 * @param {[type]} data [description] 107 * @return {[type]} [description] 108 */ 109 heartbeatTick: function( event, data ) { 110 var newest_activities_count, newest_activities, objects = bp.Nouveau.objects, 111 scope = bp.Nouveau.getStorage( 'bp-activity', 'scope' ), self = this; 112 113 // Only proceed if we have newest activities 114 if ( undefined === data || ! data.bp_activity_newest_activities ) { 115 return; 116 } 117 118 this.heartbeat_data.newest = $.trim( data.bp_activity_newest_activities.activities ) + this.heartbeat_data.newest; 119 this.heartbeat_data.last_recorded = Number( data.bp_activity_newest_activities.last_recorded ); 120 121 // Parse activities 122 newest_activities = $( this.heartbeat_data.newest ).filter( '.activity-item' ); 123 124 // Count them 125 newest_activities_count = Number( newest_activities.length ); 126 127 /** 128 * It's not a regular object but we need it! 129 * so let's add it temporarly.. 130 */ 131 objects.push( 'mentions' ); 132 133 /** 134 * On the All Members tab, we need to know what these activities are about 135 * in order to update all the other tabs dynamic span 136 */ 137 if ( 'all' === scope ) { 138 139 $.each( newest_activities, function( a, activity ) { 140 activity = $( activity ); 141 142 $.each( objects, function( o, object ) { 143 if ( -1 !== $.inArray( 'bp-my-' + object, activity.get( 0 ).classList ) ) { 144 if ( undefined === self.heartbeat_data.highlights[ object ] ) { 145 self.heartbeat_data.highlights[ object ] = [ activity.data( 'bp-activity-id' ) ]; 146 } else if ( -1 === $.inArray( activity.data( 'bp-activity-id' ), self.heartbeat_data.highlights[ object ] ) ) { 147 self.heartbeat_data.highlights[ object ].push( activity.data( 'bp-activity-id' ) ); 148 } 149 } 150 } ); 151 } ); 152 153 // Remove the specific classes to count highligthts 154 var regexp = new RegExp( 'bp-my-(' + objects.join( '|' ) + ')', 'g' ); 155 this.heartbeat_data.newest = this.heartbeat_data.newest.replace( regexp, '' ); 156 157 /** 158 * Deal with the 'All Members' dynamic span from here as HeartBeat is working even when 159 * the user is not logged in 160 */ 161 $( bp.Nouveau.objectNavParent + ' [data-bp-scope="all"]' ).find( 'a span' ).html( newest_activities_count ); 162 163 // Set all activities to be highlighted for the current scope 164 } else { 165 // Init the array of highlighted activities 166 this.heartbeat_data.highlights[ scope ] = []; 167 168 $.each( newest_activities, function( a, activity ) { 169 self.heartbeat_data.highlights[ scope ].push( $( activity ).data( 'bp-activity-id' ) ); 170 } ); 171 } 172 173 $.each( objects, function( o, object ) { 174 if ( undefined !== self.heartbeat_data.highlights[ object ] && self.heartbeat_data.highlights[ object ].length ) { 175 var count = 0; 176 177 if ( 'mentions' === object ) { 178 count = self.mentions_count; 179 } 180 181 $( bp.Nouveau.objectNavParent + ' [data-bp-scope="' + object + '"]' ).find( 'a span' ).html( Number( self.heartbeat_data.highlights[ object ].length ) + count ); 182 } 183 } ); 184 185 /** 186 * Let's remove the mentions from objects! 187 */ 188 objects.pop(); 189 190 // Add an information about the number of newest activities inside the document's title 191 $( document ).prop( 'title', '(' + newest_activities_count + ') ' + this.heartbeat_data.document_title ); 192 193 // Update the Load Newest li if it already exists. 194 if ( $( '#buddypress [data-bp-list="activity"] li' ).first().hasClass( 'load-newest' ) ) { 195 var newest_link = $( '#buddypress [data-bp-list="activity"] .load-newest a' ).html(); 196 $( '#buddypress [data-bp-list="activity"] .load-newest a' ).html( newest_link.replace( /([0-9]+)/, newest_activities_count ) ); 197 198 // Otherwise add it 199 } else { 200 $( '#buddypress [data-bp-list="activity"] ul.activity-list' ).prepend( '<li class="load-newest"><a href="#newest">' + BP_Nouveau.newest + ' (' + newest_activities_count + ')</a></li>' ); 201 } 202 203 /** 204 * Finally trigger a pending event containing the activity heartbeat data 205 */ 206 $( '#buddypress [data-bp-list="activity"]' ).trigger( 'bp_heartbeat_pending', this.heartbeat_data ); 207 }, 208 209 /** 210 * [injectQuery description] 211 * @param {[type]} event [description] 212 * @return {[type]} [description] 213 */ 214 injectActivities: function( event ) { 215 var store = bp.Nouveau.getStorage( 'bp-activity' ), 216 scope = store.scope || null, filter = store.filter || null; 217 218 // Load newest activities 219 if ( $( event.currentTarget ).hasClass( 'load-newest' ) ) { 220 // Stop event propagation 221 event.preventDefault(); 222 223 $( event.currentTarget ).remove(); 224 225 /** 226 * If a plugin is updating the recorded_date of an activity 227 * it will be loaded as a new one. We need to look in the 228 * stream and eventually remove similar ids to avoid "double". 229 */ 230 var activities = $.parseHTML( this.heartbeat_data.newest ); 231 232 $.each( activities, function( a, activity ){ 233 if( 'LI' === activity.nodeName && $( activity ).hasClass( 'just-posted' ) ) { 234 if( $( '#' + $( activity ).prop( 'id' ) ).length ) { 235 $( '#' + $( activity ).prop( 'id' ) ).remove(); 236 } 237 } 238 } ); 239 240 // Now the stream is cleaned, prepend newest 241 $( event.delegateTarget ).find( '.activity-list' ).prepend( this.heartbeat_data.newest ).trigger( 'bp_heartbeat_prepend', this.heartbeat_data ); 242 243 // Reset the newest activities now they're displayed 244 this.heartbeat_data.newest = ''; 245 246 // Reset the All members tab dynamic span id it's the current one 247 if ( 'all' === scope ) { 248 $( bp.Nouveau.objectNavParent + ' [data-bp-scope="all"]' ).find( 'a span' ).html( '' ); 249 } 250 251 // Specific to mentions 252 if ( 'mentions' === scope ) { 253 // Now mentions are displayed, remove the user_metas 254 bp.Nouveau.ajax( { action: 'activity_clear_new_mentions' }, 'activity' ); 255 this.mentions_count = 0; 256 } 257 258 // Activities are now displayed, clear the newest count for the scope 259 $( bp.Nouveau.objectNavParent + ' [data-bp-scope="' + scope + '"]' ).find( 'a span' ).html( '' ); 260 261 // Activities are now displayed, clear the highlighted activities for the scope 262 if ( undefined !== this.heartbeat_data.highlights[ scope ] ) { 263 this.heartbeat_data.highlights[ scope ] = []; 264 } 265 266 // Remove highlighted for the current scope 267 setTimeout( function () { 268 $( event.delegateTarget ).find( '[data-bp-activity-id]' ).removeClass( 'newest_' + scope + '_activity' ); 269 }, 3000 ); 270 271 // Reset the document title 272 $( document ).prop( 'title', this.heartbeat_data.document_title ); 273 274 // Load more activities 275 } else if ( $( event.currentTarget ).hasClass( 'load-more' ) ) { 276 var next_page = ( Number( this.current_page ) * 1 ) + 1, self = this, search_terms = ''; 277 278 // Stop event propagation 279 event.preventDefault(); 280 281 $( event.currentTarget ).find( 'a' ).first().addClass( 'loading' ); 282 283 // reset the just posted 284 this.just_posted = []; 285 286 // Now set it 287 $( event.delegateTarget ).children( '.just-posted' ).each( function() { 288 self.just_posted.push( $( this ).data( 'bp-activity-id' ) ); 289 } ); 290 291 if ( $( '#buddypress .dir-search input[type=search]' ).length ) { 292 search_terms = $( '#buddypress .dir-search input[type=search]' ).val(); 293 } 294 295 bp.Nouveau.objectRequest( { 296 object : 'activity', 297 scope : scope, 298 filter : filter, 299 search_terms : search_terms, 300 page : next_page, 301 method : 'append', 302 exclude_just_posted : this.just_posted.join( ',' ), 303 target : '#buddypress [data-bp-list] ul.bp-list' 304 } ).done( function( response ) { 305 if ( true === response.success ) { 306 $( event.currentTarget ).remove(); 307 308 // Update the current page 309 self.current_page = next_page; 310 } 311 } ); 312 } 313 }, 314 315 /** 316 * [truncateComments description] 317 * @param {[type]} event [description] 318 * @return {[type]} [description] 319 */ 320 hideComments: function( event ) { 321 var comments = $( event.target ).find( '.activity-comments' ), 322 activity_item, comment_items, comment_count, comment_parents; 323 324 if ( ! comments.length ) { 325 return; 326 } 327 328 comments.each( function( c, comment ) { 329 comment_parents = $( comment ).children( 'ul' ); 330 comment_items = $( comment_parents ).find( 'li' ); 331 332 333 if ( ! comment_items.length ) { 334 return; 335 } 336 337 // Get the activity id 338 activity_item = $( comment ).closest( '.activity-item' ); 339 340 // Get the comment count 341 comment_count = $( '#acomment-comment-' + activity_item.data( 'bp-activity-id' ) + ' span.comment-count' ).html() || ' '; 342 343 // Keep latest 5 comments 344 comment_items.each( function( i, item ) { 345 if ( i < comment_items.length - 5 ) { 346 $( item ).addClass('bp-hidden').hide(); 347 348 // Prepend a link to display all 349 if ( ! i ) { 350 var activity_id = activity_item.data( 'bpActivityId' ); 351 if ( 'undefined' !== typeof activity_id ) { 352 activity_id = parseInt( activity_id, 10 ); 353 $( item ).before( '<li class="show-all"><button class="text-button" type="button" data-bp-show-comments-id="#activity-' + activity_id + '/show-all/"><span class="icon dashicons dashicons-visibility" aria-hidden="true"></span> ' + BP_Nouveau.show_x_comments.replace( '%d', comment_count ) + '</button></li>' ); 354 } 355 } 356 } 357 } ); 358 359 // If all parents are hidden, reveal at least one. It seems very risky to manipulate the DOM to keep exactly 5 comments! 360 if ( $( comment_parents ).children( '.bp-hidden' ).length === $( comment_parents ).children( 'li' ).length - 1 && $( comment_parents ).find( 'li.show-all' ).length ) { 361 $( comment_parents ).children( 'li' ).removeClass( 'bp-hidden' ).toggle(); 362 } 363 } ); 364 }, 365 366 /** 367 * [showComments description] 368 * @param {[type]} event [description] 369 * @return {[type]} [description] 370 */ 371 showComments: function( event ) { 372 // Stop event propagation 373 event.preventDefault(); 374 375 $( event.target ).addClass( 'loading' ); 376 377 setTimeout( function() { 378 $( event.target ).closest( 'ul' ).find( 'li' ).removeClass('bp-hidden').fadeIn( 300, function() { 379 $( event.target ).parent( 'li' ).remove(); 380 } ); 381 }, 600 ); 382 }, 383 384 /** 385 * [scopeLoaded description] 386 * @param {[type]} event [description] 387 * @param {[type]} data [description] 388 * @return {[type]} [description] 389 */ 390 scopeLoaded: function ( event, data ) { 391 // Make sure to only keep 5 root comments 392 this.hideComments( event ); 393 394 // Reset the pagination for the scope. 395 this.current_page = 1; 396 397 // Mentions are specific 398 if ( 'mentions' === data.scope && undefined !== data.response.new_mentions ) { 399 $.each( data.response.new_mentions, function( i, id ) { 400 $( '#buddypress #activity-stream' ).find( '[data-bp-activity-id="' + id + '"]' ).addClass( 'newest_mentions_activity' ); 401 } ); 402 403 // Reset mentions count 404 this.mentions_count = 0; 405 } else if ( undefined !== this.heartbeat_data.highlights[data.scope] && this.heartbeat_data.highlights[data.scope].length ) { 406 $.each( this.heartbeat_data.highlights[data.scope], function( i, id ) { 407 if ( $( '#buddypress #activity-stream' ).find( '[data-bp-activity-id="' + id + '"]' ).length ) { 408 $( '#buddypress #activity-stream' ).find( '[data-bp-activity-id="' + id + '"]' ).addClass( 'newest_' + data.scope + '_activity' ); 409 } 410 } ); 411 } 412 413 // Reset the newest activities now they're displayed 414 this.heartbeat_data.newest = ''; 415 $.each( $( bp.Nouveau.objectNavParent + ' [data-bp-scope]' ).find( 'a span' ), function( s, count ) { 416 if ( 0 === parseInt( $( count ).html(), 10 ) ) { 417 $( count ).html( '' ); 418 } 419 } ); 420 421 // Activities are now loaded, clear the highlighted activities for the scope 422 if ( undefined !== this.heartbeat_data.highlights[ data.scope ] ) { 423 this.heartbeat_data.highlights[ data.scope ] = []; 424 } 425 426 // Reset the document title 427 $( document ).prop( 'title', this.heartbeat_data.document_title ); 428 429 setTimeout( function () { 430 $( '#buddypress #activity-stream .activity-item' ).removeClass( 'newest_' + data.scope +'_activity' ); 431 }, 3000 ); 432 }, 433 434 /** 435 * [activityActions description] 436 * @param {[type]} event [description] 437 * @return {[type]} [description] 438 */ 439 activityActions: function( event ) { 440 var parent = event.data, target = $( event.target ), activity_item = $( event.currentTarget ), 441 activity_id = activity_item.data( 'bp-activity-id' ), stream = $( event.delegateTarget ), 442 item_id, form; 443 444 // In case the target is set to a span inside the link. 445 if ( $( target ).is( 'span' ) ) { 446 target = $( target ).closest( 'a' ); 447 } 448 449 // Favoriting 450 if ( target.hasClass( 'fav') || target.hasClass('unfav') ) { 451 var type = target.hasClass( 'fav' ) ? 'fav' : 'unfav'; 452 453 // Stop event propagation 454 event.preventDefault(); 455 456 target.addClass( 'loading' ); 457 458 parent.ajax( { action: 'activity_mark_' + type, 'id': activity_id }, 'activity' ).done( function( response ) { 459 target.removeClass( 'loading' ); 460 461 if ( false === response.success ) { 462 return; 463 } else { 464 target.fadeOut( 200, function() { 465 if ( $( this ).find( 'span' ).first().length ) { 466 $( this ).find( 'span' ).first().html( response.data.content ); 467 } else { 468 $( this ).html( response.data.content ); 469 } 470 $( this ).attr( 'data-bp-tooltip', response.data.content ); 471 472 if ('false' === $(this).attr('aria-pressed') ) { 473 $( this ).attr('aria-pressed', 'true'); 474 } else { 475 $( this ).attr('aria-pressed', 'false'); 476 } 477 478 $( this ).fadeIn( 200 ); 479 } ); 480 } 481 482 if ( 'fav' === type ) { 483 if ( undefined !== response.data.directory_tab ) { 484 if ( ! $( parent.objectNavParent + ' [data-bp-scope="favorites"]' ).length ) { 485 $( parent.objectNavParent + ' [data-bp-scope="all"]' ).after( response.data.directory_tab ); 486 } 487 } 488 489 target.removeClass( 'fav' ); 490 target.addClass( 'unfav' ); 491 492 } else if ( 'unfav' === type ) { 493 var favoriteScope = $( '[data-bp-user-scope="favorites"]' ).hasClass( 'selected' ) || $( parent.objectNavParent + ' [data-bp-scope="favorites"]' ).hasClass( 'selected' ); 494 495 // If on user's profile or on the favorites directory tab, remove the entry 496 if ( favoriteScope ) { 497 activity_item.remove(); 498 } 499 500 if ( undefined !== response.data.no_favorite ) { 501 // Remove the tab when on activity directory but not on the favorites tabs 502 if ( $( parent.objectNavParent + ' [data-bp-scope="all"]' ).length && $( parent.objectNavParent + ' [data-bp-scope="all"]' ).hasClass( 'selected' ) ) { 503 $( parent.objectNavParent + ' [data-bp-scope="favorites"]' ).remove(); 504 505 // In all the other cases, append a message to the empty stream 506 } else if ( favoriteScope ) { 507 stream.append( response.data.no_favorite ); 508 } 509 } 510 511 target.removeClass( 'unfav' ); 512 target.addClass( 'fav' ); 513 } 514 } ); 515 } 516 517 // Deleting or spamming 518 if ( target.hasClass( 'delete-activity' ) || target.hasClass( 'acomment-delete' ) || target.hasClass( 'spam-activity' ) || target.hasClass( 'spam-activity-comment' ) ) { 519 var activity_comment_li = target.closest( '[data-bp-activity-comment-id]' ), 520 activity_comment_id = activity_comment_li.data( 'bp-activity-comment-id' ), 521 li_parent, comment_count_span, comment_count, show_all_a, deleted_comments_count = 0; 522 523 // Stop event propagation 524 event.preventDefault(); 525 526 if ( undefined !== BP_Nouveau.confirm && false === window.confirm( BP_Nouveau.confirm ) ) { 527 return false; 528 } 529 530 target.addClass( 'loading' ); 531 532 var ajaxData = { 533 action : 'delete_activity', 534 'id' : activity_id, 535 '_wpnonce' : parent.getLinkParams( target.prop( 'href' ), '_wpnonce' ), 536 'is_single' : target.closest( '[data-bp-single]' ).length 537 }; 538 539 // Only the action changes when spamming an activity or a comment. 540 if ( target.hasClass( 'spam-activity' ) || target.hasClass( 'spam-activity-comment' ) ) { 541 ajaxData.action = 'bp_spam_activity'; 542 } 543 544 // Set defaults parent li to activity container 545 li_parent = activity_item; 546 547 // If it's a comment edit ajaxData. 548 if ( activity_comment_id ) { 549 delete ajaxData.is_single; 550 551 // Set comment data. 552 ajaxData.id = activity_comment_id; 553 ajaxData.is_comment = true; 554 555 // Set parent li to activity comment container 556 li_parent = activity_comment_li; 557 } 558 559 // Move the form if needed 560 if ( activity_comment_li.find( 'form' ).length ) { 561 activity_item.find( '.activity-comments' ).append( activity_comment_li.find( 'form' ) ); 562 } 563 564 parent.ajax( ajaxData, 'activity' ).done( function( response ) { 565 target.removeClass( 'loading' ); 566 567 if ( false === response.success ) { 568 li_parent.prepend( response.data.feedback ); 569 li_parent.find( '.bp-feedback' ).hide().fadeIn( 300 ); 570 } else { 571 // Specific case of the single activity screen. 572 if ( response.data.redirect ) { 573 return window.location.href = response.data.redirect; 574 } 575 576 if ( activity_comment_id ) { 577 deleted_comments_count = 1; 578 if ( response.data.deleted ) { 579 deleted_comments_count = response.data.deleted.length; 580 581 response.data.deleted.forEach( function( cid ) { 582 $( '[data-bp-activity-comment-id="' + cid + '"]' ).remove(); 583 } ); 584 } else { 585 // Count child comments if there are some 586 $.each( activity_comment_li.find( 'li' ), function() { 587 deleted_comments_count += 1; 588 } ); 589 } 590 591 // Update the button count 592 comment_count_span = activity_item.find( '.acomment-reply span.comment-count' ); 593 comment_count = Number( comment_count_span.html() - deleted_comments_count ); 594 comment_count_span.html( comment_count ); 595 596 // Update the show all count 597 show_all_a = activity_item.find( 'li.show-all a' ); 598 if ( show_all_a.length ) { 599 show_all_a.html( BP_Nouveau.show_x_comments.replace( '%d', comment_count ) ); 600 } 601 602 // Clean up the parent activity classes. 603 if ( 0 === comment_count ) { 604 activity_item.removeClass( 'has-comments' ); 605 } 606 } 607 608 // Remove the entry 609 li_parent.slideUp( 300, function() { 610 li_parent.remove(); 611 } ); 612 613 // reset vars to get newest activities when an activity is deleted 614 if ( ! activity_comment_id && activity_item.data( 'bp-timestamp' ) === parent.Activity.heartbeat_data.last_recorded ) { 615 parent.Activity.heartbeat_data.newest = ''; 616 parent.Activity.heartbeat_data.last_recorded = 0; 617 } 618 } 619 } ); 620 } 621 622 // Reading more 623 if ( target.closest( 'span' ).hasClass( 'activity-read-more' ) ) { 624 var content = target.closest( 'div' ), readMore = target.closest( 'span' ); 625 626 item_id = null; 627 628 if ( $( content ).hasClass( 'activity-inner' ) ) { 629 item_id = activity_id; 630 } else if ( $( content ).hasClass( 'acomment-content' ) ) { 631 item_id = target.closest( 'li' ).data( 'bp-activity-comment-id' ); 632 } 633 634 if ( ! item_id ) { 635 return event; 636 } 637 638 // Stop event propagation 639 event.preventDefault(); 640 641 $( readMore ).addClass( 'loading' ); 642 643 parent.ajax( { 644 action : 'get_single_activity_content', 645 id : item_id 646 }, 'activity' ).done( function( response ) { 647 $( readMore ).removeClass( 'loading' ); 648 649 if ( content.parent().find( '.bp-feedback' ).length ) { 650 content.parent().find( '.bp-feedback' ).remove(); 651 } 652 653 if ( false === response.success ) { 654 content.after( response.data.feedback ); 655 content.parent().find( '.bp-feedback' ).hide().fadeIn( 300 ); 656 } else { 657 $( content ).slideUp( 300 ).html( response.data.contents ).slideDown( 300 ); 658 } 659 } ); 660 } 661 662 // Displaying the comment form 663 if ( target.hasClass( 'acomment-reply' ) || target.parent().hasClass( 'acomment-reply' ) ) { 664 var comment_link = target; 665 666 form = $( '#ac-form-' + activity_id ); 667 item_id = activity_id; 668 669 // Stop event propagation 670 event.preventDefault(); 671 672 if ( ! form.length ) { 673 var viewDiscussionLink = target.closest( 'li.activity' ).find( '.activity-meta a.view' ).prop( 'href' ); 674 675 if ( viewDiscussionLink ) { 676 window.location.href = viewDiscussionLink; 677 } 678 679 return false; 680 } 681 682 // If the comment count span inside the link is clicked 683 if ( target.parent().hasClass( 'acomment-reply' ) ) { 684 comment_link = target.parent(); 685 } 686 687 if ( target.closest( 'li' ).data( 'bp-activity-comment-id' ) ) { 688 item_id = target.closest( 'li' ).data( 'bp-activity-comment-id' ); 689 } 690 691 // ?? hide and display none.. 692 //form.css( 'display', 'none' ); 693 form.removeClass( 'root' ); 694 $('.ac-form').hide(); 695 696 /* Remove any error messages */ 697 $.each( form.children( 'div' ), function( e, err ) { 698 if ( $( err ).hasClass( 'error' ) ) { 699 $( err ).remove(); 700 } 701 } ); 702 703 // It's an activity we're commenting 704 if ( item_id === activity_id ) { 705 $( '[data-bp-activity-id="' + item_id + '"] .activity-comments' ).append( form ); 706 form.addClass( 'root' ); 707 708 // It's a comment we're replying to 709 } else { 710 $( '[data-bp-activity-comment-id="' + item_id + '"]' ).append( form ); 711 } 712 713 form.slideDown( 200 ); 714 715 // change the aria state from false to true 716 target.attr( 'aria-expanded', 'true' ); 717 718 $.scrollTo( form, 500, { 719 offset:-100, 720 easing:'swing' 721 } ); 722 723 $( '#ac-form-' + activity_id + ' textarea' ).trigger( 'focus' ); 724 } 725 726 // Removing the form 727 if ( target.hasClass( 'ac-reply-cancel' ) ) { 728 729 $( target ).closest( '.ac-form' ).slideUp( 200 ); 730 731 // Change the aria state back to false on comment cancel 732 $( '.acomment-reply').attr( 'aria-expanded', 'false' ); 733 734 // Stop event propagation 735 event.preventDefault(); 736 } 737 738 // Submitting comments and replies 739 if ( 'ac_form_submit' === target.prop( 'name' ) ) { 740 var comment_content, comment_data; 741 742 form = target.closest( 'form' ); 743 item_id = activity_id; 744 745 // Stop event propagation 746 event.preventDefault(); 747 748 if ( target.closest( 'li' ).data( 'bp-activity-comment-id' ) ) { 749 item_id = target.closest( 'li' ).data( 'bp-activity-comment-id' ); 750 } 751 752 comment_content = $( form ).find( 'textarea' ).first(); 753 754 target.addClass( 'loading' ).prop( 'disabled', true ); 755 comment_content.addClass( 'loading' ).prop( 'disabled', true ); 756 757 comment_data = { 758 action : 'new_activity_comment', 759 _wpnonce_new_activity_comment : $( '#_wpnonce_new_activity_comment' + '_' + activity_id ).val(), 760 comment_id : item_id, 761 form_id : activity_id, 762 content : comment_content.val() 763 }; 764 765 // Add the Akismet nonce if it exists 766 if ( $( '#_bp_as_nonce_' + activity_id ).val() ) { 767 comment_data['_bp_as_nonce_' + activity_id] = $( '#_bp_as_nonce_' + activity_id ).val(); 768 } 769 770 parent.ajax( comment_data, 'activity' ).done( function( response ) { 771 target.removeClass( 'loading' ); 772 comment_content.removeClass( 'loading' ); 773 $( '.acomment-reply' ).attr( 'aria-expanded', 'false' ); 774 775 if ( false === response.success ) { 776 form.append( $( response.data.feedback ).hide().fadeIn( 200 ) ); 777 } else { 778 var activity_comments = form.parent(); 779 var the_comment = $.trim( response.data.contents ); 780 781 form.fadeOut( 200, function() { 782 if ( 0 === activity_comments.children( 'ul' ).length ) { 783 if ( activity_comments.hasClass( 'activity-comments' ) ) { 784 activity_comments.prepend( '<ul></ul>' ); 785 } else { 786 activity_comments.append( '<ul></ul>' ); 787 } 788 } 789 790 activity_comments.children( 'ul' ).append( $( the_comment ).hide().fadeIn( 200 ) ); 791 $( form ).find( 'textarea' ).first().val( '' ); 792 793 activity_comments.parent().addClass( 'has-comments' ); 794 } ); 795 796 // why, as it's already done a few lines ahead ??? 797 //jq( '#' + form.attr('id') + ' textarea').val(''); 798 799 // Set the new count 800 comment_count = Number( $( activity_item ).find( 'a span.comment-count' ).html() || 0 ) + 1; 801 802 // Increase the "Reply (X)" button count 803 $( activity_item ).find( 'a span.comment-count' ).html( comment_count ); 804 805 // Increment the 'Show all x comments' string, if present 806 show_all_a = $( activity_item ).find( '.show-all a' ); 807 if ( show_all_a ) { 808 show_all_a.html( BP_Nouveau.show_x_comments.replace( '%d', comment_count ) ); 809 } 810 } 811 812 target.prop( 'disabled', false ); 813 comment_content.prop( 'disabled', false ); 814 } ); 815 } 816 }, 817 818 /** 819 * [closeCommentForm description] 820 * @param {[type]} event [description] 821 * @return {[type]} [description] 822 */ 823 commentFormAction: function( event ) { 824 var element, keyCode; 825 826 event = event || window.event; 827 828 if ( event.target ) { 829 element = event.target; 830 } else if ( event.srcElement) { 831 element = event.srcElement; 832 } 833 834 if ( element.nodeType === 3 ) { 835 element = element.parentNode; 836 } 837 838 if ( event.altKey === true || event.metaKey === true ) { 839 return event; 840 } 841 842 // Not in a comment textarea, return 843 if ( element.tagName !== 'TEXTAREA' || ! $( element ).hasClass( 'ac-input' ) ) { 844 return event; 845 } 846 847 keyCode = ( event.keyCode ) ? event.keyCode : event.which; 848 849 if ( 27 === keyCode && false === event.ctrlKey ) { 850 if ( element.tagName === 'TEXTAREA' ) { 851 $( element ).closest( 'form' ).slideUp( 200 ); 852 } 853 } else if ( event.ctrlKey && 13 === keyCode && $( element ).val() ) { 854 $( element ).closest( 'form' ).find( '[type=submit]' ).first().trigger( 'click' ); 855 } 856 }, 857 858 updateRssLink: function( event, data ) { 859 var rssLink = data.response.feed_url || ''; 860 861 if ( rssLink && $( 'body:not(.bp-user) #activity-rss-feed' ).length ) { 862 $( '#activity-rss-feed' ).find( 'a' ).first().prop( 'href', rssLink ); 863 } 864 } 865 }; 866 867 // Launch BP Nouveau Activity 868 bp.Nouveau.Activity.start(); 869 870 } )( window.bp, jQuery );
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sat Dec 7 01:00:57 2024 | Cross-referenced by PHPXref 0.7.1 |