Skip to content

Commit

Permalink
[Wallet] Fix last alert banner redisplayed on re-render (#6325)
Browse files Browse the repository at this point in the history
### Description

This fixes the regression described in #6314.

The change in #6230 made the underlying problem in `AlertBanner` more prominent as it caused the top level navigator to re-render on app state change (background/foreground/inactive) and hence the `AlertBanner`.

### Other changes

Globally mock `Animated.View` and `Animated.ScrollView` to prevent out of memory error when a ref is set.
See callstack/react-native-testing-library#539

Note: This change caused the Snapshot updates, because the styles are not flattened anymore for the mocked `Animated.View`.

### Tested

- Last alert is not redisplayed when navigating to different screens.
- New alert banner with same content can still be redisplayed when dispatched (causing a state change).

### Related issues

- Fixes #6314

### Backwards compatibility

Yes
  • Loading branch information
jeanregisser committed Dec 22, 2020
1 parent 51f643d commit d8bee97
Show file tree
Hide file tree
Showing 21 changed files with 1,100 additions and 965 deletions.
9 changes: 9 additions & 0 deletions packages/mobile/jest_setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,12 @@ afterEach(cleanup)

// Mock LayoutAnimation as it's done not automatically
jest.mock('react-native/Libraries/LayoutAnimation/LayoutAnimation.js')

// Mock Animated Views this way otherwise we get a
// `JavaScript heap out of memory` error when a ref is set (?!)
// See https://github.com/callstack/react-native-testing-library/issues/539
jest.mock('react-native/Libraries/Animated/src/components/AnimatedView.js', () => 'View')
jest.mock(
'react-native/Libraries/Animated/src/components/AnimatedScrollView.js',
() => 'RCTScrollView'
)
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,18 @@ exports[`FiatExchange renders correctly 1`] = `
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"left": 0,
"marginBottom": 0,
"marginLeft": 16,
"opacity": 1,
"padding": 0,
"position": "absolute",
}
Array [
Object {
"left": 0,
"marginBottom": 0,
"marginLeft": 16,
"padding": 0,
"position": "absolute",
},
Object {
"opacity": 1,
},
]
}
testID="Hamburguer"
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,18 @@ exports[`renders correctly 1`] = `
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"left": 0,
"marginBottom": 0,
"marginLeft": 16,
"opacity": 1,
"padding": 0,
"position": "absolute",
}
Array [
Object {
"left": 0,
"marginBottom": 0,
"marginLeft": 16,
"padding": 0,
"position": "absolute",
},
Object {
"opacity": 1,
},
]
}
testID="Hamburguer"
>
Expand Down
135 changes: 86 additions & 49 deletions packages/mobile/src/account/__snapshots__/Settings.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,18 @@ exports[`Account renders correctly 1`] = `
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"left": 0,
"marginBottom": 0,
"marginLeft": 16,
"opacity": 1,
"padding": 0,
"position": "absolute",
}
Array [
Object {
"left": 0,
"marginBottom": 0,
"marginLeft": 16,
"padding": 0,
"position": "absolute",
},
Object {
"opacity": 1,
},
]
}
testID="Hamburguer"
>
Expand Down Expand Up @@ -2297,14 +2301,18 @@ exports[`Account renders correctly when dev mode active 1`] = `
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"left": 0,
"marginBottom": 0,
"marginLeft": 16,
"opacity": 1,
"padding": 0,
"position": "absolute",
}
Array [
Object {
"left": 0,
"marginBottom": 0,
"marginLeft": 16,
"padding": 0,
"position": "absolute",
},
Object {
"opacity": 1,
},
]
}
testID="Hamburguer"
>
Expand Down Expand Up @@ -3349,10 +3357,14 @@ exports[`Account renders correctly when dev mode active 1`] = `
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"opacity": 1,
"width": 215,
}
Array [
Object {
"width": 215,
},
Object {
"opacity": 1,
},
]
}
>
<Text
Expand Down Expand Up @@ -3388,9 +3400,12 @@ exports[`Account renders correctly when dev mode active 1`] = `
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"opacity": 1,
}
Array [
undefined,
Object {
"opacity": 1,
},
]
}
>
<Text>
Expand All @@ -3417,9 +3432,12 @@ exports[`Account renders correctly when dev mode active 1`] = `
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"opacity": 1,
}
Array [
undefined,
Object {
"opacity": 1,
},
]
}
>
<Text>
Expand All @@ -3446,9 +3464,12 @@ exports[`Account renders correctly when dev mode active 1`] = `
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"opacity": 1,
}
Array [
undefined,
Object {
"opacity": 1,
},
]
}
>
<Text>
Expand All @@ -3475,9 +3496,12 @@ exports[`Account renders correctly when dev mode active 1`] = `
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"opacity": 1,
}
Array [
undefined,
Object {
"opacity": 1,
},
]
}
>
<Text>
Expand All @@ -3504,9 +3528,12 @@ exports[`Account renders correctly when dev mode active 1`] = `
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"opacity": 1,
}
Array [
undefined,
Object {
"opacity": 1,
},
]
}
>
<Text>
Expand All @@ -3533,9 +3560,12 @@ exports[`Account renders correctly when dev mode active 1`] = `
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"opacity": 1,
}
Array [
undefined,
Object {
"opacity": 1,
},
]
}
>
<Text>
Expand All @@ -3562,9 +3592,12 @@ exports[`Account renders correctly when dev mode active 1`] = `
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"opacity": 1,
}
Array [
undefined,
Object {
"opacity": 1,
},
]
}
>
<Text>
Expand Down Expand Up @@ -4818,14 +4851,18 @@ exports[`Account renders correctly when verification is not possible 1`] = `
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"left": 0,
"marginBottom": 0,
"marginLeft": 16,
"opacity": 1,
"padding": 0,
"position": "absolute",
}
Array [
Object {
"left": 0,
"marginBottom": 0,
"marginLeft": 16,
"padding": 0,
"position": "absolute",
},
Object {
"opacity": 1,
},
]
}
testID="Hamburguer"
>
Expand Down
20 changes: 12 additions & 8 deletions packages/mobile/src/account/__snapshots__/Support.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,18 @@ exports[`Support renders correctly 1`] = `
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"left": 0,
"marginBottom": 0,
"marginLeft": 16,
"opacity": 1,
"padding": 0,
"position": "absolute",
}
Array [
Object {
"left": 0,
"marginBottom": 0,
"marginLeft": 16,
"padding": 0,
"position": "absolute",
},
Object {
"opacity": 1,
},
]
}
testID="Hamburguer"
>
Expand Down
47 changes: 27 additions & 20 deletions packages/mobile/src/alert/AlertBanner.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,37 @@
import SmartTopAlert, { AlertTypes } from '@celo/react-components/components/SmartTopAlert'
import * as React from 'react'
import SmartTopAlert from '@celo/react-components/components/SmartTopAlert'
import React, { memo, useMemo } from 'react'
import { useDispatch } from 'react-redux'
import { hideAlert } from 'src/alert/actions'
import { ErrorDisplayType } from 'src/alert/reducer'
import useSelector from 'src/redux/useSelector'

export default function AlertBanner() {
function AlertBanner() {
const alert = useSelector((state) => state.alert)
const dispatch = useDispatch()

const onPress = () => {
const action = alert?.action ?? hideAlert()
dispatch(action)
}
const displayAlert = useMemo(() => {
if (alert?.displayMethod === ErrorDisplayType.BANNER && (alert.title || alert.message)) {
const onPress = () => {
const action = alert?.action ?? hideAlert()
dispatch(action)
}

return (
<SmartTopAlert
isVisible={!!alert && alert.displayMethod === ErrorDisplayType.BANNER}
// TODO: this looks like a hack to re-render, refactor!
timestamp={Date.now()}
text={alert && alert.message}
onPress={onPress}
type={alert && alert.type === 'error' ? AlertTypes.ERROR : AlertTypes.MESSAGE}
dismissAfter={alert && alert.dismissAfter}
buttonMessage={alert && alert.buttonMessage}
title={alert && alert.title}
/>
)
const { type, title, message, buttonMessage, dismissAfter } = alert

return {
type,
title,
message,
buttonMessage,
dismissAfter,
onPress,
}
} else {
return null
}
}, [alert])

return <SmartTopAlert alert={displayAlert} />
}

export default memo(AlertBanner)

0 comments on commit d8bee97

Please sign in to comment.