You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
698 lines
20 KiB
698 lines
20 KiB
import moment from 'moment'
|
|
import mime from 'mime-type/with-db'
|
|
|
|
socialSharing = (options = {}) ->
|
|
window.plugins.socialsharing.share(options.message, options.subject, options.file, options.link)
|
|
|
|
isSubscribed = (_id) ->
|
|
return ChatSubscription.find({ rid: _id }).count() > 0
|
|
|
|
favoritesEnabled = ->
|
|
return RocketChat.settings.get 'Favorite_Rooms'
|
|
|
|
userCanDrop = (_id) ->
|
|
return !RocketChat.roomTypes.readOnly _id, Meteor.user()
|
|
|
|
Template.room.helpers
|
|
isTranslated: ->
|
|
sub = ChatSubscription.findOne { rid: this._id }, { fields: { autoTranslate: 1, autoTranslateLanguage: 1 } }
|
|
return RocketChat.settings.get('AutoTranslate_Enabled') and sub?.autoTranslate is true and sub.autoTranslateLanguage?
|
|
|
|
embeddedVersion: ->
|
|
return RocketChat.Layout.isEmbedded()
|
|
|
|
favorite: ->
|
|
sub = ChatSubscription.findOne { rid: this._id }, { fields: { f: 1 } }
|
|
return 'icon-star favorite-room pending-color' if sub?.f? and sub.f and favoritesEnabled()
|
|
return 'icon-star-empty'
|
|
|
|
favoriteLabel: ->
|
|
sub = ChatSubscription.findOne { rid: this._id }, { fields: { f: 1 } }
|
|
return "Unfavorite" if sub?.f? and sub.f and favoritesEnabled()
|
|
return "Favorite"
|
|
|
|
subscribed: ->
|
|
return isSubscribed(this._id)
|
|
|
|
messagesHistory: ->
|
|
hideMessagesOfType = []
|
|
RocketChat.settings.collection.find({_id: /Message_HideType_.+/}).forEach (record) ->
|
|
type = record._id.replace('Message_HideType_', '')
|
|
switch (type)
|
|
when 'mute_unmute'
|
|
types = [ 'user-muted', 'user-unmuted' ]
|
|
else
|
|
types = [ type ]
|
|
types.forEach (type) ->
|
|
index = hideMessagesOfType.indexOf(type)
|
|
|
|
if record.value is true and index is -1
|
|
hideMessagesOfType.push(type)
|
|
else if index > -1
|
|
hideMessagesOfType.splice(index, 1)
|
|
|
|
query =
|
|
rid: this._id
|
|
|
|
if hideMessagesOfType.length > 0
|
|
query.t =
|
|
$nin: hideMessagesOfType
|
|
|
|
options =
|
|
sort:
|
|
ts: 1
|
|
|
|
return ChatMessage.find(query, options)
|
|
|
|
hasMore: ->
|
|
return RoomHistoryManager.hasMore this._id
|
|
|
|
hasMoreNext: ->
|
|
return RoomHistoryManager.hasMoreNext this._id
|
|
|
|
isLoading: ->
|
|
return RoomHistoryManager.isLoading this._id
|
|
|
|
windowId: ->
|
|
return "chat-window-#{this._id}"
|
|
|
|
uploading: ->
|
|
return Session.get 'uploading'
|
|
|
|
roomName: ->
|
|
roomData = Session.get('roomData' + this._id)
|
|
return '' unless roomData
|
|
|
|
return RocketChat.roomTypes.getRoomName roomData.t, roomData
|
|
|
|
secondaryName: ->
|
|
roomData = Session.get('roomData' + this._id)
|
|
return '' unless roomData
|
|
|
|
return RocketChat.roomTypes.getSecondaryRoomName roomData.t, roomData
|
|
|
|
roomTopic: ->
|
|
roomData = Session.get('roomData' + this._id)
|
|
return '' unless roomData
|
|
return roomData.topic
|
|
|
|
showAnnouncement: ->
|
|
roomData = Session.get('roomData' + this._id)
|
|
return false unless roomData
|
|
Meteor.defer =>
|
|
if window.chatMessages and window.chatMessages[roomData._id]
|
|
window.chatMessages[roomData._id].resize()
|
|
return roomData.announcement isnt undefined and roomData.announcement isnt ''
|
|
|
|
roomAnnouncement: ->
|
|
roomData = Session.get('roomData' + this._id)
|
|
return '' unless roomData
|
|
return roomData.announcement
|
|
|
|
roomIcon: ->
|
|
roomData = Session.get('roomData' + this._id)
|
|
return '' unless roomData?.t
|
|
|
|
return RocketChat.roomTypes.getIcon roomData?.t
|
|
|
|
userStatus: ->
|
|
roomData = Session.get('roomData' + this._id)
|
|
return RocketChat.roomTypes.getUserStatus(roomData.t, this._id) or 'offline'
|
|
|
|
maxMessageLength: ->
|
|
return RocketChat.settings.get('Message_MaxAllowedSize')
|
|
|
|
unreadData: ->
|
|
data =
|
|
count: RoomHistoryManager.getRoom(this._id).unreadNotLoaded.get() + Template.instance().unreadCount.get()
|
|
|
|
room = RoomManager.getOpenedRoomByRid this._id
|
|
if room?
|
|
data.since = room.unreadSince?.get()
|
|
|
|
return data
|
|
|
|
containerBarsShow: (unreadData, uploading) ->
|
|
return 'show' if (unreadData?.count > 0 and unreadData.since?) or uploading?.length > 0
|
|
|
|
formatUnreadSince: ->
|
|
if not this.since? then return
|
|
|
|
return moment(this.since).calendar(null, {sameDay: 'LT'})
|
|
|
|
flexData: ->
|
|
flexData =
|
|
tabBar: Template.instance().tabBar
|
|
data:
|
|
rid: this._id
|
|
userDetail: Template.instance().userDetail.get(),
|
|
clearUserDetail: Template.instance().clearUserDetail
|
|
|
|
return flexData
|
|
|
|
adminClass: ->
|
|
return 'admin' if RocketChat.authz.hasRole(Meteor.userId(), 'admin')
|
|
|
|
showToggleFavorite: ->
|
|
return true if isSubscribed(this._id) and favoritesEnabled()
|
|
|
|
viewMode: ->
|
|
viewMode = Meteor.user()?.settings?.preferences?.viewMode
|
|
switch viewMode
|
|
when 1 then cssClass = 'cozy'
|
|
when 2 then cssClass = 'compact'
|
|
else cssClass = ''
|
|
return cssClass
|
|
|
|
selectable: ->
|
|
return Template.instance().selectable.get()
|
|
|
|
hideUsername: ->
|
|
return if Meteor.user()?.settings?.preferences?.hideUsernames then 'hide-usernames'
|
|
|
|
hideAvatar: ->
|
|
return if Meteor.user()?.settings?.preferences?.hideAvatars then 'hide-avatars'
|
|
|
|
userCanDrop: ->
|
|
return userCanDrop @_id
|
|
|
|
canPreview: ->
|
|
room = Session.get('roomData' + this._id)
|
|
if room.t isnt 'c'
|
|
return true
|
|
|
|
if RocketChat.settings.get('Accounts_AllowAnonymousRead') is true
|
|
return true
|
|
|
|
if RocketChat.authz.hasAllPermission('preview-c-room')
|
|
return true
|
|
|
|
return RocketChat.models.Subscriptions.findOne({rid: this._id})?
|
|
|
|
isSocialSharingOpen = false
|
|
touchMoved = false
|
|
|
|
Template.room.events
|
|
"click, touchend": (e, t) ->
|
|
Meteor.setTimeout ->
|
|
t.sendToBottomIfNecessaryDebounced()
|
|
, 100
|
|
|
|
"click .messages-container": (e) ->
|
|
if Template.instance().tabBar.getState() is 'opened' and Meteor.user()?.settings?.preferences?.hideFlexTab
|
|
Template.instance().tabBar.close()
|
|
|
|
"touchstart .message": (e, t) ->
|
|
touchMoved = false
|
|
isSocialSharingOpen = false
|
|
if e.originalEvent.touches.length isnt 1
|
|
return
|
|
|
|
if $(e.currentTarget).hasClass('system')
|
|
return
|
|
|
|
if e.target and e.target.nodeName is 'AUDIO'
|
|
return
|
|
|
|
if e.target and e.target.nodeName is 'A' and /^https?:\/\/.+/.test(e.target.getAttribute('href'))
|
|
e.preventDefault()
|
|
e.stopPropagation()
|
|
|
|
message = this._arguments[1]
|
|
doLongTouch = =>
|
|
|
|
if window.plugins?.socialsharing?
|
|
isSocialSharingOpen = true
|
|
|
|
if e.target and e.target.nodeName is 'A' and /^https?:\/\/.+/.test(e.target.getAttribute('href'))
|
|
if message.attachments?
|
|
attachment = _.find message.attachments, (item) -> return item.title is e.target.innerText
|
|
if attachment?
|
|
socialSharing
|
|
file: e.target.href
|
|
subject: e.target.innerText
|
|
message: message.msg
|
|
return
|
|
|
|
socialSharing
|
|
link: e.target.href
|
|
subject: e.target.innerText
|
|
message: message.msg
|
|
return
|
|
|
|
if e.target and e.target.nodeName is 'IMG'
|
|
socialSharing
|
|
file: e.target.src
|
|
message: message.msg
|
|
return
|
|
|
|
mobileMessageMenu.show(message, t, e, this)
|
|
|
|
Meteor.clearTimeout t.touchtime
|
|
t.touchtime = Meteor.setTimeout doLongTouch, 500
|
|
|
|
"click .message img": (e, t) ->
|
|
Meteor.clearTimeout t.touchtime
|
|
if isSocialSharingOpen is true or touchMoved is true
|
|
e.preventDefault()
|
|
e.stopPropagation()
|
|
|
|
"touchend .message": (e, t) ->
|
|
Meteor.clearTimeout t.touchtime
|
|
if isSocialSharingOpen is true
|
|
e.preventDefault()
|
|
e.stopPropagation()
|
|
return
|
|
|
|
if e.target and e.target.nodeName is 'A' and /^https?:\/\/.+/.test(e.target.getAttribute('href'))
|
|
if touchMoved is true
|
|
e.preventDefault()
|
|
e.stopPropagation()
|
|
return
|
|
|
|
if cordova?.InAppBrowser?
|
|
cordova.InAppBrowser.open(e.target.href, '_system')
|
|
else
|
|
window.open(e.target.href)
|
|
|
|
"touchmove .message": (e, t) ->
|
|
touchMoved = true
|
|
Meteor.clearTimeout t.touchtime
|
|
|
|
"touchcancel .message": (e, t) ->
|
|
Meteor.clearTimeout t.touchtime
|
|
|
|
"click .upload-progress-text > button": (e) ->
|
|
e.preventDefault();
|
|
Session.set "uploading-cancel-#{this.id}", true
|
|
|
|
"click .unread-bar > button.mark-read": ->
|
|
readMessage.readNow(true)
|
|
|
|
"click .unread-bar > button.jump-to": (e, t) ->
|
|
_id = t.data._id
|
|
message = RoomHistoryManager.getRoom(_id)?.firstUnread.get()
|
|
if message?
|
|
RoomHistoryManager.getSurroundingMessages(message, 50)
|
|
else
|
|
subscription = ChatSubscription.findOne({ rid: _id })
|
|
message = ChatMessage.find({ rid: _id, ts: { $gt: subscription?.ls } }, { sort: { ts: 1 }, limit: 1 }).fetch()[0]
|
|
RoomHistoryManager.getSurroundingMessages(message, 50)
|
|
|
|
'click .toggle-favorite': (event) ->
|
|
event.stopPropagation()
|
|
event.preventDefault()
|
|
Meteor.call 'toggleFavorite', @_id, !$('i', event.currentTarget).hasClass('favorite-room'), (err) ->
|
|
if err
|
|
return handleError(err)
|
|
|
|
'click .edit-room-title': (event) ->
|
|
event.preventDefault()
|
|
Session.set('editRoomTitle', true)
|
|
$(".fixed-title").addClass "visible"
|
|
Meteor.setTimeout ->
|
|
$('#room-title-field').focus().select()
|
|
, 10
|
|
|
|
"click .flex-tab .user-image > button" : (e, instance) ->
|
|
if not Meteor.userId()?
|
|
return
|
|
|
|
instance.tabBar.open()
|
|
instance.setUserDetail @user.username
|
|
|
|
'click .user-card-message': (e, instance) ->
|
|
if not Meteor.userId()?
|
|
return
|
|
|
|
roomData = Session.get('roomData' + this._arguments[1].rid)
|
|
|
|
if RocketChat.Layout.isEmbedded()
|
|
fireGlobalEvent('click-user-card-message', { username: this._arguments[1].u.username })
|
|
e.preventDefault()
|
|
e.stopPropagation()
|
|
return
|
|
|
|
if roomData.t in ['c', 'p', 'd']
|
|
instance.setUserDetail this._arguments[1].u.username
|
|
|
|
instance.tabBar.setTemplate('membersList')
|
|
instance.tabBar.open()
|
|
|
|
'scroll .wrapper': _.throttle (e, instance) ->
|
|
if RoomHistoryManager.isLoading(@_id) is false and (RoomHistoryManager.hasMore(@_id) is true or RoomHistoryManager.hasMoreNext(@_id) is true)
|
|
if RoomHistoryManager.hasMore(@_id) is true and e.target.scrollTop is 0
|
|
RoomHistoryManager.getMore(@_id)
|
|
else if RoomHistoryManager.hasMoreNext(@_id) is true and e.target.scrollTop >= e.target.scrollHeight - e.target.clientHeight
|
|
RoomHistoryManager.getMoreNext(@_id)
|
|
, 200
|
|
|
|
'click .new-message': (e) ->
|
|
Template.instance().atBottom = true
|
|
Template.instance().find('.input-message').focus()
|
|
|
|
'click .message-cog': (e) ->
|
|
message = @_arguments[1]
|
|
RocketChat.MessageAction.hideDropDown()
|
|
|
|
dropDown = $(".messages-box \##{message._id} .message-dropdown")
|
|
|
|
if dropDown.length is 0
|
|
actions = RocketChat.MessageAction.getButtons message, 'message'
|
|
|
|
el = Blaze.toHTMLWithData Template.messageDropdown,
|
|
actions: actions
|
|
|
|
$(".messages-box \##{message._id} .message-cog-container").append el
|
|
|
|
dropDown = $(".messages-box \##{message._id} .message-dropdown")
|
|
|
|
dropDown.show()
|
|
|
|
'click .message-dropdown .message-action': (e, t) ->
|
|
el = $(e.currentTarget)
|
|
|
|
button = RocketChat.MessageAction.getButtonById el.data('id')
|
|
if button?.action?
|
|
button.action.call @, e, t
|
|
|
|
'click .message-dropdown-close': ->
|
|
RocketChat.MessageAction.hideDropDown()
|
|
|
|
"click .mention-link": (e, instance) ->
|
|
if not Meteor.userId()?
|
|
return
|
|
|
|
channel = $(e.currentTarget).data('channel')
|
|
if channel?
|
|
if RocketChat.Layout.isEmbedded()
|
|
return fireGlobalEvent('click-mention-link', { path: FlowRouter.path('channel', {name: channel}), channel: channel })
|
|
|
|
FlowRouter.go 'channel', { name: channel }, FlowRouter.current().queryParams
|
|
return
|
|
|
|
if RocketChat.Layout.isEmbedded()
|
|
fireGlobalEvent('click-mention-link', { username: $(e.currentTarget).data('username') })
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
return
|
|
|
|
instance.tabBar.setTemplate 'membersList'
|
|
instance.setUserDetail $(e.currentTarget).data('username')
|
|
|
|
instance.tabBar.open()
|
|
|
|
'click .image-to-download': (event) ->
|
|
ChatMessage.update {_id: this._arguments[1]._id, 'urls.url': $(event.currentTarget).data('url')}, {$set: {'urls.$.downloadImages': true}}
|
|
ChatMessage.update {_id: this._arguments[1]._id, 'attachments.image_url': $(event.currentTarget).data('url')}, {$set: {'attachments.$.downloadImages': true}}
|
|
|
|
'click .collapse-switch': (e) ->
|
|
index = $(e.currentTarget).data('index')
|
|
collapsed = $(e.currentTarget).data('collapsed')
|
|
id = @_arguments[1]._id
|
|
|
|
if @_arguments[1]?.attachments?
|
|
ChatMessage.update {_id: id}, {$set: {"attachments.#{index}.collapsed": !collapsed}}
|
|
|
|
if @_arguments[1]?.urls?
|
|
ChatMessage.update {_id: id}, {$set: {"urls.#{index}.collapsed": !collapsed}}
|
|
|
|
'dragenter .dropzone': (e) ->
|
|
types = e.originalEvent?.dataTransfer?.types
|
|
if types?.length > 0 and _.every(types, (type) => type.indexOf('text/') is -1 or type.indexOf('text/uri-list') isnt -1) and userCanDrop this._id
|
|
e.currentTarget.classList.add 'over'
|
|
|
|
'dragleave .dropzone-overlay': (e) ->
|
|
e.currentTarget.parentNode.classList.remove 'over'
|
|
|
|
'dragover .dropzone-overlay': (e) ->
|
|
e = e.originalEvent or e
|
|
if e.dataTransfer.effectAllowed in ['move', 'linkMove']
|
|
e.dataTransfer.dropEffect = 'move'
|
|
else
|
|
e.dataTransfer.dropEffect = 'copy'
|
|
|
|
'dropped .dropzone-overlay': (event) ->
|
|
event.currentTarget.parentNode.classList.remove 'over'
|
|
|
|
e = event.originalEvent or event
|
|
files = e.dataTransfer?.files or []
|
|
|
|
filesToUpload = []
|
|
for file in files
|
|
# `file.type = mime.lookup(file.name)` does not work.
|
|
Object.defineProperty(file, 'type', { value: mime.lookup(file.name) })
|
|
filesToUpload.push
|
|
file: file
|
|
name: file.name
|
|
|
|
fileUpload filesToUpload
|
|
|
|
'load img': (e, template) ->
|
|
template.sendToBottomIfNecessary?()
|
|
|
|
'click .jump-recent button': (e, template) ->
|
|
e.preventDefault()
|
|
template.atBottom = true
|
|
RoomHistoryManager.clear(template?.data?._id)
|
|
|
|
'click .message': (e, template) ->
|
|
if template.selectable.get()
|
|
document.selection?.empty() or window.getSelection?().removeAllRanges()
|
|
data = Blaze.getData(e.currentTarget)
|
|
_id = data?._arguments?[1]?._id
|
|
|
|
if !template.selectablePointer
|
|
template.selectablePointer = _id
|
|
|
|
if !e.shiftKey
|
|
template.selectedMessages = template.getSelectedMessages()
|
|
template.selectedRange = []
|
|
template.selectablePointer = _id
|
|
|
|
template.selectMessages _id
|
|
|
|
selectedMessages = $('.messages-box .message.selected').map((i, message) -> message.id)
|
|
removeClass = _.difference selectedMessages, template.getSelectedMessages()
|
|
addClass = _.difference template.getSelectedMessages(), selectedMessages
|
|
for message in removeClass
|
|
$(".messages-box ##{message}").removeClass('selected')
|
|
for message in addClass
|
|
$(".messages-box ##{message}").addClass('selected')
|
|
|
|
|
|
Template.room.onCreated ->
|
|
# this.scrollOnBottom = true
|
|
# this.typing = new msgTyping this.data._id
|
|
this.showUsersOffline = new ReactiveVar false
|
|
this.atBottom = if FlowRouter.getQueryParam('msg') then false else true
|
|
this.unreadCount = new ReactiveVar 0
|
|
|
|
this.selectable = new ReactiveVar false
|
|
this.selectedMessages = []
|
|
this.selectedRange = []
|
|
this.selectablePointer = null
|
|
|
|
this.flexTemplate = new ReactiveVar
|
|
|
|
this.userDetail = new ReactiveVar FlowRouter.getParam('username')
|
|
|
|
this.tabBar = new RocketChatTabBar();
|
|
this.tabBar.showGroup(FlowRouter.current().route.name);
|
|
|
|
this.resetSelection = (enabled) =>
|
|
this.selectable.set(enabled)
|
|
$('.messages-box .message.selected').removeClass 'selected'
|
|
this.selectedMessages = []
|
|
this.selectedRange = []
|
|
this.selectablePointer = null
|
|
|
|
this.selectMessages = (to) =>
|
|
if this.selectablePointer is to and this.selectedRange.length > 0
|
|
this.selectedRange = []
|
|
else
|
|
message1 = ChatMessage.findOne this.selectablePointer
|
|
message2 = ChatMessage.findOne to
|
|
|
|
minTs = _.min([message1.ts, message2.ts])
|
|
maxTs = _.max([message1.ts, message2.ts])
|
|
|
|
this.selectedRange = _.pluck(ChatMessage.find({ rid: message1.rid, ts: { $gte: minTs, $lte: maxTs } }).fetch(), '_id')
|
|
|
|
this.getSelectedMessages = =>
|
|
messages = this.selectedMessages
|
|
addMessages = false
|
|
for message in this.selectedRange
|
|
if messages.indexOf(message) is -1
|
|
addMessages = true
|
|
break
|
|
|
|
if addMessages
|
|
previewMessages = _.compact(_.uniq(this.selectedMessages.concat(this.selectedRange)))
|
|
else
|
|
previewMessages = _.compact(_.difference(this.selectedMessages, this.selectedRange))
|
|
|
|
return previewMessages
|
|
|
|
this.setUserDetail = (username) =>
|
|
this.userDetail.set username
|
|
|
|
this.clearUserDetail = =>
|
|
this.userDetail.set null
|
|
|
|
Meteor.call 'getRoomRoles', @data._id, (error, results) ->
|
|
if error
|
|
return handleError(error)
|
|
|
|
for record in results
|
|
delete record._id
|
|
RoomRoles.upsert { rid: record.rid, "u._id": record.u._id }, record
|
|
|
|
RoomRoles.find({ rid: @data._id }).observe
|
|
added: (role) =>
|
|
ChatMessage.update { rid: @data._id, "u._id": role?.u?._id }, { $addToSet: { roles: role._id } }, { multi: true } # Update message to re-render DOM
|
|
changed: (role, oldRole) =>
|
|
ChatMessage.update { rid: @data._id, "u._id": role?.u?._id }, { $inc: { rerender: 1 } }, { multi: true } # Update message to re-render DOM
|
|
removed: (role) =>
|
|
ChatMessage.update { rid: @data._id, "u._id": role?.u?._id }, { $pull: { roles: role._id } }, { multi: true } # Update message to re-render DOM
|
|
|
|
Template.room.onDestroyed ->
|
|
window.removeEventListener 'resize', this.onWindowResize
|
|
|
|
Template.room.onRendered ->
|
|
unless window.chatMessages
|
|
window.chatMessages = {}
|
|
unless window.chatMessages[Session.get('openedRoom')]
|
|
window.chatMessages[Session.get('openedRoom')] = new ChatMessages
|
|
chatMessages[Session.get('openedRoom')].init(this.firstNode)
|
|
|
|
if Meteor.Device.isDesktop()
|
|
setTimeout ->
|
|
$('.message-form .input-message').focus()
|
|
, 100
|
|
|
|
# ScrollListener.init()
|
|
|
|
wrapper = this.find('.wrapper')
|
|
wrapperUl = this.find('.wrapper > ul')
|
|
newMessage = this.find(".new-message")
|
|
|
|
template = this
|
|
|
|
messageBox = $('.messages-box')
|
|
|
|
template.isAtBottom = (scrollThreshold) ->
|
|
if not scrollThreshold? then scrollThreshold = 0
|
|
if wrapper.scrollTop + scrollThreshold >= wrapper.scrollHeight - wrapper.clientHeight
|
|
newMessage.className = "new-message background-primary-action-color color-content-background-color not"
|
|
return true
|
|
return false
|
|
|
|
template.sendToBottom = ->
|
|
wrapper.scrollTop = wrapper.scrollHeight - wrapper.clientHeight
|
|
newMessage.className = "new-message background-primary-action-color color-content-background-color not"
|
|
|
|
template.checkIfScrollIsAtBottom = ->
|
|
template.atBottom = template.isAtBottom(100)
|
|
readMessage.enable()
|
|
readMessage.read()
|
|
|
|
template.sendToBottomIfNecessary = ->
|
|
if template.atBottom is true and template.isAtBottom() isnt true
|
|
template.sendToBottom()
|
|
|
|
template.sendToBottomIfNecessaryDebounced = _.debounce template.sendToBottomIfNecessary, 10
|
|
|
|
template.sendToBottomIfNecessary()
|
|
|
|
if not window.MutationObserver?
|
|
wrapperUl.addEventListener 'DOMSubtreeModified', ->
|
|
template.sendToBottomIfNecessaryDebounced()
|
|
else
|
|
observer = new MutationObserver (mutations) ->
|
|
mutations.forEach (mutation) ->
|
|
template.sendToBottomIfNecessaryDebounced()
|
|
|
|
observer.observe wrapperUl,
|
|
childList: true
|
|
# observer.disconnect()
|
|
|
|
template.onWindowResize = ->
|
|
Meteor.defer ->
|
|
template.sendToBottomIfNecessaryDebounced()
|
|
|
|
window.addEventListener 'resize', template.onWindowResize
|
|
|
|
wrapper.addEventListener 'mousewheel', ->
|
|
template.atBottom = false
|
|
Meteor.defer ->
|
|
template.checkIfScrollIsAtBottom()
|
|
|
|
wrapper.addEventListener 'wheel', ->
|
|
template.atBottom = false
|
|
Meteor.defer ->
|
|
template.checkIfScrollIsAtBottom()
|
|
|
|
wrapper.addEventListener 'touchstart', ->
|
|
template.atBottom = false
|
|
|
|
wrapper.addEventListener 'touchend', ->
|
|
Meteor.defer ->
|
|
template.checkIfScrollIsAtBottom()
|
|
Meteor.setTimeout ->
|
|
template.checkIfScrollIsAtBottom()
|
|
, 1000
|
|
Meteor.setTimeout ->
|
|
template.checkIfScrollIsAtBottom()
|
|
, 2000
|
|
|
|
wrapper.addEventListener 'scroll', ->
|
|
template.atBottom = false
|
|
Meteor.defer ->
|
|
template.checkIfScrollIsAtBottom()
|
|
|
|
$('.flex-tab-bar').on 'click', (e, t) ->
|
|
Meteor.setTimeout ->
|
|
template.sendToBottomIfNecessaryDebounced()
|
|
, 50
|
|
|
|
rtl = $('html').hasClass('rtl')
|
|
|
|
updateUnreadCount = _.throttle ->
|
|
messageBoxOffset = messageBox.offset()
|
|
|
|
if rtl
|
|
lastInvisibleMessageOnScreen = document.elementFromPoint(messageBoxOffset.left+messageBox.width()-1, messageBoxOffset.top+1)
|
|
else
|
|
lastInvisibleMessageOnScreen = document.elementFromPoint(messageBoxOffset.left+1, messageBoxOffset.top+1)
|
|
|
|
if lastInvisibleMessageOnScreen?.id?
|
|
lastMessage = ChatMessage.findOne lastInvisibleMessageOnScreen.id
|
|
if lastMessage?
|
|
subscription = ChatSubscription.findOne rid: template.data._id
|
|
count = ChatMessage.find({rid: template.data._id, ts: {$lte: lastMessage.ts, $gt: subscription?.ls}}).count()
|
|
template.unreadCount.set count
|
|
else
|
|
template.unreadCount.set 0
|
|
, 300
|
|
|
|
readMessage.onRead (rid) ->
|
|
if rid is template.data._id
|
|
template.unreadCount.set 0
|
|
|
|
wrapper.addEventListener 'scroll', ->
|
|
updateUnreadCount()
|
|
|
|
# salva a data da renderização para exibir alertas de novas mensagens
|
|
$.data(this.firstNode, 'renderedAt', new Date)
|
|
|
|
webrtc = WebRTC.getInstanceByRoomId template.data._id
|
|
if webrtc?
|
|
Tracker.autorun =>
|
|
if webrtc.remoteItems.get()?.length > 0
|
|
@tabBar.setTemplate 'membersList'
|
|
@tabBar.open()
|
|
|
|
if webrtc.localUrl.get()?
|
|
@tabBar.setTemplate 'membersList'
|
|
@tabBar.open()
|
|
|