_ = require 'underscore' {Thread, Actions, CategoryStore, DatabaseStore, NamespaceStore} = require 'nylas-exports' module.exports = activate: -> @unlisteners = [] @unlisteners.push Actions.didPassivelyReceiveNewModels.listen(@_onNewMailReceived, @) @activationTime = Date.now() @stack = [] @stackProcessTimer = null deactivate: -> fn() for fn in @unlisteners serialize: -> _notifyAll: -> new Notification("#{@stack.length} Unread Messages", { tag: 'unread-update' }) @stack = [] _notifyOne: ({message, thread}) -> body = message.subject if not body or body.length is 0 body = message.snippet from = message.from[0]?.displayName() ? "Unknown" notif = new Notification(from, { body: body tag: 'unread-update' }) notif.onclick = => atom.displayWindow() Actions.focusCategory(CategoryStore.getStandardCategory("inbox")) Actions.setFocus(collection: 'thread', item: thread) _notifyMessages: -> if @stack.length >= 5 @_notifyAll() else if @stack.length > 0 @_notifyOne(@stack.pop()) @stackProcessTimer = null if @stack.length > 0 @stackProcessTimer = setTimeout(( => @_notifyMessages()), 2000) _onNewMailReceived: (incoming) -> new Promise (resolve, reject) => incomingMessages = incoming['message'] ? [] 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 return isUnread and isNew and not isFromMe return resolve() if newUnread.length is 0 # For each message, find it's corresponding thread. First, look to see # if it's already in the `incoming` payload (sent via delta sync # at the same time as the message.) If it's not, try loading it from # the local cache. # # Note we may receive multiple unread msgs for the same thread. # Using a map and ?= to avoid repeating work. threads = {} for msg in newUnread threads[msg.threadId] ?= _.findWhere(incomingThreads, {id: msg.threadId}) threads[msg.threadId] ?= DatabaseStore.find(Thread, msg.threadId) Promise.props(threads).then (threads) => # Filter new unread messages to just the ones in the inbox newUnreadInInbox = _.filter newUnread, (msg) -> threads[msg.threadId]?.hasCategoryName('inbox') return resolve() if newUnreadInInbox.length is 0 atom.playSound('new_mail.ogg') for msg in newUnreadInInbox @stack.push({message: msg, thread: threads[msg.threadId]}) if not @stackProcessTimer @_notifyMessages() resolve()