Skip to content

Commit aac3668

Browse files
committed
Show qr codes for current app and playground app when keys from keyboard are pressed.
1 parent 04e741b commit aac3668

File tree

12 files changed

+314
-40
lines changed

12 files changed

+314
-40
lines changed

lib/bootstrap.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ $injector.requireCommand("platform|clean", "./commands/platform-clean");
122122
$injector.require("bundleValidatorHelper", "./helpers/bundle-validator-helper");
123123
$injector.require("liveSyncCommandHelper", "./helpers/livesync-command-helper");
124124
$injector.require("deployCommandHelper", "./helpers/deploy-command-helper");
125+
$injector.require("previewCommandHelper", "./helpers/preview-command-helper");
125126

126127
$injector.requirePublicClass("localBuildService", "./services/local-build-service");
127128
$injector.requirePublicClass("liveSyncService", "./services/livesync/livesync-service");
@@ -132,6 +133,7 @@ $injector.require("usbLiveSyncService", "./services/livesync/livesync-service");
132133
$injector.require("previewAppLiveSyncService", "./services/livesync/playground/preview-app-livesync-service");
133134
$injector.require("previewAppPluginsService", "./services/livesync/playground/preview-app-plugins-service");
134135
$injector.require("previewSdkService", "./services/livesync/playground/preview-sdk-service");
136+
$injector.require("playgroundQrCodeGenerator", "./services/livesync/playground/qr-code-generator");
135137
$injector.requirePublic("sysInfo", "./sys-info");
136138

137139
$injector.require("iOSNotificationService", "./services/ios-notification-service");

lib/commands/preview.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@ export class PreviewCommand implements ICommand {
33

44
constructor(private $liveSyncService: ILiveSyncService,
55
private $projectData: IProjectData,
6-
private $options: IOptions) { }
6+
private $options: IOptions,
7+
private $previewCommandHelper: IPreviewCommandHelper) { }
78

89
public async execute(args: string[]): Promise<void> {
10+
this.$previewCommandHelper.run();
11+
912
await this.$liveSyncService.liveSync([], {
1013
syncToPreviewApp: true,
1114
projectDir: this.$projectData.projectDir,

lib/definitions/preview-app-livesync.d.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,24 @@ declare global {
1010
interface IPreviewAppLiveSyncData extends IProjectDir, IAppFilesUpdaterOptionsComposition, IEnvOptions { }
1111

1212
interface IPreviewSdkService extends NodeJS.EventEmitter {
13+
qrCodeUrl: string;
1314
connectedDevices: Device[];
1415
initialize(): void;
1516
applyChanges(files: FilePayload[]): Promise<void>;
16-
shortenQrCodeUrl(): Promise<string>;
1717
stop(): void;
1818
}
1919

2020
interface IPreviewAppPluginsService {
2121
comparePluginsOnDevice(device: Device): Promise<void>;
2222
}
23+
24+
interface IPreviewCommandHelper {
25+
run(): void;
26+
}
27+
28+
interface IPlaygroundQrCodeGenerator {
29+
generateQrCodeForiOS(): Promise<void>;
30+
generateQrCodeForAndroid(): Promise<void>;
31+
generateQrCodeForCurrentApp(): Promise<void>;
32+
}
2333
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import * as readline from "readline";
2+
import { ReadStream } from "tty";
3+
import * as helpers from "../common/helpers";
4+
const chalk = require("chalk");
5+
6+
export class PreviewCommandHelper implements IPreviewCommandHelper {
7+
private ctrlcReader: readline.ReadLine;
8+
9+
constructor(private $logger: ILogger,
10+
private $playgroundQrCodeGenerator: IPlaygroundQrCodeGenerator,
11+
private $processService: IProcessService) {
12+
this.$processService.attachToProcessExitSignals(this, () => {
13+
this.stopWaitingForCommand();
14+
});
15+
}
16+
17+
public run() {
18+
this.printUsage();
19+
this.startWaitingForCommand();
20+
}
21+
22+
private startWaitingForCommand(): void {
23+
if (helpers.isInteractive()) {
24+
this.ctrlcReader = readline.createInterface(<any>{
25+
input: process.stdin,
26+
output: process.stdout
27+
});
28+
this.ctrlcReader.on("SIGINT", process.exit);
29+
30+
(<ReadStream>process.stdin).setRawMode(true);
31+
process.stdin.resume();
32+
process.stdin.setEncoding("utf8");
33+
process.stdin.on("data", this.handleKeypress.bind(this));
34+
}
35+
}
36+
37+
private stopWaitingForCommand(): void {
38+
if (helpers.isInteractive()) {
39+
process.stdin.removeListener("data", this.handleKeypress);
40+
(<ReadStream>process.stdin).setRawMode(false);
41+
process.stdin.resume();
42+
this.closeCtrlcReader();
43+
}
44+
}
45+
46+
private async handleKeypress(key: string): Promise<void> {
47+
switch (key) {
48+
case "a":
49+
await this.$playgroundQrCodeGenerator.generateQrCodeForAndroid();
50+
this.printUsage();
51+
return;
52+
case "i":
53+
await this.$playgroundQrCodeGenerator.generateQrCodeForiOS();
54+
this.printUsage();
55+
return;
56+
case "q":
57+
await this.$playgroundQrCodeGenerator.generateQrCodeForCurrentApp();
58+
this.printUsage();
59+
return;
60+
}
61+
}
62+
63+
private printUsage(): void {
64+
this.$logger.info(`
65+
-> Press ${this.underlineBoldCyan("a")} to show the QR code of NativeScript Playground app for ${this.underlineBoldCyan("Android")} devices
66+
-> Press ${this.underlineBoldCyan("i")} to show the QR code of NativeScript Playground app for ${this.underlineBoldCyan("iOS")} devices
67+
-> Press ${this.underlineBoldCyan("q")} to display the QR code of the current application.
68+
`);
69+
}
70+
71+
private underlineBoldCyan(str: string) {
72+
const { bold, underline, cyan } = chalk;
73+
return underline(bold(cyan(str)));
74+
}
75+
76+
private closeCtrlcReader() {
77+
if (this.ctrlcReader) {
78+
this.ctrlcReader.close();
79+
}
80+
}
81+
}
82+
$injector.register("previewCommandHelper", PreviewCommandHelper);

lib/services/livesync/livesync-service.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -581,14 +581,16 @@ export class LiveSyncService extends EventEmitter implements IDebugLiveSyncServi
581581
timeoutTimer = setTimeout(async () => {
582582
if (liveSyncData.syncToPreviewApp) {
583583
await this.addActionToChain(projectData.projectDir, async () => {
584-
await this.$previewAppLiveSyncService.syncFiles({
585-
appFilesUpdaterOptions: {
586-
bundle: liveSyncData.bundle,
587-
release: liveSyncData.release
588-
},
589-
env: liveSyncData.env,
590-
projectDir: projectData.projectDir
591-
}, filesToSync);
584+
if (filesToSync.length || filesToRemove.length) {
585+
await this.$previewAppLiveSyncService.syncFiles({
586+
appFilesUpdaterOptions: {
587+
bundle: liveSyncData.bundle,
588+
release: liveSyncData.release
589+
},
590+
env: liveSyncData.env,
591+
projectDir: projectData.projectDir
592+
}, filesToSync);
593+
}
592594
});
593595
} else {
594596
// Push actions to the queue, do not start them simultaneously

lib/services/livesync/playground/preview-app-constants.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,8 @@ export class PubnubKeys {
77
public static PUBLISH_KEY = "pub-c-78911a3d-9dc9-4316-96e5-83e6fd17263f";
88
public static SUBSCRIBE_KEY = "sub-c-2c059576-47a1-11e7-b66e-0619f8945a4f";
99
}
10+
11+
export class PlaygroundStoreUrls {
12+
public static GOOGLE_PLAY_URL = "https://play.google.com/store/apps/details?id=org.nativescript.play";
13+
public static APP_STORE_URL = "https://itunes.apple.com/us/app/nativescript-playground/id1263543946?mt=8&ls=1";
14+
}

lib/services/livesync/playground/preview-app-livesync-service.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@ export class PreviewAppLiveSyncService implements IPreviewAppLiveSyncService {
1212
private $previewSdkService: IPreviewSdkService,
1313
private $previewAppPluginsService: IPreviewAppPluginsService,
1414
private $projectFilesManager: IProjectFilesManager,
15-
private $qrCodeTerminalService: IQrCodeTerminalService) { }
15+
private $playgroundQrCodeGenerator: IPlaygroundQrCodeGenerator) { }
1616

1717
public async initialSync(data: IPreviewAppLiveSyncData): Promise<void> {
1818
this.$previewSdkService.initialize();
1919
this.$previewSdkService.on(PreviewSdkEventNames.DEVICE_CONNECTED, async (device: Device) => {
2020
this.$logger.trace("Found connected device", device);
2121
await this.trySyncFilesOnDevice(data, device);
2222
});
23-
await this.generateQRCode();
23+
await this.$playgroundQrCodeGenerator.generateQrCodeForCurrentApp();
2424
}
2525

2626
public async syncFiles(data: IPreviewAppLiveSyncData, files: string[]): Promise<void> {
@@ -34,11 +34,6 @@ export class PreviewAppLiveSyncService implements IPreviewAppLiveSyncService {
3434
this.$previewSdkService.stop();
3535
}
3636

37-
private async generateQRCode(): Promise<void> {
38-
const qrCodeUrl = await this.$previewSdkService.shortenQrCodeUrl();
39-
this.$qrCodeTerminalService.generate(qrCodeUrl);
40-
}
41-
4237
private async trySyncFilesOnDevice(data: IPreviewAppLiveSyncData, device: Device, files?: string[]): Promise<void> {
4338
await this.$previewAppPluginsService.comparePluginsOnDevice(device);
4439
this.showWarningsForNativeFiles(files);

lib/services/livesync/playground/preview-sdk-service.ts

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ export class PreviewSdkService extends EventEmitter implements IPreviewSdkServic
1414
super();
1515
}
1616

17-
public async shortenQrCodeUrl(): Promise<string> {
18-
return this.qrCodeUrl;
17+
public get qrCodeUrl(): string {
18+
return `nsplay://boot?instanceId=${this.instanceId}&pKey=${PubnubKeys.PUBLISH_KEY}&sKey=${PubnubKeys.SUBSCRIBE_KEY}&template=play-ng`;
1919
}
2020

2121
public initialize(): void {
@@ -40,10 +40,6 @@ export class PreviewSdkService extends EventEmitter implements IPreviewSdkServic
4040
this.messagingService.stop();
4141
}
4242

43-
private get qrCodeUrl(): string {
44-
return `nsplay://boot?instanceId=${this.instanceId}&pKey=${PubnubKeys.PUBLISH_KEY}&sKey=${PubnubKeys.SUBSCRIBE_KEY}&template=play-ng`;
45-
}
46-
4743
private getInitConfig(): Config {
4844
return {
4945
pubnubPublishKey: PubnubKeys.PUBLISH_KEY,
@@ -78,22 +74,22 @@ export class PreviewSdkService extends EventEmitter implements IPreviewSdkServic
7874
onDevicesPresence: (devices: Device[]) => ({ }),
7975
onSendingChange: (sending: boolean) => ({ }),
8076
onBiggerFilesUpload: async (filesContent, callback) => {
81-
// TODO: stop using the playground endpoint when we have a direct Amazon one
82-
const gzippedContent = new Buffer(pako.gzip(filesContent));
83-
const playgroundUploadResponse = await this.$httpClient.httpRequest({
84-
url: "https://play.telerik.rocks/api/files",
85-
method: "POST",
86-
body: gzippedContent,
87-
headers: {
88-
"Content-Encoding": "gzip",
89-
"Content-Type": "text/plain"
90-
}
91-
});
77+
// TODO: stop using the playground endpoint when we have a direct Amazon one
78+
const gzippedContent = new Buffer(pako.gzip(filesContent));
79+
const playgroundUploadResponse = await this.$httpClient.httpRequest({
80+
url: "https://play.telerik.rocks/api/files",
81+
method: "POST",
82+
body: gzippedContent,
83+
headers: {
84+
"Content-Encoding": "gzip",
85+
"Content-Type": "text/plain"
86+
}
87+
});
9288

93-
const responseBody = JSON.parse(playgroundUploadResponse.body);
94-
const location = responseBody && responseBody.location;
95-
callback(location, playgroundUploadResponse.error);
96-
}
89+
const responseBody = JSON.parse(playgroundUploadResponse.body);
90+
const location = responseBody && responseBody.location;
91+
callback(location, playgroundUploadResponse.error);
92+
}
9793
};
9894
}
9995
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { PlaygroundStoreUrls } from "./preview-app-constants";
2+
3+
export class PlaygroundQrCodeGenerator implements IPlaygroundQrCodeGenerator {
4+
constructor(private $previewSdkService: IPreviewSdkService,
5+
private $qrCodeTerminalService: IQrCodeTerminalService) { }
6+
7+
public async generateQrCodeForiOS(): Promise<void> {
8+
await this.generateQrCode(PlaygroundStoreUrls.APP_STORE_URL);
9+
}
10+
11+
public async generateQrCodeForAndroid(): Promise<void> {
12+
await this.generateQrCode(PlaygroundStoreUrls.GOOGLE_PLAY_URL);
13+
}
14+
15+
public async generateQrCodeForCurrentApp(): Promise<void> {
16+
await this.generateQrCode(this.$previewSdkService.qrCodeUrl);
17+
}
18+
19+
private async generateQrCode(url: string): Promise<void> {
20+
// TODO: Shorten url before generate QR code
21+
this.$qrCodeTerminalService.generate(url);
22+
}
23+
}
24+
$injector.register("playgroundQrCodeGenerator", PlaygroundQrCodeGenerator);

npm-shrinkwrap.json

Lines changed: 6 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)