1
1
import { send } from 'redux-electron-ipc'
2
- import groupBy from 'lodash/groupBy'
3
2
import createReducer from '@zap/utils/createReducer'
4
3
import { getIntl } from '@zap/i18n'
5
4
import { mainLog } from '@zap/utils/log'
@@ -11,8 +10,9 @@ import { settingsSelectors } from 'reducers/settings'
11
10
import { fetchBalance } from 'reducers/balance'
12
11
import { fetchChannels } from 'reducers/channels'
13
12
import { fetchInfo , infoSelectors } from 'reducers/info'
13
+ import { walletSelectors } from 'reducers/wallet'
14
14
import { showError , showNotification } from 'reducers/notification'
15
- import { createActivityPaginator , getItemType } from './utils'
15
+ import { createActivityPaginator } from './utils'
16
16
import { hasNextPage , isPageLoading } from './selectors'
17
17
import messages from './messages'
18
18
import * as constants from './constants'
@@ -77,17 +77,21 @@ const initialState = {
77
77
// activity paginator object. must be reset for each wallet login
78
78
/** @type {Function | null } */
79
79
let paginator = null
80
- let loadedPages = 0
81
80
82
81
/**
83
82
* getPaginator - Returns current activity paginator object. This acts as a singleton
84
83
* and creates paginator if it's not initialized.
85
84
*
85
+ * @param {{
86
+ * invoiceHandler: function,
87
+ * paymentHandler: function,
88
+ * transactionHandler: function
89
+ * }} handlers Pagination handlers
86
90
* @returns {Function } Paginator
87
91
*/
88
- export const getPaginator = ( ) => {
92
+ export const getPaginator = handlers => {
89
93
if ( ! paginator ) {
90
- paginator = createActivityPaginator ( )
94
+ paginator = createActivityPaginator ( handlers )
91
95
}
92
96
return paginator
93
97
}
@@ -237,22 +241,12 @@ export const hideActivityModal = () => dispatch => {
237
241
*/
238
242
export const resetActivity = ( ) => ( ) => {
239
243
paginator = null
240
- loadedPages = 0
241
- }
242
-
243
- /**
244
- * resetPaginator - Reset activity paginator.
245
- *
246
- * @returns {() => void } Thunk
247
- */
248
- export const resetPaginator = ( ) => ( ) => {
249
- paginator = null
250
244
}
251
245
252
246
/**
253
247
* loadPage - Loads next activity page if it's available.
254
248
*
255
- * @param {boolean } reload Boolean indicating if this page load is part of a reload .
249
+ * @param {boolean } reload Boolean indicating wether to load first page .
256
250
* @returns {(dispatch:Function, getState:Function) => Promise<void> } Thunk
257
251
*/
258
252
export const loadPage = ( reload = false ) => async ( dispatch , getState ) => {
@@ -262,38 +256,45 @@ export const loadPage = (reload = false) => async (dispatch, getState) => {
262
256
dispatch ( setPageLoading ( true ) )
263
257
264
258
await dispatch ( fetchInfo ( ) )
265
- const config = settingsSelectors . currentConfig ( getState ( ) )
266
- const blockHeight = infoSelectors . blockHeight ( getState ( ) )
267
- const thisPaginator = getPaginator ( )
259
+ const state = getState ( )
260
+ const config = settingsSelectors . currentConfig ( state )
261
+ const blockHeight = infoSelectors . blockHeight ( state )
262
+ const activeWallet = walletSelectors . activeWallet ( state )
263
+
264
+ // Checks to see if the currently active wallet is the same one as when the page load started.
265
+ const isStllActiveWallet = ( ) => walletSelectors . activeWallet ( getState ( ) ) === activeWallet
266
+
267
+ // It's possible that the grpc response is received after the wallet has been disconnected.
268
+ // See https://github.com/grpc/grpc-node/issues/1603
269
+ // Ensure that the items received belong to the currently active wallet.
270
+ const shouldUpdate = items => items && isStllActiveWallet ( )
271
+
272
+ const handlers = {
273
+ invoiceHandler : items => shouldUpdate ( items ) && dispatch ( receiveInvoices ( items ) ) ,
274
+ paymentHandler : items => shouldUpdate ( items ) && dispatch ( receivePayments ( items ) ) ,
275
+ transactionHandler : items => shouldUpdate ( items ) && dispatch ( receiveTransactions ( items ) ) ,
276
+ }
277
+ const thisPaginator = reload ? createActivityPaginator ( handlers ) : getPaginator ( handlers )
268
278
269
- if ( reload || hasNextPage ( getState ( ) ) ) {
279
+ if ( hasNextPage ( getState ( ) ) ) {
270
280
const { pageSize } = config . activity
271
- const { items, hasNextPage : paginatorHasNextPage } = await thisPaginator ( pageSize , blockHeight )
272
-
273
- if ( ! reload ) {
274
- loadedPages += 1
275
- dispatch ( { type : SET_HAS_NEXT_PAGE , value : paginatorHasNextPage } )
281
+ const { hasNextPage } = await thisPaginator ( pageSize , blockHeight )
282
+ if ( ! isStllActiveWallet ( ) ) {
283
+ return
276
284
}
277
-
278
- const { invoices, payments, transactions } = groupBy ( items , getItemType )
279
-
280
- invoices && dispatch ( receiveInvoices ( invoices ) )
281
- payments && dispatch ( receivePayments ( payments ) )
282
- transactions && dispatch ( receiveTransactions ( transactions ) )
285
+ dispatch ( { type : SET_HAS_NEXT_PAGE , value : hasNextPage } )
283
286
}
284
287
285
288
dispatch ( setPageLoading ( false ) )
286
289
}
287
290
288
291
/**
289
- * reloadPages - Reloads all already loaded activity pages .
292
+ * reloadActivityHead - Reloads activity head .
290
293
*
291
294
* @returns {(dispatch:Function) => Promise<void> } Thunk
292
295
*/
293
- export const reloadPages = ( ) => async dispatch => {
294
- const pageCount = loadedPages
295
- mainLog . debug ( `reloading ${ pageCount } activity pages` )
296
- dispatch ( resetPaginator ( ) )
296
+ export const reloadActivityHead = ( ) => async dispatch => {
297
+ mainLog . debug ( `reloading activity pages` )
297
298
await dispatch ( loadPage ( true ) )
298
299
}
299
300
@@ -321,7 +322,7 @@ export const reloadActivityHistory = () => async dispatch => {
321
322
dispatch ( { type : FETCH_ACTIVITY_HISTORY } )
322
323
try {
323
324
await Promise . all ( [
324
- dispatch ( reloadPages ( ) ) ,
325
+ dispatch ( reloadActivityHead ( ) ) ,
325
326
dispatch ( fetchChannels ( ) ) ,
326
327
dispatch ( fetchBalance ( ) ) ,
327
328
] )
0 commit comments