Skip to content

Commit

Permalink
feat: add install/enable/disable/error messages
Browse files Browse the repository at this point in the history
License: MIT
Signed-off-by: Henrique Dias <hacdias@gmail.com>
Co-Authored-By: Jessica Schilling <jessica@protocol.ai>
  • Loading branch information
hacdias and jessicaschilling committed Apr 19, 2020
1 parent 14ad914 commit 1ca47ca
Show file tree
Hide file tree
Showing 11 changed files with 223 additions and 71 deletions.
50 changes: 45 additions & 5 deletions assets/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"close": "Close",
"ok": "OK",
"cancel": "Cancel",
"enable": "Enable",
"reportTheError": "Report the error",
"restartIpfsDesktop": "Restart IPFS Desktop",
"openLogs": "Open logs",
Expand Down Expand Up @@ -150,14 +151,53 @@
"title": "IPFS on PATH",
"message": "Could not add IPFS to the PATH."
},
"launchAtLoginNotSupported": {
"title": "Error",
"message": "Launch at login is not supported on your platform."
},
"launchAtLoginFailed": {
"title": "Error",
"message": "Launch at login could not be enabled on your machine."
},
"enableIpfsOnPath": {
"title": "Enable IPFS on PATH",
"message": "By enabling this option, IPFS will be available on your command line as \"ipfs\". This action is reversible.",
"action": "Enable"
},
"disableIpfsOnPath": {
"title": "Disable IPFS on PATH",
"message": "By disabling this option, IPFS will no longer be available on your command line as \"ipfs\".",
"action": "Disable"
},
"enableGlobalTakeScreenshotShortcut": {
"title": "Enable screenshot shortcut",
"message": "By enabling this, the shortcut \"{ accelerator }\" will be available to take screenshots as long as IPFS Desktop is running."
},
"enableGlobalDownloadShortcut": {
"title": "Enable download shortcut",
"message": "By enabling this, the shortcut \"{ accelerator }\" will be available to download files as long as IPFS Desktop is running."
},
"installNpmOnIpfsWarning": {
"title": "Install npm on IPFS",
"message": "This experimental feature installs the \"ipfs-npm\" package on your system. It requires Node.js to be installed.",
"action": "Install"
},
"unableToInstallNpmOnIpfs": {
"title": "Error",
"message": "It was not possible to install \"ipfs-npm\" package on your system. Please check the logs for more information or try installing it manually by running \"npm install -g ipfs-npm\" on your command line."
},
"unableToUninstallNpmOnIpfs": {
"title": "Error",
"message": "It was not possible to uninstall \"ipfs-npm\" package on your system. Please check the logs for more information or try uninstalling it manually by running \"npm uninstall -g ipfs-npm\" on your command line."
},
"settings": {
"settings": "Settings",
"preferences": "Preferences",
"launchOnStartup": "Enable Launch at Login",
"ipfsCommandLineTools": "Enable Command Line Tools",
"takeScreenshotShortcut": "Enable Take Screenshot Shortcut",
"downloadHashShortcut": "Enable Download Hash Shortcut",
"launchOnStartup": "Launch at Login",
"ipfsCommandLineTools": "Command Line Tools",
"takeScreenshotShortcut": "Global Screenshot Shortcut",
"downloadHashShortcut": "Global Download Shortcut",
"experiments": "Experiments",
"npmOnIpfs": "Enable npm on IPFS"
"npmOnIpfs": "npm on IPFS"
}
}
37 changes: 33 additions & 4 deletions src/auto-launch.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const { app } = require('electron')
const i18n = require('i18next')
const os = require('os')
const path = require('path')
const fs = require('fs-extra')
Expand All @@ -7,6 +8,7 @@ const createToggler = require('./create-toggler')
const logger = require('./common/logger')
const store = require('./common/store')
const { IS_MAC, IS_WIN } = require('./common/consts')
const { showDialog, recoverableErrorDialog } = require('./dialogs')

const CONFIG_KEY = 'autoLaunch'

Expand Down Expand Up @@ -48,21 +50,39 @@ async function disable () {
}

module.exports = async function () {
const activate = async (value, oldValue) => {
const activate = async ({ newValue, oldValue, feedback }) => {
if (process.env.NODE_ENV === 'development') {
logger.info('[launch on startup] unavailable during development')

if (feedback) {
showDialog({
title: 'Launch at Login',
message: 'Not available during development.',
buttons: [i18n.t('close')]
})
}

return
}

if (!isSupported()) {
logger.info('[launch on startup] not supported on this platform')

if (feedback) {
showDialog({
title: i18n.t('launchAtLoginNotSupported.title'),
message: i18n.t('launchAtLoginNotSupported.message'),
buttons: [i18n.t('close')]
})
}

return false
}

if (value === oldValue) return
if (newValue === oldValue) return

try {
if (value === true) {
if (newValue === true) {
await enable()
logger.info('[launch on startup] enabled')
} else {
Expand All @@ -73,12 +93,21 @@ module.exports = async function () {
return true
} catch (err) {
logger.error(`[launch on startup] ${err.toString()}`)

if (feedback) {
recoverableErrorDialog(err, {
title: i18n.t('launchAtLoginFailed.title'),
message: i18n.t('launchAtLoginFailed.message')
})
}

return false
}
}

activate(store.get(CONFIG_KEY, false))
activate({ newValue: store.get(CONFIG_KEY, false) })
createToggler(CONFIG_KEY, activate)
}

module.exports.CONFIG_KEY = CONFIG_KEY
module.exports.isSupported = isSupported
14 changes: 8 additions & 6 deletions src/dialogs/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ function criticalErrorDialog (e) {
// Shows a recoverable error dialog with the default title and message.
// Passing an options object alongside the error can be used to override
// the title and message.
function recoverableErrorDialog (e, options = {}) {
function recoverableErrorDialog (e, options) {
const cfg = {
title: i18n.t('recoverableErrorDialog.title'),
message: i18n.t('recoverableErrorDialog.message'),
Expand All @@ -59,12 +59,14 @@ function recoverableErrorDialog (e, options = {}) {
]
}

if (options.title) {
cfg.title = options.title
}
if (options) {
if (options.title) {
cfg.title = options.title
}

if (options.message) {
cfg.message = options.message
if (options.message) {
cfg.message = options.message
}
}

const option = dialog(cfg)
Expand Down
6 changes: 5 additions & 1 deletion src/download-hash.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,11 @@ async function downloadHash (ctx) {
}

module.exports = function (ctx) {
setupGlobalShortcut(ctx, {
setupGlobalShortcut({
confirmationDialog: {
title: i18n.t('enableGlobalDownloadShortcut.title'),
message: i18n.t('enableGlobalDownloadShortcut.message', { accelerator: SHORTCUT })
},
settingsOption: CONFIG_KEY,
accelerator: SHORTCUT,
action: () => {
Expand Down
10 changes: 5 additions & 5 deletions src/exec-or-sudo.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const env = {
sudo: 'env ELECTRON_RUN_AS_NODE=1'
}

const getResult = (err, stdout, stderr, scope, failSilently) => {
const getResult = (err, stdout, stderr, scope, failSilently, errorOptions) => {
if (stdout) {
logger.info(`[${scope}] sudo: stdout: ${stdout.toString().trim()}`)
}
Expand All @@ -37,14 +37,14 @@ const getResult = (err, stdout, stderr, scope, failSilently) => {
} else if (str.includes('User did not grant permission')) {
dialog.showErrorBox(i18n.t('noPermissionDialog.title'), i18n.t('noPermissionDialog.message'))
} else {
recoverableErrorDialog(err)
recoverableErrorDialog(err, errorOptions)
}
}

return false
}

module.exports = async function ({ script, scope, failSilently, trySudo = true }) {
module.exports = async function ({ script, scope, failSilently, trySudo = true, errorOptions }) {
const dataArg = `--data="${app.getPath('userData')}"`
let err = null

Expand All @@ -61,7 +61,7 @@ module.exports = async function ({ script, scope, failSilently, trySudo = true }

if (!trySudo) {
if (!failSilently) {
recoverableErrorDialog(err)
recoverableErrorDialog(err, errorOptions)
}

return false
Expand All @@ -71,7 +71,7 @@ module.exports = async function ({ script, scope, failSilently, trySudo = true }
const command = `${env.sudo} "${process.execPath}" "${script}" ${dataArg}`
return new Promise(resolve => {
sudo.exec(command, { name: 'IPFS Desktop' }, (err, stdout, stderr) => {
resolve(getResult(err, stdout, stderr, scope, failSilently))
resolve(getResult(err, stdout, stderr, scope, failSilently, errorOptions))
})
})
}
53 changes: 43 additions & 10 deletions src/ipfs-on-path/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,49 @@ const execOrSudo = require('../exec-or-sudo')
const logger = require('../common/logger')
const store = require('../common/store')
const { IS_WIN } = require('../common/consts')
const { recoverableErrorDialog } = require('../dialogs')
const { showDialog, recoverableErrorDialog } = require('../dialogs')

const CONFIG_KEY = 'ipfsOnPath'

module.exports = async function (ctx) {
createToggler(CONFIG_KEY, async (value, oldValue) => {
if (value === oldValue || (oldValue === null && !value)) return
if (value === true) return run('install')
const errorMessage = {
title: i18n.t('cantAddIpfsToPath.title'),
message: i18n.t('cantAddIpfsToPath.message')
}

module.exports = async function () {
createToggler(CONFIG_KEY, async ({ newValue, oldValue }) => {
if (newValue === oldValue || (oldValue === null && !newValue)) {
return
}

if (newValue === true) {
if (showDialog({
title: i18n.t('enableIpfsOnPath.title'),
message: i18n.t('enableIpfsOnPath.message'),
buttons: [
i18n.t('enableIpfsOnPath.action'),
i18n.t('cancel')
]
}) !== 0) {
// User canceled
return
}

return run('install')
}

if (showDialog({
title: i18n.t('disableIpfsOnPath.title'),
message: i18n.t('disableIpfsOnPath.message'),
buttons: [
i18n.t('disableIpfsOnPath.action'),
i18n.t('cancel')
]
}) !== 0) {
// User canceled
return
}

return run('uninstall')
})

Expand Down Expand Up @@ -56,10 +91,7 @@ async function runWindows (script, { failSilently }) {
logger.error(`[ipfs on path] ${err.toString()}`)

if (!failSilently) {
recoverableErrorDialog(err, {
title: i18n.t('cantAddIpfsToPath.title'),
message: i18n.t('cantAddIpfsToPath.message')
})
recoverableErrorDialog(err, errorMessage)
}

return resolve(false)
Expand All @@ -80,6 +112,7 @@ async function run (script, { trySudo = true, failSilently = false } = {}) {
script: join(__dirname, `./scripts/${script}.js`),
scope: 'ipfs on path',
trySudo,
failSilently
failSilently,
errorOptions: errorMessage
})
}
Loading

0 comments on commit 1ca47ca

Please sign in to comment.