Basic WebSocket implementaion

Downgrade to Socket.io 2.3.0
This commit is contained in:
2020-12-27 22:38:20 +01:00
parent 04d2115f96
commit 4955b098c4
22 changed files with 404 additions and 131 deletions

View File

@@ -1,26 +0,0 @@
.bg {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: #F7A12F;
z-index: -999;
}
.content {
margin: 0 auto;
transform: translateY(20vh);
transform-origin: center;
min-width: 900px;
width: 50vw;
/* Shadow */
box-shadow:
0 -0.5px 2.8px -9px rgba(0, 0, 0, 0.39)
;
}
.content * {
width: 100%;
}

View File

@@ -1,5 +1 @@
<div class="bg"></div>
<div class="content">
<app-header></app-header>
<app-payment></app-payment>
</div>
<router-outlet></router-outlet>

View File

@@ -5,16 +5,31 @@ import { AppComponent } from './app.component';
import { HeaderComponent } from './header/header.component';
import { PaymentComponent } from './payment/payment.component';
import { QRCodeModule } from 'angularx-qrcode';
import { PayComponent } from './pay/pay.component';
import { RouterModule } from '@angular/router';
import { HelloComponent } from './hello/hello.component';
import { SocketIoConfig, SocketIoModule } from 'ngx-socket-io';
import { HttpClientModule } from '@angular/common/http';
import { AppRoutingModule } from 'src/routes';
import { NotFoundComponent } from './not-found/not-found.component';
const config: SocketIoConfig = { url: 'http://localhost:2009', options: {} };
@NgModule({
declarations: [
AppComponent,
HeaderComponent,
PaymentComponent
PaymentComponent,
PayComponent,
HelloComponent,
NotFoundComponent
],
imports: [
BrowserModule,
QRCodeModule
QRCodeModule,
HttpClientModule,
AppRoutingModule,
SocketIoModule.forRoot(config)
],
providers: [],
bootstrap: [AppComponent]

View File

@@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { BackendService } from './backend.service';
describe('BackendService', () => {
let service: BackendService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(BackendService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

View File

@@ -0,0 +1,94 @@
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Socket } from 'ngx-socket-io';
/*
* The following interfaces are copied from the backend.
*
* Checkout src/helper/types.ts and src/models/invoice/invoice.interface.ts
* (in the backend repository) for more information.
*/
export enum CryptoUnits {
BITCOIN = 'BTC',
BITCOINCASH = 'BCH',
ETHEREUM = 'ETH',
LITECOIN = 'LTC',
DOGECOIN = 'DOGE',
MONERO = 'XMR'
}
export interface ICart {
price: number;
name: string;
image: string;
quantity: number;
}
export interface IPaymentMethod {
method: any;
amount: number
}
export enum PaymentStatus {
PENDING = 0,
PARTIALLY = 1,
UNCONFIRMED = 2,
DONE = 3,
CANCELLED = 4
}
export interface IInvoice {
selector: string;
paymentMethods: IPaymentMethod[];
receiveAddress: string;
paidWith?: CryptoUnits;
paid?: number;
transcationHashes?: string[];
cart?: ICart[];
totalPrice?: number;
currency: string;
dueBy: number;
status?: PaymentStatus;
email?: string;
successUrl: string;
cancelUrl: string;
createdAt?: number;
}
@Injectable({
providedIn: 'root'
})
export class BackendService {
SERVER_URL = 'http://localhost:2009';
constructor(
private socket: Socket,
private http: HttpClient
) {
this.socket.on('status', (data: any) => {
console.log('Status has been updated to: ', data);
});
this.socket.on('subscribe', (success: boolean) => {
if (success) { console.log('We\'re getting the progress of this invoice!'); }
else { console.log('Subscription failed'); }
});
}
subscribeTo(selector: string) {
this.socket.emit('subscribe', { selector });
}
getInvoice(selector: string): Promise<IInvoice> {
return new Promise(async (resolve, reject) => {
this.http.get(this.SERVER_URL + '/invoice/' + selector, {
observe: 'body',
responseType: 'json'
}).toPromise().then((invoice) => {
resolve(invoice as IInvoice);
}).catch(err => {
reject(err);
});
});
}
}

View File

View File

@@ -0,0 +1 @@
<p>hello works!</p>

View File

@@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { HelloComponent } from './hello.component';
describe('HelloComponent', () => {
let component: HelloComponent;
let fixture: ComponentFixture<HelloComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ HelloComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(HelloComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,15 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-hello',
templateUrl: './hello.component.html',
styleUrls: ['./hello.component.css']
})
export class HelloComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}

View File

@@ -0,0 +1 @@
<p>not-found works!</p>

View File

@@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { NotFoundComponent } from './not-found.component';
describe('NotFoundComponent', () => {
let component: NotFoundComponent;
let fixture: ComponentFixture<NotFoundComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ NotFoundComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(NotFoundComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,15 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-not-found',
templateUrl: './not-found.component.html',
styleUrls: ['./not-found.component.css']
})
export class NotFoundComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}

View File

@@ -0,0 +1,26 @@
.bg {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: #F7A12F;
z-index: -999;
}
.content {
margin: 0 auto;
transform: translateY(20vh);
transform-origin: center;
min-width: 900px;
width: 50vw;
/* Shadow */
box-shadow:
0 -0.5px 2.8px -9px rgba(0, 0, 0, 0.39)
;
}
.content * {
width: 100%;
}

View File

@@ -0,0 +1,5 @@
<div class="bg"></div>
<div class="content">
<app-header></app-header>
<app-payment></app-payment>
</div>

View File

@@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PayComponent } from './pay.component';
describe('PayComponent', () => {
let component: PayComponent;
let fixture: ComponentFixture<PayComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PayComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PayComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,15 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-pay',
templateUrl: './pay.component.html',
styleUrls: ['./pay.component.css']
})
export class PayComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}

View File

@@ -3,7 +3,7 @@
<div class="qr">
<img src="assets/Bitcoin.svg">
<qrcode
[qrdata]="'bitcoin:1QFrbboisCYgeBdowGAuCTK3r2YnZuApYd'"
[qrdata]="'bitcoin:' + invoice!!.receiveAddress"
[width]="256"
[errorCorrectionLevel]="'M'"
[elementType]="'svg'"
@@ -12,16 +12,16 @@
</div>
</div>
<div class="data">
<div class="data" *ngIf="ready">
<!-- Payment data -->
<span id="target">Send to
<h3>1QFrbboisCYgeBdowGAuCTK3r2YnZuApYd</h3>
<h3>{{ invoice!!.receiveAddress }}</h3>
</span>
<span id="amount">Amount
<h3>0.00133700 BTC</h3>
<h3>{{ getAmount() }} BTC</h3>
</span>
<span id="status">Status
<h3>Pending</h3>
<h3>{{ getStatus() }}</h3>
</span>
</div>
</div>

View File

@@ -1,4 +1,6 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { BackendService, IInvoice, CryptoUnits, PaymentStatus } from '../backend.service';
@Component({
selector: 'app-payment',
@@ -7,9 +9,50 @@ import { Component, OnInit } from '@angular/core';
})
export class PaymentComponent implements OnInit {
constructor() { }
paymentSelector = '';
choosenPaymentMethod = CryptoUnits.BITCOIN;
ready = false;
invoice: IInvoice | null = null;
constructor(
private backend: BackendService,
private route: ActivatedRoute
) { }
ngOnInit(): void {
this.route.params.subscribe(params => {
this.paymentSelector = params.id;
this.backend.subscribeTo(this.paymentSelector);
this.get();
});
}
async get() {
this.invoice = await this.backend.getInvoice(this.paymentSelector);
this.ready = true;
}
getAmount() {
return this.invoice?.paymentMethods.find(item => {
return item.method === CryptoUnits.BITCOIN;
})?.amount.toFixed(8);
}
getStatus() {
switch (this.invoice?.status) {
case PaymentStatus.PENDING:
return 'Pending';
case PaymentStatus.PARTIALLY:
return 'Partly';
case PaymentStatus.UNCONFIRMED:
return 'Unconfirmed';
case PaymentStatus.DONE:
return 'Paid';
case PaymentStatus.CANCELLED:
return 'Cancelled';
default:
return 'Unknown';
}
}
}

17
src/routes.ts Normal file
View File

@@ -0,0 +1,17 @@
import { NgModule } from "@angular/core";
import { RouterModule, Routes } from "@angular/router";
import { HelloComponent } from "./app/hello/hello.component";
import { NotFoundComponent } from "./app/not-found/not-found.component";
import { PayComponent } from "./app/pay/pay.component";
const routes: Routes = [
{ path: 'pay/:id', component: PayComponent, data: { title: 'Payment' } },
{ path: '', component: HelloComponent },
{ path: '**', component: NotFoundComponent }
]
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {}