Merge pull request #5267 from mempool/mononaut/fix-ln-invoice-flicker
fix ln invoice flicker
This commit is contained in:
		
						commit
						69cd054a97
					
				@ -373,7 +373,7 @@
 | 
			
		||||
              <div class="col-sm text-center d-flex flex-column justify-content-center align-items-center">
 | 
			
		||||
                @if (invoice) {
 | 
			
		||||
                  <p><ng-container i18n="transaction.pay|Pay button label">Pay</ng-container> <span><small style="font-family: monospace;">{{ ((invoice.btcDue * 100_000_000) || cost) | number }}</small> <span class="symbol" i18n="shared.sats">sats</span></span></p>
 | 
			
		||||
                  <app-bitcoin-invoice style="width: 100%;" [invoiceId]="invoice.btcpayInvoiceId" [minimal]="true" (completed)="bitcoinPaymentCompleted()"></app-bitcoin-invoice>
 | 
			
		||||
                  <app-bitcoin-invoice style="width: 100%;" [invoice]="invoice" [minimal]="true" (completed)="bitcoinPaymentCompleted()"></app-bitcoin-invoice>
 | 
			
		||||
                } @else {
 | 
			
		||||
                  <p i18n="accelerator.loading-invoice">Loading invoice...</p>
 | 
			
		||||
                  <div class="d-flex align-items-center justify-content-center" style="width: 100%; height: 292px;">
 | 
			
		||||
 | 
			
		||||
@ -6,7 +6,7 @@
 | 
			
		||||
    </span>
 | 
			
		||||
 | 
			
		||||
    <span *ngIf="paymentStatus === 4" class="valid-feedback d-block mt-5">
 | 
			
		||||
      A transaction <a [href]="'/tx/' + loadedInvoice.cryptoInfo[0].payments[0].id.split('-')[0]">has been detected in the mempool</a> fully paying for this invoice. Waiting for on-chain confirmation.
 | 
			
		||||
      A transaction <a [href]="'/tx/' + invoice.cryptoInfo[0].payments[0].id.split('-')[0]">has been detected in the mempool</a> fully paying for this invoice. Waiting for on-chain confirmation.
 | 
			
		||||
    </span>
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -16,13 +16,13 @@
 | 
			
		||||
 | 
			
		||||
      <div *ngIf="availableMethods.length > 1" class="form-group">
 | 
			
		||||
        <div class="btn-group btn-group-toggle" data-toggle="buttons">
 | 
			
		||||
          <!-- <label *ngIf="loadedInvoice.addresses.BTC" class="btn btn-primary" [ngClass]="{'active': paymentForm.get('method')?.value === 'chain'}">
 | 
			
		||||
          <!-- <label *ngIf="invoice.addresses.BTC" class="btn btn-primary" [ngClass]="{'active': paymentForm.get('method')?.value === 'chain'}">
 | 
			
		||||
            <input type="radio" value="chain" formControlName="method"> <fa-icon [icon]="['fas', 'link']" [fixedWidth]="true" title="Onchain"></fa-icon>
 | 
			
		||||
          </label> -->
 | 
			
		||||
          <label *ngIf="loadedInvoice.addresses.BTC_LightningLike" class="btn btn-primary" [ngClass]="{'active': paymentForm.get('method')?.value === 'lightning'}">
 | 
			
		||||
          <label *ngIf="invoice.addresses.BTC_LightningLike" class="btn btn-primary" [ngClass]="{'active': paymentForm.get('method')?.value === 'lightning'}">
 | 
			
		||||
            <input type="radio" value="lightning" formControlName="method"> <fa-icon [icon]="['fas', 'bolt']" [fixedWidth]="true" title="Lightning"></fa-icon>
 | 
			
		||||
          </label>
 | 
			
		||||
          <!-- <label *ngIf="loadedInvoice.addresses.LBTC" class="btn btn-primary" [ngClass]="{'active': paymentForm.get('method')?.value === 'lbtc'}">
 | 
			
		||||
          <!-- <label *ngIf="invoice.addresses.LBTC" class="btn btn-primary" [ngClass]="{'active': paymentForm.get('method')?.value === 'lbtc'}">
 | 
			
		||||
            <input type="radio" value="lbtc" formControlName="method"> <fa-icon [icon]="['fas', 'tint']" [fixedWidth]="true" title="Liquid Bitcoin"></fa-icon>
 | 
			
		||||
          </label> -->
 | 
			
		||||
        </div>
 | 
			
		||||
@ -30,63 +30,63 @@
 | 
			
		||||
 | 
			
		||||
    </form>
 | 
			
		||||
 | 
			
		||||
    <ng-template [ngIf]="paymentForm.get('method')?.value === 'chain' && loadedInvoice">
 | 
			
		||||
    <ng-template [ngIf]="paymentForm.get('method')?.value === 'chain' && invoice">
 | 
			
		||||
 | 
			
		||||
        <div class="qr-wrapper" [class.mt-0]="minimal">
 | 
			
		||||
          <a [href]="bypassSecurityTrustUrl('bitcoin:' + loadedInvoice.addresses.BTC + '?amount=' + loadedInvoice.btcDue)" target="_blank">
 | 
			
		||||
              <app-qrcode imageUrl="/resources/bitcoin-logo.png" [size]="200" [data]="'bitcoin:' + loadedInvoice.addresses.BTC + '?amount=' + loadedInvoice.btcDue"></app-qrcode>
 | 
			
		||||
          <a [href]="bypassSecurityTrustUrl('bitcoin:' + invoice.addresses.BTC + '?amount=' + invoice.btcDue)" target="_blank">
 | 
			
		||||
              <app-qrcode imageUrl="/resources/bitcoin-logo.png" [size]="200" [data]="'bitcoin:' + invoice.addresses.BTC + '?amount=' + invoice.btcDue"></app-qrcode>
 | 
			
		||||
          </a>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div class="input-group input-group-sm info-group">
 | 
			
		||||
          <input type="text" class="form-control input-dark" readonly [value]="loadedInvoice.addresses.BTC">
 | 
			
		||||
          <input type="text" class="form-control input-dark" readonly [value]="invoice.addresses.BTC">
 | 
			
		||||
          <div class="input-group-append">
 | 
			
		||||
              <button class="btn btn-outline-secondary" type="button" ><app-clipboard [text]="loadedInvoice.addresses.BTC"></app-clipboard></button>
 | 
			
		||||
              <button class="btn btn-outline-secondary" type="button" ><app-clipboard [text]="invoice.addresses.BTC"></app-clipboard></button>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        @if (!minimal) {
 | 
			
		||||
          <p>{{ loadedInvoice.btcDue | number: '1.0-8' }} <span class="symbol">BTC</span></p>
 | 
			
		||||
          <p>{{ invoice.btcDue | number: '1.0-8' }} <span class="symbol">BTC</span></p>
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    </ng-template>
 | 
			
		||||
 | 
			
		||||
    <ng-template [ngIf]="paymentForm.get('method')?.value === 'lightning' && loadedInvoice && loadedInvoice.addresses.BTC_LightningLike">
 | 
			
		||||
    <ng-template [ngIf]="paymentForm.get('method')?.value === 'lightning' && invoice && invoice.addresses.BTC_LightningLike">
 | 
			
		||||
 | 
			
		||||
        <div class="qr-wrapper" [class.mt-0]="minimal">
 | 
			
		||||
          <a [href]="bypassSecurityTrustUrl('lightning:' + loadedInvoice.addresses.BTC_LightningLike)" target="_blank">
 | 
			
		||||
              <app-qrcode imageUrl="/resources/lightning-logo.png" [size]="200" [data]="loadedInvoice.addresses.BTC_LightningLike.toUpperCase()"></app-qrcode>
 | 
			
		||||
          <a [href]="bypassSecurityTrustUrl('lightning:' + invoice.addresses.BTC_LightningLike)" target="_blank">
 | 
			
		||||
              <app-qrcode imageUrl="/resources/lightning-logo.png" [size]="200" [data]="invoice.addresses.BTC_LightningLike.toUpperCase()"></app-qrcode>
 | 
			
		||||
          </a>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div class="input-group input-group-sm info-group">
 | 
			
		||||
          <input type="text" class="form-control input-dark" readonly [value]="loadedInvoice.addresses.BTC_LightningLike">
 | 
			
		||||
          <input type="text" class="form-control input-dark" readonly [value]="invoice.addresses.BTC_LightningLike">
 | 
			
		||||
          <div class="input-group-append">
 | 
			
		||||
              <button class="btn btn-outline-secondary" type="button"><app-clipboard [text]="loadedInvoice.addresses.BTC_LightningLike"></app-clipboard></button>
 | 
			
		||||
              <button class="btn btn-outline-secondary" type="button"><app-clipboard [text]="invoice.addresses.BTC_LightningLike"></app-clipboard></button>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        @if (!minimal) {
 | 
			
		||||
          <p>{{ loadedInvoice.btcDue * 100_000_000 | number: '1.0-0' }} <span class="symbol">sats</span></p>
 | 
			
		||||
          <p>{{ invoice.btcDue * 100_000_000 | number: '1.0-0' }} <span class="symbol">sats</span></p>
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    </ng-template>
 | 
			
		||||
 | 
			
		||||
    <ng-template [ngIf]="loadedInvoice && (paymentForm.get('method')?.value === 'lbtc' || paymentForm.get('method')?.value === 'tlbtc')">
 | 
			
		||||
    <ng-template [ngIf]="invoice && (paymentForm.get('method')?.value === 'lbtc' || paymentForm.get('method')?.value === 'tlbtc')">
 | 
			
		||||
 | 
			
		||||
        <div class="qr-wrapper" [class.mt-0]="minimal">
 | 
			
		||||
          <a [href]="bypassSecurityTrustUrl('liquidnetwork:' + loadedInvoice.addresses.LBTC + '?amount=' + loadedInvoice.btcDue + '&assetid=6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d')" target="_blank">
 | 
			
		||||
              <app-qrcode imageUrl="/resources/liquid-bitcoin.png" [size]="200" [data]="'liquidnetwork:' + loadedInvoice.addresses.LBTC + '?amount=' + loadedInvoice.btcDue + '&assetid=6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d'"></app-qrcode>
 | 
			
		||||
          <a [href]="bypassSecurityTrustUrl('liquidnetwork:' + invoice.addresses.LBTC + '?amount=' + invoice.btcDue + '&assetid=6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d')" target="_blank">
 | 
			
		||||
              <app-qrcode imageUrl="/resources/liquid-bitcoin.png" [size]="200" [data]="'liquidnetwork:' + invoice.addresses.LBTC + '?amount=' + invoice.btcDue + '&assetid=6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d'"></app-qrcode>
 | 
			
		||||
          </a>
 | 
			
		||||
        </div>
 | 
			
		||||
        <br>
 | 
			
		||||
        <div class="input-group input-group-sm info-group">
 | 
			
		||||
          <input type="text" class="form-control input-dark" readonly [value]="loadedInvoice.addresses.LBTC" />
 | 
			
		||||
          <input type="text" class="form-control input-dark" readonly [value]="invoice.addresses.LBTC" />
 | 
			
		||||
          <div class="input-group-append">
 | 
			
		||||
              <button class="btn btn-outline-secondary" type="button" ><app-clipboard [text]="loadedInvoice.addresses.LBTC"></app-clipboard></button>
 | 
			
		||||
              <button class="btn btn-outline-secondary" type="button" ><app-clipboard [text]="invoice.addresses.LBTC"></app-clipboard></button>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        @if (!minimal) {
 | 
			
		||||
          <p>{{ loadedInvoice.btcDue | number: '1.0-8' }} <span class="symbol">BTC</span></p>
 | 
			
		||||
          <p>{{ invoice.btcDue | number: '1.0-8' }} <span class="symbol">BTC</span></p>
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    </ng-template>
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,6 @@ import { ServicesApiServices } from '../../services/services-api.service';
 | 
			
		||||
})
 | 
			
		||||
export class BitcoinInvoiceComponent implements OnInit, OnChanges, OnDestroy {
 | 
			
		||||
  @Input() invoice;
 | 
			
		||||
  @Input() invoiceId: string;
 | 
			
		||||
  @Input() redirect = true;
 | 
			
		||||
  @Input() minimal = false;
 | 
			
		||||
  @Output() completed = new EventEmitter();
 | 
			
		||||
@ -21,7 +20,6 @@ export class BitcoinInvoiceComponent implements OnInit, OnChanges, OnDestroy {
 | 
			
		||||
  paymentForm: FormGroup;
 | 
			
		||||
  requestSubscription: Subscription | undefined;
 | 
			
		||||
  paymentStatusSubscription: Subscription | undefined;
 | 
			
		||||
  loadedInvoice: any;
 | 
			
		||||
  paymentStatus = 1; // 1 - Waiting for invoice | 2 - Pending payment | 3 - Payment completed
 | 
			
		||||
  paramMapSubscription: Subscription | undefined;
 | 
			
		||||
  invoiceSubscription: Subscription | undefined;
 | 
			
		||||
@ -53,55 +51,37 @@ export class BitcoinInvoiceComponent implements OnInit, OnChanges, OnDestroy {
 | 
			
		||||
    this.paymentForm = this.formBuilder.group({
 | 
			
		||||
      'method': 'lightning'
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * If the invoice is passed in the url, fetch it and display btcpay payment
 | 
			
		||||
     * Otherwise get a new invoice
 | 
			
		||||
     */
 | 
			
		||||
    this.paramMapSubscription = this.activatedRoute.paramMap
 | 
			
		||||
      .pipe(
 | 
			
		||||
        tap((paramMap) => {
 | 
			
		||||
          this.fetchInvoice(paramMap.get('invoiceId') ?? this.invoiceId);
 | 
			
		||||
        })
 | 
			
		||||
      ).subscribe();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ngOnChanges(changes: SimpleChanges): void {
 | 
			
		||||
    if ((changes.invoice || changes.invoiceId) && this.invoiceId) {
 | 
			
		||||
      this.fetchInvoice(this.invoiceId);
 | 
			
		||||
    if (changes.invoice) {
 | 
			
		||||
      this.watchInvoice();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  fetchInvoice(invoiceId: string): void {
 | 
			
		||||
    if (invoiceId) {
 | 
			
		||||
  watchInvoice(): void {
 | 
			
		||||
    if (this.paymentStatusSubscription) {
 | 
			
		||||
      this.paymentStatusSubscription.unsubscribe();
 | 
			
		||||
    }
 | 
			
		||||
      this.paymentStatusSubscription = ((this.invoice && this.invoice.id === invoiceId) ? of(this.invoice) : this.apiService.retreiveInvoice$(invoiceId)).pipe(
 | 
			
		||||
        tap((invoice: any) => {
 | 
			
		||||
          this.loadedInvoice = invoice;
 | 
			
		||||
          if (this.loadedInvoice.btcDue > 0) {
 | 
			
		||||
    if (!this.invoice) {
 | 
			
		||||
      this.paymentStatus = 1;
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    if (this.invoice.btcDue > 0) {
 | 
			
		||||
      this.paymentStatus = 2;
 | 
			
		||||
    } else {
 | 
			
		||||
      this.paymentStatus = 4;
 | 
			
		||||
    }
 | 
			
		||||
        }),
 | 
			
		||||
        switchMap(() => this.apiService.getPaymentStatus$(this.loadedInvoice.id)
 | 
			
		||||
          .pipe(
 | 
			
		||||
    this.paymentStatusSubscription = this.apiService.getPaymentStatus$(this.invoice.btcpayInvoiceId).pipe(
 | 
			
		||||
      retry({ delay: () => timer(2000)})
 | 
			
		||||
          )
 | 
			
		||||
        ),
 | 
			
		||||
      ).subscribe({
 | 
			
		||||
        next: ((result) => {
 | 
			
		||||
    ).subscribe((result) => {
 | 
			
		||||
      this.paymentStatus = 3;
 | 
			
		||||
      this.completed.emit();
 | 
			
		||||
        }),
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  get availableMethods(): string[] {
 | 
			
		||||
    return Object.keys(this.loadedInvoice?.addresses || {}).filter(k => k === 'BTC_LightningLike');
 | 
			
		||||
    return Object.keys(this.invoice?.addresses || {}).filter(k => k === 'BTC_LightningLike');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bypassSecurityTrustUrl(text: string): SafeUrl {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user