Skip to content

Commit c8d5ba0

Browse files
committed
Auto scroll to end after adding or editing addresses & amounts
1 parent 6274ea5 commit c8d5ba0

File tree

3 files changed

+38
-0
lines changed

3 files changed

+38
-0
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@
55
- added: Add eCash.
66
- changed: Auto launch QR scanner for multi-out payments if previously used
77
- changed: Auto populate amount for multi-out payments if prior amounts are similar
8+
- changed: Auto scroll to end of `SendScene2` when addresses or amounts change
89
- fixed: No longer show FIO onboarding modal while in Duress Mode.
910
- fixed: Prevent pin changes which match duress pin.
11+
- changed: Auto launch QR scanner for multi-out payments if previously used
12+
- changed: Auto populate amount for multi-out payments if prior amounts are similar
1013

1114
## 4.28.0 (staging)
1215

src/__tests__/scenes/__snapshots__/SendScene2.ui.test.tsx.snap

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ exports[`SendScene2 1 spendTarget 1`] = `
209209
extraScrollHeight={62}
210210
getScrollResponder={[Function]}
211211
handleOnScroll={[Function]}
212+
innerRef={[Function]}
212213
keyboardDismissMode="interactive"
213214
keyboardOpeningTime={250}
214215
keyboardSpace={0}
@@ -1605,6 +1606,7 @@ exports[`SendScene2 1 spendTarget with info tiles 1`] = `
16051606
extraScrollHeight={62}
16061607
getScrollResponder={[Function]}
16071608
handleOnScroll={[Function]}
1609+
innerRef={[Function]}
16081610
keyboardDismissMode="interactive"
16091611
keyboardOpeningTime={250}
16101612
keyboardSpace={0}
@@ -3229,6 +3231,7 @@ exports[`SendScene2 2 spendTargets 1`] = `
32293231
extraScrollHeight={62}
32303232
getScrollResponder={[Function]}
32313233
handleOnScroll={[Function]}
3234+
innerRef={[Function]}
32323235
keyboardDismissMode="interactive"
32333236
keyboardOpeningTime={250}
32343237
keyboardSpace={0}
@@ -4811,6 +4814,7 @@ exports[`SendScene2 2 spendTargets hide tiles 1`] = `
48114814
extraScrollHeight={62}
48124815
getScrollResponder={[Function]}
48134816
handleOnScroll={[Function]}
4817+
innerRef={[Function]}
48144818
keyboardDismissMode="interactive"
48154819
keyboardOpeningTime={250}
48164820
keyboardSpace={0}
@@ -6052,6 +6056,7 @@ exports[`SendScene2 2 spendTargets hide tiles 2`] = `
60526056
extraScrollHeight={62}
60536057
getScrollResponder={[Function]}
60546058
handleOnScroll={[Function]}
6059+
innerRef={[Function]}
60556060
keyboardDismissMode="interactive"
60566061
keyboardOpeningTime={250}
60576062
keyboardSpace={0}
@@ -7269,6 +7274,7 @@ exports[`SendScene2 2 spendTargets hide tiles 3`] = `
72697274
extraScrollHeight={62}
72707275
getScrollResponder={[Function]}
72717276
handleOnScroll={[Function]}
7277+
innerRef={[Function]}
72727278
keyboardDismissMode="interactive"
72737279
keyboardOpeningTime={250}
72747280
keyboardSpace={0}
@@ -8304,6 +8310,7 @@ exports[`SendScene2 2 spendTargets lock tiles 1`] = `
83048310
extraScrollHeight={62}
83058311
getScrollResponder={[Function]}
83068312
handleOnScroll={[Function]}
8313+
innerRef={[Function]}
83078314
keyboardDismissMode="interactive"
83088315
keyboardOpeningTime={250}
83098316
keyboardSpace={0}
@@ -9661,6 +9668,7 @@ exports[`SendScene2 2 spendTargets lock tiles 2`] = `
96619668
extraScrollHeight={62}
96629669
getScrollResponder={[Function]}
96639670
handleOnScroll={[Function]}
9671+
innerRef={[Function]}
96649672
keyboardDismissMode="interactive"
96659673
keyboardOpeningTime={250}
96669674
keyboardSpace={0}
@@ -10976,6 +10984,7 @@ exports[`SendScene2 2 spendTargets lock tiles 3`] = `
1097610984
extraScrollHeight={62}
1097710985
getScrollResponder={[Function]}
1097810986
handleOnScroll={[Function]}
10987+
innerRef={[Function]}
1097910988
keyboardDismissMode="interactive"
1098010989
keyboardOpeningTime={250}
1098110990
keyboardSpace={0}
@@ -12225,6 +12234,7 @@ exports[`SendScene2 Render SendScene 1`] = `
1222512234
extraScrollHeight={62}
1222612235
getScrollResponder={[Function]}
1222712236
handleOnScroll={[Function]}
12237+
innerRef={[Function]}
1222812238
keyboardDismissMode="interactive"
1222912239
keyboardOpeningTime={250}
1223012240
keyboardSpace={0}

src/components/scenes/SendScene2.tsx

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ import { ErrorTile } from '../tiles/ErrorTile'
6969

7070
// TODO: Check contentPadding
7171

72+
const SCROLL_TO_END_DELAY_MS = 150
73+
7274
interface Props extends EdgeAppSceneProps<'send2'> {}
7375

7476
export interface SendScene2Params {
@@ -128,7 +130,9 @@ const SendComponent = (props: Props) => {
128130
const theme = useTheme()
129131
const styles = getStyles(theme)
130132

133+
const needsScrollToEnd = React.useRef<boolean>(false)
131134
const makeSpendCounter = React.useRef<number>(0)
135+
const scrollViewRef = React.useRef<KeyboardAwareScrollView | null>(null)
132136

133137
const initialMount = React.useRef<boolean>(true)
134138
const pinInputRef = React.useRef<TextInput>(null)
@@ -269,6 +273,7 @@ const SendComponent = (props: Props) => {
269273
setMinNativeAmount(parsedUri.minNativeAmount)
270274
setExpireDate(parsedUri?.expireDate)
271275
setSpendInfo({ ...spendInfo })
276+
needsScrollToEnd.current = true
272277
}
273278
}
274279

@@ -278,6 +283,7 @@ const SendComponent = (props: Props) => {
278283
setLastAddressEntryMethod(undefined)
279284
spendInfo.spendTargets.splice(index, 1)
280285
setSpendInfo({ ...spendInfo })
286+
needsScrollToEnd.current = true
281287
}
282288

283289
const renderAddressAmountTile = (index: number, spendTarget: EdgeSpendTarget) => {
@@ -357,6 +363,7 @@ const SendComponent = (props: Props) => {
357363
setSpendInfo({ ...spendInfo })
358364
setMaxSpendSetter(-1)
359365
setFieldChanged(newField)
366+
needsScrollToEnd.current = true
360367
}
361368

362369
const handleSetMax = (index: number) => () => {
@@ -482,6 +489,7 @@ const SendComponent = (props: Props) => {
482489
const handleAddAddress = useHandler(() => {
483490
spendInfo.spendTargets.push({})
484491
setSpendInfo({ ...spendInfo })
492+
needsScrollToEnd.current = true
485493
})
486494

487495
const renderAddAddress = () => {
@@ -1139,6 +1147,19 @@ const SendComponent = (props: Props) => {
11391147
backgroundColors[0] = scaledColor
11401148
}
11411149

1150+
React.useEffect(() => {
1151+
// Hack: While you would think to use InteractionManager.runAfterInteractions,
1152+
// it doesn't work because several renders occur before the full height is
1153+
// determined and the scrollToEnd call would be effective.
1154+
const timeout = setTimeout(() => {
1155+
if (needsScrollToEnd.current) {
1156+
scrollViewRef.current?.scrollToEnd(true)
1157+
needsScrollToEnd.current = false
1158+
}
1159+
}, SCROLL_TO_END_DELAY_MS)
1160+
return () => clearTimeout(timeout)
1161+
})
1162+
11421163
return (
11431164
<SceneWrapper
11441165
hasNotifications
@@ -1152,6 +1173,10 @@ const SendComponent = (props: Props) => {
11521173
{({ insetStyle }) => (
11531174
<>
11541175
<StyledKeyboardAwareScrollView
1176+
innerRef={ref => {
1177+
const kbRef: KeyboardAwareScrollView | null = ref as any
1178+
scrollViewRef.current = kbRef
1179+
}}
11551180
contentContainerStyle={{
11561181
...insetStyle,
11571182
paddingTop: 0,

0 commit comments

Comments
 (0)