From 080c252c8b283eb57d87a3bd8995ef1d155b11c5 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Wed, 14 Sep 2016 16:25:19 -0700 Subject: [PATCH] Adjusted some things after looking at Sentry errors --- app/app.html | 2 +- app/app.js | 116 +++++++++++++----- app/app.json | 2 +- app/components/RequestPane.js | 2 +- app/components/RequestUrlBar.js | 26 +++- app/components/base/Dropdown.js | 50 ++++---- app/components/base/KeyValueEditor.js | 2 +- app/components/editors/EnvironmentEditor.js | 2 +- app/components/modals/ChangelogModal.js | 9 ++ app/components/modals/GenerateCodeModal.js | 4 +- .../modals/WorkspaceEnvironmentsEditModal.js | 3 +- app/components/viewers/ResponseRaw.js | 14 ++- app/containers/App.js | 2 +- app/redux/modules/requests.js | 2 +- package.json | 2 +- 15 files changed, 164 insertions(+), 74 deletions(-) diff --git a/app/app.html b/app/app.html index bea87abbe7..38f9234aa7 100644 --- a/app/app.html +++ b/app/app.html @@ -14,7 +14,7 @@ if (process.env.INSOMNIA_ENV !== 'development') { Raven.config('https://fb3242f902b54cdd934b8ffa204426c0:23430fbe203a4189a68efb63c38fc50b@app.getsentry.com/88289', { allowSecretKey: true, - logger: 'sentry', + logger: 'renderer', environment: process.env.INSOMNIA_ENV || 'production', level: 'warning', release: require('./app.json').version, diff --git a/app/app.js b/app/app.js index bdc5b450ff..18fba377bc 100644 --- a/app/app.js +++ b/app/app.js @@ -4,12 +4,19 @@ if (require('electron-squirrel-startup')) { process.exit(0); } +// Some useful helpers +const IS_DEV = process.env.INSOMNIA_ENV === 'development'; +const IS_MAC = process.platform === 'darwin'; +const IS_WINDOWS = process.platform === 'win32'; +const IS_LINUX = !IS_MAC && !IS_WINDOWS; + var raven = require('raven'); var ravenClient = new raven.Client( 'https://fb3242f902b54cdd934b8ffa204426c0:23430fbe203a' + '4189a68efb63c38fc50b@app.getsentry.com/88289', { environment: process.env.INSOMNIA_ENV || 'production', release: require('./app.json').version, + logger: 'main' }); if (!IS_DEV) { @@ -33,11 +40,6 @@ const { webContents } = electron; -const IS_DEV = process.env.INSOMNIA_ENV === 'development'; -const IS_MAC = process.platform === 'darwin'; -const IS_WINDOWS = process.platform === 'win32'; -const IS_LINUX = !IS_MAC && !IS_WINDOWS; - const UPDATE_URLS = { darwin: `https://updates.insomnia.rest/builds/check/mac?v=${appVersion}`, win32: 'https://s3.amazonaws.com/builds-insomnia-rest/win', @@ -66,7 +68,9 @@ autoUpdater.on('error', e => { if (IS_DEV) { console.error(e); } else { - ravenClient.captureError(e, {}); + ravenClient.captureError(e, { + level: 'warning' + }); } }); @@ -191,22 +195,50 @@ ipcMain.on('check-for-updates', () => { checkForUpdates(); }); +function storeValue (key, obj) { + try { + localStorage.setItem(key, JSON.stringify(obj)); + } catch (e) { + console.error('Failed to save to LocalStorage', obj, e); + ravenClient.captureError(e, { + level: 'warning' + }); + } +} + +function getValue (key, defaultObj) { + try { + return JSON.parse(localStorage.getItem(key) || JSON.stringify(defaultObj)) + } catch (e) { + console.error('Failed to get from LocalStorage', e); + ravenClient.captureError(e, { + level: 'warning' + }); + } +} + function saveBounds () { - const fullscreen = mainWindow.isFullScreen(); - if (!fullscreen) { - // Only save the size if we're not in fullscreen - localStorage.setItem('bounds', JSON.stringify(mainWindow.getBounds())); + if (!mainWindow) { + return; } - localStorage.setItem('fullscreen', JSON.stringify(mainWindow.isFullScreen())); + const fullscreen = mainWindow.isFullScreen(); + + // Only save the size if we're not in fullscreen + if (!fullscreen) { + storeValue('bounds', mainWindow.getBounds()); + storeValue('fullscreen', false); + } else { + storeValue('fullscreen', true); + } } function getBounds () { let bounds = {}; let fullscreen = false; try { - bounds = JSON.parse(localStorage.getItem('bounds') || '{}'); - fullscreen = JSON.parse(localStorage.getItem('fullscreen') || 'false') + bounds = getValue('bounds', {}); + fullscreen = getValue('fullscreen', false); } catch (e) { // This should never happen, but if it does...! console.error('Failed to parse window bounds', e); @@ -216,13 +248,13 @@ function getBounds () { } function saveZoomFactor (zoomFactor) { - localStorage.setItem('zoomFactor', JSON.stringify(zoomFactor)); + storeValue('zoomFactor', zoomFactor); } function getZoomFactor () { let zoomFactor = 1; try { - zoomFactor = JSON.parse(localStorage.getItem('zoomFactor') || '1'); + zoomFactor = getValue('zoomFactor', 1); } catch (e) { // This should never happen, but if it does...! console.error('Failed to parse zoomFactor', e); @@ -240,6 +272,7 @@ app.on('window-all-closed', () => { // Mac-only, when the user clicks the doc icon app.on('activate', (e, hasVisibleWindows) => { + // Create a new window when clicking the doc icon if there isn't one open if (!hasVisibleWindows) { createWindow() } @@ -251,8 +284,14 @@ app.on('ready', () => { createWindow(); }); +function initLocalStorage () { + if (!localStorage) { + localStorage = new LocalStorage(path.join(app.getPath('userData'), 'localStorage')); + } +} + function createWindow () { - localStorage = new LocalStorage(path.join(app.getPath('userData'), 'localStorage')); + initLocalStorage(); const zoomFactor = getZoomFactor(); const {bounds, fullscreen} = getBounds(); @@ -313,10 +352,11 @@ function createWindow () { label: "Preferences", accelerator: "CmdOrCtrl+,", click: function (menuItem, window, e) { - // NOTE: Checking for window because it might be closed - if (window && window.webContents) { - window.webContents.send('toggle-preferences'); + if (!window || !window.webContents) { + return } + + window.webContents.send('toggle-preferences'); } }, { @@ -382,11 +422,13 @@ function createWindow () { accelerator: "CmdOrCtrl+0", click: () => { const window = BrowserWindow.getFocusedWindow(); - if (window && window.webContents) { - const zoomFactor = 1; - window.webContents.setZoomFactor(zoomFactor); - saveZoomFactor(zoomFactor); + if (!window || !window.webContents) { + return; } + + const zoomFactor = 1; + window.webContents.setZoomFactor(zoomFactor); + saveZoomFactor(zoomFactor); } }, { @@ -394,12 +436,14 @@ function createWindow () { accelerator: IS_MAC ? "CmdOrCtrl+Plus" : "CmdOrCtrl+=", click: () => { const window = BrowserWindow.getFocusedWindow(); - if (window && window.webContents) { - const zoomFactor = Math.min(1.8, getZoomFactor() + 0.1); - window.webContents.setZoomFactor(zoomFactor); - - saveZoomFactor(zoomFactor); + if (!window || !window.webContents) { + return; } + + const zoomFactor = Math.min(1.8, getZoomFactor() + 0.1); + window.webContents.setZoomFactor(zoomFactor); + + saveZoomFactor(zoomFactor); } }, { @@ -407,11 +451,13 @@ function createWindow () { accelerator: "CmdOrCtrl+-", click: () => { const window = BrowserWindow.getFocusedWindow(); - if (window && window.webContents) { - const zoomFactor = Math.max(0.5, getZoomFactor() - 0.1); - window.webContents.setZoomFactor(zoomFactor); - saveZoomFactor(zoomFactor); + if (!window || !window.webContents) { + return; } + + const zoomFactor = Math.max(0.5, getZoomFactor() - 0.1); + window.webContents.setZoomFactor(zoomFactor); + saveZoomFactor(zoomFactor); } }, { @@ -419,7 +465,11 @@ function createWindow () { accelerator: "CmdOrCtrl+\\", click: () => { const window = BrowserWindow.getFocusedWindow(); - window && window.webContents.send('toggle-sidebar'); + if (!window || !window.webContents) { + return; + } + + window.webContents.send('toggle-sidebar'); } } ] diff --git a/app/app.json b/app/app.json index f6c10dca7b..2a8d366044 100644 --- a/app/app.json +++ b/app/app.json @@ -1,7 +1,7 @@ { "private": true, "name": "insomnia", - "version": "3.4.0", + "version": "3.4.1", "productName": "Insomnia", "longName": "Insomnia REST Client", "description": "A simple and beautiful REST API client", diff --git a/app/components/RequestPane.js b/app/components/RequestPane.js index 99bf05d8a3..a5e2aa86b6 100644 --- a/app/components/RequestPane.js +++ b/app/components/RequestPane.js @@ -77,7 +77,7 @@ class RequestPane extends Component { diff --git a/app/components/RequestUrlBar.js b/app/components/RequestUrlBar.js index 114bf1b2f5..b3832a5107 100644 --- a/app/components/RequestUrlBar.js +++ b/app/components/RequestUrlBar.js @@ -5,6 +5,7 @@ import MethodTag from './tags/MethodTag'; import {METHODS, DEBOUNCE_MILLIS} from '../lib/constants'; import Mousetrap from '../lib/mousetrap'; import {trackEvent} from '../lib/analytics'; +import {isMac} from '../lib/appInfo'; class RequestUrlBar extends Component { @@ -21,10 +22,25 @@ class RequestUrlBar extends Component { } componentDidMount () { - Mousetrap.bindGlobal('mod+l', () => { - this.input.focus(); - this.input.select() - }); + this._bodyKeydownHandler = e => { + if (!this._input) { + return; + } + + // meta+l + const metaPressed = isMac() ? e.metaKey : e.ctrlKey; + if (metaPressed && e.keyCode === 76) { + e.preventDefault(); + this._input.focus(); + this._input.select(); + } + }; + + document.body.addEventListener('keydown', this._bodyKeydownHandler); + } + + componentWillUnmount () { + document.body.removeEventListener('keydown', this._bodyKeydownHandler); } render () { @@ -58,7 +74,7 @@ class RequestUrlBar extends Component {
this.input = n} + ref={n => this._input = n} type="text" placeholder="https://api.myproduct.com/v1/users" defaultValue={url} diff --git a/app/components/base/Dropdown.js b/app/components/base/Dropdown.js index 3c2dc1b7b0..96ceb2bc25 100644 --- a/app/components/base/Dropdown.js +++ b/app/components/base/Dropdown.js @@ -15,27 +15,7 @@ class Dropdown extends Component { this.toggle(); } - hide () { - this.setState({open: false}); - } - - show () { - const bodyHeight = document.body.getBoundingClientRect().height; - const dropdownTop = ReactDOM.findDOMNode(this).getBoundingClientRect().top; - const dropUp = dropdownTop > bodyHeight * 0.65; - - this.setState({open: true, dropUp}); - } - - toggle () { - if (this.state.open) { - this.hide(); - } else { - this.show(); - } - } - - componentDidMount () { + _addKeyListener () { this._bodyKeydownHandler = e => { if (!this.state.open) { return; @@ -54,10 +34,36 @@ class Dropdown extends Component { document.body.addEventListener('keydown', this._bodyKeydownHandler); } - componentWillUnmount () { + _removeKeyListener () { document.body.removeEventListener('keydown', this._bodyKeydownHandler); } + hide () { + this.setState({open: false}); + this._removeKeyListener(); + } + + show () { + const bodyHeight = document.body.getBoundingClientRect().height; + const dropdownTop = ReactDOM.findDOMNode(this).getBoundingClientRect().top; + const dropUp = dropdownTop > bodyHeight * 0.65; + + this.setState({open: true, dropUp}); + this._addKeyListener(); + } + + toggle () { + if (this.state.open) { + this.hide(); + } else { + this.show(); + } + } + + componentWillUnmount () { + this._removeKeyListener(); + } + render () { const {right, className, outline} = this.props; const {dropUp, open} = this.state; diff --git a/app/components/base/KeyValueEditor.js b/app/components/base/KeyValueEditor.js index 741988659f..b512e2fe22 100644 --- a/app/components/base/KeyValueEditor.js +++ b/app/components/base/KeyValueEditor.js @@ -95,7 +95,7 @@ class KeyValueEditor extends Component { } _focusPreviousPair () { - if (this._focusedPair >= 0) { + if (this._focusedPair > 0) { this._focusedPair--; this._updateFocus(); } diff --git a/app/components/editors/EnvironmentEditor.js b/app/components/editors/EnvironmentEditor.js index 6697b3adb6..0725bea460 100644 --- a/app/components/editors/EnvironmentEditor.js +++ b/app/components/editors/EnvironmentEditor.js @@ -27,7 +27,7 @@ class EnvironmentEditor extends Component { ref={n => this._editor = n} onChange={this._handleChange.bind(this)} value={JSON.stringify(environment)} - prettify={true} + autoPrettify={true} mode="application/json" {...props} /> diff --git a/app/components/modals/ChangelogModal.js b/app/components/modals/ChangelogModal.js index 359d0e2368..0db3cce49d 100644 --- a/app/components/modals/ChangelogModal.js +++ b/app/components/modals/ChangelogModal.js @@ -32,6 +32,15 @@ class ChangelogModal extends Component { return; } + if (response.statusCode !== 200) { + console.warn( + 'Failed to fetch changelog', + response.statusCode, + response.body + ); + return; + } + let changelog; try { changelog = JSON.parse(response.body); diff --git a/app/components/modals/GenerateCodeModal.js b/app/components/modals/GenerateCodeModal.js index 594289a55e..248d5298ce 100644 --- a/app/components/modals/GenerateCodeModal.js +++ b/app/components/modals/GenerateCodeModal.js @@ -38,8 +38,8 @@ class GenerateCodeModal extends Component { } _handleClientChange (client) { - const {target} = this.state; - this._generateCode(this.state.request, target, client); + const {target, request} = this.state; + this._generateCode(request, target, client); } _handleTargetChange (target) { diff --git a/app/components/modals/WorkspaceEnvironmentsEditModal.js b/app/components/modals/WorkspaceEnvironmentsEditModal.js index dbd888644d..6ad11b39d9 100644 --- a/app/components/modals/WorkspaceEnvironmentsEditModal.js +++ b/app/components/modals/WorkspaceEnvironmentsEditModal.js @@ -62,7 +62,8 @@ class WorkspaceEnvironmentsEditModal extends Component { return; } - this.setState({activeEnvironmentId: environment._id}); + const {workspace} = this.state; + this._load(workspace, environment); } _handleDeleteEnvironment (environment) { diff --git a/app/components/viewers/ResponseRaw.js b/app/components/viewers/ResponseRaw.js index 73ca43408a..29abd709c3 100644 --- a/app/components/viewers/ResponseRaw.js +++ b/app/components/viewers/ResponseRaw.js @@ -2,9 +2,17 @@ import React, {Component, PropTypes} from 'react'; class ResponseRaw extends Component { _update (value) { - setTimeout(() => { - this._textarea.value = value; - }, 50) + // Use a timeout so it doesn't block the UI + setTimeout(() => this._setTextAreaValue(value), 50) + } + + _setTextAreaValue (value) { + // Bail if we're not mounted + if (!this._textarea) { + return; + } + + this._textarea.value = value; } componentDidUpdate () { diff --git a/app/containers/App.js b/app/containers/App.js index 8d10469022..aed28a07bf 100644 --- a/app/containers/App.js +++ b/app/containers/App.js @@ -158,7 +158,7 @@ class App extends Component { // If sort keys get too close together, we need to redistribute the list. This is // not performant at all (need to update all siblings in DB), but it is extremely rare // anyway - console.warn('-- Recreating Sort Keys --'); + console.log('-- Recreating Sort Keys --'); requestGroups.map((r, i) => { db.requestGroupUpdate(r, { diff --git a/app/redux/modules/requests.js b/app/redux/modules/requests.js index 5c61fba1d4..daaef1899a 100644 --- a/app/redux/modules/requests.js +++ b/app/redux/modules/requests.js @@ -66,7 +66,7 @@ export function send(request) { network.send(request._id).then(response => { dispatch({type: REQUEST_SEND_STOP, requestId: request._id}); }, err => { - console.warn('Error sending request', err); + console.info('Error sending request', err); dispatch({type: REQUEST_SEND_STOP, requestId: request._id}); }); } diff --git a/package.json b/package.json index 262ebb6050..cb95338e1d 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "build-n-package-win": "npm run build && npm run package-win", "build-n-package-mac": "npm run build && npm run package-mac", "build-n-package-linux": "npm run build && npm run package-linux", - "release": "npm test && npm run package && bash scripts/sentry-release.sh" + "release": "npm test && npm run build-n-package && bash scripts/sentry-release.sh" }, "jest": { "rootDir": "app",