diff --git a/apps/block_scout_web/assets/__tests__/pages/block.js b/apps/block_scout_web/assets/__tests__/pages/blocks.js similarity index 98% rename from apps/block_scout_web/assets/__tests__/pages/block.js rename to apps/block_scout_web/assets/__tests__/pages/blocks.js index d854fb9746..2ddad6a5a3 100644 --- a/apps/block_scout_web/assets/__tests__/pages/block.js +++ b/apps/block_scout_web/assets/__tests__/pages/blocks.js @@ -1,4 +1,4 @@ -import { reducer, initialState } from '../../js/pages/block' +import { reducer, initialState } from '../../js/pages/blocks' test('CHANNEL_DISCONNECTED', () => { const state = initialState diff --git a/apps/block_scout_web/assets/__tests__/pages/pending_transactions.js b/apps/block_scout_web/assets/__tests__/pages/pending_transactions.js new file mode 100644 index 0000000000..25d03aed61 --- /dev/null +++ b/apps/block_scout_web/assets/__tests__/pages/pending_transactions.js @@ -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) + }) +}) diff --git a/apps/block_scout_web/assets/__tests__/pages/transaction.js b/apps/block_scout_web/assets/__tests__/pages/transaction.js index ea4eb3595f..55aa68f4b4 100644 --- a/apps/block_scout_web/assets/__tests__/pages/transaction.js +++ b/apps/block_scout_web/assets/__tests__/pages/transaction.js @@ -1,16 +1,5 @@ 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', () => { const state = { ...initialState, blockNumber: 1 } const action = { @@ -23,374 +12,3 @@ test('RECEIVED_NEW_BLOCK', () => { 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) - }) -}) diff --git a/apps/block_scout_web/assets/__tests__/pages/transactions.js b/apps/block_scout_web/assets/__tests__/pages/transactions.js new file mode 100644 index 0000000000..f45a4960d4 --- /dev/null +++ b/apps/block_scout_web/assets/__tests__/pages/transactions.js @@ -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) + }) +}) diff --git a/apps/block_scout_web/assets/js/app.js b/apps/block_scout_web/assets/js/app.js index 935a325d04..83e3080c5c 100644 --- a/apps/block_scout_web/assets/js/app.js +++ b/apps/block_scout_web/assets/js/app.js @@ -20,6 +20,13 @@ import 'bootstrap' 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/currency' import './lib/from_now' @@ -37,8 +44,3 @@ import './lib/token_balance_dropdown_search' import './lib/token_transfers_toggle' import './lib/tooltip' import './lib/try_api' - -import './pages/address' -import './pages/block' -import './pages/chain' -import './pages/transaction' diff --git a/apps/block_scout_web/assets/js/pages/block.js b/apps/block_scout_web/assets/js/pages/blocks.js similarity index 100% rename from apps/block_scout_web/assets/js/pages/block.js rename to apps/block_scout_web/assets/js/pages/blocks.js diff --git a/apps/block_scout_web/assets/js/pages/pending_transactions.js b/apps/block_scout_web/assets/js/pages/pending_transactions.js new file mode 100644 index 0000000000..75c3ef8d0f --- /dev/null +++ b/apps/block_scout_web/assets/js/pages/pending_transactions.js @@ -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() + } + } + }) +} diff --git a/apps/block_scout_web/assets/js/pages/transaction.js b/apps/block_scout_web/assets/js/pages/transaction.js index beda3482c4..335a59e974 100644 --- a/apps/block_scout_web/assets/js/pages/transaction.js +++ b/apps/block_scout_web/assets/js/pages/transaction.js @@ -1,42 +1,19 @@ 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 +import { initRedux } from '../utils' export const initialState = { - batchCountAccumulator: 0, - newPendingTransactionHashesBatch: [], - beyondPageOne: null, blockNumber: null, - channelDisconnected: false, - confirmations: null, - newPendingTransactions: [], - newTransactions: [], - newTransactionHashes: [], - transactionCount: null, - pendingTransactionCount: null + confirmations: null } export function reducer (state = initialState, action) { switch (action.type) { case 'PAGE_LOAD': { return Object.assign({}, state, { - beyondPageOne: action.beyondPageOne, - 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 + blockNumber: parseInt(action.blockNumber, 10) }) } case 'RECEIVED_NEW_BLOCK': { @@ -46,62 +23,6 @@ export function reducer (state = initialState, action) { }) } 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: 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() - } - } - }) -} diff --git a/apps/block_scout_web/assets/js/pages/transactions.js b/apps/block_scout_web/assets/js/pages/transactions.js new file mode 100644 index 0000000000..04544e83b4 --- /dev/null +++ b/apps/block_scout_web/assets/js/pages/transactions.js @@ -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() + } + } + }) +}