(Bugfix) - #1312 Assets disappear when loading a safe (#1333)

* fix currency middleware, actinos, cleanup & bugfix

* mergeDeep in reducer

* dont modify state in add_safe if same already exists

Co-authored-by: Daniel Sanchez <daniel.sanchez@gnosis.pm>
This commit is contained in:
Mikhail Mikheev 2020-09-15 18:30:30 +04:00 committed by GitHub
parent 33018172df
commit e000958c28
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 47 additions and 64 deletions

View File

@ -1,46 +0,0 @@
import { List } from 'immutable'
import { batch } from 'react-redux'
import { setCurrencyBalances } from 'src/logic/currencyValues/store/actions/setCurrencyBalances'
import { setCurrencyRate } from 'src/logic/currencyValues/store/actions/setCurrencyRate'
import { setSelectedCurrency } from 'src/logic/currencyValues/store/actions/setSelectedCurrency'
import { AVAILABLE_CURRENCIES, CurrencyRateValue } from 'src/logic/currencyValues/store/model/currencyValues'
import { loadCurrencyValues } from 'src/logic/currencyValues/store/utils/currencyValuesStorage'
import { Dispatch } from 'redux'
export const fetchCurrencyValues = (safeAddress: string) => async (
dispatch: Dispatch<typeof setCurrencyBalances | typeof setSelectedCurrency | typeof setCurrencyRate>,
): Promise<void> => {
try {
const storedCurrencies = await loadCurrencyValues()
const storedCurrency = storedCurrencies[safeAddress]
if (!storedCurrency) {
return batch(() => {
dispatch(setCurrencyBalances(safeAddress, List([])))
dispatch(setSelectedCurrency(safeAddress, AVAILABLE_CURRENCIES.USD))
dispatch(setCurrencyRate(safeAddress, 1))
})
}
// Loads the stored state on redux
Object.entries(storedCurrencies).forEach((kv) => {
const safeAddr = kv[0]
const value = kv[1]
let { currencyRate, selectedCurrency }: CurrencyRateValue = value
// Fallback for users that got an undefined saved on localStorage
if (!selectedCurrency || selectedCurrency === AVAILABLE_CURRENCIES.USD) {
currencyRate = 1
selectedCurrency = AVAILABLE_CURRENCIES.USD
}
batch(() => {
dispatch(setSelectedCurrency(safeAddr, selectedCurrency))
dispatch(setCurrencyRate(safeAddr, currencyRate))
})
})
} catch (err) {
console.error('Error fetching currency values', err)
}
return Promise.resolve()
}

View File

@ -0,0 +1,19 @@
import { setCurrencyBalances } from 'src/logic/currencyValues/store/actions/setCurrencyBalances'
import { setCurrencyRate } from 'src/logic/currencyValues/store/actions/setCurrencyRate'
import { setSelectedCurrency } from 'src/logic/currencyValues/store/actions/setSelectedCurrency'
import { AVAILABLE_CURRENCIES } from 'src/logic/currencyValues/store/model/currencyValues'
import { loadSelectedCurrency } from 'src/logic/currencyValues/store/utils/currencyValuesStorage'
import { Dispatch } from 'redux'
export const fetchSelectedCurrency = (safeAddress: string) => async (
dispatch: Dispatch<typeof setCurrencyBalances | typeof setSelectedCurrency | typeof setCurrencyRate>,
): Promise<void> => {
try {
const storedSelectedCurrency = await loadSelectedCurrency()
dispatch(setSelectedCurrency(safeAddress, storedSelectedCurrency || AVAILABLE_CURRENCIES.USD))
} catch (err) {
console.error('Error fetching currency values', err)
}
return Promise.resolve()
}

View File

@ -1,12 +1,23 @@
import { createAction } from 'redux-actions'
import { ThunkDispatch } from 'redux-thunk'
import { AnyAction } from 'redux'
import { AppReduxState } from 'src/store'
import { AVAILABLE_CURRENCIES } from '../model/currencyValues'
import fetchCurrencyRate from 'src/logic/currencyValues/store/actions/fetchCurrencyRate'
export const SET_CURRENT_CURRENCY = 'SET_CURRENT_CURRENCY'
export const setSelectedCurrency = createAction(
const setCurrentCurrency = createAction(
SET_CURRENT_CURRENCY,
(safeAddress: string, selectedCurrency: AVAILABLE_CURRENCIES) => ({
safeAddress,
selectedCurrency,
}),
)
export const setSelectedCurrency = (safeAddress: string, selectedCurrency: AVAILABLE_CURRENCIES) => (
dispatch: ThunkDispatch<AppReduxState, undefined, AnyAction>,
): void => {
dispatch(setCurrentCurrency(safeAddress, selectedCurrency))
dispatch(fetchCurrencyRate(safeAddress, selectedCurrency))
}

View File

@ -1,16 +1,16 @@
import fetchCurrencyRate from 'src/logic/currencyValues/store/actions/fetchCurrencyRate'
import { SET_CURRENT_CURRENCY } from 'src/logic/currencyValues/store/actions/setSelectedCurrency'
import { saveSelectedCurrency } from 'src/logic/currencyValues/store/utils/currencyValuesStorage'
const watchedActions = [SET_CURRENT_CURRENCY]
const currencyValuesStorageMiddleware = (store) => (next) => async (action) => {
const currencyValuesStorageMiddleware = () => (next) => async (action) => {
const handledAction = next(action)
if (watchedActions.includes(action.type)) {
const { dispatch } = store
switch (action.type) {
case SET_CURRENT_CURRENCY: {
const { safeAddress, selectedCurrency } = action.payload
dispatch(fetchCurrencyRate(safeAddress, selectedCurrency))
const { selectedCurrency } = action.payload
saveSelectedCurrency(selectedCurrency)
break
}

View File

@ -1,16 +1,15 @@
import { loadFromStorage, saveToStorage } from 'src/utils/storage'
import { CurrencyRateValue } from '../model/currencyValues'
import { Map } from 'immutable'
import { AVAILABLE_CURRENCIES } from '../model/currencyValues'
const CURRENCY_VALUES_STORAGE_KEY = 'CURRENCY_VALUES_STORAGE_KEY'
export const saveCurrencyValues = async (currencyValues: Map<string, CurrencyRateValue>): Promise<void> => {
const SELECTED_CURRENCY_STORAGE_KEY = 'SELECTED_CURRENCY'
export const saveSelectedCurrency = async (selectedCurrency: AVAILABLE_CURRENCIES): Promise<void> => {
try {
await saveToStorage(CURRENCY_VALUES_STORAGE_KEY, currencyValues)
await saveToStorage(SELECTED_CURRENCY_STORAGE_KEY, selectedCurrency)
} catch (err) {
console.error('Error storing currency values info in localstorage', err)
}
}
export const loadCurrencyValues = async (): Promise<Record<string, CurrencyRateValue>> => {
return (await loadFromStorage(CURRENCY_VALUES_STORAGE_KEY)) || {}
export const loadSelectedCurrency = async (): Promise<AVAILABLE_CURRENCIES | undefined> => {
return await loadFromStorage(SELECTED_CURRENCY_STORAGE_KEY)
}

View File

@ -3,7 +3,7 @@ import { batch, useDispatch } from 'react-redux'
import { useLocation } from 'react-router-dom'
import fetchCollectibles from 'src/logic/collectibles/store/actions/fetchCollectibles'
import { fetchCurrencyValues } from 'src/logic/currencyValues/store/actions/fetchCurrencyValues'
import { fetchSelectedCurrency } from 'src/logic/currencyValues/store/actions/fetchSelectedCurrency'
import activateAssetsByBalance from 'src/logic/tokens/store/actions/activateAssetsByBalance'
import fetchSafeTokens from 'src/logic/tokens/store/actions/fetchSafeTokens'
import { fetchTokens } from 'src/logic/tokens/store/actions/fetchTokens'
@ -19,7 +19,7 @@ export const useFetchTokens = (safeAddress: string): void => {
batch(() => {
// fetch tokens there to get symbols for tokens in TXs list
dispatch(fetchTokens())
dispatch(fetchCurrencyValues(safeAddress))
dispatch(fetchSelectedCurrency(safeAddress))
dispatch(fetchSafeTokens(safeAddress))
})
}

View File

@ -65,7 +65,7 @@ export default handleActions(
const safeActiveTokens = map.getIn(['safes', safeAddress, 'activeTokens'])
const activeTokens = safeActiveTokens.add(tokenAddress)
map.updateIn(['safes', safeAddress], (prevSafe) => prevSafe.merge({ activeTokens }))
map.updateIn(['safes', safeAddress], (prevSafe) => prevSafe.mergeDeep({ activeTokens }))
})
})
},
@ -77,7 +77,7 @@ export default handleActions(
// with initial props and it would overwrite existing ones
if (state.hasIn(['safes', safe.address])) {
return state.updateIn(['safes', safe.address], (prevSafe) => prevSafe.mergeDeep(safe))
return state
}
return state.setIn(['safes', safe.address], makeSafe(safe))

View File

@ -24,7 +24,7 @@ import etherIcon from 'src/assets/icons/icon_etherTokens.svg'
const CurrencyDropdown = (): React.ReactElement | null => {
const currenciesList = Object.values(AVAILABLE_CURRENCIES)
const safeAddress = useSelector(safeParamAddressFromStateSelector)
const safeAddress = useSelector(safeParamAddressFromStateSelector) as string
const dispatch = useDispatch()
const [anchorEl, setAnchorEl] = useState(null)
const selectedCurrency = useSelector(currentCurrencySelector)