Merge pull request #5333 from mempool/natsoni/timeline-updates
Acceleration timeline refactor
This commit is contained in:
		
						commit
						74e59d6ea5
					
				@ -1,6 +1,38 @@
 | 
			
		||||
@if (tx.status.confirmed) {
 | 
			
		||||
<div class="acceleration-timeline box">
 | 
			
		||||
<div class="acceleration-timeline box" [class.lower-padding]="!tx.status.confirmed">
 | 
			
		||||
  <div class="timeline-wrapper">
 | 
			
		||||
    @if (!tx.status.confirmed) {
 | 
			
		||||
    <div class="timeline">
 | 
			
		||||
      <div class="intervals">
 | 
			
		||||
        <div class="node-spacer"></div>
 | 
			
		||||
        <div class="interval-spacer"></div>
 | 
			
		||||
        <div class="node-spacer"></div>
 | 
			
		||||
        <div class="interval">
 | 
			
		||||
          <div class="interval-time">
 | 
			
		||||
            @if (eta) {
 | 
			
		||||
              ~<app-time [time]="eta?.wait / 1000"></app-time> <!-- <span *ngIf="accelerateRatio > 1" class="compare"> ({{ accelerateRatio }}x faster)</span> -->
 | 
			
		||||
              }
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="node-spacer"></div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="nodes">
 | 
			
		||||
        <div class="node-spacer"></div>
 | 
			
		||||
        <div class="interval-spacer"></div>
 | 
			
		||||
        <div class="node">
 | 
			
		||||
          <div class="acc-to-confirmed right go-faster"></div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="interval-spacer">
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="node" [id]="'confirmed'">
 | 
			
		||||
          <div class="acc-to-confirmed left go-faster"></div>
 | 
			
		||||
          <div class="shape-border waiting">
 | 
			
		||||
            <div class="shape animate"></div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="status"><span class="badge badge-waiting" i18n="transaction.rbf.mined">Mined</span></div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    }
 | 
			
		||||
    <div class="timeline">
 | 
			
		||||
      <div class="intervals">
 | 
			
		||||
        <div class="node-spacer"></div>
 | 
			
		||||
@ -12,7 +44,13 @@
 | 
			
		||||
        <div class="node-spacer"></div>
 | 
			
		||||
        <div class="interval">
 | 
			
		||||
          <div class="interval-time">
 | 
			
		||||
            <app-time [time]="tx.status.block_time - acceleratedAt"></app-time>
 | 
			
		||||
            @if (tx.status.confirmed) {
 | 
			
		||||
              <div class="interval-time">
 | 
			
		||||
                <app-time [time]="tx.status.block_time - acceleratedAt"></app-time>
 | 
			
		||||
              </div>
 | 
			
		||||
            } @else if (standardETA && !tx.status.confirmed) {
 | 
			
		||||
              <!-- ~<app-time [time]="standardETA / 1000 - now"></app-time> -->
 | 
			
		||||
            }
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="node-spacer"></div>
 | 
			
		||||
@ -25,128 +63,71 @@
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="status"><span class="badge badge-primary" i18n="transaction.first-seen|Transaction first seen">First seen</span></div>
 | 
			
		||||
          <div class="time">
 | 
			
		||||
            <app-time *ngIf="transactionTime > 0" kind="since" [time]="transactionTime"></app-time>
 | 
			
		||||
            @if (useAbsoluteTime) {
 | 
			
		||||
            <span>{{ transactionTime * 1000 | date }}</span>
 | 
			
		||||
            } @else {
 | 
			
		||||
            <app-time kind="since" [time]="transactionTime"></app-time>
 | 
			
		||||
            }
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="interval-spacer">
 | 
			
		||||
          <div class="seen-to-acc"></div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="node" [id]="'accelerated'">
 | 
			
		||||
        <div class="node" [class.accelerated]="!tx.status.confirmed" [id]="'accelerated'">
 | 
			
		||||
          <div class="seen-to-acc left"></div>
 | 
			
		||||
          <div class="acc-to-confirmed right"></div>
 | 
			
		||||
          <div class="shape-border">
 | 
			
		||||
          @if (tx.status.confirmed) {
 | 
			
		||||
            <div class="acc-to-confirmed right"></div>
 | 
			
		||||
          } @else {
 | 
			
		||||
          <div class="seen-to-acc right"></div>
 | 
			
		||||
          }
 | 
			
		||||
          <div  class="shape-border">
 | 
			
		||||
            <div class="shape"></div>
 | 
			
		||||
            @if (!tx.status.confirmed) {
 | 
			
		||||
            <div class="connector down loading"></div>
 | 
			
		||||
            }
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="status"><span class="badge badge-accelerated" i18n="transaction.audit.accelerated">Accelerated</span></div>
 | 
			
		||||
          <div class="time">
 | 
			
		||||
            <app-time *ngIf="acceleratedAt" kind="since" [time]="acceleratedAt" [lowercaseStart]="true"></app-time>
 | 
			
		||||
          @if (tx.status.confirmed) {
 | 
			
		||||
            <div class="status"><span class="badge badge-accelerated" i18n="transaction.audit.accelerated">Accelerated</span></div>
 | 
			
		||||
          }
 | 
			
		||||
          <div class="time offset-left" [class.no-margin]="!tx.status.confirmed">
 | 
			
		||||
            @if (!tx.status.confirmed) {
 | 
			
		||||
            <span i18n="transaction.audit.accelerated">Accelerated</span>{{ "" }} 
 | 
			
		||||
            }
 | 
			
		||||
            @if (useAbsoluteTime) {
 | 
			
		||||
            <span>{{ acceleratedAt * 1000 | date }}</span>
 | 
			
		||||
            } @else {
 | 
			
		||||
            <app-time kind="since" [time]="acceleratedAt"></app-time>
 | 
			
		||||
            }
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="interval-spacer">
 | 
			
		||||
          @if (tx.status.confirmed) {
 | 
			
		||||
          <div class="acc-to-confirmed"></div>
 | 
			
		||||
          } @else {
 | 
			
		||||
          <div class="seen-to-acc"></div>
 | 
			
		||||
          }
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="node selected" [id]="'confirmed'">
 | 
			
		||||
          <div class="acc-to-confirmed left" ></div>
 | 
			
		||||
          <div class="shape-border">
 | 
			
		||||
        <div class="node" [class.selected]="tx.status.confirmed" [id]="'confirmed'">
 | 
			
		||||
          @if (tx.status.confirmed) {
 | 
			
		||||
          <div class="acc-to-confirmed left"></div>
 | 
			
		||||
          } @else {
 | 
			
		||||
          <div class="seen-to-acc left"></div>
 | 
			
		||||
          }
 | 
			
		||||
          <div class="shape-border" [class.waiting]="!tx.status.confirmed">
 | 
			
		||||
            <div class="shape"></div>
 | 
			
		||||
          </div>
 | 
			
		||||
          @if (tx.status.confirmed) {
 | 
			
		||||
          <div class="status"><span class="badge badge-success" i18n="transaction.rbf.mined">Mined</span></div>
 | 
			
		||||
          <div class="time">
 | 
			
		||||
            @if (useAbsoluteTime) {
 | 
			
		||||
            <span>{{ tx.status.block_time * 1000 | date }}</span>
 | 
			
		||||
            } @else {
 | 
			
		||||
            <app-time kind="since" [time]="tx.status.block_time"></app-time>
 | 
			
		||||
            }
 | 
			
		||||
          </div>
 | 
			
		||||
          }
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>  
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</div>
 | 
			
		||||
} @else if (acceleratedETA) { <!-- Not yet accelerated; to be shown only in acceleration checkout -->
 | 
			
		||||
} @else if (standardETA) { <!-- Accelerated -->
 | 
			
		||||
  <div class="acceleration-timeline box lower-padding">
 | 
			
		||||
    <div class="timeline-wrapper">
 | 
			
		||||
      <div class="timeline">
 | 
			
		||||
        <div class="intervals">
 | 
			
		||||
          <div class="node-spacer"></div>
 | 
			
		||||
          <div class="interval-spacer"></div>
 | 
			
		||||
          <div class="node-spacer"></div>
 | 
			
		||||
          <div class="interval">
 | 
			
		||||
            <div class="interval-time">
 | 
			
		||||
              @if (eta) {
 | 
			
		||||
                ~<app-time [time]="eta?.wait / 1000"></app-time> <!-- <span *ngIf="accelerateRatio > 1" class="compare"> ({{ accelerateRatio }}x faster)</span> -->
 | 
			
		||||
                }
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="node-spacer"></div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="nodes">
 | 
			
		||||
          <div class="node-spacer"></div>
 | 
			
		||||
          <div class="interval-spacer"></div>
 | 
			
		||||
          <div class="node">
 | 
			
		||||
            <div class="acc-to-confirmed right go-faster"></div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="interval-spacer">
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="node" [id]="'confirmed'">
 | 
			
		||||
            <div class="acc-to-confirmed left go-faster"></div>
 | 
			
		||||
            <div class="shape-border waiting">
 | 
			
		||||
              <div class="shape animate"></div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="status"><span class="badge badge-waiting" i18n="transaction.rbf.mined">Mined</span></div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="timeline">
 | 
			
		||||
        <div class="intervals">
 | 
			
		||||
          <div class="node-spacer"></div>
 | 
			
		||||
          <div class="interval">
 | 
			
		||||
            <div class="interval-time">
 | 
			
		||||
              <app-time [time]="acceleratedAt - transactionTime"></app-time>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="node-spacer"></div>
 | 
			
		||||
          <div class="interval">
 | 
			
		||||
            <div class="interval-time">
 | 
			
		||||
                <!-- ~<app-time [time]="standardETA / 1000 - now"></app-time> -->
 | 
			
		||||
                -
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="node-spacer"></div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="nodes">
 | 
			
		||||
          <div class="node" [id]="'first-seen'">
 | 
			
		||||
            <div class="seen-to-acc right"></div>
 | 
			
		||||
            <div class="shape-border">
 | 
			
		||||
              <div class="shape"></div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="status"><span class="badge badge-primary" i18n="transaction.first-seen|Transaction first seen">First seen</span></div>
 | 
			
		||||
            <div class="time">
 | 
			
		||||
              <app-time *ngIf="transactionTime > 0" kind="since" [time]="transactionTime"></app-time>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="interval-spacer">
 | 
			
		||||
            <div class="seen-to-acc"></div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="node accelerated" [id]="'accelerated'">
 | 
			
		||||
            <div class="seen-to-acc left"></div>
 | 
			
		||||
            <div class="seen-to-acc right"></div>
 | 
			
		||||
            <div  class="shape-border">
 | 
			
		||||
              <div class="shape"></div>
 | 
			
		||||
              <div class="connector down loading"></div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="time" style="margin-top: 3px;">
 | 
			
		||||
              <span i18n="transaction.audit.accelerated">Accelerated</span> <app-time *ngIf="acceleratedAt" kind="since" [time]="acceleratedAt"></app-time>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="interval-spacer">
 | 
			
		||||
            <div class="seen-to-acc"></div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="node" [id]="'confirmed'">
 | 
			
		||||
            <div class="seen-to-acc left"></div>
 | 
			
		||||
            <div class="shape-border waiting">
 | 
			
		||||
              <div class="shape"></div>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
}
 | 
			
		||||
@ -209,7 +209,7 @@
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .status {
 | 
			
		||||
        margin-top: -64px;
 | 
			
		||||
        margin-top: -66px;
 | 
			
		||||
 | 
			
		||||
        .badge.badge-waiting {
 | 
			
		||||
          opacity: 0.5;
 | 
			
		||||
@ -224,10 +224,20 @@
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .time {
 | 
			
		||||
        margin-top: 33px;
 | 
			
		||||
        margin-top: 32px;
 | 
			
		||||
        font-size: 12px;
 | 
			
		||||
        line-height: 16px;
 | 
			
		||||
        white-space: nowrap;
 | 
			
		||||
 | 
			
		||||
        &.offset-left {
 | 
			
		||||
          @media (max-width: 650px) {
 | 
			
		||||
            margin-left: -20px;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        &.no-margin {
 | 
			
		||||
          margin-top: 0px;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -19,15 +19,23 @@ export class AccelerationTimelineComponent implements OnInit, OnChanges {
 | 
			
		||||
  acceleratedAt: number;
 | 
			
		||||
  now: number;
 | 
			
		||||
  accelerateRatio: number;
 | 
			
		||||
  useAbsoluteTime: boolean = false;
 | 
			
		||||
  interval: number;
 | 
			
		||||
 | 
			
		||||
  constructor() {}
 | 
			
		||||
 | 
			
		||||
  ngOnInit(): void {
 | 
			
		||||
    this.acceleratedAt = this.tx.acceleratedAt ?? new Date().getTime() / 1000;
 | 
			
		||||
    this.now = Math.floor(new Date().getTime() / 1000);
 | 
			
		||||
    this.useAbsoluteTime = this.tx.status.block_time < this.now - 7 * 24 * 3600;
 | 
			
		||||
 | 
			
		||||
    this.interval = window.setInterval(() => {
 | 
			
		||||
      this.now = Math.floor(new Date().getTime() / 1000);
 | 
			
		||||
      this.useAbsoluteTime = this.tx.status.block_time < this.now - 7 * 24 * 3600;
 | 
			
		||||
    }, 60000);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ngOnChanges(changes): void {
 | 
			
		||||
    this.now = Math.floor(new Date().getTime() / 1000);
 | 
			
		||||
    // Hide standard ETA while we don't have a proper standard ETA calculation, see https://github.com/mempool/mempool/issues/65
 | 
			
		||||
    
 | 
			
		||||
    // if (changes?.eta?.currentValue || changes?.standardETA?.currentValue || changes?.acceleratedETA?.currentValue) {
 | 
			
		||||
@ -40,4 +48,8 @@ export class AccelerationTimelineComponent implements OnInit, OnChanges {
 | 
			
		||||
    //   }
 | 
			
		||||
    // }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ngOnDestroy(): void {
 | 
			
		||||
    clearInterval(this.interval);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user