Skip to content

Commit dc345f4

Browse files
Merge pull request #3396 from NativeScript/fatme/playground
feat(Analytics): Respect playground key from package.json file
2 parents 4b5c98c + 76e29f8 commit dc345f4

11 files changed

+309
-13
lines changed

PublicAPI.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -898,6 +898,29 @@ getUserAgentString(identifier: string): string;
898898
const userAgentString = tns.analyticsSettingsService.getUserAgentString("tns/3.3.0");
899899
```
900900
901+
### getPlaygroundInfo
902+
The `getPlaygroundInfo` method allows retrieving information for projects that are exported from playground
903+
904+
* Definition:
905+
```TypeScript
906+
/**
907+
* Gets information for projects that are exported from playground.
908+
* Returns null in case when project does not have playground key in package.json file (e.g is not exported from playground) and no playground info is saved in userSettings file
909+
* @param {string} projectDir The project directory.
910+
* @returns {Promise<IPlaygroundInfo>} Playground info. { id: string, usedTutorial: boolean }
911+
*/
912+
getPlaygroundInfo(projectDir: string): Promise<IPlaygroundInfo>;
913+
```
914+
915+
* Usage:
916+
```JavaScript
917+
tns.analyticsSettingsService.getPlaygroundInfo("/my/project/path")
918+
.then(playgroundInfo => {
919+
console.log(playgroundInfo.id);
920+
console.log(playgroundInfo.usedTutorial);
921+
});
922+
```
923+
901924
## How to add a new method to Public API
902925
CLI is designed as command line tool and when it is used as a library, it does not give you access to all of the methods. This is mainly implementation detail. Most of the CLI's code is created to work in command line, not as a library, so before adding method to public API, most probably it will require some modification.
903926
For example the `$options` injected module contains information about all `--` options passed on the terminal. When the CLI is used as a library, the options are not populated. Before adding method to public API, make sure its implementation does not rely on `$options`.

lib/bootstrap.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,3 +144,5 @@ $injector.requirePublic("extensibilityService", "./services/extensibility-servic
144144

145145
$injector.require("nodeModulesDependenciesBuilder", "./tools/node-modules/node-modules-dependencies-builder");
146146
$injector.require("subscriptionService", "./services/subscription-service");
147+
148+
$injector.require('playgroundService', './services/playground-service');

lib/definitions/project.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ interface IProjectDataService {
105105
*/
106106
removeDependency(projectDir: string, dependencyName: string): void;
107107

108-
getProjectData(projectDir: string): IProjectData;
108+
getProjectData(projectDir?: string): IProjectData;
109109
}
110110

111111
/**

lib/services/analytics-settings-service.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ class AnalyticsSettingsService implements IAnalyticsSettingsService {
88
private $staticConfig: IStaticConfig,
99
private $hostInfo: IHostInfo,
1010
private $osInfo: IOsInfo,
11-
private $logger: ILogger) { }
11+
private $logger: ILogger,
12+
private $playgroundService: IPlaygroundService) { }
1213

1314
public async canDoRequest(): Promise<boolean> {
1415
return true;
@@ -23,6 +24,11 @@ class AnalyticsSettingsService implements IAnalyticsSettingsService {
2324
return this.getSettingValueOrDefault(this.$staticConfig.ANALYTICS_INSTALLATION_ID_SETTING_NAME);
2425
}
2526

27+
@exported("analyticsSettingsService")
28+
public async getPlaygroundInfo(projectDir: string): Promise<IPlaygroundInfo> {
29+
return this.$playgroundService.getPlaygroundInfo(projectDir);
30+
}
31+
2632
public getClientName(): string {
2733
return "" + this.$staticConfig.CLIENT_NAME_ALIAS.cyan.bold;
2834
}

lib/services/analytics/google-analytics-custom-dimensions.d.ts

Lines changed: 0 additions & 8 deletions
This file was deleted.

lib/services/analytics/google-analytics-provider.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export class GoogleAnalyticsProvider implements IGoogleAnalyticsProvider {
4646
this.setCrossClientCustomDimensions(visitor, sessionId);
4747
break;
4848
default:
49-
this.setCustomDimensions(visitor, trackInfo.customDimensions, sessionId);
49+
await this.setCustomDimensions(visitor, trackInfo.customDimensions, sessionId);
5050
break;
5151
}
5252

@@ -60,7 +60,7 @@ export class GoogleAnalyticsProvider implements IGoogleAnalyticsProvider {
6060
}
6161
}
6262

63-
private setCustomDimensions(visitor: ua.Visitor, customDimensions: IStringDictionary, sessionId: string): void {
63+
private async setCustomDimensions(visitor: ua.Visitor, customDimensions: IStringDictionary, sessionId: string): Promise<void> {
6464
const defaultValues: IStringDictionary = {
6565
[GoogleAnalyticsCustomDimensions.cliVersion]: this.$staticConfig.version,
6666
[GoogleAnalyticsCustomDimensions.nodeVersion]: process.version,
@@ -70,6 +70,12 @@ export class GoogleAnalyticsProvider implements IGoogleAnalyticsProvider {
7070
[GoogleAnalyticsCustomDimensions.client]: AnalyticsClients.Unknown
7171
};
7272

73+
const playgrounInfo = await this.$analyticsSettingsService.getPlaygroundInfo();
74+
if (playgrounInfo && playgrounInfo.id) {
75+
defaultValues[GoogleAnalyticsCustomDimensions.playgroundId] = playgrounInfo.id;
76+
defaultValues[GoogleAnalyticsCustomDimensions.usedTutorial] = playgrounInfo.usedTutorial.toString();
77+
}
78+
7379
customDimensions = _.merge(defaultValues, customDimensions);
7480

7581
_.each(customDimensions, (value, key) => {

lib/services/playground-service.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
export class PlaygroundService implements IPlaygroundService {
2+
constructor(private $fs: IFileSystem,
3+
private $projectDataService: IProjectDataService,
4+
private $userSettingsService: IUserSettingsService) { }
5+
6+
public async getPlaygroundInfo(projectDir?: string): Promise<IPlaygroundInfo> {
7+
const projectData = this.getProjectData(projectDir);
8+
if (projectData) {
9+
const projectFileContent = this.$fs.readJson(projectData.projectFilePath);
10+
if (this.hasPlaygroundKey(projectFileContent)) {
11+
const id = projectFileContent.nativescript.playground.id;
12+
let usedTutorial = projectFileContent.nativescript.playground.usedTutorial || false;
13+
14+
// In case when usedTutorial=true is already saved in userSettings file, we shouldn't overwrite it
15+
const playgroundInfo = await this.getPlaygroundInfoFromUserSettingsFile();
16+
if (playgroundInfo && playgroundInfo.usedTutorial) {
17+
usedTutorial = true;
18+
}
19+
20+
delete projectFileContent.nativescript.playground;
21+
this.$fs.writeJson(projectData.projectFilePath, projectFileContent);
22+
23+
const result = { id , usedTutorial };
24+
await this.$userSettingsService.saveSettings(<any>{playground: result});
25+
return result;
26+
}
27+
}
28+
29+
return this.getPlaygroundInfoFromUserSettingsFile();
30+
}
31+
32+
private getProjectData(projectDir: string): IProjectData {
33+
try {
34+
return this.$projectDataService.getProjectData(projectDir);
35+
} catch (e) {
36+
// in case command is executed in non-project folder
37+
return null;
38+
}
39+
}
40+
41+
private hasPlaygroundKey(projectFileContent: any): boolean {
42+
return projectFileContent && projectFileContent.nativescript && projectFileContent.nativescript.playground && projectFileContent.nativescript.playground.id;
43+
}
44+
45+
private async getPlaygroundInfoFromUserSettingsFile(): Promise<IPlaygroundInfo> {
46+
return this.$userSettingsService.getSettingValue<IPlaygroundInfo>("playground");
47+
}
48+
}
49+
$injector.register('playgroundService', PlaygroundService);

test/platform-commands.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,9 @@ function createTestInjector() {
160160
message: (): void => undefined
161161
})
162162
});
163+
testInjector.register("analyticsSettingsService", {
164+
getPlaygroundInfo: () => Promise.resolve(null)
165+
});
163166

164167
return testInjector;
165168
}

test/plugins-service.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@ function createTestInjector() {
110110
message: (): void => undefined
111111
})
112112
});
113+
testInjector.register("analyticsSettingsService", {
114+
getPlaygroundInfo: () => Promise.resolve(null)
115+
});
113116

114117
return testInjector;
115118
}

0 commit comments

Comments
 (0)