From 1c91bd3100e3387341e7858d9b2c1e78b683f1fd Mon Sep 17 00:00:00 2001 From: probablycorey Date: Mon, 7 Apr 2014 09:14:35 -0700 Subject: [PATCH 01/21] Create AutoUpdater class --- src/browser/auto-updater.coffee | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 src/browser/auto-updater.coffee diff --git a/src/browser/auto-updater.coffee b/src/browser/auto-updater.coffee new file mode 100644 index 000000000..62aa36624 --- /dev/null +++ b/src/browser/auto-updater.coffee @@ -0,0 +1,2 @@ +module.exports = +class AutoUpdater From d39c422da95bd60f3f4ff5f575705f06be4280e4 Mon Sep 17 00:00:00 2001 From: probablycorey Date: Mon, 7 Apr 2014 09:37:44 -0700 Subject: [PATCH 02/21] Add content to AutoUpdater --- src/browser/auto-updater.coffee | 53 +++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/browser/auto-updater.coffee b/src/browser/auto-updater.coffee index 62aa36624..a0f7356b1 100644 --- a/src/browser/auto-updater.coffee +++ b/src/browser/auto-updater.coffee @@ -1,2 +1,55 @@ +autoUpdater = require 'auto-updater' +dialog = require 'dialog' + module.exports = class AutoUpdater + constructor: (@applicationMenu) -> + + # Only released versions should check for updates. + return if /\w{7}/.test(@getVersion()) + + autoUpdater.setFeedUrl "https://atom.io/api/updates?version=#{@getVersion()}" + + autoUpdater.on 'checking-for-update', => + @applicationMenu.showDownloadingUpdateItem(false) + @applicationMenu.showInstallUpdateItem(false) + @applicationMenu.showCheckForUpdateItem(false) + + autoUpdater.on 'update-not-available', => + @applicationMenu.showCheckForUpdateItem(true) + + autoUpdater.on 'update-available', => + @applicationMenu.showDownloadingUpdateItem(true) + + autoUpdater.on 'update-downloaded', (event, releaseNotes, releaseVersion, releaseDate, releaseURL) => + for atomWindow in @getWindows() + atomWindow.sendCommand('window:update-available', [releaseVersion, releaseNotes]) + @applicationMenu.showInstallUpdateItem(true) + + autoUpdater.on 'error', (event, message) => + @applicationMenu.showCheckForUpdateItem(true) + + # Check for update after Atom has fully started and the menus are created + setTimeout((-> autoUpdater.checkForUpdates()), 5000) + + checkForUpdate: -> + autoUpdater.once 'update-not-available', @onUpdateNotAvailable + autoUpdater.once 'error', @onUpdateError + autoUpdater.checkForUpdates() + + installUpdate: -> + autoUpdater.quitAndInstall() + + onUpdateNotAvailable: => + autoUpdater.removeListener 'error', @onUpdateError + dialog.showMessageBox type: 'info', buttons: ['OK'], message: 'No update available.', detail: "Version #{@version} is the latest version." + + onUpdateError: (event, message) => + autoUpdater.removeListener 'update-not-available', @onUpdateNotAvailable + dialog.showMessageBox type: 'warning', buttons: ['OK'], message: 'There was an error checking for updates.', detail: message + + getVersion: -> + global.atomApplication.version + + getWindows: -> + global.atomApplication.windows From 23d3405ae79b42a84f4d71910118bd1a4f03e41b Mon Sep 17 00:00:00 2001 From: probablycorey Date: Mon, 7 Apr 2014 09:38:36 -0700 Subject: [PATCH 03/21] Rename to AutoUpdateManager So it isn't confused with Atom Shell's auto-updater class --- src/browser/{auto-updater.coffee => auto-update-manager.coffee} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/browser/{auto-updater.coffee => auto-update-manager.coffee} (98%) diff --git a/src/browser/auto-updater.coffee b/src/browser/auto-update-manager.coffee similarity index 98% rename from src/browser/auto-updater.coffee rename to src/browser/auto-update-manager.coffee index a0f7356b1..284bfbca7 100644 --- a/src/browser/auto-updater.coffee +++ b/src/browser/auto-update-manager.coffee @@ -2,7 +2,7 @@ autoUpdater = require 'auto-updater' dialog = require 'dialog' module.exports = -class AutoUpdater +class AutoUpdateManager constructor: (@applicationMenu) -> # Only released versions should check for updates. From e21a1339a2d20deaee35999941338ce653e4785e Mon Sep 17 00:00:00 2001 From: probablycorey Date: Mon, 7 Apr 2014 10:20:32 -0700 Subject: [PATCH 04/21] Use AutoUpdateManager --- src/browser/atom-application.coffee | 47 ++--------------------------- 1 file changed, 3 insertions(+), 44 deletions(-) diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index c0f5636e8..45943a49f 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -1,11 +1,10 @@ AtomWindow = require './atom-window' ApplicationMenu = require './application-menu' AtomProtocolHandler = require './atom-protocol-handler' +AutoUpdateManager = require './auto-update-manager' BrowserWindow = require 'browser-window' Menu = require 'menu' -autoUpdater = require 'auto-updater' app = require 'app' -dialog = require 'dialog' fs = require 'fs' ipc = require 'ipc' path = require 'path' @@ -68,11 +67,11 @@ class AtomApplication @applicationMenu = new ApplicationMenu(@version) @atomProtocolHandler = new AtomProtocolHandler(@resourcePath) + @autoUpdateManager = new AutoUpdateManager() @listenForArgumentsFromNewProcess() @setupJavaScriptArguments() @handleEvents() - @setupAutoUpdater() @openWithOptions(options) @@ -127,46 +126,6 @@ class AtomApplication setupJavaScriptArguments: -> app.commandLine.appendSwitch 'js-flags', '--harmony' - # Enable updates unless running from a local build of Atom. - setupAutoUpdater: -> - return if /\w{7}/.test(@version) # Only released versions should check for updates. - - autoUpdater.setFeedUrl "https://atom.io/api/updates?version=#{@version}" - - autoUpdater.on 'checking-for-update', => - @applicationMenu.showDownloadingUpdateItem(false) - @applicationMenu.showInstallUpdateItem(false) - @applicationMenu.showCheckForUpdateItem(false) - - autoUpdater.on 'update-not-available', => - @applicationMenu.showCheckForUpdateItem(true) - - autoUpdater.on 'update-available', => - @applicationMenu.showDownloadingUpdateItem(true) - - autoUpdater.on 'update-downloaded', (event, releaseNotes, releaseVersion, releaseDate, releaseURL) => - atomWindow.sendCommand('window:update-available', [releaseVersion, releaseNotes]) for atomWindow in @windows - @applicationMenu.showInstallUpdateItem(true) - - autoUpdater.on 'error', (event, message) => - @applicationMenu.showCheckForUpdateItem(true) - - # Check for update after Atom has fully started and the menus are created - setTimeout((-> autoUpdater.checkForUpdates()), 5000) - - checkForUpdate: -> - @onUpdateNotAvailable ?= => - autoUpdater.removeListener 'error', @onUpdateError - dialog.showMessageBox type: 'info', buttons: ['OK'], message: 'No update available.', detail: "Version #{@version} is the latest version." - - @onUpdateError ?= (event, message) => - autoUpdater.removeListener 'update-not-available', @onUpdateNotAvailable - dialog.showMessageBox type: 'warning', buttons: ['OK'], message: 'There was an error checking for updates.', detail: message - - autoUpdater.once 'update-not-available', @onUpdateNotAvailable - autoUpdater.once 'error', @onUpdateError - autoUpdater.checkForUpdates() - # Registers basic application commands, non-idempotent. handleEvents: -> @on 'application:run-all-specs', -> @runSpecs(exitWhenDone: false, resourcePath: global.devResourcePath) @@ -178,7 +137,7 @@ class AtomApplication @on 'application:open-dev', -> @promptForPath(devMode: true) @on 'application:inspect', ({x,y}) -> @focusedWindow().browserWindow.inspectElement(x, y) @on 'application:open-documentation', -> shell.openExternal('https://atom.io/docs/latest/?app') - @on 'application:install-update', -> autoUpdater.quitAndInstall() + @on 'application:install-update', -> @autoUpdateManager.install() @on 'application:check-for-update', => @checkForUpdate() if process.platform is 'darwin' From 33adaab8b1c25946762cc648fd8b92aa684ee157 Mon Sep 17 00:00:00 2001 From: probablycorey Date: Mon, 7 Apr 2014 10:21:25 -0700 Subject: [PATCH 05/21] Add getMenu method --- src/browser/auto-update-manager.coffee | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/browser/auto-update-manager.coffee b/src/browser/auto-update-manager.coffee index 284bfbca7..02a7d458d 100644 --- a/src/browser/auto-update-manager.coffee +++ b/src/browser/auto-update-manager.coffee @@ -3,31 +3,30 @@ dialog = require 'dialog' module.exports = class AutoUpdateManager - constructor: (@applicationMenu) -> - + constructor: -> # Only released versions should check for updates. return if /\w{7}/.test(@getVersion()) autoUpdater.setFeedUrl "https://atom.io/api/updates?version=#{@getVersion()}" autoUpdater.on 'checking-for-update', => - @applicationMenu.showDownloadingUpdateItem(false) - @applicationMenu.showInstallUpdateItem(false) - @applicationMenu.showCheckForUpdateItem(false) + @getMenu().showDownloadingUpdateItem(false) + @getMenu().showInstallUpdateItem(false) + @getMenu().showCheckForUpdateItem(false) autoUpdater.on 'update-not-available', => - @applicationMenu.showCheckForUpdateItem(true) + @getMenu().showCheckForUpdateItem(true) autoUpdater.on 'update-available', => - @applicationMenu.showDownloadingUpdateItem(true) + @getMenu().showDownloadingUpdateItem(true) autoUpdater.on 'update-downloaded', (event, releaseNotes, releaseVersion, releaseDate, releaseURL) => for atomWindow in @getWindows() atomWindow.sendCommand('window:update-available', [releaseVersion, releaseNotes]) - @applicationMenu.showInstallUpdateItem(true) + @getMenu().showInstallUpdateItem(true) autoUpdater.on 'error', (event, message) => - @applicationMenu.showCheckForUpdateItem(true) + @getMenu().showCheckForUpdateItem(true) # Check for update after Atom has fully started and the menus are created setTimeout((-> autoUpdater.checkForUpdates()), 5000) @@ -48,6 +47,9 @@ class AutoUpdateManager autoUpdater.removeListener 'update-not-available', @onUpdateNotAvailable dialog.showMessageBox type: 'warning', buttons: ['OK'], message: 'There was an error checking for updates.', detail: message + getMenu: -> + global.atomApplication.applicationMenu + getVersion: -> global.atomApplication.version From 82081aa5e948101c1ab1e8ded3549a1a28779bdb Mon Sep 17 00:00:00 2001 From: probablycorey Date: Mon, 7 Apr 2014 10:21:37 -0700 Subject: [PATCH 06/21] Rename methods --- src/browser/auto-update-manager.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/browser/auto-update-manager.coffee b/src/browser/auto-update-manager.coffee index 02a7d458d..b8ade987b 100644 --- a/src/browser/auto-update-manager.coffee +++ b/src/browser/auto-update-manager.coffee @@ -31,12 +31,12 @@ class AutoUpdateManager # Check for update after Atom has fully started and the menus are created setTimeout((-> autoUpdater.checkForUpdates()), 5000) - checkForUpdate: -> + check: -> autoUpdater.once 'update-not-available', @onUpdateNotAvailable autoUpdater.once 'error', @onUpdateError autoUpdater.checkForUpdates() - installUpdate: -> + install: -> autoUpdater.quitAndInstall() onUpdateNotAvailable: => From f5ea098417fd8ce7ab9d5d8ae6e3f092578ed40f Mon Sep 17 00:00:00 2001 From: probablycorey Date: Mon, 7 Apr 2014 11:04:55 -0700 Subject: [PATCH 07/21] Don't overwrite menu item's metadata field --- src/browser/application-menu.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/browser/application-menu.coffee b/src/browser/application-menu.coffee index 5aa611666..828229e9e 100644 --- a/src/browser/application-menu.coffee +++ b/src/browser/application-menu.coffee @@ -122,7 +122,7 @@ class ApplicationMenu # Returns a complete menu configuration object for atom-shell's menu API. translateTemplate: (template, keystrokesByCommand) -> template.forEach (item) => - item.metadata = {} + item.metadata ?= {} if item.command item.accelerator = @acceleratorForCommand(item.command, keystrokesByCommand) item.click = => global.atomApplication.sendCommand(item.command) From 789f29e0b561eb175b46f342584829c1bc3da21f Mon Sep 17 00:00:00 2001 From: probablycorey Date: Mon, 7 Apr 2014 12:25:55 -0700 Subject: [PATCH 08/21] AutoUpdateManager barely works --- menus/darwin.cson | 4 +- src/browser/application-menu.coffee | 51 ++++++++++++++------------ src/browser/atom-application.coffee | 6 +-- src/browser/auto-update-manager.coffee | 49 ++++++++++++++++--------- 4 files changed, 63 insertions(+), 47 deletions(-) diff --git a/menus/darwin.cson b/menus/darwin.cson index 01c4283d2..607e8d5e5 100644 --- a/menus/darwin.cson +++ b/menus/darwin.cson @@ -5,9 +5,7 @@ { label: 'About Atom', command: 'application:about' } { label: 'View License', command: 'application:open-license' } { label: "VERSION", enabled: false } - { label: "Restart and Install Update", command: 'application:install-update', visible: false} - { label: "Check for Update", command: 'application:check-for-update', visible: false} - { label: "Downloading Update", command: 'application:check-for-update', enabled: false, visible: false} + { label: "Check for Update", command: 'application:noop', metadata: {autoUpdate: true}} { type: 'separator' } { label: 'Preferences...', command: 'application:show-settings' } { label: 'Open Your Config', command: 'application:open-your-config' } diff --git a/src/browser/application-menu.coffee b/src/browser/application-menu.coffee index 828229e9e..f4d220483 100644 --- a/src/browser/application-menu.coffee +++ b/src/browser/application-menu.coffee @@ -12,6 +12,8 @@ class ApplicationMenu constructor: (@version) -> @menu = Menu.buildFromTemplate @getDefaultTemplate() Menu.setApplicationMenu @menu + global.atomApplication.autoUpdateManager.on 'state-changed', (state) => + @update(@template, @keystrokesByCommand) if @template? # Public: Updates the entire menu with the given keybindings. # @@ -21,8 +23,12 @@ class ApplicationMenu # An Object where the keys are commands and the values are Arrays containing # the keystroke. update: (template, keystrokesByCommand) -> + @template = _.clone(template) + @keystrokesByCommand = _.clone(keystrokesByCommand) + @translateTemplate(template, keystrokesByCommand) @substituteVersion(template) + @setUpdateMenuItemState(template) @menu = Menu.buildFromTemplate(template) Menu.setApplicationMenu(@menu) @@ -66,32 +72,28 @@ class ApplicationMenu if (item = _.find(@flattenMenuTemplate(template), (i) -> i.label == 'VERSION')) item.label = "Version #{@version}" - # Toggles Install Update Item - showInstallUpdateItem: (visible=true) -> - if visible - @showDownloadingUpdateItem(false) - @showCheckForUpdateItem(false) + # Sets the proper label, command and enabled state for the update menu item + setUpdateMenuItemState: (template) -> + item = _.find(@flattenMenuTemplate(template), (i) -> i.metadata.autoUpdate) + return unless item? - if (item = _.find(@flattenMenuItems(@menu), (i) -> i.label == 'Restart and Install Update')) - item.visible = visible + item.enabled = true + console.log global.atomApplication.autoUpdateManager.getState() + switch global.atomApplication.autoUpdateManager.getState() + when 'idle', 'error', 'no-update-available' + item.label = 'Check for Update' + item.command = 'application:check-for-update' + when 'checking' + item.enabled = false + item.label = 'Checking for Update' + when 'downloading' + item.enabled = false + item.label = 'Downloading Update' + when 'update-available' + item.label = 'Restart and Install Update' + item.command = 'application:install-update' - # Toggles Downloading Update Item - showDownloadingUpdateItem: (visible=true) -> - if visible - @showInstallUpdateItem(false) - @showCheckForUpdateItem(false) - - if (item = _.find(@flattenMenuItems(@menu), (i) -> i.label == 'Downloading Update')) - item.visible = visible - - # Toggles Check For Update Item - showCheckForUpdateItem: (visible=true) -> - if visible - @showDownloadingUpdateItem(false) - @showInstallUpdateItem(false) - - if (item = _.find(@flattenMenuItems(@menu), (i) -> i.label == 'Check for Update')) - item.visible = visible + console.log require('util').inspect(item) # Default list of menu items. # @@ -100,6 +102,7 @@ class ApplicationMenu [ label: "Atom" submenu: [ + { label: "Check for Update", metadata: {autoUpdate: true}} { label: 'Reload', accelerator: 'Command+R', click: => @focusedWindow()?.reload() } { label: 'Close Window', accelerator: 'Command+Shift+W', click: => @focusedWindow()?.close() } { label: 'Toggle Dev Tools', accelerator: 'Command+Alt+I', click: => @focusedWindow()?.toggleDevTools() } diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 45943a49f..733b41f74 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -65,9 +65,9 @@ class AtomApplication @pathsToOpen ?= [] @windows = [] - @applicationMenu = new ApplicationMenu(@version) - @atomProtocolHandler = new AtomProtocolHandler(@resourcePath) @autoUpdateManager = new AutoUpdateManager() + @applicationMenu = new ApplicationMenu(@version, @autoUpdateManager) + @atomProtocolHandler = new AtomProtocolHandler(@resourcePath) @listenForArgumentsFromNewProcess() @setupJavaScriptArguments() @@ -138,7 +138,7 @@ class AtomApplication @on 'application:inspect', ({x,y}) -> @focusedWindow().browserWindow.inspectElement(x, y) @on 'application:open-documentation', -> shell.openExternal('https://atom.io/docs/latest/?app') @on 'application:install-update', -> @autoUpdateManager.install() - @on 'application:check-for-update', => @checkForUpdate() + @on 'application:check-for-update', => @autoUpdateManager.check() if process.platform is 'darwin' @on 'application:about', -> Menu.sendActionToFirstResponder('orderFrontStandardAboutPanel:') diff --git a/src/browser/auto-update-manager.coffee b/src/browser/auto-update-manager.coffee index b8ade987b..78287af90 100644 --- a/src/browser/auto-update-manager.coffee +++ b/src/browser/auto-update-manager.coffee @@ -1,35 +1,53 @@ autoUpdater = require 'auto-updater' dialog = require 'dialog' +{Emitter} = require 'emissary' + +IDLE_STATE='idle' +CHECKING_STATE='checking' +DOWNLOADING_STATE='downloading' +UPDATE_AVAILABLE_STATE='update-available' +NO_UPDATE_AVAILABLE_STATE='no-update-available' +ERROR_STATE='error' module.exports = class AutoUpdateManager + Emitter.includeInto(this) + constructor: -> + @state = IDLE_STATE + # Only released versions should check for updates. - return if /\w{7}/.test(@getVersion()) + # return if /\w{7}/.test(@getVersion()) autoUpdater.setFeedUrl "https://atom.io/api/updates?version=#{@getVersion()}" autoUpdater.on 'checking-for-update', => - @getMenu().showDownloadingUpdateItem(false) - @getMenu().showInstallUpdateItem(false) - @getMenu().showCheckForUpdateItem(false) + @setState(CHECKING_STATE) autoUpdater.on 'update-not-available', => - @getMenu().showCheckForUpdateItem(true) + @setState(NO_UPDATE_AVAILABLE_STATE) autoUpdater.on 'update-available', => - @getMenu().showDownloadingUpdateItem(true) - - autoUpdater.on 'update-downloaded', (event, releaseNotes, releaseVersion, releaseDate, releaseURL) => - for atomWindow in @getWindows() - atomWindow.sendCommand('window:update-available', [releaseVersion, releaseNotes]) - @getMenu().showInstallUpdateItem(true) + @setState(DOWNLOADING_STATE) autoUpdater.on 'error', (event, message) => - @getMenu().showCheckForUpdateItem(true) + @setState(ERROR_STATE) + console.error "Error Downloading Update: #{message}" - # Check for update after Atom has fully started and the menus are created - setTimeout((-> autoUpdater.checkForUpdates()), 5000) + autoUpdater.on 'update-downloaded', (event, releaseNotes, releaseVersion, releaseDate, releaseURL) => + @setState(UPDATE_AVAILABLE_STATE) + for atomWindow in @getWindows() + atomWindow.sendCommand('window:update-available', [releaseVersion, releaseNotes]) + + @check() + + setState: (state) -> + return unless @state != state + @state = state + @emit 'state-changed', @state + + getState: -> + @state check: -> autoUpdater.once 'update-not-available', @onUpdateNotAvailable @@ -47,9 +65,6 @@ class AutoUpdateManager autoUpdater.removeListener 'update-not-available', @onUpdateNotAvailable dialog.showMessageBox type: 'warning', buttons: ['OK'], message: 'There was an error checking for updates.', detail: message - getMenu: -> - global.atomApplication.applicationMenu - getVersion: -> global.atomApplication.version From d4ae8362255624c7506a5b4cc44031e14fc15415 Mon Sep 17 00:00:00 2001 From: probablycorey Date: Mon, 7 Apr 2014 14:17:44 -0700 Subject: [PATCH 09/21] Use hidden menu items for update processes --- menus/darwin.cson | 6 ++-- src/browser/application-menu.coffee | 41 +++++++++++--------------- src/browser/auto-update-manager.coffee | 12 ++++---- 3 files changed, 29 insertions(+), 30 deletions(-) diff --git a/menus/darwin.cson b/menus/darwin.cson index 607e8d5e5..6c93c78f3 100644 --- a/menus/darwin.cson +++ b/menus/darwin.cson @@ -4,8 +4,10 @@ submenu: [ { label: 'About Atom', command: 'application:about' } { label: 'View License', command: 'application:open-license' } - { label: "VERSION", enabled: false } - { label: "Check for Update", command: 'application:noop', metadata: {autoUpdate: true}} + { label: 'VERSION', enabled: false } + { label: 'Check for Update', command: 'application:check-for-update', visible: false} + { label: 'Downloading Update', enabled: false, visible: false} + { label: 'Restart and Install Update', command: 'application:install-update', enabled: false, visible: false} { type: 'separator' } { label: 'Preferences...', command: 'application:show-settings' } { label: 'Open Your Config', command: 'application:open-your-config' } diff --git a/src/browser/application-menu.coffee b/src/browser/application-menu.coffee index f4d220483..6e874573e 100644 --- a/src/browser/application-menu.coffee +++ b/src/browser/application-menu.coffee @@ -13,7 +13,7 @@ class ApplicationMenu @menu = Menu.buildFromTemplate @getDefaultTemplate() Menu.setApplicationMenu @menu global.atomApplication.autoUpdateManager.on 'state-changed', (state) => - @update(@template, @keystrokesByCommand) if @template? + @showUpdateMenuItem(state) # Public: Updates the entire menu with the given keybindings. # @@ -23,15 +23,13 @@ class ApplicationMenu # An Object where the keys are commands and the values are Arrays containing # the keystroke. update: (template, keystrokesByCommand) -> - @template = _.clone(template) - @keystrokesByCommand = _.clone(keystrokesByCommand) - @translateTemplate(template, keystrokesByCommand) @substituteVersion(template) - @setUpdateMenuItemState(template) @menu = Menu.buildFromTemplate(template) Menu.setApplicationMenu(@menu) + @showUpdateMenuItem(global.atomApplication.autoUpdateManager.getState()) + # Flattens the given menu and submenu items into an single Array. # # * menu: @@ -73,27 +71,24 @@ class ApplicationMenu item.label = "Version #{@version}" # Sets the proper label, command and enabled state for the update menu item - setUpdateMenuItemState: (template) -> - item = _.find(@flattenMenuTemplate(template), (i) -> i.metadata.autoUpdate) - return unless item? + showUpdateMenuItem: (state) -> + checkForUpdateItem = _.find(@flattenMenuItems(@menu), (i) -> i.label == 'Check for Update') + downloadingUpdateItem = _.find(@flattenMenuItems(@menu), (i) -> i.label == 'Downloading Update') + installUpdateItem = _.find(@flattenMenuItems(@menu), (i) -> i.label == 'Restart and Install Update') - item.enabled = true - console.log global.atomApplication.autoUpdateManager.getState() - switch global.atomApplication.autoUpdateManager.getState() + return unless checkForUpdateItem? and downloadingUpdateItem? and installUpdateItem? + + checkForUpdateItem.visible = false + downloadingUpdateItem.visible = false + installUpdateItem.visible = false + + switch state when 'idle', 'error', 'no-update-available' - item.label = 'Check for Update' - item.command = 'application:check-for-update' - when 'checking' - item.enabled = false - item.label = 'Checking for Update' - when 'downloading' - item.enabled = false - item.label = 'Downloading Update' + checkForUpdateItem.visible = true + when 'checking', 'downloading' + downloadingUpdateItem.visible = true when 'update-available' - item.label = 'Restart and Install Update' - item.command = 'application:install-update' - - console.log require('util').inspect(item) + installUpdateItem.visible = true # Default list of menu items. # diff --git a/src/browser/auto-update-manager.coffee b/src/browser/auto-update-manager.coffee index 78287af90..88ab7a7a8 100644 --- a/src/browser/auto-update-manager.coffee +++ b/src/browser/auto-update-manager.coffee @@ -17,7 +17,7 @@ class AutoUpdateManager @state = IDLE_STATE # Only released versions should check for updates. - # return if /\w{7}/.test(@getVersion()) + return if /\w{7}/.test(@getVersion()) autoUpdater.setFeedUrl "https://atom.io/api/updates?version=#{@getVersion()}" @@ -39,7 +39,7 @@ class AutoUpdateManager for atomWindow in @getWindows() atomWindow.sendCommand('window:update-available', [releaseVersion, releaseNotes]) - @check() + @check(hidePopups: true) setState: (state) -> return unless @state != state @@ -49,9 +49,11 @@ class AutoUpdateManager getState: -> @state - check: -> - autoUpdater.once 'update-not-available', @onUpdateNotAvailable - autoUpdater.once 'error', @onUpdateError + check: ({hidePopups}={})-> + unless hidePopups + autoUpdater.once 'update-not-available', @onUpdateNotAvailable + autoUpdater.once 'error', @onUpdateError + autoUpdater.checkForUpdates() install: -> From bbc6433a758fcfcd07d919020d94e2041b3fdca1 Mon Sep 17 00:00:00 2001 From: probablycorey Date: Mon, 7 Apr 2014 14:18:16 -0700 Subject: [PATCH 10/21] Update comment --- src/browser/application-menu.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/browser/application-menu.coffee b/src/browser/application-menu.coffee index 6e874573e..e246aefea 100644 --- a/src/browser/application-menu.coffee +++ b/src/browser/application-menu.coffee @@ -70,7 +70,7 @@ class ApplicationMenu if (item = _.find(@flattenMenuTemplate(template), (i) -> i.label == 'VERSION')) item.label = "Version #{@version}" - # Sets the proper label, command and enabled state for the update menu item + # Sets the proper visible state the update menu items showUpdateMenuItem: (state) -> checkForUpdateItem = _.find(@flattenMenuItems(@menu), (i) -> i.label == 'Check for Update') downloadingUpdateItem = _.find(@flattenMenuItems(@menu), (i) -> i.label == 'Downloading Update') From 63e51af87d57fc380300e25cd1d3080df88a330f Mon Sep 17 00:00:00 2001 From: probablycorey Date: Mon, 7 Apr 2014 14:25:35 -0700 Subject: [PATCH 11/21] Move window_udpate-evailable emitter to method --- src/browser/auto-update-manager.coffee | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/browser/auto-update-manager.coffee b/src/browser/auto-update-manager.coffee index 88ab7a7a8..33e31f1aa 100644 --- a/src/browser/auto-update-manager.coffee +++ b/src/browser/auto-update-manager.coffee @@ -34,13 +34,17 @@ class AutoUpdateManager @setState(ERROR_STATE) console.error "Error Downloading Update: #{message}" - autoUpdater.on 'update-downloaded', (event, releaseNotes, releaseVersion, releaseDate, releaseURL) => + autoUpdater.on 'update-downloaded', (event, @releaseNotes, @releaseVersion) => @setState(UPDATE_AVAILABLE_STATE) - for atomWindow in @getWindows() - atomWindow.sendCommand('window:update-available', [releaseVersion, releaseNotes]) + @emitUpdateAvailableEvent(@getWindows()...) @check(hidePopups: true) + emitUpdateAvailableEvent: (windows...) -> + return unless @releaseVersion? and @releaseNotes + for atomWindow in windows + atomWindow.sendCommand('window:update-available', [@releaseVersion, @releaseNotes]) + setState: (state) -> return unless @state != state @state = state From 7eea30fa7f90896ea2c092f0b504176110d381ba Mon Sep 17 00:00:00 2001 From: probablycorey Date: Mon, 7 Apr 2014 14:26:07 -0700 Subject: [PATCH 12/21] Make new windows receive previously triggered update-available events --- src/browser/atom-application.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 733b41f74..38d25f6a6 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -95,6 +95,7 @@ class AtomApplication addWindow: (window) -> @windows.push window @applicationMenu?.enableWindowSpecificItems(true) + @autoUpdateManager.emitUpdateAvailableEvent(window) # Creates server to listen for additional atom application launches. # From 1f9de98eb26ef2e9d9991d6d10d35cefb8195b90 Mon Sep 17 00:00:00 2001 From: probablycorey Date: Mon, 7 Apr 2014 14:54:27 -0700 Subject: [PATCH 13/21] Make AtomWindow emit window:loaded --- src/browser/atom-window.coffee | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/browser/atom-window.coffee b/src/browser/atom-window.coffee index fed11e4d6..f67adb1ad 100644 --- a/src/browser/atom-window.coffee +++ b/src/browser/atom-window.coffee @@ -7,9 +7,12 @@ path = require 'path' fs = require 'fs' url = require 'url' _ = require 'underscore-plus' +{EventEmitter} = require 'events' module.exports = class AtomWindow + _.extend @prototype, EventEmitter.prototype + @iconPath: path.resolve(__dirname, '..', '..', 'resources', 'atom.png') @includeShellLoadTime: true @@ -38,7 +41,10 @@ class AtomWindow loadSettings.initialPath = path.dirname(pathToOpen) @browserWindow.loadSettings = loadSettings - @browserWindow.once 'window:loaded', => @loaded = true + @browserWindow.once 'window:loaded', => + @emit 'window:loaded' + @loaded = true + @browserWindow.loadUrl @getUrl(loadSettings) @browserWindow.focusOnWebView() if @isSpec From 4b3240eeee9309692f8f02bda3cc2f3fecc76ed0 Mon Sep 17 00:00:00 2001 From: probablycorey Date: Mon, 7 Apr 2014 14:55:12 -0700 Subject: [PATCH 14/21] Use EventEmitter instead of emissary To be consistent with other browser process classes --- src/browser/auto-update-manager.coffee | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/browser/auto-update-manager.coffee b/src/browser/auto-update-manager.coffee index 33e31f1aa..ee10bed46 100644 --- a/src/browser/auto-update-manager.coffee +++ b/src/browser/auto-update-manager.coffee @@ -1,6 +1,7 @@ autoUpdater = require 'auto-updater' dialog = require 'dialog' -{Emitter} = require 'emissary' +_ = require 'underscore-plus' +{EventEmitter} = require 'events' IDLE_STATE='idle' CHECKING_STATE='checking' @@ -11,7 +12,7 @@ ERROR_STATE='error' module.exports = class AutoUpdateManager - Emitter.includeInto(this) + _.extend @prototype, EventEmitter.prototype constructor: -> @state = IDLE_STATE From 6bc471cef1c01b0bb84721fc35cab0171df3df82 Mon Sep 17 00:00:00 2001 From: probablycorey Date: Mon, 7 Apr 2014 14:55:50 -0700 Subject: [PATCH 15/21] Only emit window:update-available event after window is loaded --- src/browser/atom-application.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 38d25f6a6..40969db8c 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -95,7 +95,8 @@ class AtomApplication addWindow: (window) -> @windows.push window @applicationMenu?.enableWindowSpecificItems(true) - @autoUpdateManager.emitUpdateAvailableEvent(window) + window.once 'window:loaded', => + @autoUpdateManager.emitUpdateAvailableEvent(window) # Creates server to listen for additional atom application launches. # From 3168751c9745ae5a798c13b5a92281d319d4e804 Mon Sep 17 00:00:00 2001 From: probablycorey Date: Mon, 7 Apr 2014 15:04:06 -0700 Subject: [PATCH 16/21] Enable `Restart and Install Update` item --- menus/darwin.cson | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/menus/darwin.cson b/menus/darwin.cson index 6c93c78f3..517a33b06 100644 --- a/menus/darwin.cson +++ b/menus/darwin.cson @@ -5,9 +5,9 @@ { label: 'About Atom', command: 'application:about' } { label: 'View License', command: 'application:open-license' } { label: 'VERSION', enabled: false } + { label: 'Restart and Install Update', command: 'application:install-update', visible: false} { label: 'Check for Update', command: 'application:check-for-update', visible: false} { label: 'Downloading Update', enabled: false, visible: false} - { label: 'Restart and Install Update', command: 'application:install-update', enabled: false, visible: false} { type: 'separator' } { label: 'Preferences...', command: 'application:show-settings' } { label: 'Open Your Config', command: 'application:open-your-config' } From 6613b9fd4d5377d55856a49966bfa8a556dd1007 Mon Sep 17 00:00:00 2001 From: probablycorey Date: Mon, 7 Apr 2014 15:19:48 -0700 Subject: [PATCH 17/21] Don't send autoUpdateManager to ApplicationMenu --- src/browser/atom-application.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 40969db8c..3536e4f7a 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -66,7 +66,7 @@ class AtomApplication @windows = [] @autoUpdateManager = new AutoUpdateManager() - @applicationMenu = new ApplicationMenu(@version, @autoUpdateManager) + @applicationMenu = new ApplicationMenu(@version) @atomProtocolHandler = new AtomProtocolHandler(@resourcePath) @listenForArgumentsFromNewProcess() From 980c17e50c1ea96ff28bac1a7f83bd9d2b4fcca6 Mon Sep 17 00:00:00 2001 From: probablycorey Date: Mon, 7 Apr 2014 15:28:42 -0700 Subject: [PATCH 18/21] Pass current version to AutoUpdateManager --- src/browser/atom-application.coffee | 2 +- src/browser/auto-update-manager.coffee | 9 +++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 3536e4f7a..1f789f10e 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -65,7 +65,7 @@ class AtomApplication @pathsToOpen ?= [] @windows = [] - @autoUpdateManager = new AutoUpdateManager() + @autoUpdateManager = new AutoUpdateManager(@version) @applicationMenu = new ApplicationMenu(@version) @atomProtocolHandler = new AtomProtocolHandler(@resourcePath) diff --git a/src/browser/auto-update-manager.coffee b/src/browser/auto-update-manager.coffee index ee10bed46..a1f8108b7 100644 --- a/src/browser/auto-update-manager.coffee +++ b/src/browser/auto-update-manager.coffee @@ -14,13 +14,13 @@ module.exports = class AutoUpdateManager _.extend @prototype, EventEmitter.prototype - constructor: -> + constructor: (@version) -> @state = IDLE_STATE # Only released versions should check for updates. - return if /\w{7}/.test(@getVersion()) + return if /\w{7}/.test(@version()) - autoUpdater.setFeedUrl "https://atom.io/api/updates?version=#{@getVersion()}" + autoUpdater.setFeedUrl "https://atom.io/api/updates?version=#{@version()}" autoUpdater.on 'checking-for-update', => @setState(CHECKING_STATE) @@ -72,8 +72,5 @@ class AutoUpdateManager autoUpdater.removeListener 'update-not-available', @onUpdateNotAvailable dialog.showMessageBox type: 'warning', buttons: ['OK'], message: 'There was an error checking for updates.', detail: message - getVersion: -> - global.atomApplication.version - getWindows: -> global.atomApplication.windows From 8ca5d6db357087012017aaac934e6b505bb9ddc6 Mon Sep 17 00:00:00 2001 From: probablycorey Date: Mon, 7 Apr 2014 15:29:15 -0700 Subject: [PATCH 19/21] Remove trailing whitespace --- src/browser/atom-window.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/browser/atom-window.coffee b/src/browser/atom-window.coffee index f67adb1ad..f7d89535d 100644 --- a/src/browser/atom-window.coffee +++ b/src/browser/atom-window.coffee @@ -41,7 +41,7 @@ class AtomWindow loadSettings.initialPath = path.dirname(pathToOpen) @browserWindow.loadSettings = loadSettings - @browserWindow.once 'window:loaded', => + @browserWindow.once 'window:loaded', => @emit 'window:loaded' @loaded = true From 4b089b62a6ee154db373311d5de5be1c84c99730 Mon Sep 17 00:00:00 2001 From: probablycorey Date: Mon, 7 Apr 2014 17:01:11 -0700 Subject: [PATCH 20/21] Destructure item instead of calling it `i` --- src/browser/application-menu.coffee | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/browser/application-menu.coffee b/src/browser/application-menu.coffee index e246aefea..730c0e17d 100644 --- a/src/browser/application-menu.coffee +++ b/src/browser/application-menu.coffee @@ -67,14 +67,14 @@ class ApplicationMenu # Replaces VERSION with the current version. substituteVersion: (template) -> - if (item = _.find(@flattenMenuTemplate(template), (i) -> i.label == 'VERSION')) + if (item = _.find(@flattenMenuTemplate(template), ({label}) -> label == 'VERSION')) item.label = "Version #{@version}" # Sets the proper visible state the update menu items showUpdateMenuItem: (state) -> - checkForUpdateItem = _.find(@flattenMenuItems(@menu), (i) -> i.label == 'Check for Update') - downloadingUpdateItem = _.find(@flattenMenuItems(@menu), (i) -> i.label == 'Downloading Update') - installUpdateItem = _.find(@flattenMenuItems(@menu), (i) -> i.label == 'Restart and Install Update') + checkForUpdateItem = _.find(@flattenMenuItems(@menu), ({label}) -> label == 'Check for Update') + downloadingUpdateItem = _.find(@flattenMenuItems(@menu), ({label}) -> label == 'Downloading Update') + installUpdateItem = _.find(@flattenMenuItems(@menu), ({label}) -> label == 'Restart and Install Update') return unless checkForUpdateItem? and downloadingUpdateItem? and installUpdateItem? From e9a975fd92f4a332c198b510b190cbaaaca539ab Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Thu, 10 Apr 2014 14:28:30 -0700 Subject: [PATCH 21/21] Don't use version as a method --- src/browser/auto-update-manager.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/browser/auto-update-manager.coffee b/src/browser/auto-update-manager.coffee index a1f8108b7..cb76c2481 100644 --- a/src/browser/auto-update-manager.coffee +++ b/src/browser/auto-update-manager.coffee @@ -18,9 +18,9 @@ class AutoUpdateManager @state = IDLE_STATE # Only released versions should check for updates. - return if /\w{7}/.test(@version()) + return if /\w{7}/.test(@version) - autoUpdater.setFeedUrl "https://atom.io/api/updates?version=#{@version()}" + autoUpdater.setFeedUrl "https://atom.io/api/updates?version=#{@version}" autoUpdater.on 'checking-for-update', => @setState(CHECKING_STATE)