Reversible block arrows & key navigation
This commit is contained in:
parent
678977a2a0
commit
03c6a7c54f
@ -1,36 +1,24 @@
|
||||
<div class="container-xl" (window:resize)="onResize($event)">
|
||||
|
||||
<div class="title-block" id="block">
|
||||
<div class="title-block" [class.time-ltr]="timeLtr" id="block">
|
||||
<h1>
|
||||
<ng-template [ngIf]="blockHeight === 0"><ng-container i18n="@@2303359202781425764">Genesis</ng-container>
|
||||
<span class="next-previous-blocks">
|
||||
<a *ngIf="showNextBlocklink" [routerLink]="['/block/' | relativeUrl, nextBlockHeight]" (click)="navigateToNextBlock()" i18n-ngbTooltip="Next Block" ngbTooltip="Next Block" placement="bottom">
|
||||
<fa-icon [icon]="['fas', 'angle-left']" [fixedWidth]="true"></fa-icon>
|
||||
</a>
|
||||
<a [routerLink]="['/block/' | relativeUrl, blockHash]">{{ blockHeight }}</a>
|
||||
<span placement="bottom" class="disable">
|
||||
<fa-icon [icon]="['fas', 'angle-right']" [fixedWidth]="true"></fa-icon>
|
||||
</span>
|
||||
<ng-container *ngIf="blockHeight > 0; else genesis" i18n="shared.block-title">Block</ng-container>
|
||||
<ng-template #genesis i18n="@@2303359202781425764">Genesis</ng-template>
|
||||
<span class="next-previous-blocks">
|
||||
<a *ngIf="showNextBlocklink" class="nav-arrow next" [routerLink]="['/block/' | relativeUrl, nextBlockHeight]" (click)="navigateToNextBlock()" i18n-ngbTooltip="Next Block" ngbTooltip="Next Block" placement="bottom">
|
||||
<fa-icon [icon]="['fas', 'angle-left']" [fixedWidth]="true"></fa-icon>
|
||||
</a>
|
||||
<span *ngIf="!showNextBlocklink" placement="bottom" class="disable nav-arrow next">
|
||||
<fa-icon [icon]="['fas', 'angle-left']" [fixedWidth]="true"></fa-icon>
|
||||
</span>
|
||||
</ng-template>
|
||||
<ng-template [ngIf]="blockHeight" i18n="shared.block-title">Block <ng-container *ngTemplateOutlet="blockTemplateContent"></ng-container></ng-template>
|
||||
<ng-template #blockTemplateContent>
|
||||
<span class="next-previous-blocks">
|
||||
<a *ngIf="showNextBlocklink" [routerLink]="['/block/' | relativeUrl, nextBlockHeight]" (click)="navigateToNextBlock()" i18n-ngbTooltip="Next Block" ngbTooltip="Next Block" placement="bottom">
|
||||
<fa-icon [icon]="['fas', 'angle-left']" [fixedWidth]="true"></fa-icon>
|
||||
</a>
|
||||
<span *ngIf="!showNextBlocklink" placement="bottom" class="disable">
|
||||
<fa-icon [icon]="['fas', 'angle-left']" [fixedWidth]="true"></fa-icon>
|
||||
</span>
|
||||
<a [routerLink]="['/block/' | relativeUrl, blockHash]">{{ blockHeight }}</a>
|
||||
<a *ngIf="showPreviousBlocklink && block" [routerLink]="['/block/' | relativeUrl, block.previousblockhash]" (click)="navigateToPreviousBlock()" i18n-ngbTooltip="Previous Block" ngbTooltip="Previous Block" placement="bottom">
|
||||
<fa-icon [icon]="['fas', 'angle-right']" [fixedWidth]="true"></fa-icon>
|
||||
</a>
|
||||
<span *ngIf="!showPreviousBlocklink" placement="bottom" class="disable">
|
||||
<fa-icon [icon]="['fas', 'angle-right']" [fixedWidth]="true"></fa-icon>
|
||||
</span>
|
||||
<a [routerLink]="['/block/' | relativeUrl, blockHash]" class="block-link">{{ blockHeight }}</a>
|
||||
<a *ngIf="showPreviousBlocklink && block" class="nav-arrow prev" [routerLink]="['/block/' | relativeUrl, block.previousblockhash]" (click)="navigateToPreviousBlock()" i18n-ngbTooltip="Previous Block" ngbTooltip="Previous Block" placement="bottom">
|
||||
<fa-icon [icon]="['fas', 'angle-right']" [fixedWidth]="true"></fa-icon>
|
||||
</a>
|
||||
<span *ngIf="!showPreviousBlocklink || !block" placement="bottom" class="disable nav-arrow prev">
|
||||
<fa-icon [icon]="['fas', 'angle-right']" [fixedWidth]="true"></fa-icon>
|
||||
</span>
|
||||
</ng-template>
|
||||
</span>
|
||||
</h1>
|
||||
|
||||
<div class="grow"></div>
|
||||
|
@ -111,7 +111,8 @@ h1 {
|
||||
|
||||
.next-previous-blocks {
|
||||
font-size: 28px;
|
||||
display: inline-block;
|
||||
display: inline-flex;
|
||||
flex-direction: row;
|
||||
@media (min-width: 768px) {
|
||||
font-size: 36px;
|
||||
}
|
||||
@ -125,6 +126,21 @@ h1 {
|
||||
}
|
||||
}
|
||||
|
||||
.time-ltr .next-previous-blocks {
|
||||
.nav-arrow {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
.nav-arrow.next {
|
||||
order: 2;
|
||||
}
|
||||
.block-link {
|
||||
order: 1;
|
||||
}
|
||||
.nav-arrow.prev {
|
||||
order: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.disable {
|
||||
font-size: 28px;
|
||||
color: #393e5c73;
|
||||
|
@ -57,6 +57,8 @@ export class BlockComponent implements OnInit, OnDestroy {
|
||||
nextBlockSubscription: Subscription = undefined;
|
||||
nextBlockSummarySubscription: Subscription = undefined;
|
||||
nextBlockTxListSubscription: Subscription = undefined;
|
||||
timeLtrSubscription: Subscription;
|
||||
timeLtr: boolean;
|
||||
|
||||
@ViewChild('blockGraph') blockGraph: BlockOverviewGraphComponent;
|
||||
|
||||
@ -80,6 +82,10 @@ export class BlockComponent implements OnInit, OnDestroy {
|
||||
this.network = this.stateService.network;
|
||||
this.itemsPerPage = this.stateService.env.ITEMS_PER_PAGE;
|
||||
|
||||
this.timeLtrSubscription = this.stateService.timeLtr.subscribe((ltr) => {
|
||||
this.timeLtr = !!ltr;
|
||||
});
|
||||
|
||||
this.txsLoadingStatus$ = this.route.paramMap
|
||||
.pipe(
|
||||
switchMap(() => this.stateService.loadingIndicators$),
|
||||
@ -277,10 +283,12 @@ export class BlockComponent implements OnInit, OnDestroy {
|
||||
});
|
||||
|
||||
this.keyNavigationSubscription = this.stateService.keyNavigation$.subscribe((event) => {
|
||||
if (this.showPreviousBlocklink && event.key === 'ArrowRight' && this.nextBlockHeight - 2 >= 0) {
|
||||
const prevKey = this.timeLtr ? 'ArrowLeft' : 'ArrowRight';
|
||||
const nextKey = this.timeLtr ? 'ArrowRight' : 'ArrowLeft';
|
||||
if (this.showPreviousBlocklink && event.key === prevKey && this.nextBlockHeight - 2 >= 0) {
|
||||
this.navigateToPreviousBlock();
|
||||
}
|
||||
if (event.key === 'ArrowLeft') {
|
||||
if (event.key === nextKey) {
|
||||
if (this.showNextBlocklink) {
|
||||
this.navigateToNextBlock();
|
||||
} else {
|
||||
@ -298,6 +306,7 @@ export class BlockComponent implements OnInit, OnDestroy {
|
||||
this.blocksSubscription.unsubscribe();
|
||||
this.networkChangedSubscription.unsubscribe();
|
||||
this.queryParamsSubscription.unsubscribe();
|
||||
this.timeLtrSubscription.unsubscribe();
|
||||
this.unsubscribeNextBlockSubscriptions();
|
||||
}
|
||||
|
||||
@ -392,8 +401,8 @@ export class BlockComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
setNextAndPreviousBlockLink(){
|
||||
if (this.latestBlock && this.blockHeight) {
|
||||
if (this.blockHeight === 0){
|
||||
if (this.latestBlock) {
|
||||
if (!this.blockHeight){
|
||||
this.showPreviousBlocklink = false;
|
||||
} else {
|
||||
this.showPreviousBlocklink = true;
|
||||
|
@ -36,6 +36,8 @@ export class MempoolBlocksComponent implements OnInit, OnDestroy {
|
||||
now = new Date().getTime();
|
||||
timeOffset = 0;
|
||||
showMiningInfo = false;
|
||||
timeLtrSubscription: Subscription;
|
||||
timeLtr: boolean;
|
||||
|
||||
blockWidth = 125;
|
||||
blockPadding = 30;
|
||||
@ -72,6 +74,10 @@ export class MempoolBlocksComponent implements OnInit, OnDestroy {
|
||||
this.location.onUrlChange((url) => this.enabledMiningInfoIfNeeded(url));
|
||||
}
|
||||
|
||||
this.timeLtrSubscription = this.stateService.timeLtr.subscribe((ltr) => {
|
||||
this.timeLtr = !!ltr;
|
||||
});
|
||||
|
||||
if (this.stateService.network === 'liquid' || this.stateService.network === 'liquidtestnet') {
|
||||
this.feeRounding = '1.0-1';
|
||||
}
|
||||
@ -160,8 +166,10 @@ export class MempoolBlocksComponent implements OnInit, OnDestroy {
|
||||
if (this.markIndex === undefined) {
|
||||
return;
|
||||
}
|
||||
const prevKey = this.timeLtr ? 'ArrowLeft' : 'ArrowRight';
|
||||
const nextKey = this.timeLtr ? 'ArrowRight' : 'ArrowLeft';
|
||||
|
||||
if (event.key === 'ArrowRight') {
|
||||
if (event.key === prevKey) {
|
||||
if (this.mempoolBlocks[this.markIndex - 1]) {
|
||||
this.router.navigate([this.relativeUrlPipe.transform('mempool-block/'), this.markIndex - 1]);
|
||||
} else {
|
||||
@ -173,7 +181,7 @@ export class MempoolBlocksComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if (event.key === 'ArrowLeft') {
|
||||
} else if (event.key === nextKey) {
|
||||
if (this.mempoolBlocks[this.markIndex + 1]) {
|
||||
this.router.navigate([this.relativeUrlPipe.transform('/mempool-block/'), this.markIndex + 1]);
|
||||
}
|
||||
@ -185,6 +193,7 @@ export class MempoolBlocksComponent implements OnInit, OnDestroy {
|
||||
this.markBlocksSubscription.unsubscribe();
|
||||
this.blockSubscription.unsubscribe();
|
||||
this.networkSubscription.unsubscribe();
|
||||
this.timeLtrSubscription.unsubscribe();
|
||||
clearTimeout(this.resetTransitionTimeout);
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ import { BlockExtended, DifficultyAdjustment, OptimizedMempoolStats } from '../i
|
||||
import { Router, NavigationStart } from '@angular/router';
|
||||
import { isPlatformBrowser } from '@angular/common';
|
||||
import { map, shareReplay } from 'rxjs/operators';
|
||||
import { StorageService } from './storage.service';
|
||||
|
||||
interface MarkBlockState {
|
||||
blockHeight?: number;
|
||||
@ -108,10 +109,12 @@ export class StateService {
|
||||
keyNavigation$ = new Subject<KeyboardEvent>();
|
||||
|
||||
blockScrolling$: Subject<boolean> = new Subject<boolean>();
|
||||
timeLtr: BehaviorSubject<boolean>;
|
||||
|
||||
constructor(
|
||||
@Inject(PLATFORM_ID) private platformId: any,
|
||||
private router: Router,
|
||||
private storageService: StorageService,
|
||||
) {
|
||||
const browserWindow = window || {};
|
||||
// @ts-ignore
|
||||
@ -147,6 +150,11 @@ export class StateService {
|
||||
}
|
||||
|
||||
this.blockVSize = this.env.BLOCK_WEIGHT_UNITS / 4;
|
||||
|
||||
this.timeLtr = new BehaviorSubject<boolean>(this.storageService.getValue('time-preference-ltr') === 'true');
|
||||
this.timeLtr.subscribe((ltr) => {
|
||||
this.storageService.setValue('time-preference-ltr', ltr ? 'true' : 'false');
|
||||
});
|
||||
}
|
||||
|
||||
setNetworkBasedonUrl(url: string) {
|
||||
|
@ -4,7 +4,7 @@ import { NgbCollapse, NgbCollapseModule, NgbRadioGroup, NgbTypeaheadModule } fro
|
||||
import { FontAwesomeModule, FaIconLibrary } from '@fortawesome/angular-fontawesome';
|
||||
import { faFilter, faAngleDown, faAngleUp, faAngleRight, faAngleLeft, faBolt, faChartArea, faCogs, faCubes, faHammer, faDatabase, faExchangeAlt, faInfoCircle,
|
||||
faLink, faList, faSearch, faCaretUp, faCaretDown, faTachometerAlt, faThList, faTint, faTv, faAngleDoubleDown, faSortUp, faAngleDoubleUp, faChevronDown,
|
||||
faFileAlt, faRedoAlt, faArrowAltCircleRight, faExternalLinkAlt, faBook, faListUl, faDownload, faQrcode, faArrowRightArrowLeft } from '@fortawesome/free-solid-svg-icons';
|
||||
faFileAlt, faRedoAlt, faArrowAltCircleRight, faExternalLinkAlt, faBook, faListUl, faDownload, faQrcode, faArrowRightArrowLeft, faArrowsRotate } from '@fortawesome/free-solid-svg-icons';
|
||||
import { InfiniteScrollModule } from 'ngx-infinite-scroll';
|
||||
import { MasterPageComponent } from '../components/master-page/master-page.component';
|
||||
import { PreviewTitleComponent } from '../components/master-page-preview/preview-title.component';
|
||||
@ -291,6 +291,7 @@ export class SharedModule {
|
||||
library.addIcons(faFileAlt);
|
||||
library.addIcons(faRedoAlt);
|
||||
library.addIcons(faArrowAltCircleRight);
|
||||
library.addIcons(faArrowsRotate);
|
||||
library.addIcons(faExternalLinkAlt);
|
||||
library.addIcons(faSortUp);
|
||||
library.addIcons(faCaretUp);
|
||||
|
Loading…
x
Reference in New Issue
Block a user