From 04cf441c5ae18400c6b4865b0b37a71718dc9d46 Mon Sep 17 00:00:00 2001 From: Ola Bini Date: Thu, 31 Jul 2014 19:29:33 -0300 Subject: Add web-ui based on previous code --- web-ui/app/js/mail_view/ui/mail_view.js | 242 ++++++++++++++++++++++++++++++++ 1 file changed, 242 insertions(+) create mode 100644 web-ui/app/js/mail_view/ui/mail_view.js (limited to 'web-ui/app/js/mail_view/ui/mail_view.js') diff --git a/web-ui/app/js/mail_view/ui/mail_view.js b/web-ui/app/js/mail_view/ui/mail_view.js new file mode 100644 index 00000000..1e27c879 --- /dev/null +++ b/web-ui/app/js/mail_view/ui/mail_view.js @@ -0,0 +1,242 @@ +/*global Smail */ +/*global _ */ +/*global Bloodhound */ + +'use strict'; + +define( + [ + 'flight/lib/component', + 'views/templates', + 'mail_view/ui/mail_actions', + 'helpers/view_helper', + 'mixins/with_hide_and_show', + 'page/events', + 'views/i18n' + ], + + function (defineComponent, templates, mailActions, viewHelpers, withHideAndShow, events, i18n) { + + return defineComponent(mailView, mailActions, withHideAndShow); + + function mailView() { + this.defaultAttrs({ + tags: '.tag', + newTagInput: '#new-tag-input', + newTagButton: '#new-tag-button', + addNew: '.add-new', + deleteModal: '#delete-modal', + trashButton: '#trash-button', + archiveButton: '#archive-button', + closeModalButton: '.close-reveal-modal', + closeMailButton: '.close-mail-button' + }); + + this.attachTagCompletion = function() { + this.attr.tagCompleter = new Bloodhound({ + datumTokenizer: function(d) { return [d.value]; }, + queryTokenizer: function(q) { return [q.trim()]; }, + remote: { + url: '/tags?q=%QUERY', + filter: function(pr) { return _.map(pr, function(pp) { return {value: pp.name}; }); } + } + }); + + this.attr.tagCompleter.initialize(); + + this.select('newTagInput').typeahead({ + hint: true, + highlight: true, + minLength: 1 + }, { + source: this.attr.tagCompleter.ttAdapter() + }); + }; + + this.displayMail = function (event, data) { + this.attr.mail = data.mail; + + var date = new Date(data.mail.header.date); + data.mail.header.formattedDate = viewHelpers.getFormattedDate(date); + + data.mail.security_casing = data.mail.security_casing || {}; + var signed = this.checkSigned(data.mail); + var encrypted = this.checkEncrypted(data.mail); + + this.$node.html(templates.mails.fullView({ + header: data.mail.header, + body: [], + statuses: viewHelpers.formatStatusClasses(data.mail.status), + ident: data.mail.ident, + tags: data.mail.tags, + encryptionStatus: encrypted, + signatureStatus: signed + })); + + this.$node.find('.bodyArea').html(viewHelpers.formatMailBody(data.mail)); + this.trigger(document, events.search.highlightResults, {where: '.bodyArea'}); + this.trigger(document, events.search.highlightResults, {where: '.subjectArea'}); + this.trigger(document, events.search.highlightResults, {where: '.msg-header .recipients'}); + + this.attachTagCompletion(); + + this.select('tags').on('click', function (event) { + this.removeTag($(event.target).data('tag')); + }.bind(this)); + + this.addTagLoseFocus(); + this.on(this.select('newTagButton'), 'click', this.showNewTagInput); + this.on(this.select('newTagInput'), 'keydown', this.handleKeyDown); + this.on(this.select('newTagInput'), 'typeahead:selected typeahead:autocompleted', this.createNewTag.bind(this)); + this.on(this.select('newTagInput'), 'blur', this.addTagLoseFocus); + this.on(this.select('trashButton'), 'click', this.moveToTrash); + this.on(this.select('archiveButton'), 'click', this.archiveIt); + this.on(this.select('closeModalButton'), 'click', this.closeModal); + this.on(this.select('closeMailButton'), 'click', this.openNoMessageSelectedPane); + + mailActions.attachTo('#mail-actions', data); + this.resetScroll(); + }; + + this.resetScroll = function(){ + $('#right-pane').scrollTop(0); + }; + + this.checkEncrypted = function(mail) { + if(_.isEmpty(mail.security_casing.locks)) { return 'not-encrypted'; } + + var status = ['encrypted']; + + if(_.any(mail.security_casing.locks, function (lock) { return lock.state === 'valid'; })) { status.push('encryption-valid'); } + else { status.push('encryption-failure'); } + + return status.join(' '); + }; + + this.checkSigned = function(mail) { + if(_.isEmpty(mail.security_casing.imprints)) { return 'not-signed'; } + + var status = ['signed']; + + if(_.any(mail.security_casing.imprints, function(imprint) { return imprint.state === 'from_revoked'; })) { + status.push('signature-revoked'); + } + if(_.any(mail.security_casing.imprints, function(imprint) { return imprint.state === 'from_expired'; })) { + status.push('signature-expired'); + } + + if(this.isNotTrusted(mail)) { + status.push('signature-not-trusted'); + } + + + return status.join(' '); + }; + + this.isNotTrusted = function(mail){ + return _.any(mail.security_casing.imprints, function(imprint) { + if(_.isNull(imprint.seal)){ + return true; + } + var currentTrust = _.isUndefined(imprint.seal.trust) ? imprint.seal.validity : imprint.seal.trust; + return currentTrust === 'no_trust'; + }); + }; + + this.openNoMessageSelectedPane = function(ev, data) { + this.trigger(document, events.dispatchers.rightPane.openNoMessageSelected); + }; + + this.createNewTag = function() { + var tagsCopy = this.attr.mail.tags.slice(); + tagsCopy.push(this.select('newTagInput').val()); + this.attr.tagCompleter.clear(); + this.attr.tagCompleter.clearPrefetchCache(); + this.attr.tagCompleter.clearRemoteCache(); + this.trigger(document, events.mail.tags.update, { ident: this.attr.mail.ident, tags: _.uniq(tagsCopy)}); + this.trigger(document, events.dispatchers.tags.refreshTagList); + }; + + this.handleKeyDown = function(event) { + var ENTER_KEY = 13; + var ESC_KEY = 27; + + if (event.which === ENTER_KEY){ + event.preventDefault(); + this.createNewTag(); + } else if (event.which === ESC_KEY) { + event.preventDefault(); + this.addTagLoseFocus(); + } + }; + + this.addTagLoseFocus = function () { + this.select('newTagInput').hide(); + this.select('newTagInput').typeahead('val', ''); + this.select('addNew').show(); + }; + + this.showNewTagInput = function () { + this.select('newTagInput').show(); + this.select('newTagInput').focus(); + this.select('addNew').hide(); + }; + + this.removeTag = function (tag) { + var filteredTags = _.without(this.attr.mail.tags, tag); + if (_.isEmpty(filteredTags)){ + this.displayMail({}, { mail: this.attr.mail }); + this.select('deleteModal').foundation('reveal', 'open'); + } else { + this.updateTags(filteredTags); + } + }; + + this.moveToTrash = function(){ + this.closeModal(); + this.trigger(document, events.ui.mail.delete, { mail: this.attr.mail }); + }; + + this.archiveIt = function() { + this.updateTags([]); + this.closeModal(); + this.trigger(document, events.ui.userAlerts.displayMessage, { message: i18n.get('Your message was archive it!') }); + this.openNoMessageSelectedPane(); + }; + + this.closeModal = function() { + $('#delete-modal').foundation('reveal', 'close'); + }; + + this.updateTags = function(tags) { + this.trigger(document, events.mail.tags.update, {ident: this.attr.mail.ident, tags: tags}); + }; + + this.tagsUpdated = function(ev, data) { + data = data || {}; + this.attr.mail.tags = data.tags; + this.displayMail({}, { mail: this.attr.mail }); + this.trigger(document, events.ui.tagList.refresh); + }; + + this.mailDeleted = function(ev, data) { + if (_.contains(_.pluck(data.mails, 'ident'), this.attr.mail.ident)) { + this.openNoMessageSelectedPane(); + } + }; + + this.fetchMailToShow = function () { + this.trigger(events.mail.want, {mail: this.attr.ident, caller: this}); + }; + + this.after('initialize', function () { + this.on(this, events.mail.here, this.displayMail); + this.on(this, events.mail.notFound, this.openNoMessageSelectedPane); + this.on(document, events.dispatchers.rightPane.clear, this.teardown); + this.on(document, events.mail.tags.updated, this.tagsUpdated); + this.on(document, events.mail.deleted, this.mailDeleted); + this.fetchMailToShow(); + }); + } + } +); -- cgit v1.2.3