Skip to content

Instantly share code, notes, and snippets.

@vakrilov
Last active November 13, 2017 16:03
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vakrilov/a512e0073c593f029f2a26dd9197ab44 to your computer and use it in GitHub Desktop.
Save vakrilov/a512e0073c593f029f2a26dd9197ab44 to your computer and use it in GitHub Desktop.
NativeScript 101
<ActionBar title="The Morse Code App" class="action-bar">
</ActionBar>
import { Injectable } from '@angular/core';
const morseCode = {
"a": "._", "b": "_...", "c": "_._.", "d": "_..",
"e": ".", "f": ".._.", "g": "__.", "h": "....",
"i": "..", "j": ".___", "k": "_._", "l": "._..",
"m": "__", "n": "_.", "o": "___", "p": ".__.",
"q": "__._", "r": "._.", "s": "...", "t": "_",
"u": ".._", "v": "..._", "w": ".__", "x": "_.._",
"y": "_.__", "z": "__..", " ": " ",
"1": ".____", "2": "..___", "3": "...__", "4": "...._", "5": ".....",
"6": "_....", "7": "__...", "8": "___..", "9": "____.", "0": "_____"
}
@Injectable()
export class MorseService {
public translate(msg: string): string {
return msg.split("")
.map( char => morseCode[char.toLocaleLowerCase()])
.join(" ");
}
}
Template:
<StackLayout class="page form">
<Label [text]="code" textWrap="true" class="m-x-15 code-char"></Label>
<TextField hint="type" class="input input-border m-15" (textChange)="update($event.value)"></TextField>
</StackLayout>
Component:
export class HomeComponent {
code: string;
update(msg: string) {
this.code = this.morse.translate(msg);
}
constructor(private morse: MorseService) { }
}
import { Injectable } from '@angular/core';
import { isAndroid } from "tns-core-modules/platform";
import * as app from "tns-core-modules/application";
declare var android: any;
declare var AVCaptureDevice: any;
declare var AVMediaTypeVideo: any;
declare var AVCaptureFlashMode: any;
declare var AVCaptureMaxAvailableTorchLevel: any;
declare var AVCaptureTorchMode: any;
@Injectable()
export class FlashlightService {
turnOn() {
this.flash(true);
}
turnOff() {
this.flash(false);
}
flash(onOrOff) {
if (isAndroid) {
const context = app.android.context;
const cameraService = context.getSystemService(android.content.Context.CAMERA_SERVICE);
if (cameraService) {
const cameras = cameraService.getCameraIdList();
cameraService.setTorchMode(cameras[0], onOrOff);
}
} else {
const device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo);
if (!device) {
console.log("Device does not support flashlight");
return;
}
device.lockForConfiguration(null);
if (onOrOff) {
device.setTorchModeOnWithLevelError(AVCaptureMaxAvailableTorchLevel, null);
device.flashMode = AVCaptureFlashMode.AVCaptureFlashModeOn;
} else {
device.torchMode = AVCaptureTorchMode.AVCaptureTorchModeOff;
device.flashMode = AVCaptureFlashMode.AVCaptureFlashModeOff;
}
device.unlockForConfiguration();
}
}
}
// Constants:
const GAP_TIME = 300;
const SYMBOL_TIME_MAP = {
".": 400,
"_": 1000,
};
const sleep = async ms => new Promise(resolve => setTimeout(resolve, ms));
// Callback
async send(){
for (let i = 0; i < this.code.length; i += 1) {
await this.playSingle(this.code[i]);
await sleep(GAP_TIME);
}
}
private async playSingle(symbol: string) {
console.log("Playing: " + symbol);
const time = SYMBOL_TIME_MAP[symbol];
if (time) {
this.flash.turnOn();
await sleep(time);
this.flash.turnOff();
}
}
//Animation
trigger("jump", [
transition("down => up", [
animate(100, style({ transform: "translateY(-30)" }))],
),
transition("up => down", [
animate(100, style({ transform: "translateY(0)" }))],
),
])
//COMPONENT
code: Array<string>;
current: number = -1;
update(msg: string) {
this.code = this.morse.translate(msg).split("");
}
async send() {
for (let i = 0; i < this.code.length; i += 1) {
this.current = i;
await this.playSingle(this.code[i]);
this.current = -1;
await sleep(GAP_TIME);
}
}
//Template:
<WrapLayout orientation="horizontal" class="m-x-15">
<Label *ngFor="let char of code; index as idx" [text]="char" class="code-char"
[@jump]="idx === current ? 'up' : 'down'"></Label>
</WrapLayout>
// Animation
trigger("flyIn", [
transition("* => *",
query(":enter", [
style({ opacity: 0, transform: "translateX(100)" }),
//stagger(100, [
animate(300, style({ opacity: 1, transform: "translateX(0)" }))
//])
]),
)
]),
//Template
<WrapLayout orientation="horizontal" class="m-x-15" [@flyIn]="code">
export interface DataPoint {
name: string;
value: number;
}
export interface BigData {
pieData: DataPoint[];
dotSeries: DataPoint[];
dashSeries: DataPoint[];
}
@Injectable()
export class MorseService {
public translate(msg: string): string {
return msg.split("")
.map(char => morseCode[char.toLocaleLowerCase()])
.join(" ");
}
public getBigData(msg: string): BigData {
const code = this.translate(msg);
const res = {};
const dotSeries: DataPoint[] = [{ name: "0", value: 0 }];
const dashSeries: DataPoint[] = [{ name: "0", value: 0 }];
let count = 1;
code.split('').forEach((char, i, arr) => {
res[char] = res[char] ? res[char] + 1 : 1;
if (char === " " || i === (arr.length - 1)) {
dotSeries.push({ name: count + "", value: res["."] || 0 });
dashSeries.push({ name: count + "", value: res["_"] || 0 });
count++;
}
});
const pieData = [
{ name: "dot", value: res["."] },
{ name: "dash", value: res["_"] },
{ name: "space", value: res[" "] }
];
return { pieData, dotSeries, dashSeries };
}
}
// Pass a parameter to the route
// data.module
import { NativeScriptUIChartModule } from "nativescript-pro-ui/chart/angular";
// Template
<ActionBar title="Data" class="action-bar">
</ActionBar>
<GridLayout class="page" rows="*, *">
<RadPieChart allowAnimation="true">
<PieSeries tkPieSeries selectionMode="DataPoint" expandRadius="0.4" outerRadiusFactor="0.7"
[items]="data.pieData" valueProperty="value" legendLabel="name"></PieSeries>
<RadLegendView tkPieLegend position="Right" title="Symbols" offsetOrigin="TopRight"
width="110" enableSelection="true"></RadLegendView>
</RadPieChart>
<RadCartesianChart row="1">
<CategoricalAxis lineThickness="1" tkCartesianHorizontalAxis></CategoricalAxis>
<LinearAxis lineThickness="1" tkCartesianVerticalAxis></LinearAxis>
<SplineAreaSeries tkCartesianSeries seriesName="Dot" [items]="data.dotSeries" categoryProperty="name"
valueProperty="value" legendTitle="Dots" selectionMode="Series"></SplineAreaSeries>
<SplineAreaSeries tkCartesianSeries seriesName="Dash" [items]="data.dashSeries" categoryProperty="name"
valueProperty="value" legendTitle="Dashes" selectionMode="Series"></SplineAreaSeries>
<RadCartesianChartGrid tkCartesianGrid horizontalLinesVisible="true" verticalLinesVisible="false"
verticalStripLinesVisible="false" horizontalStripLinesVisible="false" horizontalStrokeColor="#e5e5e5"></RadCartesianChartGrid>
<RadLegendView tkCartesianLegend position="Right" title="Dots vs. Dashes" offsetOrigin="TopRight"
width="110" enableSelection="true"></RadLegendView>
</RadCartesianChart>
</GridLayout>
Start
https://play.nativescript.org/?id=cc9cgUaqn00g7Nz0ub1S0&template=play-ng
Chpater 1 (Mission Critical) Complete:
https://play.nativescript.org/?id=aCuQ6o3Qyw0ZK3-JNic80&template=play-ng
Chapter 2 (Immersive) Complete:
https://play.nativescript.org/?id=EM6xNzelM0SAdT4Tq3c0&template=play-ng
Chpater 3 (Business) Complete:
https://play.nativescript.org/?id=fFxvtzTuB0DlFmhTgnW0&template=play-ng
new start
https://play.nativescript.org/?template=play-ng&id=9nZx1w8Z-00igG80E9PS0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment