userAvatar.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. Meteor.subscribe('my-avatars');
  2. Template.userAvatar.helpers({
  3. userData() {
  4. // We need to handle a special case for the search results provided by the
  5. // `matteodem:easy-search` package. Since these results gets published in a
  6. // separate collection, and not in the standard Meteor.Users collection as
  7. // expected, we use a component parameter ("property") to distinguish the
  8. // two cases.
  9. const userCollection = this.esSearch ? ESSearchResults : Users;
  10. return userCollection.findOne(this.userId, {
  11. fields: {
  12. profile: 1,
  13. username: 1,
  14. },
  15. });
  16. },
  17. memberType() {
  18. const user = Users.findOne(this.userId);
  19. return user && user.isBoardAdmin() ? 'admin' : 'normal';
  20. },
  21. presenceStatusClassName() {
  22. const user = Users.findOne(this.userId);
  23. const userPresence = presences.findOne({ userId: this.userId });
  24. if (user && user.isInvitedTo(Session.get('currentBoard')))
  25. return 'pending';
  26. else if (!userPresence)
  27. return 'disconnected';
  28. else if (Session.equals('currentBoard', userPresence.state.currentBoardId))
  29. return 'active';
  30. else
  31. return 'idle';
  32. },
  33. });
  34. Template.userAvatar.events({
  35. 'click .js-change-avatar': Popup.open('changeAvatar'),
  36. });
  37. Template.userAvatarInitials.helpers({
  38. initials() {
  39. const user = Users.findOne(this.userId);
  40. return user && user.getInitials();
  41. },
  42. viewPortWidth() {
  43. const user = Users.findOne(this.userId);
  44. return (user && user.getInitials().length || 1) * 12;
  45. },
  46. });
  47. BlazeComponent.extendComponent({
  48. template() {
  49. return 'changeAvatarPopup';
  50. },
  51. onCreated() {
  52. this.error = new ReactiveVar('');
  53. },
  54. avatarUrlOptions() {
  55. return {
  56. auth: false,
  57. brokenIsFine: true,
  58. };
  59. },
  60. uploadedAvatars() {
  61. return Avatars.find({userId: Meteor.userId()});
  62. },
  63. isSelected() {
  64. const userProfile = Meteor.user().profile;
  65. const avatarUrl = userProfile && userProfile.avatarUrl;
  66. const currentAvatarUrl = this.currentData().url(this.avatarUrlOptions());
  67. return avatarUrl === currentAvatarUrl;
  68. },
  69. noAvatarUrl() {
  70. const userProfile = Meteor.user().profile;
  71. const avatarUrl = userProfile && userProfile.avatarUrl;
  72. return !avatarUrl;
  73. },
  74. setAvatar(avatarUrl) {
  75. Meteor.user().setAvatarUrl(avatarUrl);
  76. },
  77. setError(error) {
  78. this.error.set(error);
  79. },
  80. events() {
  81. return [{
  82. 'click .js-upload-avatar'() {
  83. this.$('.js-upload-avatar-input').click();
  84. },
  85. 'change .js-upload-avatar-input'(evt) {
  86. let file, fileUrl;
  87. FS.Utility.eachFile(evt, (f) => {
  88. try {
  89. file = Avatars.insert(new FS.File(f));
  90. fileUrl = file.url(this.avatarUrlOptions());
  91. } catch (e) {
  92. this.setError('avatar-too-big');
  93. }
  94. });
  95. if (fileUrl) {
  96. this.setError('');
  97. const fetchAvatarInterval = window.setInterval(() => {
  98. $.ajax({
  99. url: fileUrl,
  100. success: () => {
  101. this.setAvatar(file.url(this.avatarUrlOptions()));
  102. window.clearInterval(fetchAvatarInterval);
  103. },
  104. });
  105. }, 100);
  106. }
  107. },
  108. 'click .js-select-avatar'() {
  109. const avatarUrl = this.currentData().url(this.avatarUrlOptions());
  110. this.setAvatar(avatarUrl);
  111. },
  112. 'click .js-select-initials'() {
  113. this.setAvatar('');
  114. },
  115. 'click .js-delete-avatar'() {
  116. Avatars.remove(this.currentData()._id);
  117. },
  118. }];
  119. },
  120. }).register('changeAvatarPopup');
  121. Template.cardMembersPopup.helpers({
  122. isCardMember() {
  123. const cardId = Template.parentData()._id;
  124. const cardMembers = Cards.findOne(cardId).members || [];
  125. return _.contains(cardMembers, this.userId);
  126. },
  127. user() {
  128. return Users.findOne(this.userId);
  129. },
  130. });
  131. Template.cardMembersPopup.events({
  132. 'click .js-select-member'(evt) {
  133. const card = Cards.findOne(Session.get('currentCard'));
  134. const memberId = this.userId;
  135. card.toggleMember(memberId);
  136. evt.preventDefault();
  137. },
  138. });
  139. Template.cardMemberPopup.helpers({
  140. user() {
  141. return Users.findOne(this.userId);
  142. },
  143. });
  144. Template.cardMemberPopup.events({
  145. 'click .js-remove-member'() {
  146. Cards.findOne(this.cardId).unassignMember(this.userId);
  147. Popup.close();
  148. },
  149. 'click .js-edit-profile': Popup.open('editProfile'),
  150. });