OnlineUsersManager.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /* eslint-disable
  2. camelcase,
  3. handle-callback-err,
  4. max-len,
  5. no-return-assign,
  6. */
  7. // TODO: This file was created by bulk-decaffeinate.
  8. // Fix any style issues and re-enable lint.
  9. /*
  10. * decaffeinate suggestions:
  11. * DS101: Remove unnecessary use of Array.from
  12. * DS102: Remove unnecessary code created because of implicit returns
  13. * DS206: Consider reworking classes to avoid initClass
  14. * DS207: Consider shorter variations of null checks
  15. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  16. */
  17. import ColorManager from '../colors/ColorManager'
  18. import 'crypto-js/md5'
  19. import './controllers/OnlineUsersController'
  20. let OnlineUsersManager
  21. export default (OnlineUsersManager = (function() {
  22. OnlineUsersManager = class OnlineUsersManager {
  23. static initClass() {
  24. this.prototype.cursorUpdateInterval = 500
  25. }
  26. constructor(ide, $scope) {
  27. this.ide = ide
  28. this.$scope = $scope
  29. this.$scope.onlineUsers = {}
  30. this.$scope.onlineUserCursorHighlights = {}
  31. this.$scope.onlineUsersArray = []
  32. this.$scope.$on('cursor:editor:update', (event, position) => {
  33. return this.sendCursorPositionUpdate(position)
  34. })
  35. this.$scope.$on('project:joined', () => {
  36. return this.ide.socket.emit(
  37. 'clientTracking.getConnectedUsers',
  38. (error, connectedUsers) => {
  39. this.$scope.onlineUsers = {}
  40. for (let user of Array.from(connectedUsers || [])) {
  41. if (user.client_id === this.ide.socket.publicId) {
  42. // Don't store myself
  43. continue
  44. }
  45. // Store data in the same format returned by clientTracking.clientUpdated
  46. this.$scope.onlineUsers[user.client_id] = {
  47. id: user.client_id,
  48. user_id: user.user_id,
  49. email: user.email,
  50. name: `${user.first_name} ${user.last_name}`,
  51. doc_id:
  52. user.cursorData != null ? user.cursorData.doc_id : undefined,
  53. row: user.cursorData != null ? user.cursorData.row : undefined,
  54. column:
  55. user.cursorData != null ? user.cursorData.column : undefined
  56. }
  57. }
  58. return this.refreshOnlineUsers()
  59. }
  60. )
  61. })
  62. this.ide.socket.on('clientTracking.clientUpdated', client => {
  63. if (client.id !== this.ide.socket.publicId) {
  64. // Check it's not me!
  65. return this.$scope.$apply(() => {
  66. this.$scope.onlineUsers[client.id] = client
  67. return this.refreshOnlineUsers()
  68. })
  69. }
  70. })
  71. this.ide.socket.on('clientTracking.clientDisconnected', client_id => {
  72. return this.$scope.$apply(() => {
  73. delete this.$scope.onlineUsers[client_id]
  74. return this.refreshOnlineUsers()
  75. })
  76. })
  77. this.$scope.getHueForUserId = user_id => {
  78. return ColorManager.getHueForUserId(user_id)
  79. }
  80. }
  81. refreshOnlineUsers() {
  82. this.$scope.onlineUsersArray = []
  83. for (var client_id in this.$scope.onlineUsers) {
  84. const user = this.$scope.onlineUsers[client_id]
  85. if (user.doc_id != null) {
  86. user.doc = this.ide.fileTreeManager.findEntityById(user.doc_id)
  87. }
  88. // If the user's name is empty use their email as display name
  89. // Otherwise they're probably an anonymous user
  90. if (user.name === null || user.name.trim().length === 0) {
  91. if (user.email) {
  92. user.name = user.email.trim()
  93. } else if (user.user_id === 'anonymous-user') {
  94. user.name = 'Anonymous'
  95. }
  96. }
  97. user.initial = user.name != null ? user.name[0] : undefined
  98. if (!user.initial || user.initial === ' ') {
  99. user.initial = '?'
  100. }
  101. this.$scope.onlineUsersArray.push(user)
  102. }
  103. this.$scope.onlineUserCursorHighlights = {}
  104. for (client_id in this.$scope.onlineUsers) {
  105. const client = this.$scope.onlineUsers[client_id]
  106. const { doc_id } = client
  107. if (doc_id == null || client.row == null || client.column == null) {
  108. continue
  109. }
  110. if (!this.$scope.onlineUserCursorHighlights[doc_id]) {
  111. this.$scope.onlineUserCursorHighlights[doc_id] = []
  112. }
  113. this.$scope.onlineUserCursorHighlights[doc_id].push({
  114. label: client.name,
  115. cursor: {
  116. row: client.row,
  117. column: client.column
  118. },
  119. hue: ColorManager.getHueForUserId(client.user_id)
  120. })
  121. }
  122. if (this.$scope.onlineUsersArray.length > 0) {
  123. delete this.cursorUpdateTimeout
  124. return (this.cursorUpdateInterval = 500)
  125. } else {
  126. delete this.cursorUpdateTimeout
  127. return (this.cursorUpdateInterval = 60 * 1000 * 5)
  128. }
  129. }
  130. sendCursorPositionUpdate(position) {
  131. if (position != null) {
  132. this.$scope.currentPosition = position // keep track of the latest position
  133. }
  134. if (this.cursorUpdateTimeout == null) {
  135. return (this.cursorUpdateTimeout = setTimeout(() => {
  136. const doc_id = this.$scope.editor.open_doc_id
  137. // always send the latest position to other clients
  138. this.ide.socket.emit('clientTracking.updatePosition', {
  139. row:
  140. this.$scope.currentPosition != null
  141. ? this.$scope.currentPosition.row
  142. : undefined,
  143. column:
  144. this.$scope.currentPosition != null
  145. ? this.$scope.currentPosition.column
  146. : undefined,
  147. doc_id
  148. })
  149. return delete this.cursorUpdateTimeout
  150. }, this.cursorUpdateInterval))
  151. }
  152. }
  153. }
  154. OnlineUsersManager.initClass()
  155. return OnlineUsersManager
  156. })())