Improve unread behaviour

pull/744/head
Rodrigo Nascimento 11 years ago
parent 2fe71b4df5
commit 600fd068b9
  1. 18
      client/lib/RoomHistoryManager.coffee
  2. 1
      client/lib/RoomManager.coffee
  3. 57
      client/lib/readMessages.coffee
  4. 3
      client/routes/roomRoute.coffee
  5. 2
      client/startup/unread.coffee
  6. 11
      client/stylesheets/base.less
  7. 18
      client/views/app/room.coffee
  8. 16
      client/views/app/room.html
  9. 8
      packages/rocketchat-external/app/client/lib/RoomHistoryManager.coffee
  10. 37
      server/methods/countAndFirstId.coffee
  11. 19
      server/methods/loadHistory.coffee

@ -8,6 +8,7 @@
histories[rid] =
hasMore: ReactiveVar true
isLoading: ReactiveVar false
unreadNotLoaded: ReactiveVar 0
loaded: 0
return histories[rid]
@ -28,11 +29,19 @@
else
ts = new Date
Meteor.call 'loadHistory', rid, ts, limit, 0, (err, result) ->
ls = undefined
subscription = ChatSubscription.findOne rid: rid
if subscription?
ls = subscription.ls
Meteor.call 'loadHistory', rid, ts, limit, ls, (err, result) ->
room.unreadNotLoaded.set result.unreadNotLoaded
wrapper = $('.messages-box .wrapper').get(0)
previousHeight = wrapper.scrollHeight
ChatMessage.insert item for item in result
ChatMessage.insert item for item in result.messages
heightDiff = wrapper.scrollHeight - previousHeight
wrapper.scrollTop += heightDiff
@ -41,8 +50,8 @@
readMessage.refreshUnreadMark(rid, true)
room.isLoading.set false
room.loaded += result.length
if result.length < limit
room.loaded += result.messages.length
if result.messages.length < limit
room.hasMore.set false
hasMore = (rid) ->
@ -68,6 +77,7 @@
histories[rid].isLoading.set false
histories[rid].loaded = 0
getRoom: getRoom
getMore: getMore
getMoreIfIsEmpty: getMoreIfIsEmpty
hasMore: hasMore

@ -124,7 +124,6 @@ onDeleteMessageStream = (msg) ->
openedRooms[typeName] =
active: false
ready: false
unreadCount: new ReactiveVar 0
unreadSince: new ReactiveVar undefined
setRoomExpireExcept typeName

@ -7,9 +7,9 @@
- The default method *read* has a delay of 2000ms to prevent multiple reads and to user be able to see the mark
###
Meteor.startup ->
window.addEventListener 'focus', ->
readMessage.refreshUnreadMark(undefined, true)
# Meteor.startup ->
# window.addEventListener 'focus', ->
# readMessage.refreshUnreadMark(undefined, true)
@readMessage = new class
constructor: ->
@ -37,7 +37,7 @@ Meteor.startup ->
# Only read messages if user saw the first unread message
position = $('.message.first-unread').position()
if (position? and position.top >= 0) or room.unreadCount.get() is 0
if (position? and position.top >= 0) or not room.unreadSince.get()?
Meteor.call 'readMessages', rid, ->
self.refreshUnreadMark()
@ -69,30 +69,51 @@ Meteor.startup ->
if not room?
return
room.loadingUnread = true
$roomDom = $(room.dom)
$roomDom.find('.message.first-unread').addClass('first-unread-opaque')
if not subscription.alert and subscription.unread is 0
room.unreadLoading = false
room.unreadCount.set 0
room.unreadSince.set undefined
return
if not force? and subscription.rid is Session.get('openedRoom') and document.hasFocus()
return
$roomDom.find('.message.first-unread').removeClass('first-unread').removeClass('first-unread-opaque')
@disable()
Meteor.call 'countAndFirstId', subscription.rid, (error, data) ->
room.unreadLoading = false
room.unreadCount.set data.count
room.unreadSince.set data.since
room.unreadFirstId = data.firstUnreadId
self.enable()
if data.firstUnreadId?
$roomDom.find('.message#'+data.firstUnreadId).addClass('first-unread')
lastReadRecord = ChatMessage.findOne
rid: subscription.rid
ts:
$lt: subscription.ls
# 'u._id':
# $ne: Meteor.userId()
,
sort:
ts: -1
if not lastReadRecord? and RoomHistoryManager.getRoom(room.rid).unreadNotLoaded.get() is 0
lastReadRecord =
ts: new Date(0)
if lastReadRecord? or RoomHistoryManager.getRoom(room.rid).unreadNotLoaded.get() > 0
room.unreadSince.set subscription.ls
else
room.unreadSince.set undefined
if lastReadRecord?
firstUnreadRecord = ChatMessage.findOne
rid: subscription.rid
ts:
$gt: lastReadRecord.ts
'u._id':
$ne: Meteor.userId()
,
sort:
ts: 1
if firstUnreadRecord?
room.unreadFirstId = firstUnreadRecord._id
$roomDom.find('.message#'+firstUnreadRecord._id).addClass('first-unread')
Meteor.startup ->

@ -38,9 +38,6 @@ openRoom = (type, name) ->
Session.set 'editRoomTitle', false
readMessage.disable()
Meteor.setTimeout ->
readMessage.refreshUnreadMark(undefined, true)
, 1000
Meteor.setTimeout ->
readMessage.readNow()
, 2000

@ -46,7 +46,7 @@ Meteor.startup ->
Tracker.autorun ->
siteName = RocketChat.settings.get 'Site_Name'
unread = Session.get 'unread'
fireGlobalEvent 'unread-changed', unread
favico?.badge unread, bgColor: if typeof unread isnt 'number' then '#3d8a3a' else '#ac1b1b'

@ -2270,11 +2270,9 @@ a.github-fork {
.message {
font-size: 14px;
padding-left: 50px;
padding: 8px 20px 8px 70px;
position: relative;
line-height: 20px;
margin: 12px 20px 5px;
margin-top: 12px;
min-height: 40px;
&:nth-child(1) {
margin-top: 0;
@ -2331,8 +2329,8 @@ a.github-fork {
}
.thumb {
position: absolute;
left: 0;
top: 0;
left: 20px;
top: 10px;
display: block;
width: 40px;
height: 40px;
@ -2341,7 +2339,6 @@ a.github-fork {
font-size: 12px;
}
&.sequential {
margin-top: 14px;
min-height: 20px;
.user {
display: none;
@ -2352,7 +2349,7 @@ a.github-fork {
.info {
position: absolute;
text-align: right;
left: -20px;
left: 0px;
width: 65px;
.time {
display: none;

@ -280,6 +280,9 @@ Template.room.helpers
room = ChatRoom.findOne(this._id, { reactive: false })
return RoomManager.openedRooms[room.t + room.name]
unreadCount: ->
return RoomHistoryManager.getRoom(@_id).unreadNotLoaded.get() + Template.instance().unreadCount.get()
formatUnreadSince: ->
room = ChatRoom.findOne(this._id, { reactive: false })
room = RoomManager.openedRooms[room.t + room.name]
@ -663,6 +666,7 @@ Template.room.onCreated ->
this.showUsersOffline = new ReactiveVar false
this.atBottom = true
this.searchResult = new ReactiveVar
this.unreadCount = new ReactiveVar 0
self = @
@ -680,10 +684,23 @@ Template.room.onRendered ->
template = this
wrapperOffset = $('.messages-box > .wrapper').offset()
onscroll = _.throttle ->
template.atBottom = wrapper.scrollTop >= wrapper.scrollHeight - wrapper.clientHeight
, 200
updateUnreadCount = _.throttle ->
firstMessageOnScreen = document.elementFromPoint(wrapperOffset.left+1, wrapperOffset.top+50)
if firstMessageOnScreen?.id?
firstMessage = ChatMessage.findOne firstMessageOnScreen.id
if firstMessage?
subscription = ChatSubscription.findOne rid: template.data._id
template.unreadCount.set ChatMessage.find({rid: template.data._id, ts: {$lt: firstMessage.ts, $gt: subscription.ls}}).count()
else
template.unreadCount.set 0
, 300
Meteor.setInterval ->
if template.atBottom
wrapper.scrollTop = wrapper.scrollHeight - wrapper.clientHeight
@ -701,6 +718,7 @@ Template.room.onRendered ->
wrapper.addEventListener 'scroll', ->
template.atBottom = false
onscroll()
updateUnreadCount()
wrapper.addEventListener 'mousewheel', ->
template.atBottom = false

@ -38,13 +38,15 @@
</div>
{{/each}}
</div>
{{#if roomManager.unreadCount.get}}
<div class="unread-bar">
{{_ "S_new_messages_since_s" roomManager.unreadCount.get formatUnreadSince}}
<a>
{{_ "Mark_as_read"}}
</a>
</div>
{{#if unreadCount}}
{{#if roomManager.unreadSince.get}}
<div class="unread-bar">
{{_ "S_new_messages_since_s" unreadCount formatUnreadSince}}
<a>
{{_ "Mark_as_read"}}
</a>
</div>
{{/if}}
{{/if}}
<div class="messages-box">
<div class="wrapper">

@ -29,11 +29,11 @@
else
ts = new Date
Meteor.call 'loadHistory', rid, ts, limit, 0, (err, result) ->
ChatMessage.insert item for item in result
Meteor.call 'loadHistory', rid, ts, limit, undefined, (err, result) ->
ChatMessage.insert item for item in result.messages
room.isLoading.set false
room.loaded += result.length
if result.length < limit
room.loaded += result.messages.length
if result.messages.length < limit
room.hasMore.set false
hasMore = (rid) ->

@ -1,37 +0,0 @@
Meteor.methods
countAndFirstId: (rid) ->
subscription = ChatSubscription.findOne
rid: rid
'u._id': Meteor.userId()
query =
rid: rid
ts:
$gt: subscription.ls
'u._id':
$ne: Meteor.userId()
options =
sort:
ts: 1
limit: 1
firstUnread = ChatMessage.find(query, options).fetch()[0]
if not firstUnread?
return {
firstUnreadId: undefined
count: 0
since: subscription.ls
}
options =
sort:
ts: 1
count = ChatMessage.find(query, options).count()
return {
firstUnreadId: firstUnread._id
count: count
since: subscription.ls
}

@ -1,5 +1,5 @@
Meteor.methods
loadHistory: (rid, end, limit=20, skip=0) ->
loadHistory: (rid, end, limit=20, ls) ->
fromId = Meteor.userId()
# console.log '[methods] loadHistory -> '.green, 'fromId:', fromId, 'rid:', rid, 'end:', end, 'limit:', limit, 'skip:', skip
@ -16,9 +16,22 @@ Meteor.methods
sort:
ts: -1
limit: limit
skip: skip
if not RocketChat.settings.get 'Message_ShowEditedStatus'
options.fields = { ets: 0 }
return ChatMessage.find(query, options).fetch()
messages = ChatMessage.find(query, options).fetch()
unreadNotLoaded = 0
if ls?
fistMessage = messages[messages.length - 1]
if fistMessage.ts > ls
query.ts.$lt = fistMessage.ts
query.ts.$gt = ls
delete options.limit
unreadNotLoaded = ChatMessage.find(query, options).count()
return {
messages: messages
unreadNotLoaded: unreadNotLoaded
}

Loading…
Cancel
Save