diff --git a/app/common/__tests__/querystring.test.js b/app/common/__tests__/querystring.test.js
index 443afd09c3..55a5c7172b 100644
--- a/app/common/__tests__/querystring.test.js
+++ b/app/common/__tests__/querystring.test.js
@@ -62,6 +62,14 @@ describe('build()', () => {
const str = querystringUtils.build({value: 'bar'});
expect(str).toBe('');
});
+
+ it('builds with numbers', () => {
+ const str = querystringUtils.build({name: 'number', value: 10});
+ const str2 = querystringUtils.build({name: 'number', value: 0});
+
+ expect(str).toBe('number=10');
+ expect(str2).toBe('number=0');
+ });
});
describe('buildFromParams()', () => {
diff --git a/app/common/querystring.js b/app/common/querystring.js
index 152c8a9703..37bbb28e62 100644
--- a/app/common/querystring.js
+++ b/app/common/querystring.js
@@ -23,10 +23,15 @@ export function build (param, strict = true) {
return '';
}
+ // Cast number values to strings
+ if (typeof param.value === 'number') {
+ param.value += '';
+ }
+
if (!strict || param.value) {
+ // Don't encode ',' in values
+ const value = util.flexibleEncodeComponent(param.value || '').replace(/%2C/gi, ',');
const name = util.flexibleEncodeComponent(param.name || '');
- const value = util.flexibleEncodeComponent(param.value || '')
- .replace(/%2C/gi, ','); // Don't encode , in values
return `${name}=${value}`
} else {
diff --git a/app/sync/index.js b/app/sync/index.js
index 6ba29f2fe1..5f6f93dd49 100644
--- a/app/sync/index.js
+++ b/app/sync/index.js
@@ -23,7 +23,6 @@ export const logger = new Logger();
// TODO: Move this stuff somewhere else
const NO_VERSION = '__NO_VERSION__';
-const resourceGroupCache = {};
const resourceGroupSymmetricKeysCache = {};
let _pullChangesInterval = null;
let _pushChangesInterval = null;
@@ -476,7 +475,13 @@ async function _handleChangeAndPush (event, doc, timestamp) {
* @returns {*}
*/
const _fetchResourceGroupPromises = {};
-export async function fetchResourceGroup (resourceGroupId) {
+const _resourceGroupCache = {};
+export async function fetchResourceGroup (resourceGroupId, invalidateCache = false) {
+ if (invalidateCache) {
+ delete _resourceGroupCache[resourceGroupId];
+ delete _fetchResourceGroupPromises[resourceGroupId];
+ }
+
// PERF: If we're currently fetching, return stored promise
// TODO: Maybe move parallel fetch caching into the fetch helper
if (_fetchResourceGroupPromises[resourceGroupId]) {
@@ -484,7 +489,7 @@ export async function fetchResourceGroup (resourceGroupId) {
}
const promise = new Promise(async (resolve, reject) => {
- let resourceGroup = resourceGroupCache[resourceGroupId];
+ let resourceGroup = _resourceGroupCache[resourceGroupId];
if (!resourceGroup) {
try {
@@ -521,7 +526,7 @@ export async function fetchResourceGroup (resourceGroupId) {
_fetchResourceGroupPromises[resourceGroupId] = null;
// Cache the ResourceGroup for next time (they never change)
- resourceGroupCache[resourceGroupId] = resourceGroup;
+ _resourceGroupCache[resourceGroupId] = resourceGroup;
// Return the ResourceGroup
resolve(resourceGroup);
diff --git a/app/ui/components/Toast.js b/app/ui/components/Toast.js
index 2ed650b94c..82b047d04e 100644
--- a/app/ui/components/Toast.js
+++ b/app/ui/components/Toast.js
@@ -3,6 +3,10 @@ import classnames from 'classnames';
import Link from './base/Link';
import * as fetch from '../../common/fetch';
import {trackEvent} from '../../analytics/index';
+import * as models from '../../models/index';
+import * as querystring from '../../common/querystring';
+import * as constants from '../../common/constants';
+import * as db from '../../common/database';
const LOCALSTORAGE_KEY = 'insomnia::notifications::seen';
@@ -26,10 +30,26 @@ class Toast extends Component {
}
const seenNotifications = this._loadSeen();
+ const stats = await models.stats.get();
let notification;
try {
- notification = await fetch.get('/notification');
+ const queryParameters = [
+ {name: 'lastLaunch', value: stats.lastLaunch},
+ {name: 'firstLaunch', value: stats.created},
+ {name: 'launches', value: stats.launches},
+ {name: 'platform', value: constants.getAppPlatform()},
+ {name: 'version', value: constants.getAppVersion()},
+ {name: 'requests', value: (await db.count(models.request.type)) + ''},
+ {name: 'requestGroups', value: (await db.count(models.requestGroup.type)) + ''},
+ {name: 'environments', value: (await db.count(models.environment.type)) + ''},
+ {name: 'workspaces', value: (await db.count(models.workspace.type)) + ''},
+ ];
+
+ console.log(queryParameters);
+
+ const qs = querystring.buildFromParams(queryParameters);
+ notification = await fetch.get(`/notification?${qs}`);
} catch (e) {
console.warn('[toast] Failed to fetch notifications', e);
}
diff --git a/app/ui/components/dropdowns/SyncDropdown.js b/app/ui/components/dropdowns/SyncDropdown.js
index 17d9224214..9e31a7ea35 100644
--- a/app/ui/components/dropdowns/SyncDropdown.js
+++ b/app/ui/components/dropdowns/SyncDropdown.js
@@ -148,13 +148,11 @@ class SyncDropdown extends Component {
}
Automatic Sync
-
+
{loading ?
:
}
- Sync Now {syncPercent === 100 ? '(up to date)' : ''}
+ Sync Now
Other
diff --git a/app/ui/components/modals/WorkspaceShareSettingsModal.js b/app/ui/components/modals/WorkspaceShareSettingsModal.js
index 3b42c1aab1..b780f72e00 100644
--- a/app/ui/components/modals/WorkspaceShareSettingsModal.js
+++ b/app/ui/components/modals/WorkspaceShareSettingsModal.js
@@ -65,7 +65,7 @@ class WorkspaceShareSettingsModal extends Component {
const teams = await session.listTeams();
try {
- const resourceGroup = await sync.fetchResourceGroup(resource.resourceGroupId);
+ const resourceGroup = await sync.fetchResourceGroup(resource.resourceGroupId, true);
this.setState({teams, resourceGroup, loading: false, error: ''});
} catch (err) {
console.warn('Failed to fetch ResourceGroup', err);
diff --git a/package.json b/package.json
index 6e379a287e..c3eab876ab 100644
--- a/package.json
+++ b/package.json
@@ -19,8 +19,8 @@
"hot-server": "babel-node ./webpack/server.js",
"dev": "concurrently --kill-others \"npm run hot-server\" \"npm run start-hot\"",
"build:clean": "rm -rf ./build && rm -rf ./dist && mkdir ./build",
- "build:renderer": "cross-env NODE_ENV=production webpack --config ./webpack/webpack.config.production.babel.js",
- "build:main": "cross-env NODE_ENV=production webpack --config ./webpack/webpack.config.electron.babel.js",
+ "build:renderer": "cross-env NODE_ENV=development webpack --config ./webpack/webpack.config.development.babel.js",
+ "build:main": "cross-env NODE_ENV=development webpack --config ./webpack/webpack.config.electron.babel.js",
"build:copy": "cp -r ./app/package.json ./app/static ./app/icons/* ./build/",
"build:install": "cd build && npm install",
"build": "npm run build:clean && npm run build:renderer && npm run build:main && npm run build:copy && npm run build:install",