Bug fix: Blank invoice preview #1019

Bug fix: Blank invoice preview #1019
This commit is contained in:
ShahanaFarooqui 2022-09-21 17:19:25 -07:00
parent 2565d11f19
commit 72fecba40a
14 changed files with 76 additions and 66 deletions

View File

@ -55,10 +55,10 @@ export class RTLWebSocketServer {
this.mountEventsOnConnection = (websocket, request) => {
var _a;
const protocols = !request.headers['sec-websocket-protocol'] ? [] : (_a = request.headers['sec-websocket-protocol'].split(',')) === null || _a === void 0 ? void 0 : _a.map((s) => s.trim());
const cookies = parse(request.headers.cookie);
const cookies = request.headers.cookie ? parse(request.headers.cookie) : null;
websocket.clientId = Date.now();
websocket.isAlive = true;
websocket.sessionId = cookieParser.signedCookie(cookies['connect.sid'], this.common.secret_key);
websocket.sessionId = cookies && cookies['connect.sid'] ? cookieParser.signedCookie(cookies['connect.sid'], this.common.secret_key) : null;
websocket.clientNodeIndex = +protocols[1];
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Connected: ' + websocket.clientId + ', Total WS clients: ' + this.webSocketServer.clients.size });
websocket.on('error', this.sendErrorToAllLNClients);

View File

@ -13,6 +13,6 @@
<style>@font-face{font-family:Roboto;src:url(Roboto-Thin.f7a95c9c5999532c.woff2) format("woff2"),url(Roboto-Thin.c13c157cb81e8ebb.woff) format("woff");font-weight:100;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-ThinItalic.b0e084abf689f393.woff2) format("woff2"),url(Roboto-ThinItalic.1111028df6cea564.woff) format("woff");font-weight:100;font-style:italic}@font-face{font-family:Roboto;src:url(Roboto-Light.0e01b6cd13b3857f.woff2) format("woff2"),url(Roboto-Light.603ca9a537b88428.woff) format("woff");font-weight:300;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-LightItalic.232ef4b20215f720.woff2) format("woff2"),url(Roboto-LightItalic.1b5e142f787151c8.woff) format("woff");font-weight:300;font-style:italic}@font-face{font-family:Roboto;src:url(Roboto-Regular.475ba9e4e2d63456.woff2) format("woff2"),url(Roboto-Regular.bcefbfee882bc1cb.woff) format("woff");font-weight:400;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-RegularItalic.e3a9ebdaac06bbc4.woff2) format("woff2"),url(Roboto-RegularItalic.0668fae6af0cf8c2.woff) format("woff");font-weight:400;font-style:italic}@font-face{font-family:Roboto;src:url(Roboto-Medium.457532032ceb0168.woff2) format("woff2"),url(Roboto-Medium.6e1ae5f0b324a0aa.woff) format("woff");font-weight:500;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-MediumItalic.872f7060602d55d2.woff2) format("woff2"),url(Roboto-MediumItalic.e06fb533801cbb08.woff) format("woff");font-weight:500;font-style:italic}@font-face{font-family:Roboto;src:url(Roboto-Bold.447291a88c067396.woff2) format("woff2"),url(Roboto-Bold.fc482e6133cf5e26.woff) format("woff");font-weight:700;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-BoldItalic.1b15168ef6fa4e16.woff2) format("woff2"),url(Roboto-BoldItalic.e26ba339b06f09f7.woff) format("woff");font-weight:700;font-style:italic}@font-face{font-family:Roboto;src:url(Roboto-Black.2eaa390d458c877d.woff2) format("woff2"),url(Roboto-Black.b25f67ad8583da68.woff) format("woff");font-weight:900;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-BlackItalic.7dc03ee444552bc5.woff2) format("woff2"),url(Roboto-BlackItalic.c8dc642467cb3099.woff) format("woff");font-weight:900;font-style:italic}html{width:100%;height:99%;line-height:1.5;overflow-x:hidden;font-family:Roboto,sans-serif!important;font-size:62.5%}body{box-sizing:border-box;height:100%;margin:0;overflow:hidden}*{margin:0;padding:0}</style><link rel="stylesheet" href="styles.43515fc39338348b.css" media="print" onload="this.media='all'"><noscript><link rel="stylesheet" href="styles.43515fc39338348b.css"></noscript></head>
<body>
<rtl-app></rtl-app>
<script src="runtime.ba63f492df66fb3f.js" type="module"></script><script src="polyfills.eddc63f1737a019a.js" type="module"></script><script src="main.5538e49fa64c4bc4.js" type="module"></script>
<script src="runtime.ba63f492df66fb3f.js" type="module"></script><script src="polyfills.eddc63f1737a019a.js" type="module"></script><script src="main.970fbb2f9e86b4d8.js" type="module"></script>
</body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -13,7 +13,7 @@
"buildbackend": "tsc --project tsconfig.json",
"watchbackend": "tsc --project tsconfig.json --watch",
"server": "set NODE_ENV=development&&nodemon ./rtl.js",
"serverUbuntu": "NODE_ENV=development nodemon ./rtl.js",
"serverUbuntu": "NODE_ENV=development nodemon --watch backend --watch server ./rtl.js",
"testdev": "ng test --watch=true --code-coverage",
"test": "ng test --watch=false",
"lint": "ng lint",

View File

@ -57,10 +57,10 @@ export class RTLWebSocketServer {
public mountEventsOnConnection = (websocket, request) => {
const protocols = !request.headers['sec-websocket-protocol'] ? [] : request.headers['sec-websocket-protocol'].split(',')?.map((s) => s.trim());
const cookies = parse(request.headers.cookie);
const cookies = request.headers.cookie ? parse(request.headers.cookie) : null;
websocket.clientId = Date.now();
websocket.isAlive = true;
websocket.sessionId = cookieParser.signedCookie(cookies['connect.sid'], this.common.secret_key);
websocket.sessionId = cookies && cookies['connect.sid'] ? cookieParser.signedCookie(cookies['connect.sid'], this.common.secret_key) : null;
websocket.clientNodeIndex = +protocols[1];
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Connected: ' + websocket.clientId + ', Total WS clients: ' + this.webSocketServer.clients.size });
websocket.on('error', this.sendErrorToAllLNClients);

View File

@ -733,7 +733,7 @@ export class CLNEffects implements OnDestroy {
}
}
}));
}, 100);
}, 200);
return {
type: CLNActions.ADD_INVOICE_CLN,
payload: postRes

View File

@ -52,7 +52,8 @@ export class CLNInvoiceInformationComponent implements OnInit, OnDestroy {
subscribe((invoicesSelector: { listInvoices: ListInvoices, apiCallStatus: ApiCallStatusPayload }) => {
const invoiceStatus = this.invoice.status;
const invoices = invoicesSelector.listInvoices.invoices || [];
this.invoice = invoices?.find((invoice) => invoice.payment_hash === this.invoice.payment_hash)!;
const foundInvoice = invoices?.find((invoice) => invoice.payment_hash === this.invoice.payment_hash) || null;
if (foundInvoice) { this.invoice = foundInvoice; }
if (invoiceStatus !== this.invoice.status && this.invoice.status === 'paid') {
this.flgInvoicePaid = true;
setTimeout(() => { this.flgInvoicePaid = false; }, 4000);

View File

@ -551,7 +551,7 @@ export class ECLEffects implements OnDestroy {
}
}
}));
}, 100);
}, 200);
return {
type: ECLActions.ADD_INVOICE_ECL,
payload: postRes

View File

@ -51,7 +51,8 @@ export class ECLInvoiceInformationComponent implements OnInit, OnDestroy {
subscribe((invoicesSelector: { invoices: Invoice[], apiCallStatus: ApiCallStatusPayload }) => {
const invoiceStatus = this.invoice.status;
const invoices = (invoicesSelector.invoices && invoicesSelector.invoices.length > 0) ? invoicesSelector.invoices : [];
this.invoice = invoices?.find((invoice) => invoice.paymentHash === this.invoice.paymentHash) || {};
const foundInvoice = invoices?.find((invoice) => invoice.paymentHash === this.invoice.paymentHash) || null;
if (foundInvoice) { this.invoice = foundInvoice; }
if (invoiceStatus !== this.invoice.status && this.invoice.status === 'received') {
this.flgInvoicePaid = true;
setTimeout(() => { this.flgInvoicePaid = false; }, 4000);

View File

@ -250,7 +250,7 @@ export class LNDEffects implements OnDestroy {
}
}
}));
}, 100);
}, 200);
return {
type: RTLActions.CLOSE_SPINNER,
payload: action.payload.uiMessage

View File

@ -18,7 +18,7 @@
<span *ngIf="!invoice?.payment_request || invoice?.payment_request === ''" class="font-size-120">QR Code Not Applicable</span>
</div>
<mat-divider *ngIf="screenSize === screenSizeEnum.XS || screenSize === screenSizeEnum.SM" [inset]="true" class="my-1"></mat-divider>
<div [perfectScrollbar] [ngClass]="{'h-50': invoice?.htlcs && invoice?.htlcs.length > 0 && showAdvanced}" #scrollContainer>
<div [ngClass]="{'h-50': invoice?.htlcs && invoice?.htlcs.length > 0 && showAdvanced}" #scrollContainer>
<div fxLayout="row">
<div fxFlex="50">
<h4 fxLayoutAlign="start" class="font-bold-500">{{screenSize === screenSizeEnum.XS ? 'Amount' : 'Amount Requested'}}</h4>
@ -76,58 +76,7 @@
</div>
</div>
<div *ngIf="showAdvanced">
<mat-divider [inset]="true" class="my-1"></mat-divider>
<div fxLayout="row">
<div fxFlex="100">
<h4 fxLayoutAlign="start" class="font-bold-500">Preimage</h4>
<span class="overflow-wrap foreground-secondary-text">{{invoice?.r_preimage || '-'}}</span>
</div>
</div>
<mat-divider [inset]="true" class="my-1"></mat-divider>
<div fxLayout="row">
<div fxFlex="34">
<h4 fxLayoutAlign="start" class="font-bold-500">State</h4>
<span class="overflow-wrap foreground-secondary-text">{{invoice?.state}}</span>
</div>
<div fxFlex="33">
<h4 fxLayoutAlign="start" class="font-bold-500">Expiry</h4>
<span class="overflow-wrap foreground-secondary-text">{{invoice?.expiry}}</span>
</div>
<div fxFlex="33">
<h4 fxLayoutAlign="start" class="font-bold-500">Private Routing Hints</h4>
<span class="overflow-wrap foreground-secondary-text">{{invoice?.private ? 'Yes' : 'No'}}</span>
</div>
</div>
<mat-divider [inset]="true" class="my-1"></mat-divider>
<div fxLayout="row" *ngIf="invoice?.htlcs && invoice?.htlcs.length > 0">
<mat-expansion-panel (opened)="flgOpened = true" (closed)="onExpansionClosed()" class="flat-expansion-panel" fxLayout="column" fxLayoutAlign="start stretch" fxFlex="100">
<mat-expansion-panel-header>
<mat-panel-title>
<h4 fxLayoutAlign="start center" fxFlex="100" class="font-bold-500">HTLCs</h4>
</mat-panel-title>
</mat-expansion-panel-header>
<div fxLayout="column" fxLayoutAlign="start stretch" fxFlex="100">
<div fxLayout="row" fxLayoutAlign="start start" fxFlex="100" class="mt-minus-1">
<span fxFlex="60" class="foreground-secondary-text font-bold-500">Channel ID</span>
<span fxFlex="40" class="foreground-secondary-text font-bold-500">Amount (Sats)</span>
</div>
<mat-divider [inset]="true" class="my-1"></mat-divider>
<div fxLayout="column" fxLayoutAlign="start stretch" fxFlex="100" *ngFor="let htlc of invoice?.htlcs">
<div fxLayout="row" fxLayoutAlign="start start" fxFlex="100">
<span fxFlex="60" class="foreground-secondary-text">
<span *ngIf="htlc.state === 'SETTLED'" class="dot green" matTooltip="Settled" matTooltipPosition="right" [ngClass]="{'mr-0': screenSize === screenSizeEnum.XS}"></span>
<span *ngIf="htlc.state === 'ACCEPTED'" class="dot yellow" matTooltip="Accepted" matTooltipPosition="right" [ngClass]="{'mr-0': screenSize === screenSizeEnum.XS}"></span>
<span *ngIf="htlc.state === 'CANCELED'" class="dot red" matTooltip="Cancelled" matTooltipPosition="right" [ngClass]="{'mr-0': screenSize === screenSizeEnum.XS}"></span>
{{htlc.chan_id}}
</span>
<span fxFlex="40" class="foreground-secondary-text">{{((+htlc.amt_msat/1000) || 0) | number:getDecimalFormat(htlc)}}</span>
</div>
<mat-divider [inset]="true" class="my-1"></mat-divider>
</div>
</div>
</mat-expansion-panel>
</div>
<mat-divider [inset]="true" class="my-1" *ngIf="invoice?.htlcs && invoice?.htlcs.length > 0"></mat-divider>
<ng-container *ngTemplateOutlet="advancedBlock"></ng-container>
</div>
</div>
</div>
@ -147,3 +96,57 @@
</div>
</div>
</div>
<ng-template #advancedBlock>
<mat-divider [inset]="true" class="my-1"></mat-divider>
<div fxLayout="row">
<div fxFlex="100">
<h4 fxLayoutAlign="start" class="font-bold-500">Preimage</h4>
<span class="overflow-wrap foreground-secondary-text">{{invoice?.r_preimage || '-'}}</span>
</div>
</div>
<mat-divider [inset]="true" class="my-1"></mat-divider>
<div fxLayout="row">
<div fxFlex="34">
<h4 fxLayoutAlign="start" class="font-bold-500">State</h4>
<span class="overflow-wrap foreground-secondary-text">{{invoice?.state}}</span>
</div>
<div fxFlex="33">
<h4 fxLayoutAlign="start" class="font-bold-500">Expiry</h4>
<span class="overflow-wrap foreground-secondary-text">{{invoice?.expiry}}</span>
</div>
<div fxFlex="33">
<h4 fxLayoutAlign="start" class="font-bold-500">Private Routing Hints</h4>
<span class="overflow-wrap foreground-secondary-text">{{invoice?.private ? 'Yes' : 'No'}}</span>
</div>
</div>
<mat-divider [inset]="true" class="my-1"></mat-divider>
<div fxLayout="row" *ngIf="invoice?.htlcs && invoice?.htlcs.length > 0">
<mat-expansion-panel (opened)="flgOpened = true" (closed)="onExpansionClosed()" class="flat-expansion-panel" fxLayout="column" fxLayoutAlign="start stretch" fxFlex="100">
<mat-expansion-panel-header>
<mat-panel-title>
<h4 fxLayoutAlign="start center" fxFlex="100" class="font-bold-500">HTLCs</h4>
</mat-panel-title>
</mat-expansion-panel-header>
<div fxLayout="column" fxLayoutAlign="start stretch" fxFlex="100">
<div fxLayout="row" fxLayoutAlign="start start" fxFlex="100" class="mt-minus-1">
<span fxFlex="60" class="foreground-secondary-text font-bold-500">Channel ID</span>
<span fxFlex="40" class="foreground-secondary-text font-bold-500">Amount (Sats)</span>
</div>
<mat-divider [inset]="true" class="my-1"></mat-divider>
<div fxLayout="column" fxLayoutAlign="start stretch" fxFlex="100" *ngFor="let htlc of invoice?.htlcs">
<div fxLayout="row" fxLayoutAlign="start start" fxFlex="100">
<span fxFlex="60" class="foreground-secondary-text">
<span *ngIf="htlc.state === 'SETTLED'" class="dot green" matTooltip="Settled" matTooltipPosition="right" [ngClass]="{'mr-0': screenSize === screenSizeEnum.XS}"></span>
<span *ngIf="htlc.state === 'ACCEPTED'" class="dot yellow" matTooltip="Accepted" matTooltipPosition="right" [ngClass]="{'mr-0': screenSize === screenSizeEnum.XS}"></span>
<span *ngIf="htlc.state === 'CANCELED'" class="dot red" matTooltip="Cancelled" matTooltipPosition="right" [ngClass]="{'mr-0': screenSize === screenSizeEnum.XS}"></span>
{{htlc.chan_id}}
</span>
<span fxFlex="40" class="foreground-secondary-text">{{((+htlc.amt_msat/1000) || 0) | number:getDecimalFormat(htlc)}}</span>
</div>
<mat-divider [inset]="true" class="my-1"></mat-divider>
</div>
</div>
</mat-expansion-panel>
</div>
<mat-divider [inset]="true" class="my-1" *ngIf="invoice?.htlcs && invoice?.htlcs.length > 0"></mat-divider>
</ng-template>

View File

@ -59,7 +59,7 @@ export class InvoiceInformationComponent implements OnInit, OnDestroy {
const invoiceStatus = this.invoice?.state;
const invoices = invoicesSelector.listInvoices.invoices || [];
const foundInvoice = invoices.find((invoice) => invoice.r_hash === invoiceToCompare.r_hash) || null;
this.invoice = foundInvoice;
if (foundInvoice) { this.invoice = foundInvoice; }
if (invoiceStatus !== this.invoice?.state && this.invoice?.state === 'SETTLED') {
this.flgInvoicePaid = true;
setTimeout(() => { this.flgInvoicePaid = false; }, 4000);

View File

@ -2,6 +2,8 @@ import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { StoreModule } from '@ngrx/store';
import { RTLEffects } from '../../../store/rtl.effects';
import { mockRTLEffects } from '../../../shared/test-helpers/mock-services';
import { RootReducer } from '../../../store/rtl.reducers';
import { LNDReducer } from '../../../lnd/store/lnd.reducers';
import { CLNReducer } from '../../../cln/store/cln.reducers';
@ -20,6 +22,9 @@ describe('NodeConfigComponent', () => {
SharedModule,
RouterTestingModule,
StoreModule.forRoot({ root: RootReducer, lnd: LNDReducer, cln: CLNReducer, ecl: ECLReducer })
],
providers: [
{ provide: RTLEffects, useClass: mockRTLEffects }
]
}).
compileComponents();