diff --git a/exports/atom.coffee b/exports/atom.coffee index 5149a9451..676e9e4e7 100644 --- a/exports/atom.coffee +++ b/exports/atom.coffee @@ -6,6 +6,7 @@ module.exports = BufferedNodeProcess: require '../src/buffered-node-process' BufferedProcess: require '../src/buffered-process' GitRepository: require '../src/git-repository' + Notification: require '../src/notification' Point: Point Range: Range Emitter: Emitter diff --git a/spec/notification-manager-spec.coffee b/spec/notification-manager-spec.coffee new file mode 100644 index 000000000..dfc16322c --- /dev/null +++ b/spec/notification-manager-spec.coffee @@ -0,0 +1,57 @@ +NotificationManager = require '../src/notification-manager' + +describe "NotificationManager", -> + [manager] = [] + + beforeEach -> + manager = new NotificationManager + + describe "the atom global", -> + it "has a notifications instance", -> + expect(atom.notifications instanceof NotificationManager).toBe true + + describe "adding events", -> + addSpy = null + + beforeEach -> + addSpy = jasmine.createSpy() + manager.onDidAddNotification(addSpy) + + it "emits an event when a notification has been added", -> + manager.add('error', 'Some error!', icon: 'someIcon') + expect(addSpy).toHaveBeenCalled() + + notification = addSpy.mostRecentCall.args[0] + expect(notification.getType()).toBe 'error' + expect(notification.getMessage()).toBe 'Some error!' + expect(notification.getIcon()).toBe 'someIcon' + + it "emits a fatal error ::addFatalError has been called", -> + manager.addFatalError('Some error!', icon: 'someIcon') + expect(addSpy).toHaveBeenCalled() + notification = addSpy.mostRecentCall.args[0] + expect(notification.getType()).toBe 'fatal' + + it "emits an error ::addError has been called", -> + manager.addError('Some error!', icon: 'someIcon') + expect(addSpy).toHaveBeenCalled() + notification = addSpy.mostRecentCall.args[0] + expect(notification.getType()).toBe 'error' + + it "emits a warning notification ::addWarning has been called", -> + manager.addWarning('Something!', icon: 'someIcon') + expect(addSpy).toHaveBeenCalled() + notification = addSpy.mostRecentCall.args[0] + expect(notification.getType()).toBe 'warning' + + it "emits an info notification ::addInfo has been called", -> + manager.addInfo('Something!', icon: 'someIcon') + expect(addSpy).toHaveBeenCalled() + notification = addSpy.mostRecentCall.args[0] + expect(notification.getType()).toBe 'info' + + it "emits a success notification ::addSuccess has been called", -> + manager.addSuccess('Something!', icon: 'someIcon') + expect(addSpy).toHaveBeenCalled() + notification = addSpy.mostRecentCall.args[0] + expect(notification.getType()).toBe 'success' diff --git a/spec/notification-spec.coffee b/spec/notification-spec.coffee new file mode 100644 index 000000000..c564edc89 --- /dev/null +++ b/spec/notification-spec.coffee @@ -0,0 +1,18 @@ +Notification = require '../src/notification' + +describe "Notification", -> + [notification] = [] + + describe "::getTimestamp()", -> + it "returns a Date object", -> + notification = new Notification('error', 'message!') + expect(notification.getTimestamp() instanceof Date).toBe true + + describe "::getIcon()", -> + it "returns a default when no icon specified", -> + notification = new Notification('error', 'message!') + expect(notification.getIcon()).toBe 'flame' + + it "returns the icon specified", -> + notification = new Notification('error', 'message!', icon: 'my-icon') + expect(notification.getIcon()).toBe 'my-icon' diff --git a/src/atom.coffee b/src/atom.coffee index feeb7bfd7..a8b4a8ff0 100644 --- a/src/atom.coffee +++ b/src/atom.coffee @@ -146,6 +146,9 @@ class Atom extends Model # Public: A {TooltipManager} instance tooltips: null + # Experimental: A {NotificationManager} instance + notifications: null + # Public: A {Project} instance project: null @@ -220,6 +223,7 @@ class Atom extends Model ViewRegistry = require './view-registry' CommandRegistry = require './command-registry' TooltipManager = require './tooltip-manager' + NotificationManager = require './notification-manager' PackageManager = require './package-manager' Clipboard = require './clipboard' GrammarRegistry = require './grammar-registry' @@ -246,6 +250,7 @@ class Atom extends Model @keymaps = new KeymapManager({configDirPath, resourcePath}) @keymap = @keymaps # Deprecated @tooltips = new TooltipManager + @notifications = new NotificationManager @commands = new CommandRegistry @views = new ViewRegistry @packages = new PackageManager({devMode, configDirPath, resourcePath, safeMode}) diff --git a/src/notification-manager.coffee b/src/notification-manager.coffee new file mode 100644 index 000000000..499905667 --- /dev/null +++ b/src/notification-manager.coffee @@ -0,0 +1,44 @@ +{Emitter, Disposable} = require 'event-kit' +Notification = require '../src/notification' + +# Experimental: Allows messaging the user. This will likely change, dont use +# quite yet! +module.exports = +class NotificationManager + constructor: -> + @notifications = [] + @emitter = new Emitter + + ### + Section: Events + ### + + onDidAddNotification: (callback) -> + @emitter.on 'did-add-notification', callback + + ### + Section: Adding Notifications + ### + + addSuccess: (message, options) -> + @addNotification(new Notification('success', message, options)) + + addInfo: (message, options) -> + @addNotification(new Notification('info', message, options)) + + addWarning: (message, options) -> + @addNotification(new Notification('warning', message, options)) + + addError: (message, options) -> + @addNotification(new Notification('error', message, options)) + + addFatalError: (message, options) -> + @addNotification(new Notification('fatal', message, options)) + + add: (type, message, options) -> + @addNotification(new Notification(type, message, options)) + + addNotification: (notification) -> + @notifications.push(notification) + @emitter.emit('did-add-notification', notification) + notification diff --git a/src/notification.coffee b/src/notification.coffee new file mode 100644 index 000000000..04de5db18 --- /dev/null +++ b/src/notification.coffee @@ -0,0 +1,28 @@ + +# Experimental: This will likely change, do not use. +module.exports = +class Notification + constructor: (@type, @message, @options={}) -> + @timestamp = new Date() + + getOptions: -> @options + + getType: -> @type + + getMessage: -> @message + + getTimestamp: -> @timestamp + + getDetail: -> @optons.detail + + isClosable: -> + !!@options.closable + + getIcon: -> + return @options.icon if @options.icon? + switch @type + when 'fatal' then 'bug' + when 'error' then 'flame' + when 'warning' then 'alert' + when 'info' then 'info' + when 'success' then 'check' diff --git a/static/utilities.less b/static/utilities.less index 88a5209cf..dd71b44dd 100644 --- a/static/utilities.less +++ b/static/utilities.less @@ -64,13 +64,3 @@ div > .inline-block-tight:last-child { margin-left: 0; } } - -.error { - -webkit-animation: flash-error 0.3s ease-in; -} - -@-webkit-keyframes flash-error { - 0% { background: @background-color-error; } - - 100% { background: auto; } -}