avatar-crop-form.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. import Ember from 'ember';
  2. export default Ember.Component.extend({
  3. classNames: 'avatar-crop',
  4. cropit: Ember.inject.service('cropit'),
  5. isLoaded: false,
  6. isBusy: false,
  7. secret: '',
  8. isNested: false,
  9. hash: null,
  10. crop: null,
  11. apiUrl: function() {
  12. return 'users/' + this.auth.get('user.id') + '/avatar';
  13. }.property(),
  14. finalSecret: function() {
  15. return this.get('secret') || this.get('options.crop_org.secret');
  16. }.property('secret', 'options.crop_org.secret'),
  17. finalHash: function() {
  18. return this.get('hash') || this.get('auth.user.avatar_hash');
  19. }.property('hash', 'auth.user.avatar_hash'),
  20. avatarSize: function() {
  21. if (this.get('isNested')) {
  22. return this.get('options.crop_tmp.size');
  23. } else {
  24. return this.get('options.crop_org.size');
  25. }
  26. }.property('options.crop_tmp.size', 'options.crop_org.size'),
  27. imagePath: function() {
  28. var src = Ember.$('base').attr('href') + 'user-avatar/';
  29. src += this.get('finalSecret') + ':' + this.get('finalHash') + '/';
  30. src += this.get('auth.user.id') + '.png';
  31. return src;
  32. }.property('finalSecret', 'finalHash', 'auth.user.id'),
  33. loadLibrary: function() {
  34. var self = this;
  35. this.get('cropit').load().then(function() {
  36. self.set('isLoaded', true);
  37. Ember.run.scheduleOnce('afterRender', function() {
  38. // initialise cropper
  39. var $cropper = self.$('.image-cropper');
  40. $cropper.width(self.get('avatarSize'));
  41. $cropper.cropit({
  42. width: self.get('avatarSize'),
  43. height: self.get('avatarSize'),
  44. imageState: {
  45. src: self.get('imagePath')
  46. },
  47. onImageLoaded: function() {
  48. if (self.get('isNested')) {
  49. // center uploaded image
  50. var zoomLevel = $cropper.cropit('zoom');
  51. var imageSize = $cropper.cropit('imageSize');
  52. // is it wider than taller?
  53. if (imageSize.width > imageSize.height) {
  54. var displayedWidth = (imageSize.width * zoomLevel);
  55. var offsetX = (displayedWidth - self.get('avatarSize')) / -2;
  56. $cropper.cropit('offset', { x: offsetX, y: 0 });
  57. } else if (imageSize.width < imageSize.height) {
  58. var displayedHeight = (imageSize.height * zoomLevel);
  59. var offsetY = (displayedHeight - self.get('avatarSize')) / -2;
  60. $cropper.cropit('offset', { x: 0, y: offsetY });
  61. }
  62. } else {
  63. // use preserved crop
  64. var crop = self.get('options.crop_org.crop');
  65. if (crop) {
  66. $cropper.cropit('zoom', crop.zoom);
  67. $cropper.cropit('offset', { x: crop.x, y: crop.y });
  68. }
  69. }
  70. }
  71. });
  72. });
  73. });
  74. }.on('didInsertElement'),
  75. destroyCrop: function() {
  76. this.$('.image-cropper').cropit('disable');
  77. }.on('willDestroyElement'),
  78. actions: {
  79. crop: function() {
  80. if (this.get('isBusy')) { return; }
  81. this.set('isBusy', true);
  82. var opName = 'crop_org';
  83. if (this.get('isNested')) {
  84. opName = 'crop_tmp';
  85. }
  86. var $cropper = this.$('.image-cropper');
  87. var crop = {
  88. 'offset': $cropper.cropit('offset'),
  89. 'zoom': $cropper.cropit('zoom')
  90. };
  91. var self = this;
  92. this.ajax.post(this.get('apiUrl'), {
  93. 'avatar': opName,
  94. 'crop': crop
  95. }).then(function(data) {
  96. if (self.isDestroyed) { return; }
  97. self.toast.success(data.detail);
  98. self.get('options').setProperties(data.options);
  99. self.set('auth.user.avatar_hash', data.avatar_hash);
  100. self.set('activeForm', 'select-avatar-type-form');
  101. }, function(jhXHR) {
  102. if (self.isDestroyed) { return; }
  103. if (jhXHR.status === 400) {
  104. self.toast.error(jhXHR.responseJSON.detail);
  105. } else {
  106. self.toast.apiError(jhXHR);
  107. }
  108. }).finally(function() {
  109. if (self.isDestroyed) { return; }
  110. self.set('isBusy', false);
  111. });
  112. },
  113. cancel: function() {
  114. this.set('activeForm', 'select-avatar-type-form');
  115. }
  116. }
  117. });