-
Notifications
You must be signed in to change notification settings - Fork 583
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Implement Home view tasks section list #10961
feat: Implement Home view tasks section list #10961
Conversation
a1569e5
to
9fbbfc2
Compare
9fbbfc2
to
40a1ccb
Compare
fbbc2ec
to
9cdc209
Compare
const renderItem = useCallback<ListRenderItem<Task>>( | ||
({ item, index }) => { | ||
let scaleX = 1 | ||
let translateY = 0 | ||
let opacity = 1 | ||
|
||
if (!showAll && index !== 0) { | ||
scaleX = 1 - index * 0.05 | ||
translateY = -83 * index | ||
opacity = 1 - index * 0.15 | ||
if (index > 2) { | ||
opacity = 0 | ||
} | ||
} | ||
|
||
return ( | ||
<Flex> | ||
<MotiView | ||
key={item.internalID + index} | ||
transition={{ type: "timing", duration: 500 }} | ||
animate={{ transform: [{ scaleX }, { translateY }], opacity }} | ||
> | ||
<Task | ||
disableSwipeable={displayTaskStack} | ||
onClearTask={() => handleClearTask(item)} | ||
onPress={displayTaskStack ? () => setShowAll((prev) => !prev) : undefined} | ||
ref={swipeableRef} | ||
task={item} | ||
/> | ||
</MotiView> | ||
</Flex> | ||
) | ||
}, | ||
[displayTaskStack, handleClearTask, showAll] | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like this is basically a memoized component. I've seen this before in other apps but wonder if there is an established convention for functions called renderSomething
that return a JSX.Element
vs defining them as a standard functional component with a props signature.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe both would work, but having them as a memoized function makes the list rendering more performant than rendering a component without a memoization
In this case, I used it as a function inside the component to be able to access some of the states and values that are in the main component instead of passing it down to another component
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh right, I didn't look closely but assumed it was inside for access to some state. My general preference would just be to name it like a component and give it a props-style object arg, still memoizing it. This way when it's used in code it would appear as <Foo bar={true} baz={42} />
rather than {renderFoo(true, 42)}
.
But as I look at this more it is actually being passed to a renderItem
prop and so I would probably throw everything I just said out the window.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Last q: Shouldn't key
be in the wrapping flex component?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Last q: Shouldn't
key
be in the wrapping flex component?
I believe that's handled by Flatlist's keyExtractor
prop, but I used that key
for MotiView to identify which item to animate how, but I can try to remove it and see what happens :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good to me, a few basic comments but nothing blocking.
if (!task) { | ||
return | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess not 😅 I'll remove it!
const [clearedTasks, setClearedTasks] = useState<string[]>([]) | ||
const [showAll, setShowAll] = useState(false) | ||
|
||
const filteredTasks = tasks.filter((task) => !clearedTasks.includes(task.internalID)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a little confused here as this seems like the only usage of clearedTasks
. Why are these kept in state - does it have to do with the relay store and what happens after you swipe one away?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah that's correct. I tried updating the tasks list in the relay store but I wasn't successful with it, maybe I was missing something there
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My idea here was to immediately hide all swiped-away tasks without having to refetch the list of tasks. I guess this could (in theory 🙃) be possible only with the Relay store and without using the extra state.
If the dismissTask
mutation queried for the dismissedAt
field and had an optimistic response implemented, this could lead to Relay updating the task in the connection within the Relay store. But I'm not sure if this would work in practice...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh Thank you Ole! I can try that with a follow-up PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's also possible to Imperatively update the Relay store, but it's not super straightforward....
Merging this to prepare for the QA |
This PR resolves EMI-2096
Description
This PR implements the grouping of multiple tasks on the home view
It also adds the animation to the tasks when expanding
Demo
grouped-tasks-android.mov
grouped-tasks-ios.mov
PR Checklist
To the reviewers 👀
Changelog updates
Changelog updates
Cross-platform user-facing changes
iOS user-facing changes
Android user-facing changes
Dev changes
Need help with something? Have a look at our docs, or get in touch with us.