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