listMorph all the things

pull/1049/head
jimmay5469 6 years ago
parent 8ca3cbcdf4
commit 0251d00e95
  1. 74
      apps/block_scout_web/assets/__tests__/pages/pending_transactions.js
  2. 41
      apps/block_scout_web/assets/__tests__/pages/transactions.js
  3. 2
      apps/block_scout_web/assets/js/pages/address.js
  4. 25
      apps/block_scout_web/assets/js/pages/blocks.js
  5. 59
      apps/block_scout_web/assets/js/pages/chain.js
  6. 87
      apps/block_scout_web/assets/js/pages/pending_transactions.js
  7. 55
      apps/block_scout_web/assets/js/pages/transactions.js
  8. 13
      apps/block_scout_web/assets/js/utils.js
  9. 38
      apps/block_scout_web/lib/block_scout_web/templates/chain/_block.html.eex
  10. 4
      apps/block_scout_web/lib/block_scout_web/templates/chain/show.html.eex

@ -1,3 +1,4 @@
import _ from 'lodash'
import { reducer, initialState } from '../../js/pages/pending_transactions'
test('CHANNEL_DISCONNECTED', () => {
@ -22,8 +23,11 @@ describe('RECEIVED_NEW_PENDING_TRANSACTION_BATCH', () => {
}
const output = reducer(state, action)
expect(output.newPendingTransactions).toEqual(['test'])
expect(output.newPendingTransactionHashesBatch.length).toEqual(0)
expect(output.pendingTransactions).toEqual([{
transactionHash: '0x00',
transactionHtml: 'test'
}])
expect(output.pendingTransactionsBatch.length).toEqual(0)
expect(output.pendingTransactionCount).toEqual(1)
})
test('large batch of transactions', () => {
@ -67,13 +71,16 @@ describe('RECEIVED_NEW_PENDING_TRANSACTION_BATCH', () => {
}
const output = reducer(state, action)
expect(output.newPendingTransactions).toEqual([])
expect(output.newPendingTransactionHashesBatch.length).toEqual(11)
expect(output.pendingTransactions).toEqual([])
expect(output.pendingTransactionsBatch.length).toEqual(11)
expect(output.pendingTransactionCount).toEqual(11)
})
test('single transaction after single transaction', () => {
const state = Object.assign({}, initialState, {
newPendingTransactions: ['test 1'],
pendingTransactions: [{
transactionHash: '0x01',
transactionHtml: 'test 1'
}],
pendingTransactionCount: 1
})
const action = {
@ -85,13 +92,16 @@ describe('RECEIVED_NEW_PENDING_TRANSACTION_BATCH', () => {
}
const output = reducer(state, action)
expect(output.newPendingTransactions).toEqual(['test 1', 'test 2'])
expect(output.newPendingTransactionHashesBatch.length).toEqual(0)
expect(output.pendingTransactions).toEqual([
{ transactionHash: '0x02', transactionHtml: 'test 2' },
{ transactionHash: '0x01', transactionHtml: 'test 1' }
])
expect(output.pendingTransactionsBatch.length).toEqual(0)
expect(output.pendingTransactionCount).toEqual(2)
})
test('single transaction after large batch of transactions', () => {
const state = Object.assign({}, initialState, {
newPendingTransactionHashesBatch: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11']
pendingTransactionsBatch: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11']
})
const action = {
type: 'RECEIVED_NEW_PENDING_TRANSACTION_BATCH',
@ -102,12 +112,12 @@ describe('RECEIVED_NEW_PENDING_TRANSACTION_BATCH', () => {
}
const output = reducer(state, action)
expect(output.newPendingTransactions).toEqual([])
expect(output.newPendingTransactionHashesBatch.length).toEqual(12)
expect(output.pendingTransactions).toEqual([])
expect(output.pendingTransactionsBatch.length).toEqual(12)
})
test('large batch of transactions after large batch of transactions', () => {
const state = Object.assign({}, initialState, {
newPendingTransactionHashesBatch: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11']
pendingTransactionsBatch: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11']
})
const action = {
type: 'RECEIVED_NEW_PENDING_TRANSACTION_BATCH',
@ -148,8 +158,8 @@ describe('RECEIVED_NEW_PENDING_TRANSACTION_BATCH', () => {
}
const output = reducer(state, action)
expect(output.newPendingTransactions).toEqual([])
expect(output.newPendingTransactionHashesBatch.length).toEqual(22)
expect(output.pendingTransactions).toEqual([])
expect(output.pendingTransactionsBatch.length).toEqual(22)
})
test('after disconnection', () => {
const state = Object.assign({}, initialState, {
@ -164,7 +174,7 @@ describe('RECEIVED_NEW_PENDING_TRANSACTION_BATCH', () => {
}
const output = reducer(state, action)
expect(output.newPendingTransactions).toEqual([])
expect(output.pendingTransactions).toEqual([])
})
test('on page 2+', () => {
const state = Object.assign({}, initialState, {
@ -180,28 +190,50 @@ describe('RECEIVED_NEW_PENDING_TRANSACTION_BATCH', () => {
}
const output = reducer(state, action)
expect(output.newPendingTransactions).toEqual([])
expect(output.pendingTransactions).toEqual([])
expect(output.pendingTransactionCount).toEqual(2)
})
})
describe('RECEIVED_NEW_TRANSACTION', () => {
test('single transaction collated', () => {
const state = { ...initialState, pendingTransactionCount: 2 }
const state = Object.assign({}, initialState, {
pendingTransactionCount: 2,
pendingTransactions: [{
transactionHash: '0x00',
transactionHtml: 'old'
}]
})
const action = {
type: 'RECEIVED_NEW_TRANSACTION',
msg: {
transactionHash: '0x00'
transactionHash: '0x00',
transactionHtml: 'new'
}
}
const output = reducer(state, action)
expect(output.pendingTransactionCount).toBe(1)
expect(output.newTransactionHashes).toEqual(['0x00'])
expect(output.pendingTransactions).toEqual([{
transactionHash: '0x00',
transactionHtml: 'new'
}])
})
test('single transaction collated after batch', () => {
const state = Object.assign({}, initialState, {
newPendingTransactionHashesBatch: ['0x01', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11']
pendingTransactionsBatch: [
{ transactionHash: '0x01' },
{ transactionHash: '2' },
{ transactionHash: '3' },
{ transactionHash: '4' },
{ transactionHash: '5' },
{ transactionHash: '6' },
{ transactionHash: '7' },
{ transactionHash: '8' },
{ transactionHash: '9' },
{ transactionHash: '10' },
{ transactionHash: '11' }
]
})
const action = {
type: 'RECEIVED_NEW_TRANSACTION',
@ -211,8 +243,8 @@ describe('RECEIVED_NEW_TRANSACTION', () => {
}
const output = reducer(state, action)
expect(output.newPendingTransactionHashesBatch.length).toEqual(10)
expect(output.newPendingTransactionHashesBatch).not.toContain('0x01')
expect(output.pendingTransactionsBatch.length).toEqual(10)
expect(_.map(output.pendingTransactionsBatch, 'transactionHash')).not.toContain('0x01')
})
test('on page 2+', () => {
const state = Object.assign({}, initialState, {

@ -8,7 +8,7 @@ test('CHANNEL_DISCONNECTED', () => {
const output = reducer(state, action)
expect(output.channelDisconnected).toBe(true)
expect(output.batchCountAccumulator).toBe(0)
expect(output.transactionsBatch.length).toBe(0)
})
describe('RECEIVED_NEW_TRANSACTION_BATCH', () => {
@ -22,8 +22,8 @@ describe('RECEIVED_NEW_TRANSACTION_BATCH', () => {
}
const output = reducer(state, action)
expect(output.newTransactions).toEqual(['test'])
expect(output.batchCountAccumulator).toEqual(0)
expect(output.transactions).toEqual([{ transactionHtml: 'test' }])
expect(output.transactionsBatch.length).toEqual(0)
expect(output.transactionCount).toEqual(1)
})
test('large batch of transactions', () => {
@ -56,13 +56,15 @@ describe('RECEIVED_NEW_TRANSACTION_BATCH', () => {
}
const output = reducer(state, action)
expect(output.newTransactions).toEqual([])
expect(output.batchCountAccumulator).toEqual(11)
expect(output.transactions).toEqual([])
expect(output.transactionsBatch.length).toEqual(11)
expect(output.transactionCount).toEqual(11)
})
test('single transaction after single transaction', () => {
const state = Object.assign({}, initialState, {
newTransactions: ['test 1']
transactions: [{
transactionHtml: 'test 1'
}]
})
const action = {
type: 'RECEIVED_NEW_TRANSACTION_BATCH',
@ -72,12 +74,15 @@ describe('RECEIVED_NEW_TRANSACTION_BATCH', () => {
}
const output = reducer(state, action)
expect(output.newTransactions).toEqual(['test 1', 'test 2'])
expect(output.batchCountAccumulator).toEqual(0)
expect(output.transactions).toEqual([
{ transactionHtml: 'test 2' },
{ transactionHtml: 'test 1' }
])
expect(output.transactionsBatch.length).toEqual(0)
})
test('single transaction after large batch of transactions', () => {
const state = Object.assign({}, initialState, {
batchCountAccumulator: 11
transactionsBatch: [1,2,3,4,5,6,7,8,9,10,11]
})
const action = {
type: 'RECEIVED_NEW_TRANSACTION_BATCH',
@ -87,12 +92,12 @@ describe('RECEIVED_NEW_TRANSACTION_BATCH', () => {
}
const output = reducer(state, action)
expect(output.newTransactions).toEqual([])
expect(output.batchCountAccumulator).toEqual(12)
expect(output.transactions).toEqual([])
expect(output.transactionsBatch.length).toEqual(12)
})
test('large batch of transactions after large batch of transactions', () => {
const state = Object.assign({}, initialState, {
batchCountAccumulator: 11
transactionsBatch: [1,2,3,4,5,6,7,8,9,10,11]
})
const action = {
type: 'RECEIVED_NEW_TRANSACTION_BATCH',
@ -122,8 +127,8 @@ describe('RECEIVED_NEW_TRANSACTION_BATCH', () => {
}
const output = reducer(state, action)
expect(output.newTransactions).toEqual([])
expect(output.batchCountAccumulator).toEqual(22)
expect(output.transactions).toEqual([])
expect(output.transactionsBatch.length).toEqual(22)
})
test('after disconnection', () => {
const state = Object.assign({}, initialState, {
@ -137,8 +142,8 @@ describe('RECEIVED_NEW_TRANSACTION_BATCH', () => {
}
const output = reducer(state, action)
expect(output.newTransactions).toEqual([])
expect(output.batchCountAccumulator).toEqual(0)
expect(output.transactions).toEqual([])
expect(output.transactionsBatch.length).toEqual(0)
})
test('on page 2+', () => {
const state = Object.assign({}, initialState, {
@ -153,8 +158,8 @@ describe('RECEIVED_NEW_TRANSACTION_BATCH', () => {
}
const output = reducer(state, action)
expect(output.newTransactions).toEqual([])
expect(output.batchCountAccumulator).toEqual(0)
expect(output.transactions).toEqual([])
expect(output.transactionsBatch.length).toEqual(0)
expect(output.transactionCount).toEqual(2)
})
})

@ -233,7 +233,7 @@ const elements = {
}
},
'[data-selector="transactions-list"]': {
load ($el, store) {
load ($el) {
return {
transactions: $el.children().map((index, el) => ({
transactionHash: el.dataset.transactionHash,

@ -3,13 +3,12 @@ import _ from 'lodash'
import URI from 'urijs'
import humps from 'humps'
import socket from '../socket'
import { updateAllAges } from '../lib/from_now'
import { createStore, connectElements, slideDownPrepend } from '../utils'
import { createStore, connectElements, listMorph } from '../utils'
export const initialState = {
channelDisconnected: false,
newBlock: null,
blocks: [],
beyondPageOne: null
}
@ -29,7 +28,10 @@ export function reducer (state = initialState, action) {
if (state.channelDisconnected || state.beyondPageOne) return state
return Object.assign({}, state, {
newBlock: action.msg.blockHtml
blocks: [
action.msg,
...state.blocks
]
})
}
default:
@ -44,10 +46,19 @@ const elements = {
}
},
'[data-selector="blocks-list"]': {
load ($el) {
return {
blocks: $el.children().map((index, el) => ({
blockNumber: parseInt(el.dataset.blockNumber),
blockHtml: el.outerHTML
})).toArray()
}
},
render ($el, state, oldState) {
if (oldState.newBlock === state.newBlock) return
slideDownPrepend($el, state.newBlock)
updateAllAges()
if (oldState.blocks === state.blocks) return
const container = $el[0]
const newElements = _.map(state.blocks, ({ blockHtml }) => $(blockHtml)[0])
listMorph(container, newElements, { key: 'dataset.blockNumber' })
}
}
}

@ -3,9 +3,8 @@ import _ from 'lodash'
import humps from 'humps'
import numeral from 'numeral'
import socket from '../socket'
import { updateAllAges } from '../lib/from_now'
import { exchangeRateChannel, formatUsdValue } from '../lib/currency'
import { createStore, connectElements, slideDownPrepend } from '../utils'
import { createStore, connectElements, listMorph } from '../utils'
import { createMarketHistoryChart } from '../lib/market_history_chart'
export const initialState = {
@ -13,8 +12,8 @@ export const initialState = {
availableSupply: null,
averageBlockTime: null,
marketHistoryData: null,
newBlock: null,
newTransaction: null,
blocks: null,
transactions: null,
transactionCount: null,
usdMarketCap: null
}
@ -32,7 +31,10 @@ export function reducer (state = initialState, action) {
case 'RECEIVED_NEW_BLOCK': {
return Object.assign({}, state, {
averageBlockTime: action.msg.averageBlockTime,
newBlock: action.msg.chainBlockHtml
blocks: [
action.msg,
...state.blocks.slice(0, -1)
]
})
}
case 'RECEIVED_NEW_EXCHANGE_RATE': {
@ -44,8 +46,11 @@ export function reducer (state = initialState, action) {
}
case 'RECEIVED_NEW_TRANSACTION': {
return Object.assign({}, state, {
newTransaction: action.msg.transactionHtml,
transactionCount: state.transactionCount + 1
transactionCount: state.transactionCount + 1,
transactions: [
action.msg,
...state.transactions.slice(0, -1)
]
})
}
default:
@ -92,19 +97,35 @@ const elements = {
}
},
'[data-selector="chain-block-list"]': {
load ($el) {
return {
blocks: $el.children().map((index, el) => ({
blockNumber: parseInt(el.dataset.blockNumber),
chainBlockHtml: el.outerHTML
})).toArray()
}
},
render ($el, state, oldState) {
if (oldState.newBlock === state.newBlock) return
$el.children().last().remove()
$el.prepend(newBlockHtml(state.newBlock))
updateAllAges()
if (oldState.blocks === state.blocks) return
const container = $el[0]
const newElements = _.map(state.blocks, ({ chainBlockHtml }) => $(chainBlockHtml)[0])
listMorph(container, newElements, { key: 'dataset.blockNumber', horizontal: true })
}
},
'[data-selector="transactions-list"]': {
load ($el) {
return {
transactions: $el.children().map((index, el) => ({
transactionHash: el.dataset.transactionHash,
transactionHtml: el.outerHTML
})).toArray()
}
},
render ($el, state, oldState) {
if (oldState.newTransaction === state.newTransaction) return
$el.children().last().remove()
slideDownPrepend($el, state.newTransaction)
updateAllAges()
if (oldState.transactions === state.transactions) return
const container = $el[0]
const newElements = _.map(state.transactions, ({ transactionHtml }) => $(transactionHtml)[0])
listMorph(container, newElements, { key: 'dataset.transactionHash' })
}
}
}
@ -140,11 +161,3 @@ if ($chainDetailsPage.length) {
msg: humps.camelizeKeys(msg)
}))
}
function newBlockHtml (blockHtml) {
return `
<div class="col-lg-3 fade-up-blocks-chain">
${blockHtml}
</div>
`
}

@ -4,18 +4,19 @@ import URI from 'urijs'
import humps from 'humps'
import numeral from 'numeral'
import socket from '../socket'
import { updateAllAges } from '../lib/from_now'
import { createStore, connectElements, batchChannel, slideDownPrepend, slideUpRemove } from '../utils'
import { createStore, connectElements, batchChannel, listMorph } from '../utils'
const BATCH_THRESHOLD = 10
export const initialState = {
newPendingTransactionHashesBatch: [],
beyondPageOne: null,
channelDisconnected: false,
newPendingTransactions: [],
newTransactionHashes: [],
pendingTransactionCount: null
pendingTransactionCount: null,
pendingTransactions: [],
pendingTransactionsBatch: [],
beyondPageOne: null
}
export function reducer (state = initialState, action) {
@ -33,9 +34,9 @@ export function reducer (state = initialState, action) {
if (state.channelDisconnected) return state
return Object.assign({}, state, {
newPendingTransactionHashesBatch: _.without(state.newPendingTransactionHashesBatch, action.msg.transactionHash),
pendingTransactionCount: state.pendingTransactionCount - 1,
newTransactionHashes: [action.msg.transactionHash]
pendingTransactions: state.pendingTransactions.map((transaction) => action.msg.transactionHash === transaction.transactionHash ? action.msg : transaction),
pendingTransactionsBatch: state.pendingTransactionsBatch.filter((transaction) => action.msg.transactionHash !== transaction.transactionHash),
pendingTransactionCount: state.pendingTransactionCount - 1
})
}
case 'RECEIVED_NEW_PENDING_TRANSACTION_BATCH': {
@ -45,24 +46,29 @@ export function reducer (state = initialState, action) {
if (state.beyondPageOne) return Object.assign({}, state, { pendingTransactionCount })
if (!state.newPendingTransactionHashesBatch.length && action.msgs.length < BATCH_THRESHOLD) {
if (!state.pendingTransactionsBatch.length && action.msgs.length < BATCH_THRESHOLD) {
return Object.assign({}, state, {
newPendingTransactions: [
...state.newPendingTransactions,
..._.map(action.msgs, 'transactionHtml')
pendingTransactions: [
...action.msgs.reverse(),
...state.pendingTransactions
],
pendingTransactionCount
})
} else {
return Object.assign({}, state, {
newPendingTransactionHashesBatch: [
...state.newPendingTransactionHashesBatch,
..._.map(action.msgs, 'transactionHash')
pendingTransactionsBatch: [
...action.msgs.reverse(),
...state.pendingTransactionsBatch
],
pendingTransactionCount
})
}
}
case 'REMOVE_PENDING_TRANSACTION': {
return Object.assign({}, state, {
pendingTransactions: state.pendingTransactions.filter((transaction) => action.msg.transactionHash !== transaction.transactionHash)
})
}
default:
return state
}
@ -77,9 +83,9 @@ const elements = {
'[data-selector="channel-batching-count"]': {
render ($el, state, oldState) {
const $channelBatching = $('[data-selector="channel-batching-message"]')
if (state.newPendingTransactionHashesBatch.length) {
if (state.pendingTransactionsBatch.length) {
$channelBatching.show()
$el[0].innerHTML = numeral(state.newPendingTransactionHashesBatch.length).format()
$el[0].innerHTML = numeral(state.pendingTransactionsBatch.length).format()
} else {
$channelBatching.hide()
}
@ -95,24 +101,19 @@ const elements = {
}
},
'[data-selector="transactions-pending-list"]': {
render ($el, state, oldState) {
if (oldState.newTransactionHashes !== state.newTransactionHashes && state.newTransactionHashes.length > 0) {
const $transaction = $(`[data-transaction-hash="${state.newTransactionHashes[0]}"]`)
$transaction.addClass('shrink-out')
setTimeout(() => {
if ($transaction.length === 1 && $transaction.siblings().length === 0 && state.pendingTransactionCount > 0) {
window.location.href = URI(window.location).removeQuery('inserted_at').removeQuery('hash').toString()
} else {
slideUpRemove($transaction)
}
}, 400)
}
if (oldState.newPendingTransactions !== state.newPendingTransactions) {
const newTransactionsToInsert = state.newPendingTransactions.slice(oldState.newPendingTransactions.length)
slideDownPrepend($el, newTransactionsToInsert.reverse().join(''))
updateAllAges()
load ($el) {
return {
pendingTransactions: $el.children().map((index, el) => ({
transactionHash: el.dataset.transactionHash,
transactionHtml: el.outerHTML
})).toArray()
}
},
render ($el, state, oldState) {
if (oldState.pendingTransactions === state.pendingTransactions) return
const container = $el[0]
const newElements = _.map(state.pendingTransactions, ({ transactionHtml }) => $(transactionHtml)[0])
listMorph(container, newElements, { key: 'dataset.transactionHash' })
}
}
}
@ -131,10 +132,16 @@ if ($transactionPendingListPage.length) {
transactionsChannel.onError(() => store.dispatch({
type: 'CHANNEL_DISCONNECTED'
}))
transactionsChannel.on('transaction', (msg) => store.dispatch({
type: 'RECEIVED_NEW_TRANSACTION',
msg: humps.camelizeKeys(msg)
}))
transactionsChannel.on('transaction', (msg) => {
store.dispatch({
type: 'RECEIVED_NEW_TRANSACTION',
msg: humps.camelizeKeys(msg)
})
setTimeout(() => store.dispatch({
type: 'REMOVE_PENDING_TRANSACTION',
msg: humps.camelizeKeys(msg)
}), 1000)
})
const pendingTransactionsChannel = socket.channel(`transactions:new_pending_transaction`)
pendingTransactionsChannel.join()

@ -4,17 +4,19 @@ import URI from 'urijs'
import humps from 'humps'
import numeral from 'numeral'
import socket from '../socket'
import { updateAllAges } from '../lib/from_now'
import { createStore, connectElements, batchChannel, slideDownPrepend } from '../utils'
import { createStore, connectElements, batchChannel, listMorph } from '../utils'
const BATCH_THRESHOLD = 10
export const initialState = {
batchCountAccumulator: 0,
beyondPageOne: null,
channelDisconnected: false,
newTransactions: [],
transactionCount: null
transactionCount: null,
transactions: [],
transactionsBatch: [],
beyondPageOne: null
}
export function reducer (state = initialState, action) {
@ -26,7 +28,7 @@ export function reducer (state = initialState, action) {
case 'CHANNEL_DISCONNECTED': {
return Object.assign({}, state, {
channelDisconnected: true,
batchCountAccumulator: 0
transactionsBatch: []
})
}
case 'RECEIVED_NEW_TRANSACTION_BATCH': {
@ -36,17 +38,20 @@ export function reducer (state = initialState, action) {
if (state.beyondPageOne) return Object.assign({}, state, { transactionCount })
if (!state.batchCountAccumulator && action.msgs.length < BATCH_THRESHOLD) {
if (!state.transactionsBatch.length && action.msgs.length < BATCH_THRESHOLD) {
return Object.assign({}, state, {
newTransactions: [
...state.newTransactions,
..._.map(action.msgs, 'transactionHtml')
transactions: [
...action.msgs.reverse(),
...state.transactions
],
transactionCount
})
} else {
return Object.assign({}, state, {
batchCountAccumulator: state.batchCountAccumulator + action.msgs.length,
transactionsBatch: [
...action.msgs.reverse(),
...state.transactionsBatch
],
transactionCount
})
}
@ -65,12 +70,9 @@ const elements = {
'[data-selector="channel-batching-count"]': {
render ($el, state, oldState) {
const $channelBatching = $('[data-selector="channel-batching-message"]')
if (state.batchCountAccumulator) {
$channelBatching.show()
$el[0].innerHTML = numeral(state.batchCountAccumulator).format()
} else {
$channelBatching.hide()
}
if (!state.transactionsBatch.length) return $channelBatching.hide()
$channelBatching.show()
$el[0].innerHTML = numeral(state.transactionsBatch.length).format()
}
},
'[data-selector="transaction-count"]': {
@ -83,12 +85,19 @@ const elements = {
}
},
'[data-selector="transactions-list"]': {
load ($el, store) {
return {
transactions: $el.children().map((index, el) => ({
transactionHash: el.dataset.transactionHash,
transactionHtml: el.outerHTML
})).toArray()
}
},
render ($el, state, oldState) {
if (oldState.newTransactions === state.newTransactions) return
const newTransactionsToInsert = state.newTransactions.slice(oldState.newTransactions.length)
slideDownPrepend($el, newTransactionsToInsert.reverse().join(''))
updateAllAges()
if (oldState.transactions === state.transactions) return
const container = $el[0]
const newElements = _.map(state.transactions, ({ transactionHtml }) => $(transactionHtml)[0])
listMorph(container, newElements, { key: 'dataset.transactionHash' })
}
}
}

@ -47,28 +47,21 @@ export function connectElements ({ elements, store }) {
})
}
export function slideDownPrepend ($container, content) {
smarterSlideDown($(content), {
insert ($el) {
$container.prepend($el)
}
})
}
export function slideDownAppend ($container, content) {
function slideDownAppend ($container, content) {
smarterSlideDown($(content), {
insert ($el) {
$container.append($el)
}
})
}
export function slideDownBefore ($container, content) {
function slideDownBefore ($container, content) {
smarterSlideDown($(content), {
insert ($el) {
$container.before($el)
}
})
}
export function slideUpRemove ($el) {
function slideUpRemove ($el) {
smarterSlideUp($el, {
complete () {
$el.remove()

@ -1,20 +1,22 @@
<div class="tile tile-type-block d-flex flex-column" data-selector="chain-block" data-block-number="<%= @block.number %>">
<%= link(
@block,
class: "tile-title",
to: block_path(BlockScoutWeb.Endpoint, :show, @block),
"data-selector": "block-number"
) %>
<div>
<span class="mr-2"> <%= gettext("%{count} Transactions", count: Enum.count(@block.transactions)) %> </span>
<span class="text-nowrap" data-from-now="<%= @block.timestamp %>"> </span>
</div>
<span class="text-truncate">
<%= gettext "Miner" %>
<div class="col-lg-3 fade-up-blocks-chain" data-selector="chain-block" data-block-number="<%= @block.number %>">
<div class="tile tile-type-block d-flex flex-column">
<%= link(
@block,
class: "tile-title",
to: block_path(BlockScoutWeb.Endpoint, :show, @block),
"data-selector": "block-number"
) %>
<div>
<span class="mr-2"> <%= gettext("%{count} Transactions", count: Enum.count(@block.transactions)) %> </span>
<span class="text-nowrap" data-from-now="<%= @block.timestamp %>"> </span>
</div>
<span class="text-truncate">
<%= gettext "Miner" %>
<%= render BlockScoutWeb.AddressView,
"_link.html",
address: @block.miner,
contract: false %>
</span>
<%= render BlockScoutWeb.AddressView,
"_link.html",
address: @block.miner,
contract: false %>
</span>
</div>
</div>

@ -57,9 +57,7 @@
<h2 class="card-title"><%= gettext "Blocks" %></h2>
<div class="row" data-selector="chain-block-list">
<%= for block <- @blocks do %>
<div class="col-lg-3 fade-up-blocks-chain">
<%= render BlockScoutWeb.ChainView, "_block.html", block: block %>
</div>
<%= render BlockScoutWeb.ChainView, "_block.html", block: block %>
<% end %>
</div>
</div>

Loading…
Cancel
Save