Highlight matching transactions in the block visualizations
This commit is contained in:
		
							parent
							
								
									cff2022baf
								
							
						
					
					
						commit
						e9c618849d
					
				@ -6,6 +6,8 @@ import TxSprite from './tx-sprite';
 | 
			
		||||
import TxView from './tx-view';
 | 
			
		||||
import { Position } from './sprite-types';
 | 
			
		||||
import { Price } from '../../services/price.service';
 | 
			
		||||
import { StateService } from '../../services/state.service';
 | 
			
		||||
import { Subscription } from 'rxjs';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
  selector: 'app-block-overview-graph',
 | 
			
		||||
@ -44,16 +46,25 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On
 | 
			
		||||
  scene: BlockScene;
 | 
			
		||||
  hoverTx: TxView | void;
 | 
			
		||||
  selectedTx: TxView | void;
 | 
			
		||||
  highlightTx: TxView | void;
 | 
			
		||||
  mirrorTx: TxView | void;
 | 
			
		||||
  tooltipPosition: Position;
 | 
			
		||||
 | 
			
		||||
  readyNextFrame = false;
 | 
			
		||||
 | 
			
		||||
  searchText: string;
 | 
			
		||||
  searchSubscription: Subscription;
 | 
			
		||||
 | 
			
		||||
  constructor(
 | 
			
		||||
    readonly ngZone: NgZone,
 | 
			
		||||
    readonly elRef: ElementRef,
 | 
			
		||||
    private stateService: StateService,
 | 
			
		||||
  ) {
 | 
			
		||||
    this.vertexArray = new FastVertexArray(512, TxSprite.dataSize);
 | 
			
		||||
    this.searchSubscription = this.stateService.searchText$.subscribe((text) => {
 | 
			
		||||
      this.searchText = text;
 | 
			
		||||
      this.updateSearchHighlight();
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ngAfterViewInit(): void {
 | 
			
		||||
@ -109,6 +120,7 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On
 | 
			
		||||
      this.scene.setup(transactions);
 | 
			
		||||
      this.readyNextFrame = true;
 | 
			
		||||
      this.start();
 | 
			
		||||
      this.updateSearchHighlight();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -116,6 +128,7 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On
 | 
			
		||||
    if (this.scene) {
 | 
			
		||||
      this.scene.enter(transactions, direction);
 | 
			
		||||
      this.start();
 | 
			
		||||
      this.updateSearchHighlight();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -123,6 +136,7 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On
 | 
			
		||||
    if (this.scene) {
 | 
			
		||||
      this.scene.exit(direction);
 | 
			
		||||
      this.start();
 | 
			
		||||
      this.updateSearchHighlight();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -130,6 +144,7 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On
 | 
			
		||||
    if (this.scene) {
 | 
			
		||||
      this.scene.replace(transactions || [], direction, sort);
 | 
			
		||||
      this.start();
 | 
			
		||||
      this.updateSearchHighlight();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -137,6 +152,7 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On
 | 
			
		||||
    if (this.scene) {
 | 
			
		||||
      this.scene.update(add, remove, change, direction, resetLayout);
 | 
			
		||||
      this.start();
 | 
			
		||||
      this.updateSearchHighlight();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -406,6 +422,19 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  updateSearchHighlight(): void {
 | 
			
		||||
    if (this.highlightTx && this.highlightTx.txid !== this.searchText && this.scene) {
 | 
			
		||||
      this.scene.setHighlight(this.highlightTx, false);
 | 
			
		||||
      this.start();
 | 
			
		||||
    } else if (this.searchText && this.searchText.length === 64) {
 | 
			
		||||
      this.highlightTx = this.scene.txs[this.searchText];
 | 
			
		||||
      if (this.highlightTx) {
 | 
			
		||||
        this.scene.setHighlight(this.highlightTx, true);
 | 
			
		||||
        this.start();
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  setHighlightingEnabled(enabled: boolean): void {
 | 
			
		||||
    if (this.scene) {
 | 
			
		||||
      this.scene.setHighlighting(enabled);
 | 
			
		||||
 | 
			
		||||
@ -215,6 +215,10 @@ export default class BlockScene {
 | 
			
		||||
    this.animateUntil = Math.max(this.animateUntil, tx.setHover(value));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  setHighlight(tx: TxView, value: boolean): void {
 | 
			
		||||
    this.animateUntil = Math.max(this.animateUntil, tx.setHighlight(value));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private init({ width, height, resolution, blockLimit, orientation, flip, vertexArray, highlighting, pixelAlign }:
 | 
			
		||||
      { width: number, height: number, resolution: number, blockLimit: number,
 | 
			
		||||
        orientation: string, flip: boolean, vertexArray: FastVertexArray, highlighting: boolean, pixelAlign: boolean }
 | 
			
		||||
 | 
			
		||||
@ -7,6 +7,7 @@ import BlockScene from './block-scene';
 | 
			
		||||
 | 
			
		||||
const hoverTransitionTime = 300;
 | 
			
		||||
const defaultHoverColor = hexToColor('1bd8f4');
 | 
			
		||||
const defaultHighlightColor = hexToColor('800080');
 | 
			
		||||
 | 
			
		||||
const feeColors = mempoolFeeColors.map(hexToColor);
 | 
			
		||||
const auditFeeColors = feeColors.map((color) => darken(desaturate(color, 0.3), 0.9));
 | 
			
		||||
@ -44,8 +45,10 @@ export default class TxView implements TransactionStripped {
 | 
			
		||||
  initialised: boolean;
 | 
			
		||||
  vertexArray: FastVertexArray;
 | 
			
		||||
  hover: boolean;
 | 
			
		||||
  highlight: boolean;
 | 
			
		||||
  sprite: TxSprite;
 | 
			
		||||
  hoverColor: Color | void;
 | 
			
		||||
  highlightColor: Color | void;
 | 
			
		||||
 | 
			
		||||
  screenPosition: Square;
 | 
			
		||||
  gridPosition: Square | void;
 | 
			
		||||
@ -150,8 +153,40 @@ export default class TxView implements TransactionStripped {
 | 
			
		||||
    } else {
 | 
			
		||||
      this.hover = false;
 | 
			
		||||
      this.hoverColor = null;
 | 
			
		||||
      if (this.sprite) {
 | 
			
		||||
        this.sprite.resume(hoverTransitionTime);
 | 
			
		||||
      if (this.highlight) {
 | 
			
		||||
        this.setHighlight(true, this.highlightColor);
 | 
			
		||||
      } else {
 | 
			
		||||
        if (this.sprite) {
 | 
			
		||||
          this.sprite.resume(hoverTransitionTime);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    this.dirty = false;
 | 
			
		||||
    return performance.now() + hoverTransitionTime;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Temporarily override the tx color
 | 
			
		||||
  // returns minimum transition end time
 | 
			
		||||
  setHighlight(highlightOn: boolean, color: Color | void = defaultHighlightColor): number {
 | 
			
		||||
    if (highlightOn) {
 | 
			
		||||
      this.highlight = true;
 | 
			
		||||
      this.highlightColor = color;
 | 
			
		||||
 | 
			
		||||
      this.sprite.update({
 | 
			
		||||
        ...this.highlightColor,
 | 
			
		||||
        duration: hoverTransitionTime,
 | 
			
		||||
        adjust: false,
 | 
			
		||||
        temp: true
 | 
			
		||||
      });
 | 
			
		||||
    } else {
 | 
			
		||||
      this.highlight = false;
 | 
			
		||||
      this.highlightColor = null;
 | 
			
		||||
      if (this.hover) {
 | 
			
		||||
        this.setHover(true, this.hoverColor);
 | 
			
		||||
      } else {
 | 
			
		||||
        if (this.sprite) {
 | 
			
		||||
          this.sprite.resume(hoverTransitionTime);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    this.dirty = false;
 | 
			
		||||
 | 
			
		||||
@ -80,6 +80,9 @@ export class SearchFormComponent implements OnInit {
 | 
			
		||||
        }
 | 
			
		||||
        return text.trim();
 | 
			
		||||
      }),
 | 
			
		||||
      tap((text) => {
 | 
			
		||||
        this.stateService.searchText$.next(text);
 | 
			
		||||
      }),
 | 
			
		||||
      distinctUntilChanged(),
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -129,6 +129,7 @@ export class StateService {
 | 
			
		||||
 | 
			
		||||
  markBlock$ = new BehaviorSubject<MarkBlockState>({});
 | 
			
		||||
  keyNavigation$ = new Subject<KeyboardEvent>();
 | 
			
		||||
  searchText$ = new BehaviorSubject<string>('');
 | 
			
		||||
 | 
			
		||||
  blockScrolling$: Subject<boolean> = new Subject<boolean>();
 | 
			
		||||
  resetScroll$: Subject<boolean> = new Subject<boolean>();
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user