Skip to content
This repository has been archived by the owner on May 25, 2021. It is now read-only.

Commit

Permalink
implement analytics and user consent part 1
Browse files Browse the repository at this point in the history
  • Loading branch information
Paul Yoon committed Jun 1, 2017
1 parent d3eb6bf commit 6826d89
Show file tree
Hide file tree
Showing 11 changed files with 148 additions and 22 deletions.
3 changes: 1 addition & 2 deletions src/analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,9 @@ const initializeGA = function (i, s, o, g, r) {

const GA = initializeGA(window, document, 'script', 'https://www.google-analytics.com/analytics.js', 'ga');

GA('create', 'UA-41067508-12', 'auto');
GA('create', 'UA-82659841-1', 'auto');
GA('set', 'checkProtocolTask', function () {
});
GA('require', 'displayfeatures');


export default (eventType, data) => (window as any).ga('send', eventType, ...data);
22 changes: 10 additions & 12 deletions src/backend/backend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,32 +268,30 @@ const messageHandler = (message: Message<any>) => {
return getComponentInstance(previousTree, node);

case MessageType.UpdateProperty:
return tryWrap(() => updateProperty(previousTree,
return updateProperty(previousTree,
message.content.path,
message.content.newValue));
message.content.newValue);

case MessageType.UpdateProviderProperty:
return tryWrap(() => updateProviderProperty(previousTree,
return updateProviderProperty(previousTree,
message.content.path,
message.content.token,
message.content.propertyPath,
message.content.newValue));

case MessageType.AnalyticsSend:
return AnalyticsSend(message.content.eventType, message.content.data);
message.content.newValue);

case MessageType.EmitValue:
return tryWrap(() => emitValue(previousTree,
return emitValue(previousTree,
message.content.path,
message.content.value));
message.content.value);

case MessageType.Highlight:
if (previousTree == null) {
return;
}
return tryWrap(() => {
highlight(message.content.nodes.map(id => previousTree.lookup(id)));
});
highlight(message.content.nodes.map(id => previousTree.lookup(id)));

case MessageType.AnalyticsSend:
return AnalyticsSend(message.content.eventType, message.content.data);

case MessageType.FindElement:
if (previousTree == null) {
Expand Down
16 changes: 10 additions & 6 deletions src/frontend/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
Tab,
Theme,
ComponentViewState,
AnalyticsConsent,
} from './state';

import {
Expand All @@ -55,6 +56,7 @@ require('!style!css!postcss!../styles/app.css');
export class App {
private Tab = Tab;
private Theme = Theme;
private AnalyticsConsent = AnalyticsConsent;

private componentState: ComponentInstanceState;
private routerTree: Array<Route>;
Expand Down Expand Up @@ -93,14 +95,16 @@ export class App {

this.options.changes.subscribe(() => this.requestTree());

this.options.load().then(() => this.changeDetector.detectChanges());
this.options.load().then(() => {
// sends a basic 'page view' event on app load, might be better not to do it here, and have it in the backend
// todo: will discuss restricting these to specific view events, ie, clicking the modules tab
if (this.options.analyticsConsent === AnalyticsConsent.Yes) {
this.connection.send(MessageFactory.analyticsEvent('pageview', 'index'));
}
return this.changeDetector.detectChanges();
});

this.viewState.changes.subscribe(() => this.changeDetector.detectChanges());


// sends a basic 'page view' event on app load, might be better not to do it here, and have it in the backend
// todo: will discuss restricting these to specific view events, ie, clicking the modules tab
this.connection.send(MessageFactory.analyticsEvent('pageview', 'index'));
}

private hasContent() {
Expand Down
15 changes: 15 additions & 0 deletions src/frontend/components/analytics-popup/analytics-popup.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<div class="p3 flex flex-justify border">
<div>
<span>We would like to gather some data to help improve Augury but first we need your consent. Do you agree to let us collect your usage information?</span>
</div>
<form class="right-align">
<button class="btn btn-outline border-none pointer py1"
(click)="onAnalyticsConsentChange(AnalyticsConsent.Yes)">
Yes
</button>
<button class="btn btn-outline border-none pointer py1"
(click)="onAnalyticsConsentChange(AnalyticsConsent.No)">
No
</button>
</form>
</div>
29 changes: 29 additions & 0 deletions src/frontend/components/analytics-popup/analytics-popup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import {
Component,
EventEmitter,
Input,
Output,
SimpleChanges,
ChangeDetectionStrategy,
} from '@angular/core';

import {
Options,
AnalyticsConsent,
} from '../../state';

@Component({
selector: 'bt-analytics-popup',
template: require('./analytics-popup.html'),
})
export class AnalyticsPopup {
private AnalyticsConsent = AnalyticsConsent;
@Input() private options: Options;

@Output() private hideComponent = new EventEmitter<void>();

private onAnalyticsConsentChange = (analyticsConsent: AnalyticsConsent) => {
this.options.analyticsConsent = analyticsConsent;
this.hideComponent.emit();
}
}
37 changes: 37 additions & 0 deletions src/frontend/components/app-trees/app-trees.html
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,46 @@
</label>
</li>
</ul>
<ul class="p3 m0">
<label>
Usage Data
<label class="descriptive-text mw3 block m1">
Allow us to collect usage data to help improve Augury
</label>
</label>
<li class="list-style-none p3">
<input
type="radio"
id="analytics-yes"
[checked]="options.analyticsConsent === AnalyticsConsent.Yes"
[value]="AnalyticsConsent.Yes"
(click)="onAnalyticsConsentChange(AnalyticsConsent.Yes)"
name="analytics" />
<label for="analytics">
Yes
</label>
</li>
<li class="list-style-none p3">
<input
type="radio"
id="analytics-no"
[checked]="options.analyticsConsent === AnalyticsConsent.No"
[value]="AnalyticsConsent.No"
(click)="onAnalyticsConsentChange(AnalyticsConsent.No)"
name="analytics" />
<label for="analytics">
No
</label>
</li>
</ul>
</div>
</form>

<bt-analytics-popup
*ngIf="showAnalyticsConsent"
[options]="options"
(hideComponent)="onHideAnalyticsPopup()">
</bt-analytics-popup>

<split-pane #splitPane [ngClass]="{ 'flex-auto flex': selectedTab === Tab.ComponentTree, 'display-none': selectedTab !== Tab.ComponentTree }">
<div split-pane-primary-content class="flex flex-column flex-auto">
Expand Down
20 changes: 20 additions & 0 deletions src/frontend/components/app-trees/app-trees.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
Options,
Tab,
Theme,
AnalyticsConsent,
} from '../../state';

type Node = any;
Expand All @@ -29,6 +30,7 @@ export class AppTrees {
private ComponentView = ComponentView;
private Tab = Tab;
private Theme = Theme;
private AnalyticsConsent = AnalyticsConsent;

@Input() private componentState: ComponentInstanceState;
@Input() private options: Options;
Expand All @@ -53,6 +55,7 @@ export class AppTrees {
@ViewChild('menuElement') private menuElement;

private settingOpened: boolean = false;
private showAnalyticsConsent: boolean = false;

private tabs: Array<TabDescription> = [{
title: 'Component Tree',
Expand All @@ -68,6 +71,14 @@ export class AppTrees {
tab: Tab.NgModules,
}];

private ngOnInit() {
this.options.load().then((results) => {
if (results.analyticsConsent === AnalyticsConsent.NotSet) {
this.showAnalyticsConsent = true;
}
});
}

onTabSelectionChanged(index: number) {
this.splitPane.handleTabNavigation();
this.tabChange.emit(this.tabs[index].tab);
Expand Down Expand Up @@ -102,4 +113,13 @@ export class AppTrees {
this.options.componentView = view;
this.reset();
}

private onAnalyticsConsentChange = (analyticsConsent: AnalyticsConsent) => {
this.options.analyticsConsent = analyticsConsent;
this.reset();
}

private onHideAnalyticsPopup = () => {
this.showAnalyticsConsent = false;
}
}
2 changes: 2 additions & 0 deletions src/frontend/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {InfoPanel} from './components/info-panel/info-panel';
import {UserActions} from './actions/user-actions/user-actions';
import {NgModuleInfo} from './components/ng-module-info/ng-module-info';
import {NgModuleConfigView} from './components/ng-module-config-view/ng-module-config-view';
import {AnalyticsPopup} from './components/analytics-popup/analytics-popup';

import {UncaughtErrorHandler} from './utils/uncaught-error-handler';

Expand Down Expand Up @@ -77,6 +78,7 @@ import {App} from './app';
TreeView,
NgModuleInfo,
NgModuleConfigView,
AnalyticsPopup,
],
providers: [
Connection,
Expand Down
12 changes: 11 additions & 1 deletion src/frontend/state/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ import {
defaultOptions,
loadOptions,
saveOptions,
AnalyticsConsent,
} from '../../options';

export {ComponentView};
export {SimpleOptions};
export {Theme};
export {AnalyticsConsent};

@Injectable()
export class Options {
Expand Down Expand Up @@ -45,6 +47,15 @@ export class Options {
this.publish();
}

get analyticsConsent(): AnalyticsConsent {
return this.cachedOptions.analyticsConsent;
}

set analyticsConsent(analyticsConsent: AnalyticsConsent) {
this.cachedOptions.analyticsConsent = analyticsConsent;
this.publish();
}

get componentView(): ComponentView {
return this.cachedOptions.componentView;
}
Expand All @@ -60,7 +71,6 @@ export class Options {

private publish() {
saveOptions(this.cachedOptions);

this.subject.next(this);
}
}
10 changes: 9 additions & 1 deletion src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,23 @@ export enum ComponentView {
Components, // show components only
}

export enum AnalyticsConsent {
NotSet,
Yes,
No,
}

export interface SimpleOptions {
theme?: Theme;
componentView?: ComponentView;
analyticsConsent?: AnalyticsConsent;
}

export const defaultOptions = (): SimpleOptions => {
return {
theme: Theme.Light,
componentView: ComponentView.Hybrid,
analyticsConsent: AnalyticsConsent.NotSet,
};
};

Expand All @@ -42,7 +50,7 @@ export const loadOptions = (): Promise<SimpleOptions> => {

const loadFromStorage = (): Promise<SimpleOptions> => {
return new Promise(resolve => {
const keys = ['componentView', 'theme'];
const keys = ['componentView', 'theme', 'analyticsConsent'];

chrome.storage.sync.get(keys, (result: SimpleOptions) => {
resolve(result);
Expand Down
4 changes: 4 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3642,6 +3642,10 @@ range-parser@^1.0.3, range-parser@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e"

raven-js@^3.14.2:
version "3.15.0"
resolved "https://registry.yarnpkg.com/raven-js/-/raven-js-3.15.0.tgz#ebf95466b7d40fbbc3d6a5085af7c1431607926c"

raw-loader@^0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-0.5.1.tgz#0c3d0beaed8a01c966d9787bf778281252a979aa"
Expand Down

0 comments on commit 6826d89

Please sign in to comment.