From 3e63e533f300f8a76bc973fe7236222d459a25a3 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Wed, 27 Jul 2016 13:07:50 -0700 Subject: [PATCH] A few more things --- app/app.js | 276 +++++++++++++----------- app/app.json | 3 +- app/components/RequestPane.js | 41 ++-- app/components/ResponsePane.js | 35 +-- app/components/modals/ChangelogModal.js | 4 +- app/containers/App.js | 14 ++ app/containers/WorkspaceDropdown.js | 12 -- app/css/components/pane.scss | 6 + app/css/layout/base.scss | 2 + app/lib/constants.js | 1 + app/redux/modules/requestGroups.js | 14 -- app/redux/modules/requests.js | 12 +- app/redux/modules/workspaces.js | 5 - app/redux/reducer.js | 4 - package.json | 4 +- scripts/package.sh | 5 + 16 files changed, 234 insertions(+), 204 deletions(-) diff --git a/app/app.js b/app/app.js index a9abf52540..bcdab88121 100644 --- a/app/app.js +++ b/app/app.js @@ -7,6 +7,7 @@ if (require('electron-squirrel-startup')) { // Don't npm install this (it breaks). Rely on the global one. const electron = require('electron'); const appVersion = require('./app.json').version; +const storage = require('electron-json-storage'); const {app, dialog, ipcMain, autoUpdater, Menu, BrowserWindow, webContents} = electron; const IS_DEV = process.env.NODE_ENV === 'development'; @@ -84,133 +85,162 @@ app.on('window-all-closed', () => { }); app.on('ready', () => { - mainWindow = new BrowserWindow({ - width: 1200, - height: 600, - minHeight: 500, - minWidth: 500, - acceptFirstMouse: true, - webPreferences: { - zoomFactor: zoomFactor + storage.get('bounds', (err, data) => { + if (err) { + console.log('Failed to fetch window bounds', err); } - }); - // and load the app.html of the app. - mainWindow.loadURL(`file://${__dirname}/app.html`); - - // Uncomment this to test things - // mainWindow.toggleDevTools(); - - // Emitted when the window is closed. - mainWindow.on('closed', () => { - // Dereference the window object, usually you would store windows - // in an array if your app supports multi windows, this is the time - // when you should delete the corresponding element. - mainWindow = null; - }); - - var template = [ - { - label: "Application", - role: "window", - submenu: [ - {label: "About Application", selector: "orderFrontStandardAboutPanel:"}, - {type: "separator"}, - { - label: "Quit", - accelerator: "Command+Q", - click: function () { - app.quit(); - } - } - ] - }, - { - label: "Edit", - submenu: [ - {label: "Undo", accelerator: "CmdOrCtrl+Z", selector: "undo:"}, - {label: "Redo", accelerator: "Shift+CmdOrCtrl+Z", selector: "redo:"}, - {type: "separator"}, - {label: "Cut", accelerator: "CmdOrCtrl+X", selector: "cut:"}, - {label: "Copy", accelerator: "CmdOrCtrl+C", selector: "copy:"}, - {label: "Paste", accelerator: "CmdOrCtrl+V", selector: "paste:"}, - {label: "Select All", accelerator: "CmdOrCtrl+A", selector: "selectAll:"} - ] - }, - { - label: "View", - role: "window", - submenu: [ - { - label: "Actual Size", - accelerator: "CmdOrCtrl+0", - click: () => { - const window = electron.BrowserWindow.getFocusedWindow(); - zoomFactor = 1; - window.webContents.setZoomFactor(zoomFactor); - } - }, - { - label: "Zoom In", - accelerator: "CmdOrCtrl+Plus", - click: () => { - const window = electron.BrowserWindow.getFocusedWindow(); - zoomFactor = Math.min(1.8, zoomFactor + 0.1); - window.webContents.setZoomFactor(zoomFactor); - } - }, - { - label: "Zoom Out", - accelerator: "CmdOrCtrl+-", - click: () => { - const window = electron.BrowserWindow.getFocusedWindow(); - zoomFactor = Math.max(0.5, zoomFactor - 0.1); - window.webContents.setZoomFactor(zoomFactor); - } - } - ] - }, - { - label: "Help", - role: "help", - id: "help", - submenu: [ - { - label: "Report an Issue...", - click: () => { - electron.shell.openExternal('mailto:support@insomnia.rest'); - } - }, - { - label: "Insomnia Help", - accelerator: "CmdOrCtrl+?", - click: () => { - electron.shell.openExternal('http://insomnia.rest'); - } - } - ] + let bounds = {}; + try { + bounds = JSON.parse(data || '{}'); + } catch (e) { + // This should never happen, but if it does...! + console.error('Failed to parse window bounds', err, data); } - ]; - if (IS_DEV) { - template.push({ - label: 'Developer', - position: 'before=help', - submenu: [{ - label: 'Reload', - accelerator: 'Command+R', - click: function () { - mainWindow.reload(); - } - }, { - label: 'Toggle DevTools', - accelerator: 'Alt+Command+I', - click: function () { - mainWindow.toggleDevTools(); - } - }] + const {x, y, width, height} = bounds; + + mainWindow = new BrowserWindow({ + x: x, + y: y, + width: width || 800, + height: height || 500, + minHeight: 500, + minWidth: 500, + acceptFirstMouse: true, + webPreferences: { + zoomFactor: zoomFactor + } }); - } - Menu.setApplicationMenu(Menu.buildFromTemplate(template)); + const saveBounds = () => { + storage.set('bounds', JSON.stringify(mainWindow.getBounds()), err => { + if (err) { + console.log('Failed to save window bounds', err); + } + }); + }; + + mainWindow.on('resize', e => saveBounds()); + mainWindow.on('move', e => saveBounds()); + + // and load the app.html of the app. + mainWindow.loadURL(`file://${__dirname}/app.html`); + + // Uncomment this to test things + // mainWindow.toggleDevTools(); + + // Emitted when the window is closed. + mainWindow.on('closed', () => { + // Dereference the window object, usually you would store windows + // in an array if your app supports multi windows, this is the time + // when you should delete the corresponding element. + mainWindow = null; + }); + + var template = [ + { + label: "Application", + role: "window", + submenu: [ + {label: "About Application", selector: "orderFrontStandardAboutPanel:"}, + {type: "separator"}, + { + label: "Quit", + accelerator: "Command+Q", + click: function () { + app.quit(); + } + } + ] + }, + { + label: "Edit", + submenu: [ + {label: "Undo", accelerator: "CmdOrCtrl+Z", selector: "undo:"}, + {label: "Redo", accelerator: "Shift+CmdOrCtrl+Z", selector: "redo:"}, + {type: "separator"}, + {label: "Cut", accelerator: "CmdOrCtrl+X", selector: "cut:"}, + {label: "Copy", accelerator: "CmdOrCtrl+C", selector: "copy:"}, + {label: "Paste", accelerator: "CmdOrCtrl+V", selector: "paste:"}, + {label: "Select All", accelerator: "CmdOrCtrl+A", selector: "selectAll:"} + ] + }, + { + label: "View", + role: "window", + submenu: [ + { + label: "Actual Size", + accelerator: "CmdOrCtrl+0", + click: () => { + const window = electron.BrowserWindow.getFocusedWindow(); + zoomFactor = 1; + window.webContents.setZoomFactor(zoomFactor); + } + }, + { + label: "Zoom In", + accelerator: IS_MAC ? "CmdOrCtrl+Plus" : "CmdOrCtrl+=", + click: () => { + const window = electron.BrowserWindow.getFocusedWindow(); + zoomFactor = Math.min(1.8, zoomFactor + 0.1); + window.webContents.setZoomFactor(zoomFactor); + } + }, + { + label: "Zoom Out", + accelerator: "CmdOrCtrl+-", + click: () => { + const window = electron.BrowserWindow.getFocusedWindow(); + zoomFactor = Math.max(0.5, zoomFactor - 0.1); + window.webContents.setZoomFactor(zoomFactor); + } + } + ] + }, + { + label: "Help", + role: "help", + id: "help", + submenu: [ + { + label: "Report an Issue...", + click: () => { + electron.shell.openExternal('mailto:support@insomnia.rest'); + } + }, + { + label: "Insomnia Help", + accelerator: "CmdOrCtrl+?", + click: () => { + electron.shell.openExternal('http://insomnia.rest'); + } + } + ] + } + ]; + + if (IS_DEV) { + template.push({ + label: 'Developer', + position: 'before=help', + submenu: [{ + label: 'Reload', + accelerator: 'Command+R', + click: function () { + mainWindow.reload(); + } + }, { + label: 'Toggle DevTools', + accelerator: 'Alt+Command+I', + click: function () { + mainWindow.toggleDevTools(); + } + }] + }); + } + + Menu.setApplicationMenu(Menu.buildFromTemplate(template)); + }); }); diff --git a/app/app.json b/app/app.json index 13966a8e72..b14641b043 100644 --- a/app/app.json +++ b/app/app.json @@ -1,7 +1,7 @@ { "private": true, "name": "insomnia", - "version": "3.0.10", + "version": "3.0.11", "productName": "Insomnia", "longName": "Insomnia HTTP Client", "description": "The best REST API Client", @@ -11,6 +11,7 @@ "dependencies": { "analytics-node": "^2.1.0", "electron-squirrel-startup": "^1.0.0", + "electron-json-storage": "^2.0.0", "nedb": "^1.8.0", "request": "^2.71.0" } diff --git a/app/components/RequestPane.js b/app/components/RequestPane.js index ade02440c7..68392e9c1f 100644 --- a/app/components/RequestPane.js +++ b/app/components/RequestPane.js @@ -17,6 +17,7 @@ class RequestPane extends Component { render () { const { request, + importFile, showPasswords, editorFontSize, editorLineWrapping, @@ -36,22 +37,29 @@ class RequestPane extends Component {
- - - - - - - - - - - - - - - -
New Request{MOD_SYM}N
Open Settings{MOD_SYM},
Switch Requests{MOD_SYM}P
+
+ + + + + + + + + + + + + + + +
New Request{MOD_SYM}N
Open Settings{MOD_SYM},
Switch Requests{MOD_SYM}P
+ + +
) @@ -158,6 +166,7 @@ RequestPane.propTypes = { updateRequestHeaders: PropTypes.func.isRequired, updateRequestContentType: PropTypes.func.isRequired, updateSettingsShowPasswords: PropTypes.func.isRequired, + importFile: PropTypes.func.isRequired, // Other showPasswords: PropTypes.bool.isRequired, diff --git a/app/components/ResponsePane.js b/app/components/ResponsePane.js index 7b3c6da696..f69c16bf76 100644 --- a/app/components/ResponsePane.js +++ b/app/components/ResponsePane.js @@ -11,6 +11,7 @@ import {getPreviewModeName} from '../lib/previewModes'; import {PREVIEW_MODE_SOURCE} from '../lib/previewModes'; import {REQUEST_TIME_TO_SHOW_COUNTER} from '../lib/constants'; import {MOD_SYM} from '../lib/constants'; +import RequestSwitcherModal from './modals/RequestSwitcherModal'; class ResponsePane extends Component { render () { @@ -69,22 +70,24 @@ class ResponsePane extends Component {
- - - - - - - - - - - - - - - -
Send Request{MOD_SYM}Enter
Switch Requests{MOD_SYM}P
Focus Url Bar{MOD_SYM}L
+
+ + + + + + + + + + + + + + + +
Send Request{MOD_SYM}Enter
Focus Url Bar{MOD_SYM}L
Switch Requests{MOD_SYM}P
+
) diff --git a/app/components/modals/ChangelogModal.js b/app/components/modals/ChangelogModal.js index c3feb0e9d1..a001bf2524 100644 --- a/app/components/modals/ChangelogModal.js +++ b/app/components/modals/ChangelogModal.js @@ -86,7 +86,7 @@ class ChangelogModal extends ModalComponent { html = [ ...html,

{change.summary[0]}

, - ...change.summary.slice(1).map((text, i) =>

{text}

) + ...change.summary.slice(1).map((text, j) =>

{text}

) ] } } @@ -106,7 +106,7 @@ class ChangelogModal extends ModalComponent { ...html,

Fixes

, ]; } diff --git a/app/containers/App.js b/app/containers/App.js index 473725bd8e..93ceee57e7 100644 --- a/app/containers/App.js +++ b/app/containers/App.js @@ -1,4 +1,5 @@ import React, {Component, PropTypes} from 'react'; +import {ipcRenderer} from 'electron'; import ReactDOM from 'react-dom'; import {connect} from 'react-redux'; import {bindActionCreators} from 'redux'; @@ -26,6 +27,7 @@ import { DEFAULT_SIDEBAR_WIDTH } from '../lib/constants' +import * as GlobalActions from '../redux/modules/global'; import * as RequestGroupActions from '../redux/modules/requestGroups'; import * as RequestActions from '../redux/modules/requests'; @@ -33,6 +35,7 @@ import * as db from '../database'; import {importCurl} from '../lib/export/curl'; import {trackEvent} from '../lib/analytics'; import {getAppVersion} from '../lib/appInfo'; +import {CHECK_FOR_UPDATES_INTERVAL} from '../lib/constants'; class App extends Component { constructor (props) { @@ -96,6 +99,11 @@ class App extends Component { } } + _importFile () { + const workspace = this._getActiveWorkspace(); + this.props.actions.global.importFile(workspace); + } + _moveRequestGroup (requestGroupToMove, requestGroupToTarget, targetOffset) { // Oh God, this function is awful... @@ -406,6 +414,10 @@ class App extends Component { lastVersion: getAppVersion() }); }); + + setInterval(() => { + ipcRenderer.send('check-for-updates'); + }, CHECK_FOR_UPDATES_INTERVAL); } componentWillUnmount () { @@ -468,6 +480,7 @@ class App extends Component { - {/*
  • */} - {/**/} - {/*
  • */}
  • - {/*
  • */} - {/**/} - {/*
  • */} ) diff --git a/app/css/components/pane.scss b/app/css/components/pane.scss index fd882a93c0..bbf2931efd 100644 --- a/app/css/components/pane.scss +++ b/app/css/components/pane.scss @@ -41,6 +41,12 @@ & > * { min-width: 20em; } + + .pane__body--placeholder__cta { + width: auto; + margin: $padding-lg auto; + display: block; + } } } diff --git a/app/css/layout/base.scss b/app/css/layout/base.scss index dff7d6e1b5..d332ab23be 100644 --- a/app/css/layout/base.scss +++ b/app/css/layout/base.scss @@ -68,6 +68,8 @@ webview { } table { + width: 100%; + td { padding-top: $padding-sm; diff --git a/app/lib/constants.js b/app/lib/constants.js index e6dc52df02..473886bd4b 100644 --- a/app/lib/constants.js +++ b/app/lib/constants.js @@ -7,6 +7,7 @@ export const DB_PERSIST_INTERVAL = 1000 * 60 * 10; export const DEBOUNCE_MILLIS = 100; export const MASHAPE_URL = 'https://www.mashape.com/?utm_source=chrome&utm_medium=app&utm_campaign=insomnia-rest'; export const REQUEST_TIME_TO_SHOW_COUNTER = 1; // Seconds +export const CHECK_FOR_UPDATES_INTERVAL = 1000 * 60 * 30; // 30 minutes export const CHANGELOG_URL = isDevelopment() ? 'http://localhost:5000/changelog.json' : 'http://changelog.insomnia.rest/changelog.json'; diff --git a/app/redux/modules/requestGroups.js b/app/redux/modules/requestGroups.js index f47bba7137..540bd23c36 100644 --- a/app/redux/modules/requestGroups.js +++ b/app/redux/modules/requestGroups.js @@ -14,17 +14,3 @@ export const REQUEST_GROUP_TOGGLE = 'request-groups/toggle'; // ~~~~~~~ // // ACTIONS // // ~~~~~~~ // - -export function toggle (requestGroup) { - return {type: REQUEST_GROUP_TOGGLE, requestGroup} -} - -export function showUpdateNamePrompt (requestGroup) { - const defaultValue = requestGroup.name; - return show(MODAL_REQUEST_GROUP_RENAME, {defaultValue, requestGroup}); -} - -export function showEnvironmentEditModal (requestGroup) { - return show(MODAL_ENVIRONMENT_EDITOR, {requestGroup}); -} - diff --git a/app/redux/modules/requests.js b/app/redux/modules/requests.js index 3797e014ec..d6607b27d7 100644 --- a/app/redux/modules/requests.js +++ b/app/redux/modules/requests.js @@ -2,6 +2,7 @@ import {combineReducers} from 'redux'; import * as network from '../../lib/network'; import {show} from './modals'; import {MODAL_REQUEST_RENAME, MODAL_CURL_EXPORT} from '../../lib/constants'; +import {trackEvent} from '../../lib/analytics'; export const REQUEST_CHANGE_FILTER = 'requests/filter'; export const REQUEST_SEND_START = 'requests/start'; @@ -60,6 +61,7 @@ export function changeFilter(filter) { export function send(request) { return dispatch => { dispatch({type: REQUEST_SEND_START, requestId: request._id}); + trackEvent('Request Send'); network.send(request._id).then(() => { dispatch({type: REQUEST_SEND_STOP, requestId: request._id}); @@ -69,13 +71,3 @@ export function send(request) { }); } } - -export function showUpdateNamePrompt(request) { - const defaultValue = request.name; - return show(MODAL_REQUEST_RENAME, {defaultValue, request}); -} - -export function showCurlExportModal (request) { - return show(MODAL_CURL_EXPORT, {request}); -} - diff --git a/app/redux/modules/workspaces.js b/app/redux/modules/workspaces.js index 016dc2e12c..b3273b9515 100644 --- a/app/redux/modules/workspaces.js +++ b/app/redux/modules/workspaces.js @@ -31,8 +31,3 @@ export default combineReducers({ export function activate (workspace) { return {type: WORKSPACE_ACTIVATE, workspace}; } - -export function showUpdateNamePrompt (workspace) { - const defaultValue = workspace.name; - return show(MODAL_WORKSPACE_RENAME, {defaultValue, workspace}); -} diff --git a/app/redux/reducer.js b/app/redux/reducer.js index 1f0f209aef..c440506753 100644 --- a/app/redux/reducer.js +++ b/app/redux/reducer.js @@ -1,18 +1,14 @@ import {combineReducers} from 'redux'; import workspaces from './modules/workspaces'; -import requestGroups from './modules/requestGroups'; import requests from './modules/requests'; -import responses from './modules/responses'; import global from './modules/global'; import modals from './modules/modals'; import entities from './modules/entities'; export default combineReducers({ workspaces, - responses, requests, - requestGroups, modals, global, entities diff --git a/package.json b/package.json index d0f5c79548..dbb0469da0 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,8 @@ "analytics-node": "^2.1.0", "classnames": "^2.2.3", "codemirror": "^5.12.0", + "electron-json-storage": "^2.0.0", + "electron-prebuilt": "^1.2.6", "electron-squirrel-startup": "^1.0.0", "json-lint": "^0.1.0", "jsonschema": "^1.1.0", @@ -74,7 +76,7 @@ "css-loader": "^0.23.1", "electron-builder": "^5.16.0", "electron-packager": "^7.3.0", - "electron-prebuilt": "^1.3.0", + "electron-prebuilt": "^1.2.6", "express": "latest", "file-loader": "^0.8.5", "json-loader": "^0.5.4", diff --git a/scripts/package.sh b/scripts/package.sh index d6262aa1ad..987a2f9d4c 100644 --- a/scripts/package.sh +++ b/scripts/package.sh @@ -2,15 +2,20 @@ #? Package and generate installers echo "-- STARTING PACKAGING PROCESS... --" +say "Beginning platform builds" cp assets/* build/ echo "-- PACKAGING WINDOWS --" node node_modules/electron-builder/out/build-cli.js --publish='never' --x64 --win +say "Windows build complete" echo "-- PACKAGING MAC --" node node_modules/electron-builder/out/build-cli.js --publish='never' --x64 --mac +say "Mac build complete" echo "-- PACKAGING LINUX --" node node_modules/electron-builder/out/build-cli.js --publish='never' --x64 --linux +say "Linux build complete" echo "-- PACKAGING COMPLETE --" +say "All builds have now completed"