fix(notifications): Give notifications tag like HTML5 Notifications so you can de-dupe

This commit is contained in:
Ben Gotow 2015-05-25 10:27:36 -07:00
parent a7740559d2
commit a7da51617c
3 changed files with 19 additions and 14 deletions

View file

@ -18,10 +18,11 @@ module.exports =
displayNotification: (version) -> displayNotification: (version) ->
version = if version then "(#{version})" else '' version = if version then "(#{version})" else ''
Actions.postNotification Actions.postNotification
type: 'info', type: 'info'
tag: 'app-update'
sticky: true sticky: true
message: "An update to Edgehill is available #{version} - Restart now to update!", message: "An update to Nylas Mail is available #{version} - Restart now to update!",
icon: 'fa-flag', icon: 'fa-flag'
actions: [{ actions: [{
label: 'Install' label: 'Install'
id: 'release-bar:install-update' id: 'release-bar:install-update'

View file

@ -8,7 +8,7 @@ DISPLAY_TIME = 3000 # in ms
uuid_count = 0 uuid_count = 0
class Notification class Notification
constructor: ({@message, @type, @sticky, @actions, @icon} = {}) -> constructor: ({@message, @type, @tag, @sticky, @actions, @icon} = {}) ->
# Check to make sure the provided data is a valid notificaiton, since # Check to make sure the provided data is a valid notificaiton, since
# notifications may be constructed by anyone developing on Edgehill # notifications may be constructed by anyone developing on Edgehill
throw new Error "No `new` keyword when constructing Notification" unless @ instanceof Notification throw new Error "No `new` keyword when constructing Notification" unless @ instanceof Notification
@ -19,20 +19,20 @@ class Notification
throw new Error "Actions must have an `label`" unless action['label'] throw new Error "Actions must have an `label`" unless action['label']
throw new Error "Actions must have an `id`" unless action['id'] throw new Error "Actions must have an `id`" unless action['id']
@id = uuid_count++ @tag ?= uuid_count++
@creation = Date.now() @creation = Date.now()
@sticky ?= false @sticky ?= false
unless @sticky unless @sticky
@expiry = @creation + DISPLAY_TIME @expiry = @creation + DISPLAY_TIME
console.log "Created new notif with #{@id}: #{@message}" if VERBOSE console.log "Created new notif with #{@tag}: #{@message}" if VERBOSE
@ @
valid: -> valid: ->
@sticky or @expiry > Date.now() @sticky or @expiry > Date.now()
toString: -> toString: ->
"Notification.#{@constructor.name}(#{@id})" "Notification.#{@constructor.name}(#{@tag})"
module.exports = module.exports =
NotificationStore = Reflux.createStore NotificationStore = Reflux.createStore
@ -49,17 +49,17 @@ NotificationStore = Reflux.createStore
@_postNotification(new Notification(data)) @_postNotification(new Notification(data))
@listenTo Actions.multiWindowNotification, (data={}, context={}) => @listenTo Actions.multiWindowNotification, (data={}, context={}) =>
@_postNotification(new Notification(data)) if @_inWindowContext(context) @_postNotification(new Notification(data)) if @_inWindowContext(context)
######### PUBLIC ####################################################### ######### PUBLIC #######################################################
notifications: -> notifications: ->
console.log(JSON.stringify(@_notifications)) if VERBOSE console.log(JSON.stringify(@_notifications)) if VERBOSE
sorted = _.sortBy(_.values(@_notifications), (n) -> -1*(n.creation + n.id)) sorted = _.sortBy(_.values(@_notifications), (n) -> -1*(n.creation + n.tag))
_.reject sorted, (n) -> n.sticky _.reject sorted, (n) -> n.sticky
stickyNotifications: -> stickyNotifications: ->
console.log(JSON.stringify(@_notifications)) if VERBOSE console.log(JSON.stringify(@_notifications)) if VERBOSE
sorted = _.sortBy(_.values(@_notifications), (n) -> -1*(n.creation + n.id)) sorted = _.sortBy(_.values(@_notifications), (n) -> -1*(n.creation + n.tag))
_.filter sorted, (n) -> n.sticky _.filter sorted, (n) -> n.sticky
Notification: Notification Notification: Notification
@ -71,7 +71,7 @@ NotificationStore = Reflux.createStore
_postNotification: (notification) -> _postNotification: (notification) ->
console.log "Queue Notification.#{notification}" if VERBOSE console.log "Queue Notification.#{notification}" if VERBOSE
@_notifications[notification.id] = notification @_notifications[notification.tag] = notification
if notification.expiry? if notification.expiry?
timeoutVal = Math.max(0, notification.expiry - Date.now()) timeoutVal = Math.max(0, notification.expiry - Date.now())
setTimeout(@_removeNotification(notification), timeoutVal) setTimeout(@_removeNotification(notification), timeoutVal)
@ -82,7 +82,7 @@ NotificationStore = Reflux.createStore
# above in setTimeout() # above in setTimeout()
_removeNotification: (notification) -> => _removeNotification: (notification) -> =>
console.log "Removed #{notification}" if VERBOSE console.log "Removed #{notification}" if VERBOSE
delete @_notifications[notification.id] delete @_notifications[notification.tag]
@trigger() @trigger()
# If the window matches the given context then we can show a # If the window matches the given context then we can show a

View file

@ -17,11 +17,15 @@ describe 'Notification', ->
expect( -> new Notification({type: 'info', message: '2', actions:[{label: 'b'}]})).toThrow() expect( -> new Notification({type: 'info', message: '2', actions:[{label: 'b'}]})).toThrow()
expect( -> new Notification({type: 'info', message: '3', actions:[{id: 'a', label: 'b'}]})).not.toThrow() expect( -> new Notification({type: 'info', message: '3', actions:[{id: 'a', label: 'b'}]})).not.toThrow()
it 'should assign its own ID and creation time', -> it 'should assign a tag and creation time', ->
@n = new Notification({type: 'info', message: 'A', actions:[{id: 'a', label: 'b'}]}) @n = new Notification({type: 'info', message: 'A', actions:[{id: 'a', label: 'b'}]})
expect(@n.id).toBeDefined() expect(@n.tag).toBeDefined()
expect(@n.creation).toBeDefined() expect(@n.creation).toBeDefined()
it 'should use a provided tag if the notification is meant to replace an existing tag', ->
@n = new Notification({tag: 'update', type: 'info', message: 'A', actions:[{id: 'a', label: 'b'}]})
expect(@n.tag).toBe('update')
it 'should be valid at creation', -> it 'should be valid at creation', ->
@n = new Notification({type: 'info', message: 'A', actions:[{id: 'a', label: 'b'}]}) @n = new Notification({type: 'info', message: 'A', actions:[{id: 'a', label: 'b'}]})
expect(@n.valid()).toBe true expect(@n.valid()).toBe true