Skip to content

ListscreenV2#3583

Merged
bogdandobritoiu merged 9 commits intomainfrom
listscreen/v2
Feb 13, 2026
Merged

ListscreenV2#3583
bogdandobritoiu merged 9 commits intomainfrom
listscreen/v2

Conversation

@bogdandobritoiu
Copy link
Contributor

@bogdandobritoiu bogdandobritoiu commented Feb 13, 2026

Description

A new version of ListScreen with FlashList.

Simulator.Screen.Recording.-.26.-.2026-02-13.at.21.39.33.mov

Testing

Dev Testing (if applicable)

iOS - 7468
Android - 7469

  1. Open Fusion => Select a token
  2. Check if scrolling and animations have the same interactions as Swap's => Select a token
  3. Verify UI when keyboard is open and you're scrolling inside
  4. Verify you can get to the last item when keyboard is open

Checklist

Please check all that apply (if applicable)

  • I have performed a self-review of my code
  • I have verified the code works
  • I have included screenshots / videos of android and ios
  • I have added testing steps
  • I have added/updated necessary unit tests
  • I have updated the documentation

atn4z7
atn4z7 previously approved these changes Feb 13, 2026
Copy link
Collaborator

@atn4z7 atn4z7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

amazing!!

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Introduces a new ListScreenV2 component built on Shopify’s FlashList to improve list performance and scrolling/keyboard interactions, and migrates the Swap V2 token selector screen to use it.

Changes:

  • Added ListScreenV2 (FlashList-based) with animated header behavior, modal grabber support, and custom empty/footer handling.
  • Updated SelectSwapV2TokenScreen to use ListScreenV2, including providing estimatedItemSize and updating the keyExtractor.
  • Simplified the token selector empty/loading rendering now that the new list screen handles centering/layout.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
packages/core-mobile/app/new/features/swapV2/screens/SelectSwapV2TokenScreen.tsx Switches Swap V2 token selection to the new FlashList-based list screen and tweaks list configuration.
packages/core-mobile/app/new/common/components/ListScreenV2.tsx Adds a new reusable list-screen abstraction using FlashList with header/empty/footer + keyboard interaction logic.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +344 to +348
return {
...(props?.contentContainerStyle ?? {}),
paddingBottom: renderFooter ? footerHeight + 16 : 16
}
}, [renderFooter, footerHeight, props?.contentContainerStyle])
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

contentContainerStyle.paddingBottom doesn’t account for safe-area bottom inset or keyboard height. Compared to ListScreen, this can cause the last items to be obscured by the home indicator (when no footer) and/or the keyboard (when search is focused), conflicting with the PR’s keyboard-scrolling requirements. Consider computing paddingBottom similarly to ListScreen (keyboard height when visible, otherwise insets.bottom + 16, plus any footer height).

Suggested change
return {
...(props?.contentContainerStyle ?? {}),
paddingBottom: renderFooter ? footerHeight + 16 : 16
}
}, [renderFooter, footerHeight, props?.contentContainerStyle])
const basePaddingBottom = keyboard.isVisible
? keyboard.height
: insets.bottom + 16
const footerPaddingBottom = renderFooter ? footerHeight : 0
return {
...(props?.contentContainerStyle ?? {}),
paddingBottom: basePaddingBottom + footerPaddingBottom
}
}, [
footerHeight,
insets.bottom,
keyboard.height,
keyboard.isVisible,
props?.contentContainerStyle,
renderFooter
])

Copilot uses AI. Check for mistakes.
Comment on lines +186 to +189
offset:
event.nativeEvent.contentOffset.y > contentHeaderHeight
? event.nativeEvent.contentOffset.y
: contentHeaderHeight,
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In onScrollEndDrag, the conditional event.nativeEvent.contentOffset.y > contentHeaderHeight ? ... : contentHeaderHeight is unreachable because this block only runs when contentOffset.y < contentHeaderHeight. This can be simplified to always scroll to contentHeaderHeight, which makes the intent clearer and avoids dead code.

Suggested change
offset:
event.nativeEvent.contentOffset.y > contentHeaderHeight
? event.nativeEvent.contentOffset.y
: contentHeaderHeight,
offset: contentHeaderHeight,

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings February 13, 2026 22:24
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +518 to +525
const overrideProps = useMemo(() => {
return {
contentContainerStyle: {
...contentContainerStyle,
minHeight
}
}
}, [contentContainerStyle, minHeight])
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment above says FlashList contentContainerStyle should not receive unsupported props like minHeight, but overrideProps later adds minHeight into a contentContainerStyle object. Either update the comment to explain why overrideProps.contentContainerStyle is safe/intentional, or avoid passing minHeight this way to prevent confusion and potential unsupported-style issues.

Copilot uses AI. Check for mistakes.
Comment on lines +536 to +547
<FlashList
data={data}
ref={scrollViewRef}
renderScrollComponent={RenderScrollComponent}
onScroll={onScrollEvent}
onScrollEndDrag={onScrollEndDrag}
keyboardDismissMode="interactive"
keyboardShouldPersistTaps="handled"
showsVerticalScrollIndicator={false}
overrideProps={overrideProps}
contentContainerStyle={contentContainerStyle}
{...props}
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{...props} is spread after onScroll, onScrollEndDrag, contentContainerStyle, and overrideProps. If a caller passes any of these props, it will override the internal handlers/styles and can break the fading header behavior and keyboard/list layout assumptions. Consider moving {...props} earlier (before the internal props) or explicitly omitting the props you must control from the spread.

Copilot uses AI. Check for mistakes.
@bogdandobritoiu bogdandobritoiu merged commit 628bdb4 into main Feb 13, 2026
10 checks passed
@bogdandobritoiu bogdandobritoiu deleted the listscreen/v2 branch February 13, 2026 22:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants