OnlineUsersManager.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /* eslint-disable
  2. camelcase,
  3. n/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. let OnlineUsersManager
  20. export default OnlineUsersManager = (function () {
  21. OnlineUsersManager = class OnlineUsersManager {
  22. static initClass() {
  23. this.prototype.cursorUpdateInterval = 500
  24. }
  25. constructor(ide, $scope) {
  26. this.ide = ide
  27. this.$scope = $scope
  28. this.$scope.onlineUsers = {}
  29. this.$scope.onlineUserCursorHighlights = {}
  30. this.$scope.onlineUsersArray = []
  31. this.$scope.onlineUsersCount = 0
  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 (const 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 (const 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. // keep a count of the other online users
  104. this.$scope.onlineUsersCount = this.$scope.onlineUsersArray.length
  105. this.$scope.onlineUserCursorHighlights = {}
  106. for (const client_id in this.$scope.onlineUsers) {
  107. const client = this.$scope.onlineUsers[client_id]
  108. const { doc_id } = client
  109. if (doc_id == null || client.row == null || client.column == null) {
  110. continue
  111. }
  112. if (!this.$scope.onlineUserCursorHighlights[doc_id]) {
  113. this.$scope.onlineUserCursorHighlights[doc_id] = []
  114. }
  115. this.$scope.onlineUserCursorHighlights[doc_id].push({
  116. label: client.name,
  117. cursor: {
  118. row: client.row,
  119. column: client.column,
  120. },
  121. hue: ColorManager.getHueForUserId(client.user_id),
  122. })
  123. }
  124. if (this.$scope.onlineUsersArray.length > 0) {
  125. delete this.cursorUpdateTimeout
  126. return (this.cursorUpdateInterval = 500)
  127. } else {
  128. delete this.cursorUpdateTimeout
  129. return (this.cursorUpdateInterval = 60 * 1000 * 5)
  130. }
  131. }
  132. sendCursorPositionUpdate(position) {
  133. if (position != null) {
  134. this.$scope.currentPosition = position // keep track of the latest position
  135. }
  136. if (this.cursorUpdateTimeout == null) {
  137. return (this.cursorUpdateTimeout = setTimeout(() => {
  138. const doc_id = this.$scope.editor.open_doc_id
  139. // always send the latest position to other clients
  140. this.ide.socket.emit('clientTracking.updatePosition', {
  141. row:
  142. this.$scope.currentPosition != null
  143. ? this.$scope.currentPosition.row
  144. : undefined,
  145. column:
  146. this.$scope.currentPosition != null
  147. ? this.$scope.currentPosition.column
  148. : undefined,
  149. doc_id,
  150. })
  151. return delete this.cursorUpdateTimeout
  152. }, this.cursorUpdateInterval))
  153. }
  154. }
  155. }
  156. OnlineUsersManager.initClass()
  157. return OnlineUsersManager
  158. })()