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