One JS page file per route

pull/1030/head
jimmay5469 6 years ago
parent a33d5ef48f
commit 52fb43ae4a
  1. 2
      apps/block_scout_web/assets/__tests__/pages/blocks.js
  2. 232
      apps/block_scout_web/assets/__tests__/pages/pending_transactions.js
  3. 382
      apps/block_scout_web/assets/__tests__/pages/transaction.js
  4. 160
      apps/block_scout_web/assets/__tests__/pages/transactions.js
  5. 12
      apps/block_scout_web/assets/js/app.js
  6. 0
      apps/block_scout_web/assets/js/pages/blocks.js
  7. 131
      apps/block_scout_web/assets/js/pages/pending_transactions.js
  8. 186
      apps/block_scout_web/assets/js/pages/transaction.js
  9. 100
      apps/block_scout_web/assets/js/pages/transactions.js

@ -1,4 +1,4 @@
import { reducer, initialState } from '../../js/pages/block' import { reducer, initialState } from '../../js/pages/blocks'
test('CHANNEL_DISCONNECTED', () => { test('CHANNEL_DISCONNECTED', () => {
const state = initialState const state = initialState

@ -0,0 +1,232 @@
import { reducer, initialState } from '../../js/pages/pending_transactions'
test('CHANNEL_DISCONNECTED', () => {
const state = initialState
const action = {
type: 'CHANNEL_DISCONNECTED'
}
const output = reducer(state, action)
expect(output.channelDisconnected).toBe(true)
})
describe('RECEIVED_NEW_PENDING_TRANSACTION_BATCH', () => {
test('single transaction', () => {
const state = initialState
const action = {
type: 'RECEIVED_NEW_PENDING_TRANSACTION_BATCH',
msgs: [{
transactionHash: '0x00',
transactionHtml: 'test'
}]
}
const output = reducer(state, action)
expect(output.newPendingTransactions).toEqual(['test'])
expect(output.newPendingTransactionHashesBatch.length).toEqual(0)
expect(output.pendingTransactionCount).toEqual(1)
})
test('large batch of transactions', () => {
const state = initialState
const action = {
type: 'RECEIVED_NEW_PENDING_TRANSACTION_BATCH',
msgs: [{
transactionHash: '0x01',
transactionHtml: 'test 1'
},{
transactionHash: '0x02',
transactionHtml: 'test 2'
},{
transactionHash: '0x03',
transactionHtml: 'test 3'
},{
transactionHash: '0x04',
transactionHtml: 'test 4'
},{
transactionHash: '0x05',
transactionHtml: 'test 5'
},{
transactionHash: '0x06',
transactionHtml: 'test 6'
},{
transactionHash: '0x07',
transactionHtml: 'test 7'
},{
transactionHash: '0x08',
transactionHtml: 'test 8'
},{
transactionHash: '0x09',
transactionHtml: 'test 9'
},{
transactionHash: '0x10',
transactionHtml: 'test 10'
},{
transactionHash: '0x11',
transactionHtml: 'test 11'
}]
}
const output = reducer(state, action)
expect(output.newPendingTransactions).toEqual([])
expect(output.newPendingTransactionHashesBatch.length).toEqual(11)
expect(output.pendingTransactionCount).toEqual(11)
})
test('single transaction after single transaction', () => {
const state = Object.assign({}, initialState, {
newPendingTransactions: ['test 1'],
pendingTransactionCount: 1
})
const action = {
type: 'RECEIVED_NEW_PENDING_TRANSACTION_BATCH',
msgs: [{
transactionHash: '0x02',
transactionHtml: 'test 2'
}]
}
const output = reducer(state, action)
expect(output.newPendingTransactions).toEqual(['test 1', 'test 2'])
expect(output.newPendingTransactionHashesBatch.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']
})
const action = {
type: 'RECEIVED_NEW_PENDING_TRANSACTION_BATCH',
msgs: [{
transactionHash: '0x12',
transactionHtml: 'test 12'
}]
}
const output = reducer(state, action)
expect(output.newPendingTransactions).toEqual([])
expect(output.newPendingTransactionHashesBatch.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']
})
const action = {
type: 'RECEIVED_NEW_PENDING_TRANSACTION_BATCH',
msgs: [{
transactionHash: '0x12',
transactionHtml: 'test 12'
},{
transactionHash: '0x13',
transactionHtml: 'test 13'
},{
transactionHash: '0x14',
transactionHtml: 'test 14'
},{
transactionHash: '0x15',
transactionHtml: 'test 15'
},{
transactionHash: '0x16',
transactionHtml: 'test 16'
},{
transactionHash: '0x17',
transactionHtml: 'test 17'
},{
transactionHash: '0x18',
transactionHtml: 'test 18'
},{
transactionHash: '0x19',
transactionHtml: 'test 19'
},{
transactionHash: '0x20',
transactionHtml: 'test 20'
},{
transactionHash: '0x21',
transactionHtml: 'test 21'
},{
transactionHash: '0x22',
transactionHtml: 'test 22'
}]
}
const output = reducer(state, action)
expect(output.newPendingTransactions).toEqual([])
expect(output.newPendingTransactionHashesBatch.length).toEqual(22)
})
test('after disconnection', () => {
const state = Object.assign({}, initialState, {
channelDisconnected: true
})
const action = {
type: 'RECEIVED_NEW_PENDING_TRANSACTION_BATCH',
msgs: [{
transactionHash: '0x00',
transactionHtml: 'test'
}]
}
const output = reducer(state, action)
expect(output.newPendingTransactions).toEqual([])
})
test('on page 2+', () => {
const state = Object.assign({}, initialState, {
beyondPageOne: true,
pendingTransactionCount: 1
})
const action = {
type: 'RECEIVED_NEW_PENDING_TRANSACTION_BATCH',
msgs: [{
transactionHash: '0x00',
transactionHtml: 'test'
}]
}
const output = reducer(state, action)
expect(output.newPendingTransactions).toEqual([])
expect(output.pendingTransactionCount).toEqual(2)
})
})
describe('RECEIVED_NEW_TRANSACTION', () => {
test('single transaction collated', () => {
const state = { ...initialState, pendingTransactionCount: 2 }
const action = {
type: 'RECEIVED_NEW_TRANSACTION',
msg: {
transactionHash: '0x00'
}
}
const output = reducer(state, action)
expect(output.pendingTransactionCount).toBe(1)
expect(output.newTransactionHashes).toEqual(['0x00'])
})
test('single transaction collated after batch', () => {
const state = Object.assign({}, initialState, {
newPendingTransactionHashesBatch: ['0x01', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11']
})
const action = {
type: 'RECEIVED_NEW_TRANSACTION',
msg: {
transactionHash: '0x01'
}
}
const output = reducer(state, action)
expect(output.newPendingTransactionHashesBatch.length).toEqual(10)
expect(output.newPendingTransactionHashesBatch).not.toContain('0x01')
})
test('on page 2+', () => {
const state = Object.assign({}, initialState, {
beyondPageOne: true,
pendingTransactionCount: 2
})
const action = {
type: 'RECEIVED_NEW_TRANSACTION',
msg: {
transactionHash: '0x01'
}
}
const output = reducer(state, action)
expect(output.pendingTransactionCount).toEqual(1)
})
})

@ -1,16 +1,5 @@
import { reducer, initialState } from '../../js/pages/transaction' import { reducer, initialState } from '../../js/pages/transaction'
test('CHANNEL_DISCONNECTED', () => {
const state = initialState
const action = {
type: 'CHANNEL_DISCONNECTED'
}
const output = reducer(state, action)
expect(output.channelDisconnected).toBe(true)
expect(output.batchCountAccumulator).toBe(0)
})
test('RECEIVED_NEW_BLOCK', () => { test('RECEIVED_NEW_BLOCK', () => {
const state = { ...initialState, blockNumber: 1 } const state = { ...initialState, blockNumber: 1 }
const action = { const action = {
@ -23,374 +12,3 @@ test('RECEIVED_NEW_BLOCK', () => {
expect(output.confirmations).toBe(4) expect(output.confirmations).toBe(4)
}) })
describe('RECEIVED_NEW_PENDING_TRANSACTION_BATCH', () => {
test('single transaction', () => {
const state = initialState
const action = {
type: 'RECEIVED_NEW_PENDING_TRANSACTION_BATCH',
msgs: [{
transactionHash: '0x00',
transactionHtml: 'test'
}]
}
const output = reducer(state, action)
expect(output.newPendingTransactions).toEqual(['test'])
expect(output.newPendingTransactionHashesBatch.length).toEqual(0)
expect(output.pendingTransactionCount).toEqual(1)
})
test('large batch of transactions', () => {
const state = initialState
const action = {
type: 'RECEIVED_NEW_PENDING_TRANSACTION_BATCH',
msgs: [{
transactionHash: '0x01',
transactionHtml: 'test 1'
},{
transactionHash: '0x02',
transactionHtml: 'test 2'
},{
transactionHash: '0x03',
transactionHtml: 'test 3'
},{
transactionHash: '0x04',
transactionHtml: 'test 4'
},{
transactionHash: '0x05',
transactionHtml: 'test 5'
},{
transactionHash: '0x06',
transactionHtml: 'test 6'
},{
transactionHash: '0x07',
transactionHtml: 'test 7'
},{
transactionHash: '0x08',
transactionHtml: 'test 8'
},{
transactionHash: '0x09',
transactionHtml: 'test 9'
},{
transactionHash: '0x10',
transactionHtml: 'test 10'
},{
transactionHash: '0x11',
transactionHtml: 'test 11'
}]
}
const output = reducer(state, action)
expect(output.newPendingTransactions).toEqual([])
expect(output.newPendingTransactionHashesBatch.length).toEqual(11)
expect(output.pendingTransactionCount).toEqual(11)
})
test('single transaction after single transaction', () => {
const state = Object.assign({}, initialState, {
newPendingTransactions: ['test 1'],
pendingTransactionCount: 1
})
const action = {
type: 'RECEIVED_NEW_PENDING_TRANSACTION_BATCH',
msgs: [{
transactionHash: '0x02',
transactionHtml: 'test 2'
}]
}
const output = reducer(state, action)
expect(output.newPendingTransactions).toEqual(['test 1', 'test 2'])
expect(output.newPendingTransactionHashesBatch.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']
})
const action = {
type: 'RECEIVED_NEW_PENDING_TRANSACTION_BATCH',
msgs: [{
transactionHash: '0x12',
transactionHtml: 'test 12'
}]
}
const output = reducer(state, action)
expect(output.newPendingTransactions).toEqual([])
expect(output.newPendingTransactionHashesBatch.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']
})
const action = {
type: 'RECEIVED_NEW_PENDING_TRANSACTION_BATCH',
msgs: [{
transactionHash: '0x12',
transactionHtml: 'test 12'
},{
transactionHash: '0x13',
transactionHtml: 'test 13'
},{
transactionHash: '0x14',
transactionHtml: 'test 14'
},{
transactionHash: '0x15',
transactionHtml: 'test 15'
},{
transactionHash: '0x16',
transactionHtml: 'test 16'
},{
transactionHash: '0x17',
transactionHtml: 'test 17'
},{
transactionHash: '0x18',
transactionHtml: 'test 18'
},{
transactionHash: '0x19',
transactionHtml: 'test 19'
},{
transactionHash: '0x20',
transactionHtml: 'test 20'
},{
transactionHash: '0x21',
transactionHtml: 'test 21'
},{
transactionHash: '0x22',
transactionHtml: 'test 22'
}]
}
const output = reducer(state, action)
expect(output.newPendingTransactions).toEqual([])
expect(output.newPendingTransactionHashesBatch.length).toEqual(22)
})
test('after disconnection', () => {
const state = Object.assign({}, initialState, {
channelDisconnected: true
})
const action = {
type: 'RECEIVED_NEW_PENDING_TRANSACTION_BATCH',
msgs: [{
transactionHash: '0x00',
transactionHtml: 'test'
}]
}
const output = reducer(state, action)
expect(output.newPendingTransactions).toEqual([])
expect(output.batchCountAccumulator).toEqual(0)
})
test('on page 2+', () => {
const state = Object.assign({}, initialState, {
beyondPageOne: true,
pendingTransactionCount: 1
})
const action = {
type: 'RECEIVED_NEW_PENDING_TRANSACTION_BATCH',
msgs: [{
transactionHash: '0x00',
transactionHtml: 'test'
}]
}
const output = reducer(state, action)
expect(output.newPendingTransactions).toEqual([])
expect(output.batchCountAccumulator).toEqual(0)
expect(output.pendingTransactionCount).toEqual(2)
})
})
describe('RECEIVED_NEW_TRANSACTION', () => {
test('single transaction collated', () => {
const state = { ...initialState, pendingTransactionCount: 2 }
const action = {
type: 'RECEIVED_NEW_TRANSACTION',
msg: {
transactionHash: '0x00'
}
}
const output = reducer(state, action)
expect(output.pendingTransactionCount).toBe(1)
expect(output.newTransactionHashes).toEqual(['0x00'])
})
test('single transaction collated after batch', () => {
const state = Object.assign({}, initialState, {
newPendingTransactionHashesBatch: ['0x01', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11']
})
const action = {
type: 'RECEIVED_NEW_TRANSACTION',
msg: {
transactionHash: '0x01'
}
}
const output = reducer(state, action)
expect(output.newPendingTransactionHashesBatch.length).toEqual(10)
expect(output.newPendingTransactionHashesBatch).not.toContain('0x01')
})
test('on page 2+', () => {
const state = Object.assign({}, initialState, {
beyondPageOne: true,
pendingTransactionCount: 2
})
const action = {
type: 'RECEIVED_NEW_TRANSACTION',
msg: {
transactionHash: '0x01'
}
}
const output = reducer(state, action)
expect(output.pendingTransactionCount).toEqual(1)
})
})
describe('RECEIVED_NEW_TRANSACTION_BATCH', () => {
test('single transaction', () => {
const state = initialState
const action = {
type: 'RECEIVED_NEW_TRANSACTION_BATCH',
msgs: [{
transactionHtml: 'test'
}]
}
const output = reducer(state, action)
expect(output.newTransactions).toEqual(['test'])
expect(output.batchCountAccumulator).toEqual(0)
expect(output.transactionCount).toEqual(1)
})
test('large batch of transactions', () => {
const state = initialState
const action = {
type: 'RECEIVED_NEW_TRANSACTION_BATCH',
msgs: [{
transactionHtml: 'test 1'
},{
transactionHtml: 'test 2'
},{
transactionHtml: 'test 3'
},{
transactionHtml: 'test 4'
},{
transactionHtml: 'test 5'
},{
transactionHtml: 'test 6'
},{
transactionHtml: 'test 7'
},{
transactionHtml: 'test 8'
},{
transactionHtml: 'test 9'
},{
transactionHtml: 'test 10'
},{
transactionHtml: 'test 11'
}]
}
const output = reducer(state, action)
expect(output.newTransactions).toEqual([])
expect(output.batchCountAccumulator).toEqual(11)
expect(output.transactionCount).toEqual(11)
})
test('single transaction after single transaction', () => {
const state = Object.assign({}, initialState, {
newTransactions: ['test 1']
})
const action = {
type: 'RECEIVED_NEW_TRANSACTION_BATCH',
msgs: [{
transactionHtml: 'test 2'
}]
}
const output = reducer(state, action)
expect(output.newTransactions).toEqual(['test 1', 'test 2'])
expect(output.batchCountAccumulator).toEqual(0)
})
test('single transaction after large batch of transactions', () => {
const state = Object.assign({}, initialState, {
batchCountAccumulator: 11
})
const action = {
type: 'RECEIVED_NEW_TRANSACTION_BATCH',
msgs: [{
transactionHtml: 'test 12'
}]
}
const output = reducer(state, action)
expect(output.newTransactions).toEqual([])
expect(output.batchCountAccumulator).toEqual(12)
})
test('large batch of transactions after large batch of transactions', () => {
const state = Object.assign({}, initialState, {
batchCountAccumulator: 11
})
const action = {
type: 'RECEIVED_NEW_TRANSACTION_BATCH',
msgs: [{
transactionHtml: 'test 12'
},{
transactionHtml: 'test 13'
},{
transactionHtml: 'test 14'
},{
transactionHtml: 'test 15'
},{
transactionHtml: 'test 16'
},{
transactionHtml: 'test 17'
},{
transactionHtml: 'test 18'
},{
transactionHtml: 'test 19'
},{
transactionHtml: 'test 20'
},{
transactionHtml: 'test 21'
},{
transactionHtml: 'test 22'
}]
}
const output = reducer(state, action)
expect(output.newTransactions).toEqual([])
expect(output.batchCountAccumulator).toEqual(22)
})
test('after disconnection', () => {
const state = Object.assign({}, initialState, {
channelDisconnected: true
})
const action = {
type: 'RECEIVED_NEW_TRANSACTION_BATCH',
msgs: [{
transactionHtml: 'test'
}]
}
const output = reducer(state, action)
expect(output.newTransactions).toEqual([])
expect(output.batchCountAccumulator).toEqual(0)
})
test('on page 2+', () => {
const state = Object.assign({}, initialState, {
beyondPageOne: true,
transactionCount: 1
})
const action = {
type: 'RECEIVED_NEW_TRANSACTION_BATCH',
msgs: [{
transactionHtml: 'test'
}]
}
const output = reducer(state, action)
expect(output.newTransactions).toEqual([])
expect(output.batchCountAccumulator).toEqual(0)
expect(output.transactionCount).toEqual(2)
})
})

@ -0,0 +1,160 @@
import { reducer, initialState } from '../../js/pages/transactions'
test('CHANNEL_DISCONNECTED', () => {
const state = initialState
const action = {
type: 'CHANNEL_DISCONNECTED'
}
const output = reducer(state, action)
expect(output.channelDisconnected).toBe(true)
expect(output.batchCountAccumulator).toBe(0)
})
describe('RECEIVED_NEW_TRANSACTION_BATCH', () => {
test('single transaction', () => {
const state = initialState
const action = {
type: 'RECEIVED_NEW_TRANSACTION_BATCH',
msgs: [{
transactionHtml: 'test'
}]
}
const output = reducer(state, action)
expect(output.newTransactions).toEqual(['test'])
expect(output.batchCountAccumulator).toEqual(0)
expect(output.transactionCount).toEqual(1)
})
test('large batch of transactions', () => {
const state = initialState
const action = {
type: 'RECEIVED_NEW_TRANSACTION_BATCH',
msgs: [{
transactionHtml: 'test 1'
},{
transactionHtml: 'test 2'
},{
transactionHtml: 'test 3'
},{
transactionHtml: 'test 4'
},{
transactionHtml: 'test 5'
},{
transactionHtml: 'test 6'
},{
transactionHtml: 'test 7'
},{
transactionHtml: 'test 8'
},{
transactionHtml: 'test 9'
},{
transactionHtml: 'test 10'
},{
transactionHtml: 'test 11'
}]
}
const output = reducer(state, action)
expect(output.newTransactions).toEqual([])
expect(output.batchCountAccumulator).toEqual(11)
expect(output.transactionCount).toEqual(11)
})
test('single transaction after single transaction', () => {
const state = Object.assign({}, initialState, {
newTransactions: ['test 1']
})
const action = {
type: 'RECEIVED_NEW_TRANSACTION_BATCH',
msgs: [{
transactionHtml: 'test 2'
}]
}
const output = reducer(state, action)
expect(output.newTransactions).toEqual(['test 1', 'test 2'])
expect(output.batchCountAccumulator).toEqual(0)
})
test('single transaction after large batch of transactions', () => {
const state = Object.assign({}, initialState, {
batchCountAccumulator: 11
})
const action = {
type: 'RECEIVED_NEW_TRANSACTION_BATCH',
msgs: [{
transactionHtml: 'test 12'
}]
}
const output = reducer(state, action)
expect(output.newTransactions).toEqual([])
expect(output.batchCountAccumulator).toEqual(12)
})
test('large batch of transactions after large batch of transactions', () => {
const state = Object.assign({}, initialState, {
batchCountAccumulator: 11
})
const action = {
type: 'RECEIVED_NEW_TRANSACTION_BATCH',
msgs: [{
transactionHtml: 'test 12'
},{
transactionHtml: 'test 13'
},{
transactionHtml: 'test 14'
},{
transactionHtml: 'test 15'
},{
transactionHtml: 'test 16'
},{
transactionHtml: 'test 17'
},{
transactionHtml: 'test 18'
},{
transactionHtml: 'test 19'
},{
transactionHtml: 'test 20'
},{
transactionHtml: 'test 21'
},{
transactionHtml: 'test 22'
}]
}
const output = reducer(state, action)
expect(output.newTransactions).toEqual([])
expect(output.batchCountAccumulator).toEqual(22)
})
test('after disconnection', () => {
const state = Object.assign({}, initialState, {
channelDisconnected: true
})
const action = {
type: 'RECEIVED_NEW_TRANSACTION_BATCH',
msgs: [{
transactionHtml: 'test'
}]
}
const output = reducer(state, action)
expect(output.newTransactions).toEqual([])
expect(output.batchCountAccumulator).toEqual(0)
})
test('on page 2+', () => {
const state = Object.assign({}, initialState, {
beyondPageOne: true,
transactionCount: 1
})
const action = {
type: 'RECEIVED_NEW_TRANSACTION_BATCH',
msgs: [{
transactionHtml: 'test'
}]
}
const output = reducer(state, action)
expect(output.newTransactions).toEqual([])
expect(output.batchCountAccumulator).toEqual(0)
expect(output.transactionCount).toEqual(2)
})
})

@ -20,6 +20,13 @@ import 'bootstrap'
import './locale' import './locale'
import './pages/address'
import './pages/blocks'
import './pages/chain'
import './pages/pending_transactions'
import './pages/transaction'
import './pages/transactions'
import './lib/clipboard_buttons' import './lib/clipboard_buttons'
import './lib/currency' import './lib/currency'
import './lib/from_now' import './lib/from_now'
@ -37,8 +44,3 @@ import './lib/token_balance_dropdown_search'
import './lib/token_transfers_toggle' import './lib/token_transfers_toggle'
import './lib/tooltip' import './lib/tooltip'
import './lib/try_api' import './lib/try_api'
import './pages/address'
import './pages/block'
import './pages/chain'
import './pages/transaction'

@ -0,0 +1,131 @@
import $ from 'jquery'
import _ from 'lodash'
import URI from 'urijs'
import humps from 'humps'
import numeral from 'numeral'
import socket from '../socket'
import { updateAllAges } from '../lib/from_now'
import { batchChannel, initRedux, slideDownPrepend, slideUpRemove } from '../utils'
const BATCH_THRESHOLD = 10
export const initialState = {
newPendingTransactionHashesBatch: [],
beyondPageOne: null,
channelDisconnected: false,
newPendingTransactions: [],
newTransactionHashes: [],
pendingTransactionCount: null
}
export function reducer (state = initialState, action) {
switch (action.type) {
case 'PAGE_LOAD': {
return Object.assign({}, state, {
beyondPageOne: action.beyondPageOne,
pendingTransactionCount: numeral(action.pendingTransactionCount).value()
})
}
case 'CHANNEL_DISCONNECTED': {
return Object.assign({}, state, {
channelDisconnected: true
})
}
case 'RECEIVED_NEW_TRANSACTION': {
if (state.channelDisconnected) return state
return Object.assign({}, state, {
newPendingTransactionHashesBatch: _.without(state.newPendingTransactionHashesBatch, action.msg.transactionHash),
pendingTransactionCount: state.pendingTransactionCount - 1,
newTransactionHashes: [action.msg.transactionHash]
})
}
case 'RECEIVED_NEW_PENDING_TRANSACTION_BATCH': {
if (state.channelDisconnected) return state
const pendingTransactionCount = state.pendingTransactionCount + action.msgs.length
if (state.beyondPageOne) return Object.assign({}, state, { pendingTransactionCount })
if (!state.newPendingTransactionHashesBatch.length && action.msgs.length < BATCH_THRESHOLD) {
return Object.assign({}, state, {
newPendingTransactions: [
...state.newPendingTransactions,
..._.map(action.msgs, 'transactionHtml')
],
pendingTransactionCount
})
} else {
return Object.assign({}, state, {
newPendingTransactionHashesBatch: [
...state.newPendingTransactionHashesBatch,
..._.map(action.msgs, 'transactionHash')
],
pendingTransactionCount
})
}
}
default:
return state
}
}
const $transactionPendingListPage = $('[data-page="transaction-pending-list"]')
if ($transactionPendingListPage.length) {
initRedux(reducer, {
main (store) {
store.dispatch({
type: 'PAGE_LOAD',
pendingTransactionCount: $('[data-selector="transaction-pending-count"]').text(),
beyondPageOne: !!humps.camelizeKeys(URI(window.location).query(true)).insertedAt
})
const transactionsChannel = socket.channel(`transactions:new_transaction`)
transactionsChannel.join()
transactionsChannel.onError(() => store.dispatch({ type: 'CHANNEL_DISCONNECTED' }))
transactionsChannel.on('transaction', (msg) =>
store.dispatch({ type: 'RECEIVED_NEW_TRANSACTION', msg: humps.camelizeKeys(msg) })
)
const pendingTransactionsChannel = socket.channel(`transactions:new_pending_transaction`)
pendingTransactionsChannel.join()
pendingTransactionsChannel.onError(() => store.dispatch({ type: 'CHANNEL_DISCONNECTED' }))
pendingTransactionsChannel.on('pending_transaction', batchChannel((msgs) =>
store.dispatch({ type: 'RECEIVED_NEW_PENDING_TRANSACTION_BATCH', msgs: humps.camelizeKeys(msgs) }))
)
},
render (state, oldState) {
const $channelBatching = $('[data-selector="channel-batching-message"]')
const $channelBatchingCount = $('[data-selector="channel-batching-count"]')
const $channelDisconnected = $('[data-selector="channel-disconnected-message"]')
const $pendingTransactionsList = $('[data-selector="transactions-pending-list"]')
const $pendingTransactionsCount = $('[data-selector="transaction-pending-count"]')
if (state.channelDisconnected) $channelDisconnected.show()
if (oldState.pendingTransactionCount !== state.pendingTransactionCount) {
$pendingTransactionsCount.empty().append(numeral(state.pendingTransactionCount).format())
}
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 (state.newPendingTransactionHashesBatch.length) {
$channelBatching.show()
$channelBatchingCount[0].innerHTML = numeral(state.newPendingTransactionHashesBatch.length).format()
} else {
$channelBatching.hide()
}
if (oldState.newPendingTransactions !== state.newPendingTransactions) {
const newTransactionsToInsert = state.newPendingTransactions.slice(oldState.newPendingTransactions.length)
slideDownPrepend($pendingTransactionsList, newTransactionsToInsert.reverse().join(''))
updateAllAges()
}
}
})
}

@ -1,42 +1,19 @@
import $ from 'jquery' import $ from 'jquery'
import _ from 'lodash'
import URI from 'urijs'
import humps from 'humps' import humps from 'humps'
import numeral from 'numeral' import numeral from 'numeral'
import socket from '../socket' import socket from '../socket'
import { updateAllAges } from '../lib/from_now' import { initRedux } from '../utils'
import { batchChannel, initRedux, slideDownPrepend, slideUpRemove } from '../utils'
const BATCH_THRESHOLD = 10
export const initialState = { export const initialState = {
batchCountAccumulator: 0,
newPendingTransactionHashesBatch: [],
beyondPageOne: null,
blockNumber: null, blockNumber: null,
channelDisconnected: false, confirmations: null
confirmations: null,
newPendingTransactions: [],
newTransactions: [],
newTransactionHashes: [],
transactionCount: null,
pendingTransactionCount: null
} }
export function reducer (state = initialState, action) { export function reducer (state = initialState, action) {
switch (action.type) { switch (action.type) {
case 'PAGE_LOAD': { case 'PAGE_LOAD': {
return Object.assign({}, state, { return Object.assign({}, state, {
beyondPageOne: action.beyondPageOne, blockNumber: parseInt(action.blockNumber, 10)
blockNumber: parseInt(action.blockNumber, 10),
transactionCount: numeral(action.transactionCount).value(),
pendingTransactionCount: numeral(action.pendingTransactionCount).value()
})
}
case 'CHANNEL_DISCONNECTED': {
return Object.assign({}, state, {
channelDisconnected: true,
batchCountAccumulator: 0
}) })
} }
case 'RECEIVED_NEW_BLOCK': { case 'RECEIVED_NEW_BLOCK': {
@ -46,62 +23,6 @@ export function reducer (state = initialState, action) {
}) })
} else return state } else return state
} }
case 'RECEIVED_NEW_TRANSACTION': {
if (state.channelDisconnected) return state
return Object.assign({}, state, {
newPendingTransactionHashesBatch: _.without(state.newPendingTransactionHashesBatch, action.msg.transactionHash),
pendingTransactionCount: state.pendingTransactionCount - 1,
newTransactionHashes: [action.msg.transactionHash]
})
}
case 'RECEIVED_NEW_PENDING_TRANSACTION_BATCH': {
if (state.channelDisconnected) return state
const pendingTransactionCount = state.pendingTransactionCount + action.msgs.length
if (state.beyondPageOne) return Object.assign({}, state, { pendingTransactionCount })
if (!state.newPendingTransactionHashesBatch.length && action.msgs.length < BATCH_THRESHOLD) {
return Object.assign({}, state, {
newPendingTransactions: [
...state.newPendingTransactions,
..._.map(action.msgs, 'transactionHtml')
],
pendingTransactionCount
})
} else {
return Object.assign({}, state, {
newPendingTransactionHashesBatch: [
...state.newPendingTransactionHashesBatch,
..._.map(action.msgs, 'transactionHash')
],
pendingTransactionCount
})
}
}
case 'RECEIVED_NEW_TRANSACTION_BATCH': {
if (state.channelDisconnected) return state
const transactionCount = state.transactionCount + action.msgs.length
if (state.beyondPageOne) return Object.assign({}, state, { transactionCount })
if (!state.batchCountAccumulator && action.msgs.length < BATCH_THRESHOLD) {
return Object.assign({}, state, {
newTransactions: [
...state.newTransactions,
..._.map(action.msgs, 'transactionHtml')
],
transactionCount
})
} else {
return Object.assign({}, state, {
batchCountAccumulator: state.batchCountAccumulator + action.msgs.length,
transactionCount
})
}
}
default: default:
return state return state
} }
@ -134,104 +55,3 @@ if ($transactionDetailsPage.length) {
} }
}) })
} }
const $transactionPendingListPage = $('[data-page="transaction-pending-list"]')
if ($transactionPendingListPage.length) {
initRedux(reducer, {
main (store) {
store.dispatch({
type: 'PAGE_LOAD',
pendingTransactionCount: $('[data-selector="transaction-pending-count"]').text(),
beyondPageOne: !!humps.camelizeKeys(URI(window.location).query(true)).insertedAt
})
const transactionsChannel = socket.channel(`transactions:new_transaction`)
transactionsChannel.join()
transactionsChannel.onError(() => store.dispatch({ type: 'CHANNEL_DISCONNECTED' }))
transactionsChannel.on('transaction', (msg) =>
store.dispatch({ type: 'RECEIVED_NEW_TRANSACTION', msg: humps.camelizeKeys(msg) })
)
const pendingTransactionsChannel = socket.channel(`transactions:new_pending_transaction`)
pendingTransactionsChannel.join()
pendingTransactionsChannel.onError(() => store.dispatch({ type: 'CHANNEL_DISCONNECTED' }))
pendingTransactionsChannel.on('pending_transaction', batchChannel((msgs) =>
store.dispatch({ type: 'RECEIVED_NEW_PENDING_TRANSACTION_BATCH', msgs: humps.camelizeKeys(msgs) }))
)
},
render (state, oldState) {
const $channelBatching = $('[data-selector="channel-batching-message"]')
const $channelBatchingCount = $('[data-selector="channel-batching-count"]')
const $channelDisconnected = $('[data-selector="channel-disconnected-message"]')
const $pendingTransactionsList = $('[data-selector="transactions-pending-list"]')
const $pendingTransactionsCount = $('[data-selector="transaction-pending-count"]')
if (state.channelDisconnected) $channelDisconnected.show()
if (oldState.pendingTransactionCount !== state.pendingTransactionCount) {
$pendingTransactionsCount.empty().append(numeral(state.pendingTransactionCount).format())
}
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 (state.newPendingTransactionHashesBatch.length) {
$channelBatching.show()
$channelBatchingCount[0].innerHTML = numeral(state.newPendingTransactionHashesBatch.length).format()
} else {
$channelBatching.hide()
}
if (oldState.newPendingTransactions !== state.newPendingTransactions) {
const newTransactionsToInsert = state.newPendingTransactions.slice(oldState.newPendingTransactions.length)
slideDownPrepend($pendingTransactionsList, newTransactionsToInsert.reverse().join(''))
updateAllAges()
}
}
})
}
const $transactionListPage = $('[data-page="transaction-list"]')
if ($transactionListPage.length) {
initRedux(reducer, {
main (store) {
store.dispatch({
type: 'PAGE_LOAD',
transactionCount: $('[data-selector="transaction-count"]').text(),
beyondPageOne: !!humps.camelizeKeys(URI(window.location).query(true)).index
})
const transactionsChannel = socket.channel(`transactions:new_transaction`)
transactionsChannel.join()
transactionsChannel.onError(() => store.dispatch({ type: 'CHANNEL_DISCONNECTED' }))
transactionsChannel.on('transaction', batchChannel((msgs) =>
store.dispatch({ type: 'RECEIVED_NEW_TRANSACTION_BATCH', msgs: humps.camelizeKeys(msgs) }))
)
},
render (state, oldState) {
const $channelBatching = $('[data-selector="channel-batching-message"]')
const $channelBatchingCount = $('[data-selector="channel-batching-count"]')
const $channelDisconnected = $('[data-selector="channel-disconnected-message"]')
const $transactionsList = $('[data-selector="transactions-list"]')
const $transactionCount = $('[data-selector="transaction-count"]')
if (state.channelDisconnected) $channelDisconnected.show()
if (oldState.transactionCount !== state.transactionCount) $transactionCount.empty().append(numeral(state.transactionCount).format())
if (state.batchCountAccumulator) {
$channelBatching.show()
$channelBatchingCount[0].innerHTML = numeral(state.batchCountAccumulator).format()
} else {
$channelBatching.hide()
}
if (oldState.newTransactions !== state.newTransactions) {
const newTransactionsToInsert = state.newTransactions.slice(oldState.newTransactions.length)
slideDownPrepend($transactionsList, newTransactionsToInsert.reverse().join(''))
updateAllAges()
}
}
})
}

@ -0,0 +1,100 @@
import $ from 'jquery'
import _ from 'lodash'
import URI from 'urijs'
import humps from 'humps'
import numeral from 'numeral'
import socket from '../socket'
import { updateAllAges } from '../lib/from_now'
import { batchChannel, initRedux, slideDownPrepend } from '../utils'
const BATCH_THRESHOLD = 10
export const initialState = {
batchCountAccumulator: 0,
beyondPageOne: null,
channelDisconnected: false,
newTransactions: [],
transactionCount: null
}
export function reducer (state = initialState, action) {
switch (action.type) {
case 'PAGE_LOAD': {
return Object.assign({}, state, {
beyondPageOne: action.beyondPageOne,
transactionCount: numeral(action.transactionCount).value()
})
}
case 'CHANNEL_DISCONNECTED': {
return Object.assign({}, state, {
channelDisconnected: true,
batchCountAccumulator: 0
})
}
case 'RECEIVED_NEW_TRANSACTION_BATCH': {
if (state.channelDisconnected) return state
const transactionCount = state.transactionCount + action.msgs.length
if (state.beyondPageOne) return Object.assign({}, state, { transactionCount })
if (!state.batchCountAccumulator && action.msgs.length < BATCH_THRESHOLD) {
return Object.assign({}, state, {
newTransactions: [
...state.newTransactions,
..._.map(action.msgs, 'transactionHtml')
],
transactionCount
})
} else {
return Object.assign({}, state, {
batchCountAccumulator: state.batchCountAccumulator + action.msgs.length,
transactionCount
})
}
}
default:
return state
}
}
const $transactionListPage = $('[data-page="transaction-list"]')
if ($transactionListPage.length) {
initRedux(reducer, {
main (store) {
store.dispatch({
type: 'PAGE_LOAD',
transactionCount: $('[data-selector="transaction-count"]').text(),
beyondPageOne: !!humps.camelizeKeys(URI(window.location).query(true)).index
})
const transactionsChannel = socket.channel(`transactions:new_transaction`)
transactionsChannel.join()
transactionsChannel.onError(() => store.dispatch({ type: 'CHANNEL_DISCONNECTED' }))
transactionsChannel.on('transaction', batchChannel((msgs) =>
store.dispatch({ type: 'RECEIVED_NEW_TRANSACTION_BATCH', msgs: humps.camelizeKeys(msgs) }))
)
},
render (state, oldState) {
const $channelBatching = $('[data-selector="channel-batching-message"]')
const $channelBatchingCount = $('[data-selector="channel-batching-count"]')
const $channelDisconnected = $('[data-selector="channel-disconnected-message"]')
const $transactionsList = $('[data-selector="transactions-list"]')
const $transactionCount = $('[data-selector="transaction-count"]')
if (state.channelDisconnected) $channelDisconnected.show()
if (oldState.transactionCount !== state.transactionCount) $transactionCount.empty().append(numeral(state.transactionCount).format())
if (state.batchCountAccumulator) {
$channelBatching.show()
$channelBatchingCount[0].innerHTML = numeral(state.batchCountAccumulator).format()
} else {
$channelBatching.hide()
}
if (oldState.newTransactions !== state.newTransactions) {
const newTransactionsToInsert = state.newTransactions.slice(oldState.newTransactions.length)
slideDownPrepend($transactionsList, newTransactionsToInsert.reverse().join(''))
updateAllAges()
}
}
})
}
Loading…
Cancel
Save