diff --git a/js/views/conversation_list_item_view.js b/js/views/conversation_list_item_view.js
index b4949770..a2bd735d 100644
--- a/js/views/conversation_list_item_view.js
+++ b/js/views/conversation_list_item_view.js
@@ -14,52 +14,51 @@
* along with this program. If not, see .
*/
-var Whisper = Whisper || {};
(function () {
- 'use strict';
+ 'use strict';
+ var Whisper = Whisper || {};
- // list of conversations, showing user/group and last message sent
- Whisper.ConversationListItemView = Whisper.View.extend({
- tagName: 'div',
- className: 'contact',
+ // list of conversations, showing user/group and last message sent
+ Whisper.ConversationListItemView = Whisper.View.extend({
+ tagName: 'div',
+ className: 'contact',
+ template: $('#contact').html(),
+ events: {
+ 'click': 'select'
+ },
+ initialize: function() {
+ this.listenTo(this.model, 'change', this.render); // auto update
+ this.listenTo(this.model, 'destroy', this.remove); // auto update
+ },
- events: {
- 'click': 'select'
- },
- template: $('#contact').html(),
- initialize: function() {
- this.listenTo(this.model, 'change', this.render); // auto update
- this.listenTo(this.model, 'destroy', this.remove); // auto update
- },
+ select: function(e) {
+ this.$el.addClass('selected');
+ this.$el.trigger('select', {modelId: this.model.id});
+ },
- select: function(e) {
- this.$el.addClass('selected');
- this.$el.trigger('select', {modelId: this.model.id});
- },
+ render: function() {
+ this.$el.html(
+ Mustache.render(this.template, {
+ contact_name: this.model.getTitle(),
+ last_message: this.model.get('lastMessage'),
+ last_message_timestamp: moment(this.model.get('timestamp')).format('MMM D'),
+ number: this.model.getNumber()
+ })
+ );
+ if (this.model.get('avatar')) {
+ this.$el.find('.avatar').append(
+ new Whisper.AttachmentView({model: this.model.get('avatar')}).render().el
+ );
+ }
+ else {
+ this.$el.find('.avatar').append(
+ $('').attr('src', '/images/default.png')
+ );
+ }
- render: function() {
- this.$el.html(
- Mustache.render(this.template, {
- contact_name: this.model.getTitle(),
- last_message: this.model.get('lastMessage'),
- last_message_timestamp: moment(this.model.get('timestamp')).format('MMM D'),
- number: this.model.getNumber()
- })
- );
- if (this.model.get('avatar')) {
- this.$el.find('.avatar').append(
- new Whisper.AttachmentView({model: this.model.get('avatar')}).render().el
- );
- }
- else {
- this.$el.find('.avatar').append(
- $('').attr('src', '/images/default.png')
- );
- }
+ return this;
+ }
- return this;
- }
-
- });
+ });
})();
diff --git a/js/views/new_conversation_view.js b/js/views/new_conversation_view.js
index 45b12688..fb61d806 100644
--- a/js/views/new_conversation_view.js
+++ b/js/views/new_conversation_view.js
@@ -13,248 +13,248 @@
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*/
-var Whisper = Whisper || {};
(function () {
- 'use strict';
+ 'use strict';
+ var Whisper = Whisper || {};
- var ContactsTypeahead = Backbone.TypeaheadCollection.extend({
- typeaheadAttributes: [
- 'name',
- 'e164_number',
- 'national_number',
- 'international_number'
- ],
- database: Whisper.Database,
- storeName: 'conversations',
- model: Whisper.Conversation
- });
+ var ContactsTypeahead = Backbone.TypeaheadCollection.extend({
+ typeaheadAttributes: [
+ 'name',
+ 'e164_number',
+ 'national_number',
+ 'international_number'
+ ],
+ database: Whisper.Database,
+ storeName: 'conversations',
+ model: Whisper.Conversation
+ });
- Whisper.ContactPillView = Whisper.View.extend({
- tagName: 'span',
- className: 'recipient',
- events: {
- 'click .remove': 'removeModel'
- },
- template: $('#contact_pill').html(),
- initialize: function() {
- var error = this.model.validate(this.model.attributes);
- if (error) {
- this.$el.addClass('error');
- }
- },
- removeModel: function() {
- this.$el.trigger('remove', {modelId: this.model.id});
- this.remove();
- },
- attributes: function() {
- return { name: this.model.getTitle() };
- }
- });
-
- Whisper.RecipientListView = Whisper.ListView.extend({
- itemView: Whisper.ContactPillView
- });
-
- Whisper.NewConversationView = Whisper.View.extend({
- className: 'new-conversation',
- template: $('#new-conversation').html(),
- initialize: function() {
- this.render();
- this.$group_update = this.$el.find('.new-group-update-form');
- this.$buttons = this.$el.find('.buttons');
- this.$input = this.$el.find('input.new-message');
- this.$new_contact = this.$el.find('.new-contact');
-
- // Collection of contacts to match user input against
- this.typeahead = new ContactsTypeahead();
- this.typeahead.fetch({ conditions: { type: 'private' } });
-
- // View to display the matched contacts from typeahead
- this.typeahead_view = new Whisper.ConversationListView({
- collection : new Whisper.ConversationCollection([], {
- comparator: function(m) { return m.getTitle(); }
- })
- });
- this.$el.find('.contacts').append(this.typeahead_view.el);
-
- this.initNewContact();
-
- // Group avatar file input
- this.avatarInput = new Whisper.FileInputView({
- el: this.$el.find('.group-avatar')
- });
-
- // Collection of recipients selected for the new message
- this.recipients = new Whisper.ConversationCollection([], {
- comparator: false
- });
- // View to display the selected recipients
- this.recipients_view = new Whisper.RecipientListView({
- collection: this.recipients,
- el: this.$el.find('.recipients')
- });
- },
-
- events: {
- 'change input.new-message': 'filterContacts',
- 'keyup input.new-message': 'filterContacts',
- 'select .new-contact': 'addNewRecipient',
- 'select .contacts': 'addRecipient',
- 'remove .recipient': 'removeRecipient',
- 'click .create': 'create'
- },
-
- initNewContact: function() {
- if (this.new_contact) {
- this.new_contact.undelegateEvents();
- this.new_contact.$el.hide();
- }
- // Creates a view to display a new contact
- this.new_contact = new Whisper.ConversationListItemView({
- el: this.$new_contact,
- model: new Whisper.Conversation({
- active_at: null,
- type: 'private',
- newContact: true
- })
- }).render();
- },
-
- addNewRecipient: function(e, data) {
- this.recipients.add(this.new_contact.model);
- this.initNewContact();
- this.resetTypeahead();
- this.updateControls();
- },
-
- addRecipient: function(e, data) {
- this.recipients.add(this.typeahead.remove(data.modelId));
- this.filterContacts();
- this.updateControls();
- },
-
- removeRecipient: function(e, data) {
- var model = this.recipients.remove(data.modelId);
- if (!model.get('newContact')) {
- this.typeahead.add(model);
- }
- this.filterContacts();
- this.updateControls();
- },
-
- updateControls: function() {
- if (this.recipients.length > 0) {
- this.$buttons.slideDown();
- } else {
- this.$buttons.slideUp();
- }
- if (this.recipients.length > 1) {
- this.$group_update.slideDown();
- } else {
- this.$group_update.slideUp();
- }
- this.$input.focus();
- },
-
- create: function() {
- var errors = this.recipients_view.$el.find('.error');
- if (errors.length) {
-
- // TODO: css animation or error notification
- errors.removeClass('error');
- setTimeout(function(){ errors.addClass('error'); }, 300);
-
- return;
- }
- if (this.recipients.length > 1) {
- this.createGroup();
- } else {
- this.createConversation();
- }
- },
-
- createConversation: function() {
- var conversation = new Whisper.Conversation({
- active_at: null,
- id: this.recipients.at(0).id,
- type: 'private'
- });
- conversation.fetch().then(function() {
- this.$el.trigger('open', { modelId: conversation.id });
- }.bind(this)).fail(function() {
- var saved = conversation.save(); // false or indexedDBRequest
- if (saved) {
- saved.then(function() {
- this.$el.trigger('open', { modelId: conversation.id });
- }.bind(this));
+ Whisper.ContactPillView = Whisper.View.extend({
+ tagName: 'span',
+ className: 'recipient',
+ events: {
+ 'click .remove': 'removeModel'
+ },
+ template: $('#contact_pill').html(),
+ initialize: function() {
+ var error = this.model.validate(this.model.attributes);
+ if (error) {
+ this.$el.addClass('error');
}
- }.bind(this));
- },
-
- createGroup: function() {
- var name = this.$el.find('.new-group-update-form .name').val();
- if (!name.trim().length) {
- return;
+ },
+ removeModel: function() {
+ this.$el.trigger('remove', {modelId: this.model.id});
+ this.remove();
+ },
+ attributes: function() {
+ return { name: this.model.getTitle() };
}
+ });
- return this.avatarInput.getFiles().then(function(avatarFiles) {
- var attributes = {
- type: 'group',
- name: name,
- avatar: avatarFiles[0],
- members: this.recipients.pluck('id')
- };
- return textsecure.messaging.createGroup(
- attributes.members, attributes.name, attributes.avatar
- ).then(function(groupId) {
- var id = getString(groupId);
- var group = new Whisper.Conversation(attributes);
- group.save({ id: id, groupId: id }).then(function() {
- this.$el.trigger('open', {modelId: id});
- }.bind(this));
- }.bind(this));
- }.bind(this));
- },
+ Whisper.RecipientListView = Whisper.ListView.extend({
+ itemView: Whisper.ContactPillView
+ });
- resetTypeahead: function() {
- this.new_contact.$el.hide();
- this.$input.val('').focus();
- this.typeahead_view.collection.reset(this.typeahead.models);
- },
+ Whisper.NewConversationView = Whisper.View.extend({
+ className: 'new-conversation',
+ template: $('#new-conversation').html(),
+ initialize: function() {
+ this.render();
+ this.$group_update = this.$el.find('.new-group-update-form');
+ this.$buttons = this.$el.find('.buttons');
+ this.$input = this.$el.find('input.new-message');
+ this.$new_contact = this.$el.find('.new-contact');
- reset: function() {
- this.$buttons.hide();
- this.$group_update.hide();
- this.typeahead.add(
- this.recipients.filter(function(model) {
- return !model.get('newContact');
- })
- );
- this.recipients.reset([]);
- this.resetTypeahead();
- },
+ // Collection of contacts to match user input against
+ this.typeahead = new ContactsTypeahead();
+ this.typeahead.fetch({ conditions: { type: 'private' } });
- filterContacts: function() {
- var query = this.$input.val();
- if (query.length) {
- if (this.maybeNumber(query)) {
- this.new_contact.model.set('id', query);
- this.new_contact.render().$el.show();
- } else {
+ // View to display the matched contacts from typeahead
+ this.typeahead_view = new Whisper.ConversationListView({
+ collection : new Whisper.ConversationCollection([], {
+ comparator: function(m) { return m.getTitle(); }
+ })
+ });
+ this.$el.find('.contacts').append(this.typeahead_view.el);
+
+ this.initNewContact();
+
+ // Group avatar file input
+ this.avatarInput = new Whisper.FileInputView({
+ el: this.$el.find('.group-avatar')
+ });
+
+ // Collection of recipients selected for the new message
+ this.recipients = new Whisper.ConversationCollection([], {
+ comparator: false
+ });
+ // View to display the selected recipients
+ this.recipients_view = new Whisper.RecipientListView({
+ collection: this.recipients,
+ el: this.$el.find('.recipients')
+ });
+ },
+
+ events: {
+ 'change input.new-message': 'filterContacts',
+ 'keyup input.new-message': 'filterContacts',
+ 'select .new-contact': 'addNewRecipient',
+ 'select .contacts': 'addRecipient',
+ 'remove .recipient': 'removeRecipient',
+ 'click .create': 'create'
+ },
+
+ initNewContact: function() {
+ if (this.new_contact) {
+ this.new_contact.undelegateEvents();
this.new_contact.$el.hide();
}
- this.typeahead_view.collection.reset(
- this.typeahead.typeahead(query)
- );
- } else {
- this.resetTypeahead();
- }
- },
+ // Creates a view to display a new contact
+ this.new_contact = new Whisper.ConversationListItemView({
+ el: this.$new_contact,
+ model: new Whisper.Conversation({
+ active_at: null,
+ type: 'private',
+ newContact: true
+ })
+ }).render();
+ },
- maybeNumber: function(number) {
- return number.match(/^\+?[0-9]*$/);
- }
- });
+ addNewRecipient: function(e, data) {
+ this.recipients.add(this.new_contact.model);
+ this.initNewContact();
+ this.resetTypeahead();
+ this.updateControls();
+ },
+
+ addRecipient: function(e, data) {
+ this.recipients.add(this.typeahead.remove(data.modelId));
+ this.filterContacts();
+ this.updateControls();
+ },
+
+ removeRecipient: function(e, data) {
+ var model = this.recipients.remove(data.modelId);
+ if (!model.get('newContact')) {
+ this.typeahead.add(model);
+ }
+ this.filterContacts();
+ this.updateControls();
+ },
+
+ updateControls: function() {
+ if (this.recipients.length > 0) {
+ this.$buttons.slideDown();
+ } else {
+ this.$buttons.slideUp();
+ }
+ if (this.recipients.length > 1) {
+ this.$group_update.slideDown();
+ } else {
+ this.$group_update.slideUp();
+ }
+ this.$input.focus();
+ },
+
+ create: function() {
+ var errors = this.recipients_view.$el.find('.error');
+ if (errors.length) {
+
+ // TODO: css animation or error notification
+ errors.removeClass('error');
+ setTimeout(function(){ errors.addClass('error'); }, 300);
+
+ return;
+ }
+ if (this.recipients.length > 1) {
+ this.createGroup();
+ } else {
+ this.createConversation();
+ }
+ },
+
+ createConversation: function() {
+ var conversation = new Whisper.Conversation({
+ active_at: null,
+ id: this.recipients.at(0).id,
+ type: 'private'
+ });
+ conversation.fetch().then(function() {
+ this.$el.trigger('open', { modelId: conversation.id });
+ }.bind(this)).fail(function() {
+ var saved = conversation.save(); // false or indexedDBRequest
+ if (saved) {
+ saved.then(function() {
+ this.$el.trigger('open', { modelId: conversation.id });
+ }.bind(this));
+ }
+ }.bind(this));
+ },
+
+ createGroup: function() {
+ var name = this.$el.find('.new-group-update-form .name').val();
+ if (!name.trim().length) {
+ return;
+ }
+
+ return this.avatarInput.getFiles().then(function(avatarFiles) {
+ var attributes = {
+ type: 'group',
+ name: name,
+ avatar: avatarFiles[0],
+ members: this.recipients.pluck('id')
+ };
+ return textsecure.messaging.createGroup(
+ attributes.members, attributes.name, attributes.avatar
+ ).then(function(groupId) {
+ var id = getString(groupId);
+ var group = new Whisper.Conversation(attributes);
+ group.save({ id: id, groupId: id }).then(function() {
+ this.$el.trigger('open', {modelId: id});
+ }.bind(this));
+ }.bind(this));
+ }.bind(this));
+ },
+
+ resetTypeahead: function() {
+ this.new_contact.$el.hide();
+ this.$input.val('').focus();
+ this.typeahead_view.collection.reset(this.typeahead.models);
+ },
+
+ reset: function() {
+ this.$buttons.hide();
+ this.$group_update.hide();
+ this.typeahead.add(
+ this.recipients.filter(function(model) {
+ return !model.get('newContact');
+ })
+ );
+ this.recipients.reset([]);
+ this.resetTypeahead();
+ },
+
+ filterContacts: function() {
+ var query = this.$input.val();
+ if (query.length) {
+ if (this.maybeNumber(query)) {
+ this.new_contact.model.set('id', query);
+ this.new_contact.render().$el.show();
+ } else {
+ this.new_contact.$el.hide();
+ }
+ this.typeahead_view.collection.reset(
+ this.typeahead.typeahead(query)
+ );
+ } else {
+ this.resetTypeahead();
+ }
+ },
+
+ maybeNumber: function(number) {
+ return number.match(/^\+?[0-9]*$/);
+ }
+ });
})();