diff --git a/app/components/ResponseBodyViewer.js b/app/components/ResponseBodyViewer.js index 69eec51fc6..36b8c17654 100644 --- a/app/components/ResponseBodyViewer.js +++ b/app/components/ResponseBodyViewer.js @@ -5,6 +5,16 @@ import ResponseBodyWebview from '../components/ResponseBodyWebview'; import {PREVIEW_MODE_FRIENDLY, PREVIEW_MODE_SOURCE} from '../lib/previewModes'; class ResponseBodyViewer extends Component { + shouldComponentUpdate (nextProps) { + for (let k of Object.keys(nextProps)) { + if (this.props[k] !== nextProps[k]) { + return true; + } + } + + return false; + } + render () { const { previewMode, diff --git a/app/components/ResponsePane.js b/app/components/ResponsePane.js index 0d1d3ee00e..b0f2285265 100644 --- a/app/components/ResponsePane.js +++ b/app/components/ResponsePane.js @@ -30,9 +30,10 @@ class ResponsePane extends Component { if (loadStartTime) { // Set a timer to update the UI again soon + // TODO: Move this into a child component so we don't rerender too much setTimeout(() => { this.forceUpdate(); - }, 30); + }, 100); // NOTE: We subtract 200ms because the request has some time padding on either end const elapsedTime = Math.round((Date.now() - loadStartTime - 200) / 100) / 10; diff --git a/app/database/index.js b/app/database/index.js index 052391188a..b86ad54fe2 100644 --- a/app/database/index.js +++ b/app/database/index.js @@ -74,6 +74,7 @@ const MODEL_DEFAULTS = { let db = null; function getDBFilePath (modelType) { + // NOTE: Do not EVER change this. EVER! const basePath = electron.remote.app.getPath('userData'); return fsPath.join(basePath, `insomnia.${modelType}.db`); } @@ -325,6 +326,33 @@ export function requestAll () { return all(TYPE_REQUEST); } +export function requestGetAncestors (request) { + return new Promise(resolve => { + const ancestors = []; + + const next = (doc) => { + Promise.all([ + requestGroupGetById(doc.parentId), + workspaceGetById(doc.parentId) + ]).then(([requestGroup, workspace]) => { + if (requestGroup) { + ancestors.push(requestGroup); + next(requestGroup); + } else if (workspace) { + ancestors.push(workspace); + next(workspace); + // We could be done here, but let's have there only be one finish case + } else { + // We're finished + resolve(ancestors); + } + }); + }; + + next(request); + }); +} + // ~~~~~~~~~~~~~ // // REQUEST GROUP // @@ -379,6 +407,10 @@ export function responseAll () { // WORKSPACE // // ~~~~~~~~~ // +export function workspaceGetById (id) { + return get(TYPE_WORKSPACE, id); +} + export function workspaceCreate (patch = {}) { return docCreate(TYPE_WORKSPACE, 'wrk', patch); } diff --git a/app/index.js b/app/index.js index 0b61b792b1..def518be0d 100644 --- a/app/index.js +++ b/app/index.js @@ -6,6 +6,18 @@ import {Tabs} from 'react-tabs' import createStore from './redux/create'; import App from './containers/App'; +// PERFORMANCE DEBUGGING STUFF +// import * as Perf from 'react-addons-perf'; +// setTimeout(() => { +// Perf.start(); +// console.log('started'); +// }, 1000 * 5); +// setTimeout(() => { +// Perf.stop(); +// console.log('stopped'); +// Perf.printWasted(Perf.getLastMeasurements()) +// }, 1000 * 10); + // Global CSS import './css/index.scss' import './css/lib/chrome/platform_app.css' diff --git a/app/lib/render.js b/app/lib/render.js index 495c5dab91..0a17607520 100644 --- a/app/lib/render.js +++ b/app/lib/render.js @@ -16,41 +16,45 @@ export function render (template, context = {}) { } export function getRenderedRequest (request) { - return db.requestGroupGetById(request.parentId).then(requestGroup => { - const environment = requestGroup ? requestGroup.environment : {}; - let renderedRequest = null; + return db.requestGetAncestors(request).then(ancestors => { + const renderContext = {}; - if (environment) { - let template; - - try { - template = JSON.stringify(request); - } catch (e) { - // Failed to parse Request as JSON - throw new Error(`Bad Request: "${e.message}"`); - } - - let renderedJSON; - try { - renderedJSON = render(template, environment); - } catch (e) { - // Failed to render Request - throw new Error(`Render Failed: "${e.message}"`); - } - - try { - renderedRequest = JSON.parse(renderedJSON); - } catch (e) { - // Failed to parse rendered request - throw new Error(`Parse Failed: "${e.message}"`); - } - - // Default the proto if it doesn't exist - if (renderedRequest.url.indexOf('://') === -1) { - renderedRequest.url = `http://${renderedRequest.url}`; - } - - return new Promise(resolve => resolve(renderedRequest)); + for (let doc of ancestors) { + // TODO: Add support for Workspace environments + const environment = doc.environment || {}; + Object.assign(renderContext, environment); } + + let template; + + try { + template = JSON.stringify(request); + } catch (e) { + // Failed to parse Request as JSON + throw new Error(`Bad Request: "${e.message}"`); + } + + let renderedJSON; + try { + renderedJSON = render(template, renderContext); + } catch (e) { + // Failed to render Request + throw new Error(`Render Failed: "${e.message}"`); + } + + let renderedRequest = null; + try { + renderedRequest = JSON.parse(renderedJSON); + } catch (e) { + // Failed to parse rendered request + throw new Error(`Parse Failed: "${e.message}"`); + } + + // Default the proto if it doesn't exist + if (renderedRequest.url.indexOf('://') === -1) { + renderedRequest.url = `http://${renderedRequest.url}`; + } + + return new Promise(resolve => resolve(renderedRequest)); }); } diff --git a/package.json b/package.json index c897689c74..de91e1e522 100644 --- a/package.json +++ b/package.json @@ -79,6 +79,7 @@ "file-loader": "^0.9.0", "json-loader": "^0.5.4", "node-sass": "^3.4.2", + "react-addons-perf": "^15.3.0", "react-addons-test-utils": "^15.1.0", "react-hot-loader": "^1.3.0", "redux-mock-store": "^1.0.2",