Merge branch 'release/2020.5.2' into develop

This commit is contained in:
David Marby 2020-12-09 19:40:16 +01:00
commit cad2ebc932
14 changed files with 119 additions and 26 deletions

View File

@ -90,6 +90,21 @@ export function trackPageView(path: string) {
});
}
export async function getDeviceId(): Promise<string> {
const settings = await models.settings.getOrCreate();
let { deviceId } = settings;
if (!deviceId) {
// Migrate old GA ID into settings model if needed
const oldId = (window && window.localStorage.getItem('gaClientId')) || null;
deviceId = oldId || uuid.v4();
await models.settings.update(settings, { deviceId });
}
return deviceId;
}
// ~~~~~~~~~~~~~~~~~ //
// Private Functions //
// ~~~~~~~~~~~~~~~~~ //
@ -129,15 +144,7 @@ export async function _trackPageView(location: string) {
}
async function _getDefaultParams(): Promise<Array<RequestParameter>> {
const settings = await models.settings.getOrCreate();
// Migrate old GA ID into settings model
let { deviceId } = settings;
if (!deviceId) {
const oldId = (window && window.localStorage.gaClientId) || null;
deviceId = oldId || uuid.v4();
await models.settings.update(settings, { deviceId });
}
const deviceId = await getDeviceId();
// Prepping user agent string prior to sending to GA due to Electron base UA not being GA friendly.
const ua = String(window?.navigator?.userAgent)

View File

@ -1,5 +1,5 @@
import * as db from './database';
import { types as modelTypes } from '../models';
import { types as modelTypes, stats } from '../models';
import { send } from '../network/network';
import { getBodyBuffer } from '../models/response';
@ -24,6 +24,7 @@ export async function getSendRequestCallbackMemDb(environmentId, memDB) {
export function getSendRequestCallback(environmentId) {
return async function sendRequest(requestId) {
stats.incrementExecutedRequests();
return sendAndTransform(requestId, environmentId);
};
}

View File

@ -1,6 +1,9 @@
// @flow
import * as db from '../common/database';
import type { BaseModel } from './index';
import type { Workspace } from './workspace';
import type { RequestGroup } from './request-group';
import { isRequest, isGrpcRequest } from './helpers/is-model';
export const name = 'Stats';
export const type = 'Stats';
@ -14,6 +17,9 @@ type BaseStats = {
currentVersion: string | null,
lastVersion: string | null,
launches: number,
createdRequests: number,
deletedRequests: number,
executedRequests: number,
};
export type Stats = BaseModel & BaseStats;
@ -25,6 +31,9 @@ export function init(): BaseStats {
currentVersion: null,
lastVersion: null,
launches: 0,
createdRequests: 0,
deletedRequests: 0,
executedRequests: 0,
};
}
@ -49,3 +58,40 @@ export async function get(): Promise<Stats> {
return results[0];
}
}
export async function incrementRequestStats({
createdRequests,
deletedRequests,
executedRequests,
}: $Shape<Stats>) {
const stats = await get();
await update({
...(createdRequests && { createdRequests: stats.createdRequests + createdRequests }),
...(deletedRequests && { deletedRequests: stats.deletedRequests + deletedRequests }),
...(executedRequests && { executedRequests: stats.executedRequests + executedRequests }),
});
}
export async function incrementCreatedRequests() {
await incrementRequestStats({ createdRequests: 1 });
}
export async function incrementDeletedRequests() {
await incrementRequestStats({ deletedRequests: 1 });
}
export async function incrementExecutedRequests() {
await incrementRequestStats({ executedRequests: 1 });
}
export async function incrementCreatedRequestsForDescendents(doc: Workspace | RequestGroup) {
const docs = await db.withDescendants(doc);
const requests = docs.filter(doc => isRequest(doc) || isGrpcRequest(doc));
await incrementRequestStats({ createdRequests: requests.length });
}
export async function incrementDeletedRequestsForDescendents(doc: Workspace | RequestGroup) {
const docs = await db.withDescendants(doc);
const requests = docs.filter(doc => isRequest(doc) || isGrpcRequest(doc));
await incrementRequestStats({ deletedRequests: requests.length });
}

View File

@ -50,6 +50,9 @@ export const sendUnary = async (requestId: string, respond: ResponseCallbacks):
// Create callback
const callback = _createUnaryCallback(requestId, respond);
// Update request stats
models.stats.incrementExecutedRequests();
// Make call
const call = client.makeUnaryRequest(
selectedMethod.path,
@ -89,6 +92,9 @@ export const startClientStreaming = async (
// Create callback
const callback = _createUnaryCallback(requestId, respond);
// Update request stats
models.stats.incrementExecutedRequests();
// Make call
const call = client.makeClientStreamRequest(
selectedMethod.path,
@ -131,6 +137,9 @@ export const startServerStreaming = async (
return;
}
// Update request stats
models.stats.incrementExecutedRequests();
// Make call
const call = client.makeServerStreamRequest(
selectedMethod.path,
@ -170,6 +179,9 @@ export const startBidiStreaming = async (
return;
}
// Update request stats
models.stats.incrementExecutedRequests();
// Make call
const call = client.makeBidiStreamRequest(
selectedMethod.path,

View File

@ -51,6 +51,8 @@ class DocumentCardDropdown extends React.PureComponent<Props, State> {
const newWorkspace = await db.duplicate(workspace, { name: newName });
await models.apiSpec.updateOrCreateForParentId(newWorkspace._id, { fileName: newName });
models.stats.incrementCreatedRequestsForDescendents(newWorkspace);
handleSetActiveWorkspace(newWorkspace._id);
},
});
@ -94,6 +96,9 @@ class DocumentCardDropdown extends React.PureComponent<Props, State> {
if (isLastWorkspace) {
await models.workspace.create({ name: getAppName(), scope: 'spec' });
}
await models.stats.incrementDeletedRequestsForDescendents(workspace);
await models.workspace.remove(workspace);
},
});

View File

@ -13,6 +13,7 @@ import { hotKeyRefs } from '../../../common/hotkeys';
import * as misc from '../../../common/misc';
import { isRequest } from '../../../models/helpers/is-model';
import * as requestOperations from '../../../models/helpers/request-operations';
import { incrementDeletedRequests } from '../../../models/stats';
@autobind
class RequestActionsDropdown extends PureComponent {
@ -44,6 +45,7 @@ class RequestActionsDropdown extends PureComponent {
_handleRemove() {
const { request } = this.props;
incrementDeletedRequests();
return requestOperations.remove(request);
}

View File

@ -80,7 +80,9 @@ class RequestGroupActionsDropdown extends React.PureComponent<Props, State> {
this.props.handleCreateRequestGroup(this.props.requestGroup._id);
}
_handleDeleteFolder() {
async _handleDeleteFolder() {
await models.stats.incrementDeletedRequestsForDescendents(this.props.requestGroup);
models.requestGroup.remove(this.props.requestGroup);
}

View File

@ -183,6 +183,8 @@ class RequestSettingsModal extends React.PureComponent<Props, State> {
setTimeout(() => {
this.setState({ justCopied: false });
}, 2000);
models.stats.incrementCreatedRequests();
}
async show({ request, forceEditMode }: RequestSettingsModalOptions) {

View File

@ -20,6 +20,7 @@ import * as fetch from '../../account/fetch';
import imgSrcDesigner from '../images/insomnia-designer-logo.png';
import imgSrcCore from '../images/insomnia-core-logo.png';
import { APP_ID_INSOMNIA } from '../../../config';
import { getDeviceId } from '../../common/analytics';
const LOCALSTORAGE_KEY = 'insomnia::notifications::seen';
@ -127,6 +128,10 @@ class Toast extends React.PureComponent<Props, State> {
autoUpdatesDisabled: !settings.updateAutomatically,
disableUpdateNotification: settings.disableUpdateNotification,
updateChannel: settings.updateChannel,
deviceId: await getDeviceId(),
createdRequests: stats.createdRequests,
deletedRequests: stats.deletedRequests,
executedRequests: stats.executedRequests,
};
notification = await fetch.post('/notification', data, session.getCurrentSessionId());

View File

@ -431,11 +431,15 @@ class Wrapper extends React.PureComponent<WrapperProps, State> {
title: 'Deleting Last Workspace',
message: 'Since you deleted your only workspace, a new one has been created for you.',
onConfirm: async () => {
await models.stats.incrementDeletedRequestsForDescendents(activeWorkspace);
await models.workspace.create({ name: getAppName() });
await models.workspace.remove(activeWorkspace);
},
});
} else {
await models.stats.incrementDeletedRequestsForDescendents(activeWorkspace);
await models.workspace.remove(activeWorkspace);
}
}

View File

@ -210,6 +210,7 @@ class App extends PureComponent {
const parentId = activeRequest ? activeRequest.parentId : activeWorkspace._id;
const request = await models.request.create({ parentId, name: 'New Request' });
await this._handleSetActiveRequest(request._id);
models.stats.incrementCreatedRequests();
},
],
[
@ -237,6 +238,7 @@ class App extends PureComponent {
return;
}
await requestOperations.remove(activeRequest);
models.stats.incrementDeletedRequests();
},
});
},
@ -339,6 +341,7 @@ class App extends PureComponent {
parentId,
onComplete: requestId => {
this._handleSetActiveRequest(requestId);
models.stats.incrementCreatedRequests();
},
});
}
@ -381,7 +384,9 @@ class App extends PureComponent {
label: 'New Name',
selectText: true,
onComplete: async name => {
await models.requestGroup.duplicate(requestGroup, { name });
const newRequestGroup = await models.requestGroup.duplicate(requestGroup, { name });
models.stats.incrementCreatedRequestsForDescendents(newRequestGroup);
},
});
}
@ -404,6 +409,7 @@ class App extends PureComponent {
onComplete: async name => {
const newRequest = await requestOperations.duplicate(request, { name });
await this._handleSetActiveRequest(newRequest._id);
models.stats.incrementCreatedRequests();
},
});
}
@ -435,6 +441,9 @@ class App extends PureComponent {
if (!isYes) {
return;
}
await models.stats.incrementDeletedRequestsForDescendents(workspace);
await models.workspace.remove(workspace);
},
});
@ -453,6 +462,8 @@ class App extends PureComponent {
const newWorkspace = await db.duplicate(workspace, { name });
await this.props.handleSetActiveWorkspace(newWorkspace._id);
callback();
models.stats.incrementCreatedRequestsForDescendents(newWorkspace);
},
});
}
@ -681,12 +692,8 @@ class App extends PureComponent {
return;
}
// NOTE: Since request is by far the most popular event, we will throttle
// it so that we only track it if the request has changed since the last one
const key = request._id;
if (this._sendRequestTrackingKey !== key) {
this._sendRequestTrackingKey = key;
}
// Update request stats
models.stats.incrementExecutedRequests();
// Start loading
handleStartLoading(requestId);
@ -769,12 +776,8 @@ class App extends PureComponent {
return;
}
// NOTE: Since request is by far the most popular event, we will throttle
// it so that we only track it if the request has changed since the last noe
const key = `${request._id}::${request.modified}`;
if (this._sendRequestTrackingKey !== key) {
this._sendRequestTrackingKey = key;
}
// Update request stats
models.stats.incrementExecutedRequests();
handleStartLoading(requestId);

View File

@ -313,6 +313,10 @@ function handleImportResult(result: ImportResult, errorMessage: string): Array<W
return [];
}
const createdRequests =
summary[models.request.type].length + summary[models.grpcRequest.type].length;
models.stats.incrementRequestStats({ createdRequests: createdRequests });
return summary[models.workspace.type] || [];
}

View File

@ -1,5 +1,5 @@
{
"version": "2020.5.1",
"version": "2020.5.2",
"name": "insomnia",
"executableName": "insomnia",
"appId": "com.insomnia.app",

View File

@ -1,5 +1,5 @@
{
"version": "2020.5.1",
"version": "2020.5.2",
"name": "insomnia-designer",
"executableName": "insomnia-designer",
"appId": "com.insomnia.designer",