diff --git a/internal_packages/inbox-contact-elements/lib/Participants.cjsx b/internal_packages/inbox-contact-elements/lib/Participants.cjsx index 7b0a08583..f08029236 100644 --- a/internal_packages/inbox-contact-elements/lib/Participants.cjsx +++ b/internal_packages/inbox-contact-elements/lib/Participants.cjsx @@ -2,8 +2,6 @@ React = require "react" _ = require "underscore" ContactChip = require './ContactChip' -{NamespaceStore} = require "nylas-exports" - # Parameters # clickable (optional) - is this currently clickable? # thread (optional) - thread context for sorting @@ -25,12 +23,11 @@ class Participants extends React.Component getParticipants: => - myEmail = NamespaceStore.current().emailAddress list = @props.participants # Remove 'Me' if there is more than one participant if list.length > 1 - list = _.reject list, (p) -> p.email is myEmail + list = _.reject list, (contact) -> contact.isMe() list.forEach (p) -> p.id = p.name+p.email diff --git a/internal_packages/thread-list/lib/thread-list-icon.cjsx b/internal_packages/thread-list/lib/thread-list-icon.cjsx index 8c03a5a69..e27414843 100644 --- a/internal_packages/thread-list/lib/thread-list-icon.cjsx +++ b/internal_packages/thread-list/lib/thread-list-icon.cjsx @@ -24,8 +24,7 @@ class ThreadListIcon extends React.Component msgs = @_nonDraftMessages() last = msgs[msgs.length - 1] - myEmail = NamespaceStore.current()?.emailAddress - if msgs.length > 1 and last.from[0]?.email is myEmail + if msgs.length > 1 and last.from[0].isMe() if Utils.isForwardedMessage(last) return 'thread-icon-forwarded' else diff --git a/internal_packages/thread-list/lib/thread-list-participants.cjsx b/internal_packages/thread-list/lib/thread-list-participants.cjsx index 148d86044..17d6e7c84 100644 --- a/internal_packages/thread-list/lib/thread-list-participants.cjsx +++ b/internal_packages/thread-list/lib/thread-list-participants.cjsx @@ -1,6 +1,5 @@ React = require 'react' _ = require 'underscore' -{NamespaceStore} = require 'nylas-exports' class ThreadListParticipants extends React.Component @displayName: 'ThreadListParticipants' @@ -69,7 +68,7 @@ class ThreadListParticipants extends React.Component else # check adjacent email uniqueness last = msgs[i - 1][toOrFrom][0] curr = msgs[i][toOrFrom][0] - isUniqueEmail = last.email isnt curr.email + isUniqueEmail = last.email.toLowerCase() isnt curr.email.toLowerCase() isUniqueName = last.name isnt curr.name isUniqueEmail or isUniqueName @@ -80,8 +79,7 @@ class ThreadListParticipants extends React.Component if @props.thread.metadata shouldOnlyShowRecipients = @props.thread.metadata.every (msg) -> - sender = msg.from[0] - sender.email is NamespaceStore.current().emailAddress + msg.from[0]?.isMe() input = @props.thread.metadata toOrFrom = if shouldOnlyShowRecipients then "to" else "from" filterer = makeMetadataFilterer toOrFrom @@ -89,8 +87,7 @@ class ThreadListParticipants extends React.Component else input = @props.thread.participants return [] unless input and input instanceof Array - currentUserEmail = NamespaceStore.current().emailAddress - filterer = (msg) -> msg.email isnt currentUserEmail + filterer = (contact) -> not contact.isMe() mapper = (contact) -> { contact: contact, unread: false } list = _.chain(input) diff --git a/internal_packages/thread-list/spec/thread-list-participants-spec.cjsx b/internal_packages/thread-list/spec/thread-list-participants-spec.cjsx index 44923196f..499aada69 100644 --- a/internal_packages/thread-list/spec/thread-list-participants-spec.cjsx +++ b/internal_packages/thread-list/spec/thread-list-participants-spec.cjsx @@ -173,6 +173,7 @@ describe "ThreadListParticipants", -> @me = NamespaceStore.current().me() @ben = new Contact(email: 'ben@nylas.com', name: 'ben') @evan = new Contact(email: 'evan@nylas.com', name: 'evan') + @evanCapitalized = new Contact(email: 'EVAN@nylas.com', name: 'evan') @michael = new Contact(email: 'michael@nylas.com', name: 'michael') @kavya = new Contact(email: 'kavya@nylas.com', name: 'kavya') @@ -194,6 +195,13 @@ describe "ThreadListParticipants", -> {contact: @ben, unread: false}] expect(actualOut).toEqual expectedOut + it "is case insensitive", -> + input = [new Message(unread: false, from: [@me], to: [@evan]) + new Message(unread: false, from: [@me], to: [@evanCapitalized])] + actualOut = getParticipants input + expectedOut = [{contact: @evan, unread: false}] + expect(actualOut).toEqual expectedOut + it "shows only first, spacer, second to last, and last recipients if recipients count > 3", -> input = [new Message(unread: false, from: [@me], to: [@ben]) new Message(unread: false, from: [@me], to: [@evan]) @@ -215,6 +223,33 @@ describe "ThreadListParticipants", -> {contact: @kavya, unread: false}] expect(actualOut).toEqual expectedOut + it "shows only one recipient if the sender only sent to one recipient", -> + input = [new Message(unread: false, from: [@me], to: [@evan]) + new Message(unread: false, from: [@me], to: [@evan]) + new Message(unread: false, from: [@me], to: [@evan]) + new Message(unread: false, from: [@me], to: [@evan])] + actualOut = getParticipants input + expectedOut = [{contact: @evan, unread: false}] + expect(actualOut).toEqual expectedOut + + it "shows only the recipient for one sent email", -> + input = [new Message(unread: false, from: [@me], to: [@evan])] + actualOut = getParticipants input + expectedOut = [{contact: @evan, unread: false}] + expect(actualOut).toEqual expectedOut + + it "shows unread email as well", -> + input = [new Message(unread: false, from: [@me], to: [@evan]) + new Message(unread: false, from: [@me], to: [@ben]) + new Message(unread: true, from: [@me], to: [@kavya]) + new Message(unread: true, from: [@me], to: [@michael])] + actualOut = getParticipants input + expectedOut = [{contact: @evan, unread: false}, + {spacer: true}, + {contact: @kavya, unread: true}, + {contact: @michael, unread: true}] + expect(actualOut).toEqual expectedOut + describe "when thread.messages is not available", -> it "correctly produces items for display in a wide range of scenarios", -> me = NamespaceStore.current().me() diff --git a/internal_packages/unread-notifications/lib/main.coffee b/internal_packages/unread-notifications/lib/main.coffee index 638845243..14154f1f3 100644 --- a/internal_packages/unread-notifications/lib/main.coffee +++ b/internal_packages/unread-notifications/lib/main.coffee @@ -2,8 +2,7 @@ _ = require 'underscore' {Thread, Actions, CategoryStore, - DatabaseStore, - NamespaceStore} = require 'nylas-exports' + DatabaseStore} = require 'nylas-exports' module.exports = @@ -63,11 +62,10 @@ module.exports = incomingThreads = incoming['thread'] ? [] # Filter for new messages that are not sent by the current user - myEmail = NamespaceStore.current().emailAddress newUnread = _.filter incomingMessages, (msg) => isUnread = msg.unread is true isNew = msg.date?.valueOf() >= @activationTime - isFromMe = msg.from[0]?.email is myEmail + isFromMe = msg.isFromMe() return isUnread and isNew and not isFromMe return resolve() if newUnread.length is 0 diff --git a/spec-nylas/models/contact-spec.coffee b/spec-nylas/models/contact-spec.coffee index 73ce95b70..437da3c56 100644 --- a/spec-nylas/models/contact-spec.coffee +++ b/spec-nylas/models/contact-spec.coffee @@ -81,3 +81,14 @@ describe "Contact", -> expect(c1.displayName()).toBe "You" expect(c1.displayFirstName()).toBe "You" expect(c1.displayLastName()).toBe "" + + describe "isMe", -> + it "returns true if the contact name matches the namespace email address", -> + c1 = new Contact {email: NamespaceStore.current().emailAddress} + expect(c1.isMe()).toBe(true) + c1 = new Contact {email: 'ben@nylas.com'} + expect(c1.isMe()).toBe(false) + + it "is case insensitive", -> + c1 = new Contact {email: NamespaceStore.current().emailAddress.toUpperCase()} + expect(c1.isMe()).toBe(true) diff --git a/src/flux/models/contact.coffee b/src/flux/models/contact.coffee index 376158737..a40a3af08 100644 --- a/src/flux/models/contact.coffee +++ b/src/flux/models/contact.coffee @@ -71,20 +71,26 @@ class Contact extends Model json['name'] ||= json['email'] json + # Public: Returns true if the contact is the current user, false otherwise. + # You should use this method instead of comparing the user's email address to + # the namespace email, since it is case-insensitive and future-proof. + isMe: -> + @email.toLowerCase() is NamespaceStore.current()?.emailAddress.toLowerCase() + # Returns a {String} display name. # - "You" if the contact is the current user # - `name` if the contact has a populated name value # - `email` in all other cases. displayName: -> - return "You" if @email is NamespaceStore.current()?.emailAddress + return "You" if @isMe() @_nameParts().join(' ') displayFirstName: -> - return "You" if @email is NamespaceStore.current()?.emailAddress + return "You" if @isMe() @firstName() displayLastName: -> - return "" if @email is NamespaceStore.current()?.emailAddress + return "" if @isMe() @lastName() firstName: -> diff --git a/src/flux/models/message.coffee b/src/flux/models/message.coffee index 27ca05eab..f136d05c8 100644 --- a/src/flux/models/message.coffee +++ b/src/flux/models/message.coffee @@ -256,7 +256,7 @@ class Message extends Model # address. In the future, this method will take into account all of the # user's email addresses and namespaces. isFromMe: -> - @from[0].email is NamespaceStore.current().emailAddress + @from[0]?.isMe() # Public: Returns a plaintext version of the message body using Chromium's # DOMParser. Use with care.