Add new Last Seen Indicator with unread count, scroll to it

This is to ensure that when there are a lot of unread messages, the user
is given the chance to see all of them by being scrolled to the oldest
new message.

When a new message comes in, the indicator will be incremented.

When the user sends a message or switches away from the conversation,
the last seen indicator will be removed.

FREEBIE
This commit is contained in:
Scott Nonnenberg 2017-05-17 14:32:03 -07:00
parent bec69826ae
commit fed26c36ca
8 changed files with 133 additions and 2 deletions

View file

@ -201,11 +201,45 @@
this.$('.bottom-bar form').addClass('active');
},
updateUnread: function() {
this.updateLastSeenIndicator();
this.model.markRead();
},
onOpened: function() {
this.view.resetScrollPosition();
this.$el.trigger('force-resize');
this.focusMessageField();
this.model.markRead();
if (this.inProgressFetch) {
this.inProgressFetch.then(this.updateUnread.bind(this));
} else {
this.updateUnread();
}
},
removeLastSeenIndicator: function() {
if (this.lastSeenIndicator) {
this.lastSeenIndicator.remove();
this.lastSeenIndicator = null;
}
},
updateLastSeenIndicator: function() {
this.removeLastSeenIndicator();
var oldestUnread = this.model.messageCollection.find(function(model) {
return model.get('unread');
});
if (oldestUnread) {
var unreadCount = this.model.get('unreadCount');
this.lastSeenIndicator = new Whisper.LastSeenIndicatorView({count: unreadCount});
var unreadEl = this.lastSeenIndicator.render().$el;
unreadEl.insertBefore(this.$('#' + oldestUnread.get('id')));
var position = unreadEl[0].scrollIntoView(true);
}
},
focusMessageField: function() {
@ -215,15 +249,18 @@
fetchMessages: function() {
console.log('fetchMessages');
this.$('.bar-container').show();
return this.model.fetchContacts().then(function() {
this.inProgressFetch = this.model.fetchContacts().then(function() {
return this.model.fetchMessages().then(function() {
this.$('.bar-container').hide();
this.model.messageCollection.where({unread: 1}).forEach(function(m) {
m.fetch();
});
this.inProgressFetch = null;
}.bind(this));
}.bind(this));
// TODO catch?
return this.inProgressFetch;
},
onExpired: function(message) {
@ -241,6 +278,10 @@
this.model.messageCollection.add(message, {merge: true});
message.setToExpire();
if (this.lastSeenIndicator) {
this.lastSeenIndicator.increment(1);
}
if (!this.isHidden() && window.isFocused()) {
this.markRead();
}
@ -345,6 +386,8 @@
},
sendMessage: function(e) {
this.removeLastSeenIndicator();
var toast;
if (extension.expired()) {
toast = new Whisper.ExpiredToast();

View file

@ -0,0 +1,30 @@
/*
* vim: ts=4:sw=4:expandtab
*/
(function () {
'use strict';
window.Whisper = window.Whisper || {};
Whisper.LastSeenIndicatorView = Whisper.View.extend({
className: 'last-seen-indicator-view',
templateName: 'last-seen-indicator-view',
initialize: function(options) {
options = options || {};
this.count = options.count || 0;
},
increment: function(count) {
this.count += count;
this.render();
},
render_attributes: function() {
var unreadMessages = this.count === 1 ? i18n('unreadMessage')
: i18n('unreadMessages', [this.count]);
return {
unreadMessages: unreadMessages
};
}
});
})();