mirror of
https://github.com/oxen-io/session-desktop.git
synced 2023-12-14 02:12:57 +01:00
Unload conversations and old messages every half-hour
FREEBIE
This commit is contained in:
parent
4ea457a01c
commit
65283d2794
|
@ -19,6 +19,7 @@
|
|||
this.on('add remove change:unreadCount',
|
||||
_.debounce(this.updateUnreadCount.bind(this), 1000)
|
||||
);
|
||||
this.startPruning();
|
||||
},
|
||||
comparator: function(m1, m2) {
|
||||
var timestamp1 = m1.get('timestamp');
|
||||
|
@ -65,6 +66,14 @@
|
|||
if (newUnreadCount === 0) {
|
||||
window.clearAttention();
|
||||
}
|
||||
},
|
||||
startPruning: function() {
|
||||
var halfHour = 30 * 60 * 1000;
|
||||
this.interval = setInterval(function() {
|
||||
this.forEach(function(conversation) {
|
||||
conversation.trigger('prune');
|
||||
});
|
||||
}.bind(this), halfHour);
|
||||
}
|
||||
}))();
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
this.on('destroy', this.revokeImageUrl);
|
||||
this.on('change:expirationStartTimestamp', this.setToExpire);
|
||||
this.on('change:expireTimer', this.setToExpire);
|
||||
this.on('unload', this.revokeImageUrl);
|
||||
this.setToExpire();
|
||||
},
|
||||
idForLogging: function() {
|
||||
|
|
|
@ -81,6 +81,21 @@
|
|||
events: {
|
||||
'click': 'onclick'
|
||||
},
|
||||
unload: function() {
|
||||
this.blob = null;
|
||||
|
||||
if (this.lightBoxView) {
|
||||
this.lightBoxView.remove();
|
||||
}
|
||||
if (this.fileView) {
|
||||
this.fileView.remove();
|
||||
}
|
||||
if (this.view) {
|
||||
this.view.remove();
|
||||
}
|
||||
|
||||
this.remove();
|
||||
},
|
||||
getFileType: function() {
|
||||
switch(this.model.contentType) {
|
||||
case 'video/quicktime': return 'mov';
|
||||
|
@ -89,10 +104,10 @@
|
|||
},
|
||||
onclick: function(e) {
|
||||
if (this.isImage()) {
|
||||
var view = new Whisper.LightboxView({ model: this });
|
||||
view.render();
|
||||
view.$el.appendTo(this.el);
|
||||
view.$el.trigger('show');
|
||||
this.lightBoxView = new Whisper.LightboxView({ model: this });
|
||||
this.lightBoxView.render();
|
||||
this.lightBoxView.$el.appendTo(this.el);
|
||||
this.lightBoxView.$el.trigger('show');
|
||||
|
||||
} else {
|
||||
this.saveFile();
|
||||
|
|
|
@ -109,6 +109,7 @@
|
|||
this.listenTo(this.model, 'delivered', this.updateMessage);
|
||||
this.listenTo(this.model, 'opened', this.onOpened);
|
||||
this.listenTo(this.model, 'expired', this.onExpired);
|
||||
this.listenTo(this.model, 'prune', this.onPrune);
|
||||
this.listenTo(this.model.messageCollection, 'expired', this.onExpiredCollection);
|
||||
|
||||
this.lazyUpdateVerified = _.debounce(
|
||||
|
@ -126,7 +127,7 @@
|
|||
this.loadingScreen.render();
|
||||
this.loadingScreen.$el.prependTo(this.el);
|
||||
|
||||
new TimerMenuView({ el: this.$('.timer-menu'), model: this.model });
|
||||
this.timerMenu = new TimerMenuView({ el: this.$('.timer-menu'), model: this.model });
|
||||
|
||||
emoji_util.parse(this.$('.conversation-name'));
|
||||
|
||||
|
@ -151,15 +152,15 @@
|
|||
|
||||
this.$messageField = this.$('.send-message');
|
||||
|
||||
var onResize = this.forceUpdateMessageFieldSize.bind(this);
|
||||
this.window.addEventListener('resize', onResize);
|
||||
this.onResize = this.forceUpdateMessageFieldSize.bind(this);
|
||||
this.window.addEventListener('resize', this.onResize);
|
||||
|
||||
var onFocus = function() {
|
||||
this.onFocus = function() {
|
||||
if (this.$el.css('display') !== 'none') {
|
||||
this.markRead();
|
||||
}
|
||||
}.bind(this);
|
||||
this.window.addEventListener('focus', onFocus);
|
||||
this.window.addEventListener('focus', this.onFocus);
|
||||
|
||||
extension.windows.onClosed(function () {
|
||||
this.window.removeEventListener('resize', onResize);
|
||||
|
@ -207,6 +208,83 @@
|
|||
'show-identity': 'showSafetyNumber'
|
||||
},
|
||||
|
||||
onPrune: function() {
|
||||
if (!this.model.messageCollection.length || !this.lastActivity) {
|
||||
return;
|
||||
}
|
||||
|
||||
var oneHourAgo = Date.now() - 60 * 60 * 1000;
|
||||
if (this.isHidden() && this.lastActivity < oneHourAgo) {
|
||||
this.unload();
|
||||
} else if (this.view.atBottom()) {
|
||||
this.trim();
|
||||
}
|
||||
},
|
||||
|
||||
unload: function() {
|
||||
console.log('unloading conversation', this.model.id, 'due to inactivity');
|
||||
|
||||
this.timerMenu.remove();
|
||||
this.fileInput.remove();
|
||||
this.titleView.remove();
|
||||
|
||||
if (this.captureAudioView) {
|
||||
this.captureAudioView.remove();
|
||||
}
|
||||
if (this.banner) {
|
||||
this.banner.remove();
|
||||
}
|
||||
if (this.lastSeenIndicator) {
|
||||
this.lastSeenIndicator.remove();
|
||||
}
|
||||
if (this.scrollDownButton) {
|
||||
this.scrollDownButton.remove();
|
||||
}
|
||||
if (this.panels && this.panels.length) {
|
||||
for (var i = 0, max = this.panels.length; i < max; i += 1) {
|
||||
var panel = this.panels[i];
|
||||
panel.remove();
|
||||
}
|
||||
}
|
||||
|
||||
this.window.removeEventListener('resize', this.onResize);
|
||||
this.window.removeEventListener('focus', this.onFocus);
|
||||
|
||||
this.view.remove();
|
||||
|
||||
this.remove();
|
||||
|
||||
this.model.messageCollection.forEach(function(model) {
|
||||
model.trigger('unload');
|
||||
});
|
||||
this.model.messageCollection.reset([]);
|
||||
this.model.revokeAvatarUrl();
|
||||
},
|
||||
|
||||
trim: function() {
|
||||
var MAX = 100;
|
||||
var toRemove = this.model.messageCollection.length - MAX;
|
||||
if (toRemove <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var models = [];
|
||||
for (var i = 0; i < toRemove; i += 1) {
|
||||
var model = this.model.messageCollection.at(i);
|
||||
models.push(model);
|
||||
}
|
||||
|
||||
if (!models.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('trimming conversation', this.model.id, 'of', models.length, 'old messages');
|
||||
|
||||
this.model.messageCollection.remove(models);
|
||||
_.forEach(models, function(model) {
|
||||
model.trigger('unload');
|
||||
});
|
||||
},
|
||||
|
||||
markAllAsVerifiedDefault: function(unverified) {
|
||||
return Promise.all(unverified.map(function(contact) {
|
||||
|
@ -292,10 +370,18 @@
|
|||
},
|
||||
captureAudio: function(e) {
|
||||
e.preventDefault();
|
||||
var view = new Whisper.RecorderView().render();
|
||||
|
||||
if (this.captureAudioView) {
|
||||
this.captureAudioView.remove();
|
||||
this.captureAudioView = null;
|
||||
}
|
||||
|
||||
var view = this.captureAudioView = new Whisper.RecorderView();
|
||||
view.render();
|
||||
view.on('send', this.handleAudioCapture.bind(this));
|
||||
view.on('closed', this.endCaptureAudio.bind(this));
|
||||
view.$el.appendTo(this.$('.capture-audio'));
|
||||
|
||||
this.$('.send-message').attr('disabled','disabled');
|
||||
this.$('.microphone').hide();
|
||||
},
|
||||
|
@ -308,6 +394,7 @@
|
|||
endCaptureAudio: function() {
|
||||
this.$('.send-message').removeAttr('disabled');
|
||||
this.$('.microphone').show();
|
||||
this.captureAudioView = null;
|
||||
},
|
||||
|
||||
unfocusBottomBar: function() {
|
||||
|
@ -322,6 +409,7 @@
|
|||
// of messages are added to the DOM, one by one, changing window size and
|
||||
// generating scroll events.
|
||||
if (!this.isHidden() && window.isFocused() && !this.inProgressFetch) {
|
||||
this.lastActivity = Date.now();
|
||||
this.markRead();
|
||||
}
|
||||
},
|
||||
|
@ -340,6 +428,8 @@
|
|||
},
|
||||
|
||||
onOpened: function() {
|
||||
this.lastActivity = Date.now();
|
||||
|
||||
this.statusFetch = this.throttledGetProfiles().then(function() {
|
||||
this.model.updateVerified().then(function() {
|
||||
this.onVerifiedChange();
|
||||
|
@ -664,6 +754,16 @@
|
|||
view.render();
|
||||
},
|
||||
|
||||
// not currently in use
|
||||
newGroupUpdate: function() {
|
||||
var view = new Whisper.NewGroupUpdateView({
|
||||
model: this.model,
|
||||
window: this.window
|
||||
});
|
||||
view.render();
|
||||
this.listenBack(view);
|
||||
},
|
||||
|
||||
listenBack: function(view) {
|
||||
this.panels = this.panels || [];
|
||||
if (this.panels.length > 0) {
|
||||
|
@ -715,14 +815,6 @@
|
|||
this.$('.conversation-menu .menu-list').toggle();
|
||||
},
|
||||
|
||||
newGroupUpdate: function() {
|
||||
this.newGroupUpdateView = new Whisper.NewGroupUpdateView({
|
||||
model: this.model,
|
||||
window: this.window
|
||||
});
|
||||
this.listenBack(this.newGroupUpdateView);
|
||||
},
|
||||
|
||||
destroyMessages: function(e) {
|
||||
this.confirm(i18n('deleteConversationConfirmation')).then(function() {
|
||||
this.model.destroyMessages();
|
||||
|
|
|
@ -43,6 +43,9 @@
|
|||
});
|
||||
var TimerView = Whisper.View.extend({
|
||||
templateName: 'hourglass',
|
||||
initialize: function() {
|
||||
this.listenTo(this.model, 'unload', this.remove);
|
||||
},
|
||||
update: function() {
|
||||
if (this.timeout) {
|
||||
clearTimeout(this.timeout);
|
||||
|
@ -74,6 +77,7 @@
|
|||
initialize: function() {
|
||||
this.conversation = this.model.getExpirationTimerUpdateSource();
|
||||
this.listenTo(this.conversation, 'change', this.render);
|
||||
this.listenTo(this.model, 'unload', this.remove);
|
||||
},
|
||||
render_attributes: function() {
|
||||
var seconds = this.model.get('expirationTimerUpdate').expireTimer;
|
||||
|
@ -100,6 +104,7 @@
|
|||
initialize: function() {
|
||||
this.conversation = this.model.getModelForKeyChange();
|
||||
this.listenTo(this.conversation, 'change', this.render);
|
||||
this.listenTo(this.model, 'unload', this.remove);
|
||||
},
|
||||
events: {
|
||||
'click .content': 'showIdentity'
|
||||
|
@ -124,6 +129,7 @@
|
|||
initialize: function() {
|
||||
this.conversation = this.model.getModelForVerifiedChange();
|
||||
this.listenTo(this.conversation, 'change', this.render);
|
||||
this.listenTo(this.model, 'unload', this.remove);
|
||||
},
|
||||
events: {
|
||||
'click .content': 'showIdentity'
|
||||
|
@ -173,6 +179,7 @@
|
|||
this.listenTo(this.model, 'change', this.renderSent);
|
||||
this.listenTo(this.model, 'change:flags change:group_update', this.renderControl);
|
||||
this.listenTo(this.model, 'destroy', this.onDestroy);
|
||||
this.listenTo(this.model, 'unload', this.onUnload);
|
||||
this.listenTo(this.model, 'expired', this.onExpired);
|
||||
this.listenTo(this.model, 'pending', this.renderPending);
|
||||
this.listenTo(this.model, 'done', this.renderDone);
|
||||
|
@ -209,11 +216,39 @@
|
|||
// Failsafe: if in the background, animation events don't fire
|
||||
setTimeout(this.remove.bind(this), 1000);
|
||||
},
|
||||
onUnload: function() {
|
||||
if (this.avatarView) {
|
||||
this.avatarView.remove();
|
||||
}
|
||||
if (this.errorIconView) {
|
||||
this.errorIconView.remove();
|
||||
}
|
||||
if (this.networkErrorView) {
|
||||
this.networkErrorView.remove();
|
||||
}
|
||||
if (this.someFailedView) {
|
||||
this.someFailedView.remove();
|
||||
}
|
||||
if (this.timeStampView) {
|
||||
this.timeStampView.remove();
|
||||
}
|
||||
if (this.loadedAttachments && this.loadedAttachments.length) {
|
||||
for (var i = 0, max = this.loadedAttachments.length; i < max; i += 1) {
|
||||
var view = this.loadedAttachments[i];
|
||||
view.unload();
|
||||
}
|
||||
}
|
||||
|
||||
// No need to handle this one, since it listens to 'unload' itself:
|
||||
// this.timerView
|
||||
|
||||
this.remove();
|
||||
},
|
||||
onDestroy: function() {
|
||||
if (this.$el.hasClass('expired')) {
|
||||
return;
|
||||
}
|
||||
this.remove();
|
||||
this.onUnload();
|
||||
},
|
||||
select: function(e) {
|
||||
this.$el.trigger('select', {message: this.model});
|
||||
|
@ -245,24 +280,41 @@
|
|||
},
|
||||
renderErrors: function() {
|
||||
var errors = this.model.get('errors');
|
||||
|
||||
if (_.size(errors) > 0) {
|
||||
if (this.model.isIncoming()) {
|
||||
this.$('.content').text(this.model.getDescription()).addClass('error-message');
|
||||
}
|
||||
var view = new ErrorIconView({ model: errors[0] });
|
||||
view.render().$el.appendTo(this.$('.bubble'));
|
||||
this.errorIconView = new ErrorIconView({ model: errors[0] });
|
||||
this.errorIconView.render().$el.appendTo(this.$('.bubble'));
|
||||
} else {
|
||||
this.$('.error-icon-container').remove();
|
||||
if (this.errorIconView) {
|
||||
this.errorIconView.remove();
|
||||
this.errorIconView = null;
|
||||
}
|
||||
}
|
||||
this.$('.meta .hasRetry').remove();
|
||||
|
||||
if (this.model.hasNetworkError()) {
|
||||
var networkErrorView = new NetworkErrorView({model: this.model});
|
||||
this.$('.meta').prepend(networkErrorView.render().el);
|
||||
this.networkErrorView = new NetworkErrorView({model: this.model});
|
||||
this.$('.meta').prepend(this.networkErrorView.render().el);
|
||||
} else {
|
||||
this.$('.meta .hasRetry').remove();
|
||||
if (this.networkErrorView) {
|
||||
this.networkErrorView.remove();
|
||||
this.networkErrorView = null;
|
||||
}
|
||||
}
|
||||
this.$('.meta .some-failed').remove();
|
||||
|
||||
if (this.model.someRecipientsFailed()) {
|
||||
var someFailedView = new SomeFailedView();
|
||||
this.$('.meta').prepend(someFailedView.render().el);
|
||||
this.someFailedView = new SomeFailedView();
|
||||
this.$('.meta').prepend(this.someFailedView.render().el);
|
||||
} else {
|
||||
this.$('.meta .some-failed').remove();
|
||||
if (this.someFailedView) {
|
||||
this.someFailedView.remove();
|
||||
this.someFailedView = null;
|
||||
}
|
||||
}
|
||||
},
|
||||
renderControl: function() {
|
||||
|
@ -321,11 +373,11 @@
|
|||
if (color) {
|
||||
bubble.addClass(color);
|
||||
}
|
||||
var avatarView = new (Whisper.View.extend({
|
||||
this.avatarView = new (Whisper.View.extend({
|
||||
templateName: 'avatar',
|
||||
render_attributes: { avatar: model.getAvatar() }
|
||||
}))();
|
||||
this.$('.avatar').replaceWith(avatarView.render().$('.avatar'));
|
||||
this.$('.avatar').replaceWith(this.avatarView.render().$('.avatar'));
|
||||
},
|
||||
appendAttachmentView: function(view) {
|
||||
// We check for a truthy 'updated' here to ensure that a race condition in a
|
||||
|
|
Loading…
Reference in a new issue