144 lines
4.1 KiB
TypeScript
144 lines
4.1 KiB
TypeScript
|
import TxSprite from './tx-sprite'
|
||
|
import { FastVertexArray } from './fast-vertex-array'
|
||
|
import { TransactionStripped } from 'src/app/interfaces/websocket.interface';
|
||
|
import { SpriteUpdateParams, Square, Color, ViewUpdateParams } from './sprite-types'
|
||
|
import { feeLevels, mempoolFeeColors } from 'src/app/app.constants';
|
||
|
|
||
|
const hoverTransitionTime = 300
|
||
|
const defaultHoverColor = hexToColor('1bd8f4')
|
||
|
|
||
|
// convert from this class's update format to TxSprite's update format
|
||
|
function toSpriteUpdate({display, duration, delay, start, adjust} : ViewUpdateParams): SpriteUpdateParams {
|
||
|
return {
|
||
|
start: (start || performance.now()) + (delay || 0),
|
||
|
duration: duration,
|
||
|
...display.position,
|
||
|
...display.color,
|
||
|
adjust
|
||
|
}
|
||
|
}
|
||
|
|
||
|
export default class TxView implements TransactionStripped {
|
||
|
txid: string;
|
||
|
fee: number;
|
||
|
vsize: number;
|
||
|
value: number;
|
||
|
feerate: number;
|
||
|
|
||
|
initialised: boolean;
|
||
|
vertexArray: FastVertexArray;
|
||
|
hover: boolean;
|
||
|
sprite: TxSprite;
|
||
|
hoverColor: Color | void;
|
||
|
|
||
|
screenPosition: Square;
|
||
|
gridPosition : Square | void;
|
||
|
|
||
|
dirty: boolean;
|
||
|
|
||
|
constructor (tx: TransactionStripped, vertexArray: FastVertexArray) {
|
||
|
this.txid = tx.txid
|
||
|
this.fee = tx.fee
|
||
|
this.vsize = tx.vsize
|
||
|
this.value = tx.value
|
||
|
this.feerate = tx.fee / tx.vsize
|
||
|
this.initialised = false
|
||
|
this.vertexArray = vertexArray
|
||
|
|
||
|
this.hover = false
|
||
|
|
||
|
this.screenPosition = { x: 0, y: 0, s: 0 }
|
||
|
|
||
|
this.dirty = true
|
||
|
}
|
||
|
|
||
|
destroy (): void {
|
||
|
if (this.sprite) {
|
||
|
this.sprite.destroy()
|
||
|
this.sprite = null
|
||
|
this.initialised = false
|
||
|
}
|
||
|
}
|
||
|
|
||
|
applyGridPosition (position: Square): void {
|
||
|
if (!this.gridPosition) this.gridPosition = { x: 0, y: 0, s: 0 }
|
||
|
if (this.gridPosition.x != position.x || this.gridPosition.y != position.y || this.gridPosition.s != position.s) {
|
||
|
this.gridPosition.x = position.x
|
||
|
this.gridPosition.y = position.y
|
||
|
this.gridPosition.s = position.s
|
||
|
this.dirty = true
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
display: defines the final appearance of the sprite
|
||
|
position: { x, y, s } (coordinates & size)
|
||
|
color: { r, g, b, a} (color channels & alpha)
|
||
|
duration: of the tweening animation from the previous display state
|
||
|
start: performance.now() timestamp, when to start the transition
|
||
|
delay: additional milliseconds to wait before starting
|
||
|
jitter: if set, adds a random amount to the delay,
|
||
|
adjust: if true, modify an in-progress transition instead of replacing it
|
||
|
*/
|
||
|
update ({ display, duration, delay, jitter, start, adjust }: ViewUpdateParams): void {
|
||
|
if (jitter) delay += (Math.random() * jitter)
|
||
|
|
||
|
if (!this.initialised || !this.sprite) {
|
||
|
this.initialised = true
|
||
|
this.sprite = new TxSprite(
|
||
|
toSpriteUpdate({display, duration, delay, start}),
|
||
|
this.vertexArray
|
||
|
)
|
||
|
// apply any pending hover event
|
||
|
if (this.hover) {
|
||
|
this.sprite.update({
|
||
|
...this.hoverColor,
|
||
|
duration: hoverTransitionTime,
|
||
|
adjust: false,
|
||
|
temp: true
|
||
|
})
|
||
|
}
|
||
|
} else {
|
||
|
this.sprite.update(
|
||
|
toSpriteUpdate({display, duration, delay, start, adjust})
|
||
|
)
|
||
|
}
|
||
|
this.dirty = false
|
||
|
}
|
||
|
|
||
|
// Temporarily override the tx color
|
||
|
setHover (hoverOn: boolean, color: Color | void = defaultHoverColor): void {
|
||
|
if (hoverOn) {
|
||
|
this.hover = true
|
||
|
this.hoverColor = color
|
||
|
|
||
|
this.sprite.update({
|
||
|
...this.hoverColor,
|
||
|
duration: hoverTransitionTime,
|
||
|
adjust: false,
|
||
|
temp: true
|
||
|
})
|
||
|
} else {
|
||
|
this.hover = false
|
||
|
this.hoverColor = null
|
||
|
if (this.sprite) this.sprite.resume(hoverTransitionTime)
|
||
|
}
|
||
|
this.dirty = false
|
||
|
}
|
||
|
|
||
|
getColor (): Color {
|
||
|
let feeLevelIndex = feeLevels.slice().reverse().findIndex((feeLvl) => (this.feerate || 1) >= feeLvl);
|
||
|
feeLevelIndex = feeLevelIndex >= 0 ? feeLevels.length - feeLevelIndex : feeLevelIndex;
|
||
|
return hexToColor(mempoolFeeColors[feeLevelIndex - 1] || mempoolFeeColors[mempoolFeeColors.length - 1])
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function hexToColor (hex: string): Color {
|
||
|
return {
|
||
|
r: parseInt(hex.slice(0,2), 16) / 255,
|
||
|
g: parseInt(hex.slice(2,4), 16) / 255,
|
||
|
b: parseInt(hex.slice(4,6), 16) / 255,
|
||
|
a: 1
|
||
|
}
|
||
|
}
|