From 69827843c900d43dff2c515f9bd51b3a50c7b3da Mon Sep 17 00:00:00 2001 From: softsimon Date: Sat, 21 Mar 2020 03:38:18 +0700 Subject: [PATCH] Navigate between blocks using keyboard arrows. --- .../app/components/block/block.component.html | 2 +- .../blockchain-blocks.component.html | 2 +- .../blockchain-blocks.component.scss | 5 +-- .../blockchain-blocks.component.ts | 38 +++++++++++++++++-- .../blockchain/blockchain.component.ts | 4 +- .../mempool-blocks.component.html | 2 +- .../mempool-blocks.component.scss | 5 +-- .../mempool-blocks.component.ts | 30 ++++++++++++++- 8 files changed, 73 insertions(+), 15 deletions(-) diff --git a/frontend/src/app/components/block/block.component.html b/frontend/src/app/components/block/block.component.html index be1d1f4d2..3a240198f 100644 --- a/frontend/src/app/components/block/block.component.html +++ b/frontend/src/app/components/block/block.component.html @@ -46,7 +46,7 @@ Hash - {{ block.id | shortenString : 16 }} + {{ block.id | shortenString : 13 }} Median fee diff --git a/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.html b/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.html index 0fa834ffd..49dc0ab89 100644 --- a/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.html +++ b/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.html @@ -16,5 +16,5 @@ -
+
diff --git a/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.scss b/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.scss index 9f25c8830..78ee032b5 100644 --- a/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.scss +++ b/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.scss @@ -42,8 +42,8 @@ .fees { font-size: 14px; - margin-top: 10px; - margin-bottom: 8px; + margin-top: 12px; + margin-bottom: 6px; } .transaction-count { @@ -95,7 +95,6 @@ position: relative; left: 30px; top: 140px; - transition: 1s; width: 0; height: 0; border-left: 35px solid transparent; diff --git a/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.ts b/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.ts index 64a243817..8dfbd6c88 100644 --- a/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.ts +++ b/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.ts @@ -1,7 +1,8 @@ -import { Component, OnInit, OnDestroy, Input, OnChanges } from '@angular/core'; +import { Component, OnInit, OnDestroy, Input, OnChanges, HostListener } from '@angular/core'; import { Subscription } from 'rxjs'; import { Block } from 'src/app/interfaces/electrs.interface'; import { StateService } from 'src/app/services/state.service'; +import { Router } from '@angular/router'; @Component({ selector: 'app-blockchain-blocks', @@ -18,8 +19,11 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy { arrowVisible = false; arrowLeftPx = 30; + transition = '1s'; + constructor( private stateService: StateService, + private router: Router, ) { } ngOnInit() { @@ -31,12 +35,12 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy { this.blocks.unshift(block); this.blocks = this.blocks.slice(0, 8); - this.moveArrowToPosition(); + this.moveArrowToPosition(true); }); } ngOnChanges() { - this.moveArrowToPosition(); + this.moveArrowToPosition(false); } ngOnDestroy() { @@ -44,15 +48,41 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy { clearInterval(this.interval); } - moveArrowToPosition() { + @HostListener('document:keydown', ['$event']) + handleKeyboardEvents(event: KeyboardEvent) { + if (!this.markHeight) { + return; + } + if (event.key === 'ArrowRight') { + const blockindex = this.blocks.findIndex((b) => b.height === this.markHeight); + if (this.blocks[blockindex + 1]) { + this.router.navigate(['/block/', this.blocks[blockindex + 1].id], { state: { data: { block: this.blocks[blockindex + 1] } } }); + } + } else if (event.key === 'ArrowLeft') { + const blockindex = this.blocks.findIndex((b) => b.height === this.markHeight); + if (blockindex === 0) { + this.router.navigate(['/mempool-block/', '0']); + } else { + this.router.navigate(['/block/', this.blocks[blockindex - 1].id], { state: { data: { block: this.blocks[blockindex - 1] }}}); + } + } + } + + moveArrowToPosition(animate: boolean) { if (!this.markHeight) { this.arrowVisible = false; return; } const blockindex = this.blocks.findIndex((b) => b.height === this.markHeight); if (blockindex !== -1) { + if (!animate) { + this.transition = 'inherit'; + } this.arrowVisible = true; this.arrowLeftPx = blockindex * 155 + 30; + if (!animate) { + setTimeout(() => this.transition = '1s'); + } } } diff --git a/frontend/src/app/components/blockchain/blockchain.component.ts b/frontend/src/app/components/blockchain/blockchain.component.ts index 939045ecf..4660ab70f 100644 --- a/frontend/src/app/components/blockchain/blockchain.component.ts +++ b/frontend/src/app/components/blockchain/blockchain.component.ts @@ -2,6 +2,7 @@ import { Component, OnInit, OnDestroy, Input } from '@angular/core'; import { Subscription } from 'rxjs'; import { take } from 'rxjs/operators'; import { StateService } from 'src/app/services/state.service'; +import { Router } from '@angular/router'; @Component({ selector: 'app-blockchain', @@ -23,6 +24,7 @@ export class BlockchainComponent implements OnInit, OnDestroy { constructor( private stateService: StateService, + private router: Router, ) {} ngOnInit() { @@ -30,7 +32,7 @@ export class BlockchainComponent implements OnInit, OnDestroy { .pipe( take(1) ) - .subscribe((block) => this.isLoading = false); + .subscribe(() => this.isLoading = false); } ngOnDestroy() { diff --git a/frontend/src/app/components/mempool-blocks/mempool-blocks.component.html b/frontend/src/app/components/mempool-blocks/mempool-blocks.component.html index 06d908ddd..5a96daf4a 100644 --- a/frontend/src/app/components/mempool-blocks/mempool-blocks.component.html +++ b/frontend/src/app/components/mempool-blocks/mempool-blocks.component.html @@ -18,5 +18,5 @@ -
+
diff --git a/frontend/src/app/components/mempool-blocks/mempool-blocks.component.scss b/frontend/src/app/components/mempool-blocks/mempool-blocks.component.scss index 87c5ca59e..4fea06bc1 100644 --- a/frontend/src/app/components/mempool-blocks/mempool-blocks.component.scss +++ b/frontend/src/app/components/mempool-blocks/mempool-blocks.component.scss @@ -46,8 +46,8 @@ .fees { font-size: 14px; - margin-top: 10px; - margin-bottom: 8px; + margin-top: 12px; + margin-bottom: 6px; } .transaction-count { @@ -97,7 +97,6 @@ position: relative; right: 75px; top: 140px; - transition: 1s; width: 0; height: 0; border-left: 35px solid transparent; diff --git a/frontend/src/app/components/mempool-blocks/mempool-blocks.component.ts b/frontend/src/app/components/mempool-blocks/mempool-blocks.component.ts index 73824996d..8f159570f 100644 --- a/frontend/src/app/components/mempool-blocks/mempool-blocks.component.ts +++ b/frontend/src/app/components/mempool-blocks/mempool-blocks.component.ts @@ -1,7 +1,8 @@ -import { Component, OnInit, OnDestroy, Input, EventEmitter, Output, OnChanges, HostListener } from '@angular/core'; +import { Component, OnInit, OnDestroy, Input, OnChanges, HostListener } from '@angular/core'; import { Subscription } from 'rxjs'; import { MempoolBlock } from 'src/app/interfaces/websocket.interface'; import { StateService } from 'src/app/services/state.service'; +import { Router } from '@angular/router'; @Component({ selector: 'app-mempool-blocks', @@ -18,11 +19,13 @@ export class MempoolBlocksComponent implements OnInit, OnChanges, OnDestroy { arrowVisible = false; rightPosition = 0; + transition = '1s'; @Input() txFeePerVSize: number; @Input() markIndex: number; constructor( + private router: Router, private stateService: StateService, ) { } @@ -43,6 +46,29 @@ export class MempoolBlocksComponent implements OnInit, OnChanges, OnDestroy { } } + @HostListener('document:keydown', ['$event']) + handleKeyboardEvents(event: KeyboardEvent) { + if (this.markIndex === -1) { + return; + } + if (event.key === 'ArrowRight') { + if (this.mempoolBlocks[this.markIndex - 1]) { + this.router.navigate(['/mempool-block/', this.markIndex - 1]); + } else { + this.stateService.blocks$ + .subscribe((block) => { + if (this.stateService.latestBlockHeight === block.height) { + this.router.navigate(['/block/', block.id], { state: { data: { block } }}); + } + }); + } + } else if (event.key === 'ArrowLeft') { + if (this.mempoolBlocks[this.markIndex + 1]) { + this.router.navigate(['/mempool-block/', this.markIndex + 1]); + } + } + } + ngOnChanges() { this.calculateTransactionPosition(); } @@ -95,8 +121,10 @@ export class MempoolBlocksComponent implements OnInit, OnChanges, OnDestroy { this.arrowVisible = false; return; } else if (this.markIndex > -1) { + this.transition = 'inherit'; this.rightPosition = this.markIndex * (this.blockWidth + this.blockPadding) + 0.5 * this.blockWidth; this.arrowVisible = true; + setTimeout(() => this.transition = '1s'); return; }