[ Index ]

PHP Cross Reference of BuddyPress

title

Body

[close]

/src/bp-core/js/ -> avatar.js (source)

   1  /* global BP_Uploader, _, Backbone */
   2  
   3  window.bp = window.bp || {};
   4  
   5  ( function( bp, $ ) {
   6  
   7      // Bail if not set.
   8      if ( typeof BP_Uploader === 'undefined' ) {
   9          return;
  10      }
  11  
  12      bp.Models      = bp.Models || {};
  13      bp.Collections = bp.Collections || {};
  14      bp.Views       = bp.Views || {};
  15  
  16      bp.Avatar = {
  17          start: function() {
  18              var self = this;
  19  
  20              /**
  21               * Remove the bp-legacy UI
  22               *
  23               * bp.Avatar successfully loaded, we can now
  24               * safely remove the Legacy UI.
  25               */
  26              this.removeLegacyUI();
  27  
  28              // Init some vars.
  29              this.views    = new Backbone.Collection();
  30              this.jcropapi = {};
  31              this.warning = null;
  32  
  33              // Set up nav.
  34              this.setupNav();
  35  
  36              // Avatars are uploaded files.
  37              this.avatars = bp.Uploader.filesUploaded;
  38  
  39              // The Avatar Attachment object.
  40              this.Attachment = new Backbone.Model();
  41  
  42              // The Avatars history.
  43              this.historicAvatars = null;
  44  
  45              // Wait till the queue is reset.
  46              bp.Uploader.filesQueue.on( 'reset', this.cropView, this );
  47  
  48              /**
  49               * In Administration screens we're using Thickbox
  50               * We need to make sure to reset the views if it's closed or opened
  51               */
  52              $( 'body.wp-admin' ).on( 'tb_unload', '#TB_window', function() {
  53                  self.resetViews();
  54              } );
  55  
  56              $( 'body.wp-admin' ).on( 'click', '.bp-members-avatar-user-edit', function() {
  57                  self.resetViews();
  58              } );
  59          },
  60  
  61          removeLegacyUI: function() {
  62              // User.
  63              if ( $( '#avatar-upload-form' ).length ) {
  64                  $( '#avatar-upload' ).remove();
  65                  $( '#avatar-upload-form p' ).remove();
  66  
  67              // Group Manage.
  68              } else if ( $( '#group-settings-form' ).length ) {
  69                  $( '#group-settings-form p' ).each( function( i ) {
  70                      if ( 0 !== i ) {
  71                          $( this ).remove();
  72                      }
  73                  } );
  74  
  75                  if ( $( '#delete-group-avatar-button' ).length ) {
  76                      $( '#delete-group-avatar-button' ).remove();
  77                  }
  78  
  79              // Group Create.
  80              } else if ( $( '#group-create-body' ).length ) {
  81                  $( '.main-column p #file' ).remove();
  82                  $( '.main-column p #upload' ).remove();
  83  
  84              // Member Admin.
  85              } else if ( $( '#bp_members_user_admin_avatar a.bp-members-avatar-user-admin' ).length ) {
  86                  $( '#bp_members_user_admin_avatar a.bp-members-avatar-user-admin' ).remove();
  87              }
  88          },
  89  
  90          setView: function( view ) {
  91              // Clear views.
  92              if ( ! _.isUndefined( this.views.models ) ) {
  93                  _.each( this.views.models, function( model ) {
  94                      model.get( 'view' ).remove();
  95                  }, this );
  96              }
  97  
  98              // Reset Views.
  99              this.views.reset();
 100  
 101              // Reset Avatars (file uploaded).
 102              if ( ! _.isUndefined( this.avatars ) ) {
 103                  this.avatars.reset();
 104              }
 105  
 106              // Reset the Jcrop API.
 107              if ( ! _.isEmpty( this.jcropapi ) ) {
 108                  this.jcropapi.destroy();
 109                  this.jcropapi = {};
 110              }
 111  
 112              // Load the required view.
 113              switch ( view ) {
 114                  case 'upload':
 115                      this.uploaderView();
 116                      break;
 117  
 118                  case 'delete':
 119                      this.deleteView();
 120                      break;
 121  
 122                  case 'recycle':
 123                      this.recycleView();
 124                      break;
 125              }
 126          },
 127  
 128          resetViews: function() {
 129              // Reset to the uploader view.
 130              this.nav.trigger( 'bp-avatar-view:changed', 'upload' );
 131  
 132              // Reset to the uploader nav.
 133              _.each( this.navItems.models, function( model ) {
 134                  if ( model.id === 'upload' ) {
 135                      model.set( { active: 1 } );
 136                  } else {
 137                      model.set( { active: 0 } );
 138                  }
 139              } );
 140          },
 141  
 142          setupNav: function() {
 143              var self = this,
 144                  initView, activeView;
 145  
 146              this.navItems = new Backbone.Collection();
 147  
 148              _.each( BP_Uploader.settings.nav, function( item, index ) {
 149                  if ( ! _.isObject( item ) ) {
 150                      return;
 151                  }
 152  
 153                  // Reset active View.
 154                  activeView = 0;
 155  
 156                  if ( 0 === index ) {
 157                      initView = item.id;
 158                      activeView = 1;
 159                  }
 160  
 161                  self.navItems.add( {
 162                      id     : item.id,
 163                      name   : item.caption,
 164                      href   : '#',
 165                      active : activeView,
 166                      hide   : _.isUndefined( item.hide ) ? 0 : item.hide
 167                  } );
 168              } );
 169  
 170              this.nav = new bp.Views.Nav( { collection: this.navItems } );
 171              this.nav.inject( '.bp-avatar-nav' );
 172  
 173              // Activate the initial view (uploader).
 174              this.setView( initView );
 175  
 176              // Listen to nav changes (it's like a do_action!).
 177              this.nav.on( 'bp-avatar-view:changed', _.bind( this.setView, this ) );
 178          },
 179  
 180          uploaderView: function() {
 181              // Listen to the Queued uploads.
 182              bp.Uploader.filesQueue.on( 'add', this.uploadProgress, this );
 183  
 184              // Create the BuddyPress Uploader.
 185              var uploader = new bp.Views.Uploader();
 186  
 187              // Add it to views.
 188              this.views.add( { id: 'upload', view: uploader } );
 189  
 190              // Display it.
 191              uploader.inject( '.bp-avatar' );
 192          },
 193  
 194          uploadProgress: function() {
 195              // Create the Uploader status view.
 196              var avatarStatus = new bp.Views.uploaderStatus( { collection: bp.Uploader.filesQueue } );
 197  
 198              if ( ! _.isUndefined( this.views.get( 'status' ) ) ) {
 199                  this.views.set( { id: 'status', view: avatarStatus } );
 200              } else {
 201                  this.views.add( { id: 'status', view: avatarStatus } );
 202              }
 203  
 204              // Display it.
 205              avatarStatus.inject( '.bp-avatar-status' );
 206          },
 207  
 208          cropView: function() {
 209              var status;
 210  
 211              // Bail there was an error during the Upload.
 212              if ( _.isEmpty( this.avatars.models ) ) {
 213                  return;
 214              }
 215  
 216              // Make sure to remove the uploads status.
 217              if ( ! _.isUndefined( this.views.get( 'status' ) ) ) {
 218                  status = this.views.get( 'status' );
 219                  status.get( 'view' ).remove();
 220                  this.views.remove( { id: 'status', view: status } );
 221              }
 222  
 223              // Create the Avatars view.
 224              var avatar = new bp.Views.Avatars( { collection: this.avatars } );
 225              this.views.add( { id: 'crop', view: avatar } );
 226  
 227              avatar.inject( '.bp-avatar' );
 228          },
 229  
 230          setAvatar: function( avatar ) {
 231              var self = this,
 232                  crop;
 233  
 234              // Remove the crop view.
 235              if ( ! _.isUndefined( this.views.get( 'crop' ) ) ) {
 236                  // Remove the JCrop API.
 237                  if ( ! _.isEmpty( this.jcropapi ) ) {
 238                      this.jcropapi.destroy();
 239                      this.jcropapi = {};
 240                  }
 241                  crop = this.views.get( 'crop' );
 242                  crop.get( 'view' ).remove();
 243                  this.views.remove( { id: 'crop', view: crop } );
 244              }
 245  
 246              // Set the avatar !
 247              bp.ajax.post( 'bp_avatar_set', {
 248                  json:          true,
 249                  original_file: avatar.get( 'url' ),
 250                  crop_w:        avatar.get( 'w' ),
 251                  crop_h:        avatar.get( 'h' ),
 252                  crop_x:        avatar.get( 'x' ),
 253                  crop_y:        avatar.get( 'y' ),
 254                  item_id:       avatar.get( 'item_id' ),
 255                  object:        avatar.get( 'object' ),
 256                  type:          _.isUndefined( avatar.get( 'type' ) ) ? 'crop' : avatar.get( 'type' ),
 257                  nonce:         avatar.get( 'nonces' ).set
 258              } ).done( function( response ) {
 259                  var avatarStatus = new bp.Views.AvatarStatus( {
 260                      value : BP_Uploader.strings.feedback_messages[ response.feedback_code ],
 261                      type : 'success'
 262                  } );
 263  
 264                  self.views.add( {
 265                      id   : 'status',
 266                      view : avatarStatus
 267                  } );
 268  
 269                  avatarStatus.inject( '.bp-avatar-status' );
 270  
 271                  // Update each avatars of the page.
 272                  $( '.' + avatar.get( 'object' ) + '-' + response.item_id + '-avatar' ).each( function() {
 273                      $(this).prop( 'src', response.avatar );
 274                  } );
 275  
 276                  // Inject the Delete nav.
 277                  bp.Avatar.navItems.get( 'delete' ).set( { hide: 0 } );
 278  
 279                  /**
 280                   * Set the Attachment object
 281                   *
 282                   * You can run extra actions once the avatar is set using:
 283                   * bp.Avatar.Attachment.on( 'change:url', function( data ) { your code } );
 284                   *
 285                   * In this case data.attributes will include the url to the newly
 286                   * uploaded avatar, the object and the item_id concerned.
 287                   */
 288                  self.Attachment.set( _.extend(
 289                      _.pick( avatar.attributes, ['object', 'item_id'] ),
 290                      { url: response.avatar, action: 'uploaded' }
 291                  ) );
 292  
 293              } ).fail( function( response ) {
 294                  var feedback = BP_Uploader.strings.default_error;
 295                  if ( ! _.isUndefined( response ) ) {
 296                      feedback = BP_Uploader.strings.feedback_messages[ response.feedback_code ];
 297                  }
 298  
 299                  var avatarStatus = new bp.Views.AvatarStatus( {
 300                      value : feedback,
 301                      type : 'error'
 302                  } );
 303  
 304                  self.views.add( {
 305                      id   : 'status',
 306                      view : avatarStatus
 307                  } );
 308  
 309                  avatarStatus.inject( '.bp-avatar-status' );
 310              } );
 311          },
 312  
 313          deleteView: function() {
 314              // Create the delete model.
 315              var delete_model = new Backbone.Model( _.pick( BP_Uploader.settings.defaults.multipart_params.bp_params,
 316                  'object',
 317                  'item_id',
 318                  'nonces'
 319              ) );
 320  
 321              // Create the delete view.
 322              var deleteView = new bp.Views.DeleteAvatar( { model: delete_model } );
 323  
 324              // Add it to views.
 325              this.views.add( { id: 'delete', view: deleteView } );
 326  
 327              // Display it.
 328              deleteView.inject( '.bp-avatar' );
 329          },
 330  
 331          deleteAvatar: function( model ) {
 332              var self = this,
 333                  deleteView;
 334  
 335              // Remove the delete view.
 336              if ( ! _.isUndefined( this.views.get( 'delete' ) ) ) {
 337                  deleteView = this.views.get( 'delete' );
 338                  deleteView.get( 'view' ).remove();
 339                  this.views.remove( { id: 'delete', view: deleteView } );
 340              }
 341  
 342              // Remove the avatar!
 343              bp.ajax.post( 'bp_avatar_delete', {
 344                  json:          true,
 345                  item_id:       model.get( 'item_id' ),
 346                  object:        model.get( 'object' ),
 347                  nonce:         model.get( 'nonces' ).remove
 348              } ).done( function( response ) {
 349                  var avatarStatus = new bp.Views.AvatarStatus( {
 350                      value : BP_Uploader.strings.feedback_messages[ response.feedback_code ],
 351                      type : 'success'
 352                  } );
 353  
 354                  self.views.add( {
 355                      id   : 'status',
 356                      view : avatarStatus
 357                  } );
 358  
 359                  avatarStatus.inject( '.bp-avatar-status' );
 360  
 361                  // Update each avatars of the page.
 362                  $( '.' + model.get( 'object' ) + '-' + response.item_id + '-avatar').each( function() {
 363                      $( this ).prop( 'src', response.avatar );
 364                  } );
 365  
 366                  // Remove the Delete nav.
 367                  bp.Avatar.navItems.get( 'delete' ).set( { active: 0, hide: 1 } );
 368  
 369                  /**
 370                   * Reset the Attachment object.
 371                   *
 372                   * You can run extra actions once the avatar is set using:
 373                   * bp.Avatar.Attachment.on( 'change:url', function( data ) { your code } );
 374                   *
 375                   * In this case data.attributes will include the url to the gravatar,
 376                   * the object and the item_id concerned.
 377                   */
 378                  self.Attachment.set( _.extend(
 379                      _.pick( model.attributes, ['object', 'item_id'] ),
 380                      { url: response.avatar, action: 'deleted' }
 381                  ) );
 382  
 383              } ).fail( function( response ) {
 384                  var feedback = BP_Uploader.strings.default_error;
 385                  if ( ! _.isUndefined( response ) ) {
 386                      feedback = BP_Uploader.strings.feedback_messages[ response.feedback_code ];
 387                  }
 388  
 389                  var avatarStatus = new bp.Views.AvatarStatus( {
 390                      value : feedback,
 391                      type : 'error'
 392                  } );
 393  
 394                  self.views.add( {
 395                      id   : 'status',
 396                      view : avatarStatus
 397                  } );
 398  
 399                  avatarStatus.inject( '.bp-avatar-status' );
 400              } );
 401          },
 402  
 403          removeWarning: function() {
 404              if ( ! _.isNull( this.warning ) ) {
 405                  this.warning.remove();
 406              }
 407          },
 408  
 409          displayWarning: function( message ) {
 410              this.removeWarning();
 411  
 412              this.warning = new bp.Views.uploaderWarning( {
 413                  value: message
 414              } );
 415  
 416              this.warning.inject( '.bp-avatar-status' );
 417          },
 418  
 419          recycleView: function() {
 420              if ( ! this.historicAvatars ) {
 421                  this.historicAvatars = new Backbone.Collection( BP_Uploader.settings.history );
 422              }
 423  
 424              // Create the recycle view.
 425              var recycleView = new bp.Views.RecycleAvatar( { collection: this.historicAvatars } );
 426  
 427              // Add it to views.
 428              this.views.add( { id: 'recycle', view: recycleView } );
 429  
 430              // Display it.
 431              recycleView.inject( '.bp-avatar' );
 432          },
 433  
 434          recycleHistoricAvatar: function( model ) {
 435              var self = this;
 436              model.set( 'selected', false );
 437  
 438              // Recycle the avatar.
 439              bp.ajax.post( 'bp_avatar_recycle_previous', {
 440                  json: true,
 441                  item_id: BP_Uploader.settings.defaults.multipart_params.bp_params.item_id,
 442                  avatar_id: model.get( 'id' ),
 443                  object: BP_Uploader.settings.defaults.multipart_params.bp_params.object,
 444                  nonce: BP_Uploader.settings.historyNonces.recylePrevious
 445              } ).done( function( response ) {
 446                  if ( response.historicalAvatar ) {
 447                      model.collection.add( response.historicalAvatar );
 448                  }
 449  
 450                  model.collection.remove( model );
 451  
 452                  if ( response.feedback_code ) {
 453                      var avatarStatus = new bp.Views.AvatarStatus( {
 454                          value : BP_Uploader.strings.feedback_messages[ response.feedback_code ],
 455                          type : 'success'
 456                      } );
 457  
 458                      self.views.add( {
 459                          id   : 'status',
 460                          view : avatarStatus
 461                      } );
 462  
 463                      avatarStatus.inject( '.bp-avatar-status' );
 464                  }
 465  
 466                  // Update each avatars of the page.
 467                  $( '.' + BP_Uploader.settings.defaults.multipart_params.bp_params.object + '-' + response.item_id + '-avatar' ).each( function() {
 468                      $( this ).prop( 'src', response.avatar );
 469                  } );
 470  
 471              } ).fail( function( response ) {
 472                  var error_message = BP_Uploader.strings.default_error;
 473                  if ( response && response.message ) {
 474                      error_message = response.message;
 475                  }
 476  
 477                  var avatarStatus = new bp.Views.AvatarStatus( {
 478                      value : error_message,
 479                      type : 'error'
 480                  } );
 481  
 482                  self.views.add( {
 483                      id   : 'status',
 484                      view : avatarStatus
 485                  } );
 486  
 487                  avatarStatus.inject( '.bp-avatar-status' );
 488              } );
 489          },
 490  
 491          deletePreviousAvatar: function( model ) {
 492              var self = this;
 493              model.set( 'selected', false );
 494  
 495              // Recycle the avatar.
 496              bp.ajax.post( 'bp_avatar_delete_previous', {
 497                  json: true,
 498                  item_id: BP_Uploader.settings.defaults.multipart_params.bp_params.item_id,
 499                  avatar_id: model.get( 'id' ),
 500                  object: BP_Uploader.settings.defaults.multipart_params.bp_params.object,
 501                  nonce: BP_Uploader.settings.historyNonces.deletePrevious
 502              } ).done( function( response ) {
 503                  model.collection.remove( model );
 504  
 505                  if ( response.feedback_code ) {
 506                      var avatarStatus = new bp.Views.AvatarStatus( {
 507                          value : BP_Uploader.strings.feedback_messages[ response.feedback_code ],
 508                          type : 'success'
 509                      } );
 510  
 511                      self.views.add( {
 512                          id   : 'status',
 513                          view : avatarStatus
 514                      } );
 515  
 516                      avatarStatus.inject( '.bp-avatar-status' );
 517                  }
 518  
 519              } ).fail( function( response ) {
 520                  var error_message = BP_Uploader.strings.default_error;
 521                  if ( response && response.message ) {
 522                      error_message = response.message;
 523                  }
 524  
 525                  var avatarStatus = new bp.Views.AvatarStatus( {
 526                      value : error_message,
 527                      type : 'error'
 528                  } );
 529  
 530                  self.views.add( {
 531                      id   : 'status',
 532                      view : avatarStatus
 533                  } );
 534  
 535                  avatarStatus.inject( '.bp-avatar-status' );
 536              } );
 537          }
 538      };
 539  
 540      // Main Nav view.
 541      bp.Views.Nav = bp.View.extend( {
 542          tagName:    'ul',
 543          className:  'avatar-nav-items',
 544  
 545          events: {
 546              'click .bp-avatar-nav-item' : 'toggleView'
 547          },
 548  
 549          initialize: function() {
 550              var hasAvatar = _.findWhere( this.collection.models, { id: 'delete' } );
 551  
 552              // Display a message to inform about the delete tab.
 553              if ( 1 !== hasAvatar.get( 'hide' ) ) {
 554                  bp.Avatar.displayWarning( BP_Uploader.strings.has_avatar_warning );
 555              }
 556  
 557              _.each( this.collection.models, this.addNavItem, this );
 558              this.collection.on( 'change:hide', this.showHideNavItem, this );
 559          },
 560  
 561          addNavItem: function( item ) {
 562              /**
 563               * The delete nav is not added if no avatar
 564               * is set for the object.
 565               */
 566              if ( 1 === item.get( 'hide' ) ) {
 567                  return;
 568              }
 569  
 570              this.views.add( new bp.Views.NavItem( { model: item } ) );
 571          },
 572  
 573          showHideNavItem: function( item ) {
 574              var isRendered = null;
 575  
 576              /**
 577               * Loop in views to show/hide the nav item
 578               * BuddyPress is only using this for the delete nav
 579               */
 580              _.each( this.views._views[''], function( view ) {
 581                  if ( 1 === view.model.get( 'hide' ) ) {
 582                      view.remove();
 583                  }
 584  
 585                  // Check to see if the nav is not already rendered.
 586                  if ( item.get( 'id' ) === view.model.get( 'id' ) ) {
 587                      isRendered = true;
 588                  }
 589              } );
 590  
 591              // Add the Delete nav if not rendered.
 592              if ( ! _.isBoolean( isRendered ) ) {
 593                  this.addNavItem( item );
 594              }
 595          },
 596  
 597          toggleView: function( event ) {
 598              event.preventDefault();
 599  
 600              // First make sure to remove all warnings.
 601              bp.Avatar.removeWarning();
 602  
 603              var active = $( event.target ).data( 'nav' );
 604  
 605              _.each( this.collection.models, function( model ) {
 606                  if ( model.id === active ) {
 607                      model.set( { active: 1 } );
 608                      this.trigger( 'bp-avatar-view:changed', model.id );
 609                  } else {
 610                      model.set( { active: 0 } );
 611                  }
 612              }, this );
 613          }
 614      } );
 615  
 616      // Nav item view.
 617      bp.Views.NavItem = bp.View.extend( {
 618          tagName:    'li',
 619          className:  'avatar-nav-item',
 620          template: bp.template( 'bp-avatar-nav' ),
 621  
 622          initialize: function() {
 623              if ( 1 === this.model.get( 'active' ) ) {
 624                  this.el.className += ' current';
 625              }
 626              this.el.id += 'bp-avatar-' + this.model.get( 'id' );
 627  
 628              this.model.on( 'change:active', this.setCurrentNav, this );
 629          },
 630  
 631          setCurrentNav: function( model ) {
 632              if ( 1 === model.get( 'active' ) ) {
 633                  this.$el.addClass( 'current' );
 634              } else {
 635                  this.$el.removeClass( 'current' );
 636              }
 637          }
 638      } );
 639  
 640      // Avatars view.
 641      bp.Views.Avatars = bp.View.extend( {
 642          className: 'items',
 643  
 644          initialize: function() {
 645              _.each( this.collection.models, this.addItemView, this );
 646          },
 647  
 648          addItemView: function( item ) {
 649              // Defaults to 150.
 650              var full_d = { full_h: 150, full_w: 150 };
 651  
 652              // Make sure to take in account bp_core_avatar_full_height or bp_core_avatar_full_width php filters.
 653              if ( ! _.isUndefined( BP_Uploader.settings.crop.full_h ) && ! _.isUndefined( BP_Uploader.settings.crop.full_w ) ) {
 654                  full_d.full_h = BP_Uploader.settings.crop.full_h;
 655                  full_d.full_w = BP_Uploader.settings.crop.full_w;
 656              }
 657  
 658              // Set the avatar model.
 659              item.set( _.extend( _.pick( BP_Uploader.settings.defaults.multipart_params.bp_params,
 660                  'object',
 661                  'item_id',
 662                  'nonces'
 663              ), full_d ) );
 664  
 665              // Add the view.
 666              this.views.add( new bp.Views.Avatar( { model: item } ) );
 667          }
 668      } );
 669  
 670      // Avatar view.
 671      bp.Views.Avatar = bp.View.extend( {
 672          className: 'item',
 673          template: bp.template( 'bp-avatar-item' ),
 674  
 675          events: {
 676              'click .avatar-crop-submit': 'cropAvatar'
 677          },
 678  
 679          initialize: function() {
 680              _.defaults( this.options, {
 681                  full_h:  BP_Uploader.settings.crop.full_h,
 682                  full_w:  BP_Uploader.settings.crop.full_w,
 683                  aspectRatio : 1
 684              } );
 685  
 686              // Display a warning if the image is smaller than minimum advised.
 687              if ( false !== this.model.get( 'feedback' ) ) {
 688                  bp.Avatar.displayWarning( this.model.get( 'feedback' ) );
 689              }
 690  
 691              this.on( 'ready', this.initCropper );
 692          },
 693  
 694          initCropper: function() {
 695              var self = this,
 696                  tocrop = this.$el.find( '#avatar-to-crop img' ),
 697                  availableWidth = this.$el.width(),
 698                  selection = {}, crop_top, crop_bottom, crop_left, crop_right, nh, nw;
 699  
 700              if ( ! _.isUndefined( this.options.full_h ) && ! _.isUndefined( this.options.full_w ) ) {
 701                  this.options.aspectRatio = this.options.full_w / this.options.full_h;
 702              }
 703  
 704              selection.w = this.model.get( 'width' );
 705              selection.h = this.model.get( 'height' );
 706  
 707              /**
 708               * Make sure the crop preview is at the right of the avatar
 709               * if the available width allowes it.
 710               */
 711              if ( this.options.full_w + selection.w + 20 < availableWidth ) {
 712                  $( '#avatar-to-crop' ).addClass( 'adjust' );
 713                  this.$el.find( '.avatar-crop-management' ).addClass( 'adjust' );
 714              }
 715  
 716              if ( selection.h <= selection.w ) {
 717                  crop_top    = Math.round( selection.h / 4 );
 718                  nh = nw     = Math.round( selection.h / 2 );
 719                  crop_bottom = nh + crop_top;
 720                  crop_left   = ( selection.w - nw ) / 2;
 721                  crop_right  = nw + crop_left;
 722              } else {
 723                  crop_left   = Math.round( selection.w / 4 );
 724                  nh = nw     = Math.round( selection.w / 2 );
 725                  crop_right  = nw + crop_left;
 726                  crop_top    = ( selection.h - nh ) / 2;
 727                  crop_bottom = nh + crop_top;
 728              }
 729  
 730              // Add the cropping interface.
 731              tocrop.Jcrop( {
 732                  onChange: _.bind( self.showPreview, self ),
 733                  onSelect: _.bind( self.showPreview, self ),
 734                  aspectRatio: self.options.aspectRatio,
 735                  setSelect: [ crop_left, crop_top, crop_right, crop_bottom ]
 736              }, function() {
 737                  // Get the Jcrop API.
 738                  bp.Avatar.jcropapi = this;
 739              } );
 740          },
 741  
 742          cropAvatar: function( event ) {
 743              event.preventDefault();
 744  
 745              bp.Avatar.setAvatar( this.model );
 746          },
 747  
 748          showPreview: function( coords ) {
 749              if ( ! coords.w || ! coords.h ) {
 750                  return;
 751              }
 752  
 753              if ( parseInt( coords.w, 10 ) > 0 ) {
 754                  var fw = this.options.full_w;
 755                  var fh = this.options.full_h;
 756                  var rx = fw / coords.w;
 757                  var ry = fh / coords.h;
 758  
 759                  // Update the model.
 760                  this.model.set( { x: coords.x, y: coords.y, w: coords.w, h: coords.h } );
 761  
 762                  $( '#avatar-crop-preview' ).css( {
 763                      maxWidth:'none',
 764                      width: Math.round( rx *  this.model.get( 'width' ) )+ 'px',
 765                      height: Math.round( ry * this.model.get( 'height' ) )+ 'px',
 766                      marginLeft: '-' + Math.round( rx * this.model.get( 'x' ) ) + 'px',
 767                      marginTop: '-' + Math.round( ry * this.model.get( 'y' ) ) + 'px'
 768                  } );
 769              }
 770          }
 771      } );
 772  
 773      // BuddyPress Avatar Feedback view.
 774      bp.Views.AvatarStatus = bp.View.extend( {
 775          tagName: 'p',
 776          className: 'updated',
 777          id: 'bp-avatar-feedback',
 778  
 779          initialize: function() {
 780              this.el.className += ' ' + this.options.type;
 781              this.value = this.options.value;
 782          },
 783  
 784          render: function() {
 785              this.$el.html( this.value );
 786              return this;
 787          }
 788      } );
 789  
 790      // BuddyPress Avatar Delete view
 791      bp.Views.DeleteAvatar = bp.View.extend( {
 792          tagName: 'div',
 793          id: 'bp-delete-avatar-container',
 794          template: bp.template( 'bp-avatar-delete' ),
 795  
 796          events: {
 797              'click #bp-delete-avatar': 'deleteAvatar'
 798          },
 799  
 800          deleteAvatar: function( event ) {
 801              event.preventDefault();
 802  
 803              bp.Avatar.deleteAvatar( this.model );
 804          }
 805      } );
 806  
 807      bp.Views.HistoryAvatarsItem = bp.View.extend( {
 808          tagName: 'tr',
 809          className: 'historic-avatar',
 810          template: bp.template( 'bp-avatar-recycle-history-item' ),
 811  
 812          events: {
 813              'change input[name="avatar_id"]': 'selectAvatar'
 814          },
 815  
 816          initialize: function() {
 817              this.model.on( 'change:selected', this.toggleSelection, this );
 818              this.model.on( 'remove', this.clearView, this );
 819          },
 820  
 821          toggleSelection: function( model, selected ) {
 822              if ( true === selected ) {
 823                  this.$el.parent().find( '#' + model.get( 'id' ) ).addClass( 'selected' );
 824              } else {
 825                  this.$el.parent().find( '#' + model.get( 'id' ) ).removeClass( 'selected' );
 826                  this.$el.parent().find( '#avatar_' + model.get( 'id' ) ).prop( 'checked', false );
 827              }
 828          },
 829  
 830          selectAvatar: function( event ) {
 831              event.preventDefault();
 832  
 833              if ( event.currentTarget.checked ) {
 834                  var self = this;
 835  
 836                  _.each( this.model.collection.models, function( model ) {
 837                      self.$el.parent().find( '#' + model.id ).removeClass( 'selected' );
 838                      model.set( 'selected', false, { silent: true } );
 839                  } );
 840  
 841                  this.model.set( 'selected', true );
 842              }
 843          },
 844  
 845          clearView: function() {
 846              this.views.view.remove();
 847          }
 848      } );
 849  
 850      bp.Views.RecycleAvatar = bp.View.extend( {
 851          tagName: 'div',
 852          id: 'bp-avatars-history-container',
 853          template: bp.template( 'bp-avatar-recycle' ),
 854  
 855          events: {
 856              'click button.avatar-history-action': 'doAvatarAction'
 857          },
 858  
 859          initialize: function() {
 860              _.each( this.collection.models, function( model ) {
 861                  this.views.add( '#bp-avatars-history-list', new bp.Views.HistoryAvatarsItem( { model: model } ) );
 862              }, this );
 863  
 864              this.collection.on( 'change:selected', this.updateButtonStatus, this );
 865              this.collection.on( 'add', this.addView, this );
 866          },
 867  
 868          addView: function( model ) {
 869              this.views.add( '#bp-avatars-history-list', new bp.Views.HistoryAvatarsItem( { model: model } ) );
 870          },
 871  
 872          updateButtonStatus: function( model ) {
 873              if ( true === model.get( 'selected' ) ) {
 874                  this.$el.find( 'button.disabled' ).removeClass( 'disabled' );
 875              }
 876          },
 877  
 878          doAvatarAction: function( event ) {
 879              event.preventDefault();
 880              var buttonClasses = event.currentTarget.classList,
 881                  selected = this.collection.findWhere( { selected: true } );
 882  
 883              if ( ! buttonClasses.contains( 'disabled' ) && selected ) {
 884                  // Make sure it's not possible to fire 2 actions at the same time.
 885                  this.$el.find( 'button.avatar-history-action' ).addClass( 'disabled' );
 886  
 887                  if ( buttonClasses.contains( 'recycle' ) ) {
 888                      bp.Avatar.recycleHistoricAvatar( selected );
 889                  } else if ( buttonClasses.contains( 'delete' ) ) {
 890                      bp.Avatar.deletePreviousAvatar( selected );
 891                  }
 892              }
 893          }
 894      } );
 895  
 896      bp.Avatar.start();
 897  
 898  })( window.bp, jQuery );


Generated: Thu Nov 21 01:00:57 2024 Cross-referenced by PHPXref 0.7.1