multiblock interactivity
This commit is contained in:
		
							parent
							
								
									f7422f29dc
								
							
						
					
					
						commit
						580ac889df
					
				| @ -553,7 +553,7 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On | ||||
|         x: cssX, | ||||
|         y: cssY | ||||
|       }; | ||||
|       const selected = this.scene.getTxAt({ x, y }); | ||||
|       const selected = this.scene.getTxAt({ x, y: this.displayHeight - y }); | ||||
|       const currentPreview = this.selectedTx || this.hoverTx; | ||||
| 
 | ||||
|       if (selected !== currentPreview) { | ||||
| @ -627,7 +627,7 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On | ||||
|     if (this.scene) { | ||||
|       const x = cssX * window.devicePixelRatio; | ||||
|       const y = cssY * window.devicePixelRatio; | ||||
|       const selected = this.scene.getTxAt({ x, y }); | ||||
|       const selected = this.scene.getTxAt({ x, y: this.displayHeight - y }); | ||||
|       if (selected && selected.txid) { | ||||
|         this.txClickEvent.emit({ tx: selected, keyModifier }); | ||||
|       } | ||||
|  | ||||
| @ -228,10 +228,14 @@ export default class BlockScene { | ||||
|   getTxAt(position: Position): TxView | void { | ||||
|     if (this.layout) { | ||||
|       const gridPosition = this.screenToGrid(position); | ||||
|       if (gridPosition.x >= 0 && gridPosition.x < this.gridWidth && gridPosition.y >= 0 && gridPosition.y < this.gridHeight) { | ||||
|         return this.layout.getTx(gridPosition); | ||||
|       } else { | ||||
|         return null; | ||||
|       } | ||||
|     } else { | ||||
|       return null; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   setHover(tx: TxView, value: boolean): void { | ||||
| @ -465,7 +469,7 @@ export default class BlockScene { | ||||
| 
 | ||||
|   private screenToGrid(position: Position): Position { | ||||
|     let x = position.x - this.x; | ||||
|     let y = this.height - (position.y - this.y); | ||||
|     let y = position.y - this.y; | ||||
|     let t; | ||||
| 
 | ||||
|     switch (this.orientation) { | ||||
|  | ||||
| @ -523,6 +523,141 @@ export class BlockOverviewMultiComponent implements AfterViewInit, OnDestroy, On | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   @HostListener('document:click', ['$event']) | ||||
|   clickAway(event) { | ||||
|     if (!this.elRef.nativeElement.contains(event.target)) { | ||||
|       const currentPreview = this.selectedTx || this.hoverTx; | ||||
|       if (currentPreview) { | ||||
|         for (const scene of this.scenes) { | ||||
|           if (scene) { | ||||
|             scene.setHover(currentPreview, false); | ||||
|           } | ||||
|         } | ||||
|         this.start(); | ||||
|       } | ||||
|       this.hoverTx = null; | ||||
|       this.selectedTx = null; | ||||
|       this.onTxHover(null); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   @HostListener('pointerup', ['$event']) | ||||
|   onClick(event) { | ||||
|     if (!this.canvas) { | ||||
|       return; | ||||
|     } | ||||
|     if (event.target === this.canvas.nativeElement && event.pointerType === 'touch') { | ||||
|       this.setPreviewTx(event.offsetX, event.offsetY, true); | ||||
|     } else if (event.target === this.canvas.nativeElement) { | ||||
|       const keyMod = event.shiftKey || event.ctrlKey || event.metaKey; | ||||
|       const middleClick = event.which === 2 || event.button === 1; | ||||
|       this.onTxClick(event.offsetX, event.offsetY, keyMod || middleClick); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   @HostListener('pointermove', ['$event']) | ||||
|   onPointerMove(event) { | ||||
|     if (!this.canvas) { | ||||
|       return; | ||||
|     } | ||||
|     if (event.target === this.canvas.nativeElement) { | ||||
|       this.setPreviewTx(event.offsetX, event.offsetY, false); | ||||
|     } else { | ||||
|       this.onPointerLeave(event); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   @HostListener('pointerleave', ['$event']) | ||||
|   onPointerLeave(event) { | ||||
|     if (event.pointerType !== 'touch') { | ||||
|       this.setPreviewTx(-1, -1, true); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   setPreviewTx(cssX: number, cssY: number, clicked: boolean = false) { | ||||
|     const x = cssX * window.devicePixelRatio; | ||||
|     const y = cssY * window.devicePixelRatio; | ||||
|     if (!this.selectedTx || clicked) { | ||||
|       this.tooltipPosition = { | ||||
|         x: cssX, | ||||
|         y: cssY | ||||
|       }; | ||||
|       const currentPreview = this.selectedTx || this.hoverTx; | ||||
|       let selected; | ||||
|       for (const scene of this.scenes) { | ||||
|         if (scene) { | ||||
|           selected = scene.getTxAt({ x, y: this.displayHeight - y }); | ||||
|           if (selected) { | ||||
|             break; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
| 
 | ||||
|       if (selected !== currentPreview) { | ||||
|         if (currentPreview) { | ||||
|           for (const scene of this.scenes) { | ||||
|             if (scene) { | ||||
|               scene.setHover(currentPreview, false); | ||||
|               break; | ||||
|             } | ||||
|           } | ||||
|           this.start(); | ||||
|         } | ||||
|         if (selected) { | ||||
|           for (const scene of this.scenes) { | ||||
|             if (scene) { | ||||
|               scene.setHover(selected, true); | ||||
|               break; | ||||
|             } | ||||
|           } | ||||
|           this.start(); | ||||
|           if (clicked) { | ||||
|             this.selectedTx = selected; | ||||
|           } else { | ||||
|             this.hoverTx = selected; | ||||
|             this.onTxHover(this.hoverTx ? this.hoverTx.txid : null); | ||||
|           } | ||||
|         } else { | ||||
|           if (clicked) { | ||||
|             this.selectedTx = null; | ||||
|           } | ||||
|           this.hoverTx = null; | ||||
|           this.onTxHover(null); | ||||
|         } | ||||
|       } else if (clicked) { | ||||
|         if (selected === this.selectedTx) { | ||||
|           this.hoverTx = this.selectedTx; | ||||
|           this.selectedTx = null; | ||||
|           this.onTxHover(this.hoverTx ? this.hoverTx.txid : null); | ||||
|         } else { | ||||
|           this.selectedTx = selected; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   updateSearchHighlight(): void { | ||||
|     if (this.highlightTx && this.highlightTx.txid !== this.searchText) { | ||||
|       for (const scene of this.scenes) { | ||||
|         if (scene) { | ||||
|           scene.setHighlight(this.highlightTx, false); | ||||
|         } | ||||
|       } | ||||
|       this.start(); | ||||
|     } else if (this.searchText && this.searchText.length === 64) { | ||||
|       for (const scene of this.scenes) { | ||||
|         if (scene) { | ||||
|           const highlightTx = scene.txs[this.searchText]; | ||||
|           if (highlightTx) { | ||||
|             scene.setHighlight(highlightTx, true); | ||||
|             this.highlightTx = highlightTx; | ||||
|             this.start(); | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   setHighlightingEnabled(enabled: boolean): void { | ||||
|     for (const scene of this.scenes) { | ||||
|       scene.setHighlighting(enabled); | ||||
| @ -530,6 +665,24 @@ export class BlockOverviewMultiComponent implements AfterViewInit, OnDestroy, On | ||||
|     this.start(); | ||||
|   } | ||||
| 
 | ||||
|   onTxClick(cssX: number, cssY: number, keyModifier: boolean = false) { | ||||
|     for (const scene of this.scenes) { | ||||
|       if (scene) { | ||||
|         const x = cssX * window.devicePixelRatio; | ||||
|         const y = cssY * window.devicePixelRatio; | ||||
|         const selected = scene.getTxAt({ x, y: this.displayHeight - y }); | ||||
|         if (selected && selected.txid) { | ||||
|           this.txClickEvent.emit({ tx: selected, keyModifier }); | ||||
|           return; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   onTxHover(hoverId: string) { | ||||
|     this.txHoverEvent.emit(hoverId); | ||||
|   } | ||||
| 
 | ||||
|   getColorFunction(): ((tx: TxView) => Color) { | ||||
|     if (this.overrideColors) { | ||||
|       return this.overrideColors; | ||||
|  | ||||
| @ -11,4 +11,5 @@ | ||||
|   [animationDuration]="animationDuration" | ||||
|   [animationOffset]="animationOffset" | ||||
|   [disableSpinner]="true" | ||||
|   (txClickEvent)="onTxClick($event)" | ||||
| ></app-block-overview-multi> | ||||
| @ -12,6 +12,7 @@ import { BytesPipe } from '../../shared/pipes/bytes-pipe/bytes.pipe'; | ||||
| import { BlockOverviewMultiComponent } from '../block-overview-multi/block-overview-multi.component'; | ||||
| import { CacheService } from '../../services/cache.service'; | ||||
| import { isMempoolDelta, MempoolBlockDelta } from '../../interfaces/websocket.interface'; | ||||
| import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pipe'; | ||||
| 
 | ||||
| function bestFitResolution(min, max, n): number { | ||||
|   const target = (min + max) / 2; | ||||
| @ -53,7 +54,6 @@ export class EightMempoolComponent implements OnInit, OnDestroy { | ||||
|   queryParamsSubscription: Subscription; | ||||
|   graphChangeSubscription: Subscription; | ||||
|   blockSub: Subscription; | ||||
|   mempoolBlockSub: Subscription; | ||||
| 
 | ||||
|   chainDirection: string = 'right'; | ||||
|   poolDirection: string = 'left'; | ||||
| @ -178,10 +178,18 @@ export class EightMempoolComponent implements OnInit, OnDestroy { | ||||
|       .subscribe((network) => this.network = network); | ||||
|   } | ||||
| 
 | ||||
|   onTxClick(event: { tx: TransactionStripped, keyModifier: boolean }): void { | ||||
|     const url = new RelativeUrlPipe(this.stateService).transform(`/tx/${event.tx.txid}`); | ||||
|     if (!event.keyModifier) { | ||||
|       this.router.navigate([url]); | ||||
|     } else { | ||||
|       window.open(url, '_blank'); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   ngOnDestroy(): void { | ||||
|     this.stateService.markBlock$.next({}); | ||||
|     this.blockSub.unsubscribe(); | ||||
|     this.mempoolBlockSub.unsubscribe(); | ||||
|     this.networkChangedSubscription?.unsubscribe(); | ||||
|     this.queryParamsSubscription?.unsubscribe(); | ||||
|   } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user