|
|
|
@ -5,6 +5,7 @@ import socket from '../socket' |
|
|
|
|
import router from '../router' |
|
|
|
|
import { batchChannel, initRedux } from '../utils' |
|
|
|
|
import { updateAllAges } from '../lib/from_now' |
|
|
|
|
import { loadTokenBalanceDropdown } from '../lib/token_balance_dropdown' |
|
|
|
|
|
|
|
|
|
const BATCH_THRESHOLD = 10 |
|
|
|
|
|
|
|
|
@ -14,6 +15,7 @@ export const initialState = { |
|
|
|
|
beyondPageOne: null, |
|
|
|
|
channelDisconnected: false, |
|
|
|
|
filter: null, |
|
|
|
|
newInternalTransactions: [], |
|
|
|
|
newTransactions: [], |
|
|
|
|
balance: null, |
|
|
|
|
transactionCount: null |
|
|
|
@ -42,6 +44,29 @@ export function reducer (state = initialState, action) { |
|
|
|
|
balance: action.msg.balance |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
case 'RECEIVED_NEW_INTERNAL_TRANSACTION_BATCH': { |
|
|
|
|
if (state.channelDisconnected || state.beyondPageOne) return state |
|
|
|
|
|
|
|
|
|
const incomingInternalTransactions = humps.camelizeKeys(action.msgs) |
|
|
|
|
.filter(({toAddressHash, fromAddressHash}) => ( |
|
|
|
|
!state.filter || |
|
|
|
|
(state.filter === 'to' && toAddressHash === state.addressHash) || |
|
|
|
|
(state.filter === 'from' && fromAddressHash === state.addressHash) |
|
|
|
|
)) |
|
|
|
|
|
|
|
|
|
if (!state.batchCountAccumulator && action.msgs.length < BATCH_THRESHOLD) { |
|
|
|
|
return Object.assign({}, state, { |
|
|
|
|
newInternalTransactions: [ |
|
|
|
|
...state.newInternalTransactions, |
|
|
|
|
...incomingInternalTransactions.map(({internalTransactionHtml}) => internalTransactionHtml) |
|
|
|
|
] |
|
|
|
|
}) |
|
|
|
|
} else { |
|
|
|
|
return Object.assign({}, state, { |
|
|
|
|
batchCountAccumulator: state.batchCountAccumulator + action.msgs.length |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
case 'RECEIVED_NEW_TRANSACTION_BATCH': { |
|
|
|
|
if (state.channelDisconnected || state.beyondPageOne) return state |
|
|
|
|
|
|
|
|
@ -74,30 +99,44 @@ export function reducer (state = initialState, action) { |
|
|
|
|
|
|
|
|
|
router.when('/address/:addressHash').then((params) => initRedux(reducer, { |
|
|
|
|
main (store) { |
|
|
|
|
const { addressHash, blockNumber } = params |
|
|
|
|
const channel = socket.channel(`addresses:${addressHash}`, {}) |
|
|
|
|
store.dispatch({ |
|
|
|
|
const { addressHash } = params |
|
|
|
|
const addressChannel = socket.channel(`addresses:${addressHash}`, {}) |
|
|
|
|
const state = store.dispatch({ |
|
|
|
|
type: 'PAGE_LOAD', |
|
|
|
|
params, |
|
|
|
|
transactionCount: $('[data-selector="transaction-count"]').text() |
|
|
|
|
}) |
|
|
|
|
channel.join() |
|
|
|
|
channel.onError(() => store.dispatch({ type: 'CHANNEL_DISCONNECTED' })) |
|
|
|
|
channel.on('balance', (msg) => store.dispatch({ type: 'RECEIVED_UPDATED_BALANCE', msg })) |
|
|
|
|
if (!blockNumber) channel.on('transaction', batchChannel((msgs) => store.dispatch({ type: 'RECEIVED_NEW_TRANSACTION_BATCH', msgs }))) |
|
|
|
|
addressChannel.join() |
|
|
|
|
addressChannel.onError(() => store.dispatch({ type: 'CHANNEL_DISCONNECTED' })) |
|
|
|
|
addressChannel.on('balance', (msg) => store.dispatch({ type: 'RECEIVED_UPDATED_BALANCE', msg })) |
|
|
|
|
if (!state.beyondPageOne) { |
|
|
|
|
addressChannel.on('transaction', batchChannel((msgs) => |
|
|
|
|
store.dispatch({ type: 'RECEIVED_NEW_TRANSACTION_BATCH', msgs }) |
|
|
|
|
)) |
|
|
|
|
|
|
|
|
|
addressChannel.on('internal_transaction', batchChannel((msgs) => |
|
|
|
|
store.dispatch({ type: 'RECEIVED_NEW_INTERNAL_TRANSACTION_BATCH', msgs }) |
|
|
|
|
)) |
|
|
|
|
} |
|
|
|
|
}, |
|
|
|
|
render (state, oldState) { |
|
|
|
|
const $balance = $('[data-selector="balance-card"]') |
|
|
|
|
const $channelBatching = $('[data-selector="channel-batching-message"]') |
|
|
|
|
const $channelBatchingCount = $('[data-selector="channel-batching-count"]') |
|
|
|
|
const $channelDisconnected = $('[data-selector="channel-disconnected-message"]') |
|
|
|
|
const $emptyInternalTransactionsList = $('[data-selector="empty-internal-transactions-list"]') |
|
|
|
|
const $emptyTransactionsList = $('[data-selector="empty-transactions-list"]') |
|
|
|
|
const $balance = $('[data-selector="balance-card"]') |
|
|
|
|
const $internalTransactionsList = $('[data-selector="internal-transactions-list"]') |
|
|
|
|
const $transactionCount = $('[data-selector="transaction-count"]') |
|
|
|
|
const $transactionsList = $('[data-selector="transactions-list"]') |
|
|
|
|
|
|
|
|
|
if ($emptyInternalTransactionsList.length && state.newInternalTransactions.length) window.location.reload() |
|
|
|
|
if ($emptyTransactionsList.length && state.newTransactions.length) window.location.reload() |
|
|
|
|
if (state.channelDisconnected) $channelDisconnected.show() |
|
|
|
|
if (oldState.balance !== state.balance) $balance.empty().append(state.balance) |
|
|
|
|
if (oldState.balance !== state.balance) { |
|
|
|
|
$balance.empty().append(state.balance) |
|
|
|
|
loadTokenBalanceDropdown() |
|
|
|
|
} |
|
|
|
|
if (oldState.transactionCount !== state.transactionCount) $transactionCount.empty().append(numeral(state.transactionCount).format()) |
|
|
|
|
if (state.batchCountAccumulator) { |
|
|
|
|
$channelBatching.show() |
|
|
|
@ -105,6 +144,9 @@ router.when('/address/:addressHash').then((params) => initRedux(reducer, { |
|
|
|
|
} else { |
|
|
|
|
$channelBatching.hide() |
|
|
|
|
} |
|
|
|
|
if (oldState.newInternalTransactions !== state.newInternalTransactions && $internalTransactionsList.length) { |
|
|
|
|
$internalTransactionsList.prepend(state.newInternalTransactions.slice(oldState.newInternalTransactions.length).reverse().join('')) |
|
|
|
|
} |
|
|
|
|
if (oldState.newTransactions !== state.newTransactions && $transactionsList.length) { |
|
|
|
|
$transactionsList.prepend(state.newTransactions.slice(oldState.newTransactions.length).reverse().join('')) |
|
|
|
|
updateAllAges() |
|
|
|
|