Merge pull request #99 from mempool/fees-box
Adding fee estimation component to front page
This commit is contained in:
		
						commit
						51bed8e852
					
				@ -40,6 +40,7 @@ import { StatusViewComponent } from './components/status-view/status-view.compon
 | 
				
			|||||||
import { MinerComponent } from './components/miner/miner.component';
 | 
					import { MinerComponent } from './components/miner/miner.component';
 | 
				
			||||||
import { SharedModule } from './shared/shared.module';
 | 
					import { SharedModule } from './shared/shared.module';
 | 
				
			||||||
import { NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap';
 | 
					import { NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap';
 | 
				
			||||||
 | 
					import { FeesBoxComponent } from './components/fees-box/fees-box.component';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@NgModule({
 | 
					@NgModule({
 | 
				
			||||||
  declarations: [
 | 
					  declarations: [
 | 
				
			||||||
@ -70,6 +71,7 @@ import { NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap';
 | 
				
			|||||||
    AssetsComponent,
 | 
					    AssetsComponent,
 | 
				
			||||||
    MinerComponent,
 | 
					    MinerComponent,
 | 
				
			||||||
    StatusViewComponent,
 | 
					    StatusViewComponent,
 | 
				
			||||||
 | 
					    FeesBoxComponent,
 | 
				
			||||||
  ],
 | 
					  ],
 | 
				
			||||||
  imports: [
 | 
					  imports: [
 | 
				
			||||||
    BrowserModule,
 | 
					    BrowserModule,
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										19
									
								
								frontend/src/app/components/fees-box/fees-box.component.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								frontend/src/app/components/fees-box/fees-box.component.html
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					<table class="table mx-auto text-center" style="max-width: 550px">
 | 
				
			||||||
 | 
					  <tr>
 | 
				
			||||||
 | 
					    <td class="d-none d-md-table-cell border-top-0">1 hour</td>
 | 
				
			||||||
 | 
					    <td class="border-top-0">30 minutes</td>
 | 
				
			||||||
 | 
					    <td class="border-top-0">Next block</td>
 | 
				
			||||||
 | 
					  </tr>
 | 
				
			||||||
 | 
					  <tr *ngIf="(feeEstimations$ | async) as feeEstimations; else loadingFees">
 | 
				
			||||||
 | 
					    <td class="d-none d-md-table-cell">{{ feeEstimations.hourFee }} sat/vB (<app-fiat [value]="feeEstimations.hourFee * 250"></app-fiat>)</td>
 | 
				
			||||||
 | 
					    <td>{{ feeEstimations.halfHourFee }} sat/vB (<app-fiat [value]="feeEstimations.halfHourFee * 250"></app-fiat>)</td>
 | 
				
			||||||
 | 
					    <td>{{ feeEstimations.fastestFee }} sat/vB (<app-fiat [value]="feeEstimations.fastestFee * 250"></app-fiat>)</td>
 | 
				
			||||||
 | 
					  </tr>
 | 
				
			||||||
 | 
					  <ng-template #loadingFees>
 | 
				
			||||||
 | 
					    <tr>
 | 
				
			||||||
 | 
					      <td class="d-none d-md-table-cell"><span class="skeleton-loader"></span></td>
 | 
				
			||||||
 | 
					      <td><span class="skeleton-loader"></span></td>
 | 
				
			||||||
 | 
					      <td><span class="skeleton-loader"></span></td>
 | 
				
			||||||
 | 
					    </tr>
 | 
				
			||||||
 | 
					  </ng-template>
 | 
				
			||||||
 | 
					</table>
 | 
				
			||||||
@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					td {
 | 
				
			||||||
 | 
					  width: 33%;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@media (max-width: 767.98px) {
 | 
				
			||||||
 | 
					  td {
 | 
				
			||||||
 | 
					    width: 50%;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										48
									
								
								frontend/src/app/components/fees-box/fees-box.component.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								frontend/src/app/components/fees-box/fees-box.component.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,48 @@
 | 
				
			|||||||
 | 
					import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core';
 | 
				
			||||||
 | 
					import { StateService } from 'src/app/services/state.service';
 | 
				
			||||||
 | 
					import { map, filter } from 'rxjs/operators';
 | 
				
			||||||
 | 
					import { Observable } from 'rxjs';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface FeeEstimations {
 | 
				
			||||||
 | 
					  fastestFee: number;
 | 
				
			||||||
 | 
					  halfHourFee: number;
 | 
				
			||||||
 | 
					  hourFee: number;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@Component({
 | 
				
			||||||
 | 
					  selector: 'app-fees-box',
 | 
				
			||||||
 | 
					  templateUrl: './fees-box.component.html',
 | 
				
			||||||
 | 
					  styleUrls: ['./fees-box.component.scss'],
 | 
				
			||||||
 | 
					  changeDetection: ChangeDetectionStrategy.OnPush,
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					export class FeesBoxComponent implements OnInit {
 | 
				
			||||||
 | 
					  feeEstimations$: Observable<FeeEstimations>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  constructor(
 | 
				
			||||||
 | 
					    private stateService: StateService,
 | 
				
			||||||
 | 
					  ) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ngOnInit(): void {
 | 
				
			||||||
 | 
					    this.feeEstimations$ = this.stateService.mempoolBlocks$
 | 
				
			||||||
 | 
					      .pipe(
 | 
				
			||||||
 | 
					        filter((blocks) => !!blocks.length),
 | 
				
			||||||
 | 
					        map((pBlocks) => {
 | 
				
			||||||
 | 
					          let firstMedianFee = Math.ceil(pBlocks[0].medianFee);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          if (pBlocks.length === 1 && pBlocks[0].blockVSize <= 500000) {
 | 
				
			||||||
 | 
					            firstMedianFee = 1;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          const secondMedianFee = pBlocks[1] ? Math.ceil(pBlocks[1].medianFee) : firstMedianFee;
 | 
				
			||||||
 | 
					          const thirdMedianFee = pBlocks[2] ? Math.ceil(pBlocks[2].medianFee) : secondMedianFee;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          return {
 | 
				
			||||||
 | 
					            'fastestFee': firstMedianFee,
 | 
				
			||||||
 | 
					            'halfHourFee': secondMedianFee,
 | 
				
			||||||
 | 
					            'hourFee': thirdMedianFee,
 | 
				
			||||||
 | 
					          };
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,5 +1,6 @@
 | 
				
			|||||||
<div class="container-xl">
 | 
					<app-fees-box class="d-block m-2 mb-4"></app-fees-box>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="container-xl">
 | 
				
			||||||
<hr>
 | 
					<hr>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<table class="table table-borderless" [alwaysCallback]="true" [fromRoot]="true" [infiniteScrollContainer]="'body'" infiniteScroll [infiniteScrollDistance]="1.5" [infiniteScrollUpDistance]="1.5" [infiniteScrollThrottle]="50" (scrolled)="loadMore()">
 | 
					<table class="table table-borderless" [alwaysCallback]="true" [fromRoot]="true" [infiniteScrollContainer]="'body'" infiniteScroll [infiniteScrollDistance]="1.5" [infiniteScrollUpDistance]="1.5" [infiniteScrollThrottle]="50" (scrolled)="loadMore()">
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user