Cable-Desktop/js/views/message_detail_view.js
lilia 77caa63321 Normalize views' template fetching pattern
Typically, a view can specify its templateName and then use the default
render method on Whisper.View, except in some special cases like message
view or message detail where other operations are performed during
render.

// FREEBIE
2015-12-09 18:58:52 -08:00

131 lines
4.9 KiB
JavaScript

/*
* vim: ts=4:sw=4:expandtab
*/
(function () {
'use strict';
window.Whisper = window.Whisper || {};
var ContactView = Whisper.View.extend({
className: 'contact-detail',
templateName: 'contact-detail',
initialize: function(options) {
this.conflict = options.conflict;
this.errors = _.reject(options.errors, function(e) {
return (e.name === 'IncomingIdentityKeyError' ||
e.name === 'OutgoingIdentityKeyError');
});
},
events: {
'click .conflict': 'triggerConflict'
},
triggerConflict: function() {
this.$el.trigger('conflict', {conflict: this.conflict});
},
render_attributes: function() {
return {
name : this.model.getTitle(),
avatar : this.model.getAvatar(),
conflict : this.conflict,
errors : this.errors
};
}
});
Whisper.MessageDetailView = Whisper.View.extend({
className: 'message-detail',
templateName: 'message-detail',
initialize: function(options) {
this.view = new Whisper.MessageView({model: this.model});
this.view.render();
this.conversation = options.conversation;
this.listenTo(this.model, 'change', this.render);
},
events: {
'click .back': 'goBack',
'conflict': 'conflictDialogue',
'click .retry': 'retryMessage',
},
goBack: function() {
this.trigger('back');
},
verify: function(their_key) {
textsecure.storage.axolotl.getIdentityKey(textsecure.storage.user.getNumber()).then(function(our_key) {
var view = new Whisper.KeyVerificationView({
model: { their_key: their_key, your_key: our_key }
});
this.$el.hide();
view.render().$el.insertAfter(this.el);
this.listenTo(view, 'back', function() {
view.remove();
this.$el.show();
}.bind(this));
}.bind(this));
},
contacts: function() {
if (this.model.isIncoming()) {
var number = this.model.get('source');
return [this.conversation.contactCollection.get(number)];
} else {
return this.conversation.contactCollection.models;
}
},
conflictDialogue: function(e, data) {
var view = new Whisper.KeyConflictDialogueView({
model: data.conflict,
conversation: this.conversation
});
view.render().$el.appendTo(this.$el);
this.listenTo(view, 'verify', function(data) {
this.verify(data.identityKey);
});
this.listenTo(view, 'resolve', function() {
this.render();
});
},
retryMessage: function() {
var retrys = _.filter(this.model.get('errors'), function(e) {
return (e.name === 'OutgoingMessageError' ||
e.name === 'SendMessageNetworkError');
});
_.map(retrys, 'number').forEach(function(number) {
this.model.resend(number);
}.bind(this));
},
renderContact: function(contact) {
var conflict = this.model.getKeyConflict(contact.id);
var v = new ContactView({
model: contact,
conflict: conflict,
errors: this.errors[contact.id]
}).render();
this.$('.contacts').append(v.el);
},
render: function() {
this.errors = _.groupBy(this.model.get('errors'), 'number');
var hasRetry = _.find(this.model.get('errors'), function(e) {
return (e.name === 'OutgoingMessageError' ||
e.name === 'SendMessageNetworkError');
});
this.$el.html(Mustache.render(_.result(this, 'template', ''), {
sent_at : moment(this.model.get('sent_at')).toString(),
received_at : moment(this.model.get('received_at')).toString(),
tofrom : this.model.isIncoming() ? 'From' : 'To',
errors : this.errors['undefined'],
hasRetry : hasRetry
}));
this.view.$el.prependTo(this.$('.message-container'));
if (this.model.isOutgoing()) {
this.conversation.contactCollection.reject(function(c) {
return c.id === textsecure.storage.user.getNumber();
}).forEach(this.renderContact.bind(this));
} else {
this.renderContact(
this.conversation.contactCollection.get(this.model.get('source'))
);
}
}
});
})();