mirror of
https://github.com/Retropex/bitfeed.git
synced 2025-05-28 13:02:28 +02:00
Add basic txid highlighting function
This commit is contained in:
parent
75b0bb2e4e
commit
8f03a9056c
33
client/src/components/SearchTab.svelte
Normal file
33
client/src/components/SearchTab.svelte
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<script>
|
||||||
|
import SearchIcon from '../assets/icon/cil-search.svg'
|
||||||
|
import { highlight } from '../stores.js'
|
||||||
|
|
||||||
|
let query
|
||||||
|
|
||||||
|
$: {
|
||||||
|
$highlight = [{
|
||||||
|
id: query
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style type="text/scss">
|
||||||
|
.search {
|
||||||
|
.search-input {
|
||||||
|
color: var(--palette-a);
|
||||||
|
border: solid 3px var(--grey);
|
||||||
|
margin: 0;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
border-color: var(--palette-good);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="search tab-content">
|
||||||
|
<div class="input-wrapper">
|
||||||
|
<input class="search-input" type="text" bind:value={query} placeholder="Enter a txid...">
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -15,8 +15,10 @@ import atIcon from '../assets/icon/cil-at.svg'
|
|||||||
import gridIcon from '../assets/icon/grid-icon.svg'
|
import gridIcon from '../assets/icon/grid-icon.svg'
|
||||||
import peopleIcon from '../assets/icon/cil-people.svg'
|
import peopleIcon from '../assets/icon/cil-people.svg'
|
||||||
import giftIcon from '../assets/icon/cil-gift.svg'
|
import giftIcon from '../assets/icon/cil-gift.svg'
|
||||||
|
import searchIcon from '../assets/icon/cil-search.svg'
|
||||||
import MempoolLegend from '../components/MempoolLegend.svelte'
|
import MempoolLegend from '../components/MempoolLegend.svelte'
|
||||||
import ContactTab from '../components/ContactTab.svelte'
|
import ContactTab from '../components/ContactTab.svelte'
|
||||||
|
import SearchTab from '../components/SearchTab.svelte'
|
||||||
|
|
||||||
import { sidebarToggle, overlay, currentBlock, blockVisible, haveSupporters } from '../stores.js'
|
import { sidebarToggle, overlay, currentBlock, blockVisible, haveSupporters } from '../stores.js'
|
||||||
|
|
||||||
@ -112,6 +114,14 @@ function showBlock () {
|
|||||||
<MempoolLegend />
|
<MempoolLegend />
|
||||||
</div>
|
</div>
|
||||||
</SidebarTab>
|
</SidebarTab>
|
||||||
|
<SidebarTab open={$sidebarToggle === 'search'} on:click={() => {settings('search')}} tooltip="Search & Highlight">
|
||||||
|
<span slot="tab" title="Search & Highlight">
|
||||||
|
<Icon icon={searchIcon} color="var(--bold-a)" />
|
||||||
|
</span>
|
||||||
|
<div slot="content">
|
||||||
|
<SearchTab />
|
||||||
|
</div>
|
||||||
|
</SidebarTab>
|
||||||
<SidebarTab open={$sidebarToggle === 'settings'} on:click={() => {settings('settings')}} tooltip="Settings">
|
<SidebarTab open={$sidebarToggle === 'settings'} on:click={() => {settings('settings')}} tooltip="Settings">
|
||||||
<span slot="tab" title="Settings">
|
<span slot="tab" title="Settings">
|
||||||
<Icon icon={cogIcon} color="var(--bold-a)" />
|
<Icon icon={cogIcon} color="var(--bold-a)" />
|
||||||
|
@ -5,7 +5,7 @@ import BitcoinTx from '../models/BitcoinTx.js'
|
|||||||
import BitcoinBlock from '../models/BitcoinBlock.js'
|
import BitcoinBlock from '../models/BitcoinBlock.js'
|
||||||
import TxSprite from '../models/TxSprite.js'
|
import TxSprite from '../models/TxSprite.js'
|
||||||
import { FastVertexArray } from '../utils/memory.js'
|
import { FastVertexArray } from '../utils/memory.js'
|
||||||
import { txQueueLength, txCount, mempoolCount, mempoolScreenHeight, blockVisible, currentBlock, selectedTx, blockAreaSize } from '../stores.js'
|
import { txQueueLength, txCount, mempoolCount, mempoolScreenHeight, blockVisible, currentBlock, selectedTx, blockAreaSize, highlight } from '../stores.js'
|
||||||
import config from "../config.js"
|
import config from "../config.js"
|
||||||
|
|
||||||
export default class TxController {
|
export default class TxController {
|
||||||
@ -31,6 +31,11 @@ export default class TxController {
|
|||||||
this.queueTimeout = null
|
this.queueTimeout = null
|
||||||
this.queueLength = 0
|
this.queueLength = 0
|
||||||
|
|
||||||
|
highlight.subscribe(criteria => {
|
||||||
|
this.highlightCriteria = criteria
|
||||||
|
this.applyHighlighting()
|
||||||
|
})
|
||||||
|
|
||||||
this.scheduleQueue(1000)
|
this.scheduleQueue(1000)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,8 +65,16 @@ export default class TxController {
|
|||||||
this.redoLayout({ width, height })
|
this.redoLayout({ width, height })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
applyHighlighting () {
|
||||||
|
this.poolScene.applyHighlighting(this.highlightCriteria)
|
||||||
|
if (this.blockScene) {
|
||||||
|
this.blockScene.applyHighlighting(this.highlightCriteria)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
addTx (txData) {
|
addTx (txData) {
|
||||||
const tx = new BitcoinTx(txData, this.vertexArray)
|
const tx = new BitcoinTx(txData, this.vertexArray)
|
||||||
|
tx.applyHighlighting(this.highlightCriteria)
|
||||||
if (!this.txs[tx.id] && !this.expiredTxs[tx.id]) {
|
if (!this.txs[tx.id] && !this.expiredTxs[tx.id]) {
|
||||||
this.pendingTxs.push([tx, performance.now()])
|
this.pendingTxs.push([tx, performance.now()])
|
||||||
this.pendingTxs[tx.id] = tx
|
this.pendingTxs[tx.id] = tx
|
||||||
@ -169,6 +182,7 @@ export default class TxController {
|
|||||||
block: block.id
|
block: block.id
|
||||||
}, this.vertexArray)
|
}, this.vertexArray)
|
||||||
this.txs[tx.id] = tx
|
this.txs[tx.id] = tx
|
||||||
|
this.txs[tx.id].applyHighlighting(this.highlightCriteria)
|
||||||
this.blockScene.insert(tx, false)
|
this.blockScene.insert(tx, false)
|
||||||
}
|
}
|
||||||
this.expiredTxs[block.txns[i].id] = true
|
this.expiredTxs[block.txns[i].id] = true
|
||||||
|
@ -1,6 +1,15 @@
|
|||||||
import TxView from './TxView.js'
|
import TxView from './TxView.js'
|
||||||
import config from '../config.js'
|
import config from '../config.js'
|
||||||
|
|
||||||
|
const highlightColor = {
|
||||||
|
h: 0.03,
|
||||||
|
l: 0.35
|
||||||
|
}
|
||||||
|
const hoverColor = {
|
||||||
|
h: 0.4,
|
||||||
|
l: 0.42
|
||||||
|
}
|
||||||
|
|
||||||
export default class BitcoinTx {
|
export default class BitcoinTx {
|
||||||
constructor ({ version, id, value, vbytes, inputs, outputs, time, block }, vertexArray) {
|
constructor ({ version, id, value, vbytes, inputs, outputs, time, block }, vertexArray) {
|
||||||
this.version = version
|
this.version = version
|
||||||
@ -19,6 +28,7 @@ export default class BitcoinTx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.time = time
|
this.time = time
|
||||||
|
this.highlight = false
|
||||||
|
|
||||||
// Highlight transactions to the static donation address
|
// Highlight transactions to the static donation address
|
||||||
// if (config.donationHash && this.outputs) {
|
// if (config.donationHash && this.outputs) {
|
||||||
@ -70,11 +80,31 @@ export default class BitcoinTx {
|
|||||||
this.state = this.block ? 'block' : 'pool'
|
this.state = this.block ? 'block' : 'pool'
|
||||||
}
|
}
|
||||||
|
|
||||||
hoverOn () {
|
hoverOn (color = hoverColor) {
|
||||||
if (this.view) this.view.setHover(true)
|
if (this.view) this.view.setHover(true, color)
|
||||||
}
|
}
|
||||||
|
|
||||||
hoverOff () {
|
hoverOff () {
|
||||||
if (this.view) this.view.setHover(false)
|
if (this.view) this.view.setHover(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
highlightOn (color = highlightColor) {
|
||||||
|
if (this.view) this.view.setHighlight(true, color)
|
||||||
|
this.highlight = true
|
||||||
|
}
|
||||||
|
|
||||||
|
highlightOff () {
|
||||||
|
if (this.view) this.view.setHighlight(false)
|
||||||
|
this.highlight = false
|
||||||
|
}
|
||||||
|
|
||||||
|
applyHighlighting (criteria, color = highlightColor) {
|
||||||
|
this.highlight = false
|
||||||
|
criteria.forEach(criterion => {
|
||||||
|
if (criterion.id === this.id) {
|
||||||
|
this.highlight = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.view.setHighlight(this.highlight, color)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -322,4 +322,13 @@ export default class TxPoolScene {
|
|||||||
selectAt (position) {
|
selectAt (position) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
applyHighlighting (criteria) {
|
||||||
|
Object.values(this.txs).forEach(tx => {
|
||||||
|
tx.applyHighlighting(criteria)
|
||||||
|
})
|
||||||
|
Object.values(this.hiddenTxs).forEach(tx => {
|
||||||
|
tx.applyHighlighting(criteria)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import TxSprite from './TxSprite.js'
|
import TxSprite from './TxSprite.js'
|
||||||
|
|
||||||
const hoverTransitionTime = 300
|
const highlightTransitionTime = 300
|
||||||
|
|
||||||
// converts from this class's update format to TxSprite's update format
|
// converts from this class's update format to TxSprite's update format
|
||||||
// now, id, value, position, size, color, alpha, duration, adjust
|
// now, id, value, position, size, color, alpha, duration, adjust
|
||||||
@ -22,6 +22,9 @@ export default class TxView {
|
|||||||
this.vbytes = vbytes
|
this.vbytes = vbytes
|
||||||
this.initialised = false
|
this.initialised = false
|
||||||
this.vertexArray = vertexArray
|
this.vertexArray = vertexArray
|
||||||
|
|
||||||
|
this.hover = false
|
||||||
|
this.highlight = false
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy () {
|
destroy () {
|
||||||
@ -35,9 +38,9 @@ export default class TxView {
|
|||||||
display: defines the final appearance of the sprite
|
display: defines the final appearance of the sprite
|
||||||
position: { x, y }
|
position: { x, y }
|
||||||
size: in pixels
|
size: in pixels
|
||||||
color: (in HCL space)
|
color:
|
||||||
h: hue
|
i: x coord in color texture
|
||||||
l: lightness
|
j: y coord in color texture
|
||||||
alpha: alpha transparency
|
alpha: alpha transparency
|
||||||
duration: of the tweening animation from the previous display state
|
duration: of the tweening animation from the previous display state
|
||||||
delay: for queued transitions, how long to wait after current transition
|
delay: for queued transitions, how long to wait after current transition
|
||||||
@ -53,6 +56,22 @@ export default class TxView {
|
|||||||
toSpriteUpdate(display, duration, delay, start),
|
toSpriteUpdate(display, duration, delay, start),
|
||||||
this.vertexArray
|
this.vertexArray
|
||||||
)
|
)
|
||||||
|
// apply any pending modifications
|
||||||
|
if (this.hover) {
|
||||||
|
this.sprite.update({
|
||||||
|
...this.highlightColor,
|
||||||
|
duration: highlightTransitionTime,
|
||||||
|
adjust: false,
|
||||||
|
modify: true
|
||||||
|
})
|
||||||
|
} else if (this.highlight) {
|
||||||
|
this.sprite.update({
|
||||||
|
...this.highlightColor,
|
||||||
|
duration: highlightTransitionTime,
|
||||||
|
adjust: false,
|
||||||
|
modify: true
|
||||||
|
})
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this.sprite.update(
|
this.sprite.update(
|
||||||
toSpriteUpdate(display, duration, delay, start, adjust)
|
toSpriteUpdate(display, duration, delay, start, adjust)
|
||||||
@ -60,19 +79,53 @@ export default class TxView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setHover (hoverOn) {
|
setHover (hoverOn, color) {
|
||||||
if (hoverOn) {
|
if (hoverOn) {
|
||||||
if (this.sprite) {
|
this.hover = true
|
||||||
this.sprite.update({
|
this.hoverColor = color
|
||||||
h: 1.0,
|
this.sprite.update({
|
||||||
l: 0.4,
|
...this.hoverColor,
|
||||||
duration: hoverTransitionTime,
|
duration: highlightTransitionTime,
|
||||||
modify: true
|
adjust: false,
|
||||||
})
|
modify: true
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.hover = false
|
||||||
|
this.hoverColor = null
|
||||||
|
if (this.highlight) {
|
||||||
|
if (this.sprite) {
|
||||||
|
this.sprite.update({
|
||||||
|
...this.highlightColor,
|
||||||
|
duration: highlightTransitionTime,
|
||||||
|
adjust: false,
|
||||||
|
modify: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (this.sprite) this.sprite.resume(highlightTransitionTime)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setHighlight (highlightOn, color) {
|
||||||
|
if (highlightOn) {
|
||||||
|
this.highlight = true
|
||||||
|
this.highlightColor = color
|
||||||
|
if (!this.hover) {
|
||||||
|
if (this.sprite) {
|
||||||
|
this.sprite.update({
|
||||||
|
...this.highlightColor,
|
||||||
|
duration: highlightTransitionTime,
|
||||||
|
adjust: false,
|
||||||
|
modify: true
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (this.sprite) {
|
this.highlight = false
|
||||||
this.sprite.resume(hoverTransitionTime)
|
this.highlightColor = null
|
||||||
|
if (!this.hover) {
|
||||||
|
if (this.sprite) this.sprite.resume(highlightTransitionTime)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,3 +119,5 @@ export const nativeAntialias = writable(false)
|
|||||||
const newVisitor = !localStorage.getItem('seen-welcome-msg')
|
const newVisitor = !localStorage.getItem('seen-welcome-msg')
|
||||||
// export const overlay = writable(newVisitor ? 'about' : null)
|
// export const overlay = writable(newVisitor ? 'about' : null)
|
||||||
export const overlay = writable(null)
|
export const overlay = writable(null)
|
||||||
|
|
||||||
|
export const highlight = writable([])
|
||||||
|
Loading…
Reference in New Issue
Block a user