Implement session length selector

This commit is contained in:
Rene Vergara 2021-11-10 09:25:26 -06:00
parent 648324ba5f
commit b66650d34d
7 changed files with 156 additions and 22 deletions

View file

@ -11,6 +11,7 @@ import { MatDialogModule } from '@angular/material/dialog';
import { MatIconModule } from '@angular/material/icon'; import { MatIconModule } from '@angular/material/icon';
import { MatDividerModule } from '@angular/material/divider'; import { MatDividerModule } from '@angular/material/divider';
import { MatListModule } from '@angular/material/list'; import { MatListModule } from '@angular/material/list';
import { MatSelectModule } from '@angular/material/select';
import { AppRoutingModule } from './app-routing.module'; import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
@ -26,6 +27,7 @@ import { CancelComponent } from './cancel/cancel.component';
import { CheckoutComponent } from './checkout/checkout.component'; import { CheckoutComponent } from './checkout/checkout.component';
import { SettingsComponent } from './settings/settings.component'; import { SettingsComponent } from './settings/settings.component';
import { ListOrdersComponent } from './listorders/listorders.component'; import { ListOrdersComponent } from './listorders/listorders.component';
import { ScanComponent } from './scan/scan.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
@NgModule({ @NgModule({
@ -42,6 +44,7 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
CancelComponent, CancelComponent,
CheckoutComponent, CheckoutComponent,
SettingsComponent, SettingsComponent,
ScanComponent,
ListOrdersComponent ListOrdersComponent
], ],
imports: [ imports: [
@ -59,6 +62,7 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
MatDialogModule, MatDialogModule,
MatDividerModule, MatDividerModule,
MatListModule, MatListModule,
MatSelectModule,
BrowserAnimationsModule BrowserAnimationsModule
], ],
exports: [ exports: [
@ -72,7 +76,8 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
ItemAddComponent, ItemAddComponent,
CancelComponent, CancelComponent,
CheckoutComponent, CheckoutComponent,
SettingsComponent SettingsComponent,
ScanComponent
] ]
}) })
export class AppModule { } export class AppModule { }

View file

@ -5,3 +5,12 @@ mat-card.coolcard{
background-color: #FF5722; background-color: #FF5722;
color: #FFFFFF; color: #FFFFFF;
} }
.icon{
font-family: 'Material Icons';
}
.bigbutton{
display: inline-flex;
vertical-align: middle;
font-size: 120%;
padding: 3px;
}

View file

@ -18,8 +18,8 @@
<div align="center"> <div align="center">
<table width="80%"> <table width="80%">
<colgroup> <colgroup>
<col span="1" style="width: 75%;"> <col span="1" style="width: 60%;">
<col span="1" style="width: 25%;"> <col span="1" style="width: 40%;">
</colgroup> </colgroup>
<tr> <tr>
<td> <td>
@ -38,13 +38,21 @@
<mat-list-item *ngFor="let tx of txsUpdate | async">It has {{tx.confirmations}} confirmations, needs 10.</mat-list-item> <mat-list-item *ngFor="let tx of txsUpdate | async">It has {{tx.confirmations}} confirmations, needs 10.</mat-list-item>
</mat-list> </mat-list>
</mat-card> </mat-card>
<mat-card> <mat-card [formGroup]="entryForm">
<div align="center" id="info"> <div align="center" id="info">
<p> <mat-form-field appearance="outline">
Ensure you include your Reply-To shielded address! <mat-label>Session length</mat-label>
</p> <mat-select formControlName="selectedSession">
<br> <mat-option *ngFor="let ticket of tickets" [value]="ticket.value">
<div align="center" id="qrcode"></div> {{ticket.viewValue}}
</mat-option>
</mat-select>
</mat-form-field>
<mat-card-actions>
<button mat-raised-button color="primary" [disabled]="!entryForm.valid" (click)="login()">
<mat-icon class="icon">login</mat-icon><span class="bigbutton">Log in</span>
</button>
</mat-card-actions>
</div> </div>
</mat-card> </mat-card>
</td> </td>

View file

@ -1,7 +1,10 @@
import { Component, OnInit, OnDestroy, Injectable, ChangeDetectorRef } from '@angular/core'; import { Component, OnInit, OnDestroy, Injectable, ChangeDetectorRef } from '@angular/core';
import { CanActivate, Router, RouterStateSnapshot, ActivatedRouteSnapshot, ActivatedRoute } from '@angular/router'; import { CanActivate, Router, RouterStateSnapshot, ActivatedRouteSnapshot, ActivatedRoute } from '@angular/router';
import { MatDialog, MatDialogConfig} from '@angular/material/dialog';
import { FormBuilder, Validators, FormGroup, FormControl } from '@angular/forms';
import { UserService } from '../user.service'; import { UserService } from '../user.service';
import { FullnodeService } from '../fullnode.service'; import { FullnodeService } from '../fullnode.service';
import { ScanComponent} from '../scan/scan.component';
import { Tx } from '../tx.model'; import { Tx } from '../tx.model';
import { Subscription, Observable } from 'rxjs'; import { Subscription, Observable } from 'rxjs';
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
@ -20,19 +23,38 @@ export class LoginComponent implements OnInit {
txs: Tx[] = []; txs: Tx[] = [];
intervalHolder: any; intervalHolder: any;
nodeAddress: string = ''; nodeAddress: string = '';
localToken: string | null = '';
selectedValue: number = 0.001;
private FullnodeSub: Subscription = new Subscription(); private FullnodeSub: Subscription = new Subscription();
private UserSub: Subscription = new Subscription(); private UserSub: Subscription = new Subscription();
public heightUpdate: Observable<number>; public heightUpdate: Observable<number>;
public uZaddrUpdate: Observable<string>; public uZaddrUpdate: Observable<string>;
public txsUpdate: Observable<Tx[]>; public txsUpdate: Observable<Tx[]>;
tickets = [
{
value: 0.001,
viewValue: 'One hour'
},{
value: 0.005,
viewValue: 'One day'
}
];
entryForm: FormGroup;
constructor( constructor(
private fb: FormBuilder,
private activatedRoute: ActivatedRoute, private activatedRoute: ActivatedRoute,
public fullnodeService: FullnodeService, public fullnodeService: FullnodeService,
private router: Router, private router: Router,
public userService: UserService, public userService: UserService,
private dialog: MatDialog,
private _changeDetectorRef: ChangeDetectorRef private _changeDetectorRef: ChangeDetectorRef
){ ){
//this.fullnodeService.getAddr(); //this.fullnodeService.getAddr();
this.entryForm = fb.group({
selectedSession: [0.001, Validators.required]
});
this.heightUpdate = fullnodeService.heightUpdate; this.heightUpdate = fullnodeService.heightUpdate;
this.uZaddrUpdate = userService.uZaddrUpdate; this.uZaddrUpdate = userService.uZaddrUpdate;
this.txsUpdate = userService.txUpdate; this.txsUpdate = userService.txUpdate;
@ -47,12 +69,12 @@ export class LoginComponent implements OnInit {
//console.log('FETCH ADDRESS', addrData); //console.log('FETCH ADDRESS', addrData);
this.nodeAddress = addrData.response.addr; this.nodeAddress = addrData.response.addr;
//console.log('Node addres ', this.nodeAddress); //console.log('Node addres ', this.nodeAddress);
var localToken = localStorage.getItem('s4z_token'); this.localToken = localStorage.getItem('s4z_token');
//console.log(localToken); //console.log(localToken);
if(localToken == null){ if(this.localToken == null){
var token = uuidv4(); var token = uuidv4();
localStorage.setItem('s4z_token', token); localStorage.setItem('s4z_token', token);
localToken = token; this.localToken = token;
} }
this.userService.findUser(); this.userService.findUser();
this.userService.uZaddrUpdate. this.userService.uZaddrUpdate.
@ -62,16 +84,16 @@ export class LoginComponent implements OnInit {
this.router.navigate(['/shop']); this.router.navigate(['/shop']);
} else { } else {
console.log('No login for existing token found'); console.log('No login for existing token found');
console.log('Showing QR code for login'); //console.log('Showing QR code for login');
//console.log(URLSafeBase64.encode(Buffer.from('S4ZEC::'.concat(localToken)))); ////console.log(URLSafeBase64.encode(Buffer.from('S4ZEC::'.concat(localToken))));
var codeString = `zcash:${this.nodeAddress}?amount=0.005&memo=${URLSafeBase64.encode(Buffer.from('ZGO::'.concat(localToken!)))}`; //var codeString = `zcash:${this.nodeAddress}?amount=0.005&memo=${URLSafeBase64.encode(Buffer.from('ZGO::'.concat(this.localToken!)))}`;
console.log(codeString); //console.log(codeString);
var qrcode = new QRCode(document.getElementById("qrcode"), { //var qrcode = new QRCode(document.getElementById("qrcode"), {
text: codeString, //text: codeString,
logo: "/assets/zcash.png", //logo: "/assets/zcash.png",
logoWidth: 80, //logoWidth: 80,
logoHeight: 80 //logoHeight: 80
}); //});
} }
}); });
}); });
@ -97,6 +119,24 @@ export class LoginComponent implements OnInit {
}); });
} }
login() {
console.log('Dropdown:', this.entryForm.value.selectedSession);
const dialogConfig = new MatDialogConfig();
dialogConfig.disableClose = true;
dialogConfig.autoFocus = true;
dialogConfig.data = {
totalZec: this.entryForm.value.selectedSession,
addr: this.nodeAddress,
session: this.localToken
};
const dialogRef = this.dialog.open(ScanComponent, dialogConfig);
dialogRef.afterClosed().subscribe((val) => {
console.log('Awaiting confirmation');
});
}
ngOnDestroy(){ ngOnDestroy(){
this.FullnodeSub.unsubscribe(); this.FullnodeSub.unsubscribe();
this.UserSub.unsubscribe(); this.UserSub.unsubscribe();

View file

@ -0,0 +1,3 @@
.text {
font-family: "Roboto Mono", monospace;
}

View file

@ -0,0 +1,19 @@
<div align="center" mat-dialog-title>
<h2 class="text">Scan to log in!</h2>
</div>
<mat-dialog-content>
<div align="center" id="checkout-qr"></div>
</mat-dialog-content>
<mat-dialog-actions>
<table cellspacing="0" width="100%">
<tr>
<td>
<button mat-raised-button color="primary" (click)="confirm()">
<mat-icon>verified_user</mat-icon>
</button>
</td>
</tr>
</table>
</mat-dialog-actions>

View file

@ -0,0 +1,50 @@
import { Inject, Component, OnInit, ViewEncapsulation} from '@angular/core';
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog';
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
var QRCode = require('easyqrcodejs');
var URLSafeBase64 = require('urlsafe-base64');
var Buffer = require('buffer/').Buffer;
@Component({
selector: 'app-scan',
templateUrl: './scan.component.html',
styleUrls: ['./scan.component.css']
})
export class ScanComponent implements OnInit{
address: string;
total: number;
session: string;
codeString: string = '';
zcashUrl: SafeUrl;
constructor(
private dialogRef: MatDialogRef<ScanComponent>,
private sanitizer: DomSanitizer,
@Inject(MAT_DIALOG_DATA) public data: { totalZec: number, addr: string, session: string}
) {
this.address = data.addr;
this.total = data.totalZec;
this.session = data.session;
this.codeString = `zcash:${this.address}?amount=${this.total.toFixed(6)}&memo=${URLSafeBase64.encode(Buffer.from('ZGO::'.concat(this.session)))}`;
this.zcashUrl = this.sanitizer.bypassSecurityTrustUrl(this.codeString);
}
ngOnInit() {
var qrcode = new QRCode(document.getElementById("checkout-qr"), {
text: this.codeString,
logo: "/assets/zcash.png",
logoWidth: 80,
logoHeight: 80
});
}
confirm() {
this.dialogRef.close(true);
}
close() {
this.dialogRef.close(false);
}
}