Hello ! I'm currently programming an online card g...
# compose-desktop
d
Hello ! I'm currently programming an online card game for my bachelor thesis (on Windows, using JVM). But I have a big issue implementing the drag gesture of the cards. A card moves while dragged, but when mouse button is released, two things happen: • card is added to the new row (this is the normal behaviour) • but dragged card stays displayed and so creates problems of display and duplication I join a video showing the issue and put in a thread the code. This is a shortened version of the code (just to replicate the problem), the real project is significantly bigger. I use Compose 0.4.0 and Kotlin 1.5.10. I am struggling with that issue for a long time now, so.... any help would be appreciated :)
b
Jesus, use slack text snippets for text blocks that long 😀
o
this kind of requests (
please debug my code
) are not really the intended usage of this channel. Please localize your problem and if you believe it’s CfD bug - file an issue on https://github.com/JetBrains/compose-jb/issues
👆 1
d
That's precisely what i'm asking help for : localize my problem. It is probably nested in the first code block, the others are just here to make it compile and so reproduce the problem.
i
Not sure, but my guess that
.pointerInput(key1 = null)
captures lambdas from the old recomposition (onDragEndUp/onDragEndDown) It is a common mistake. To fix it there two ways: 1. use rememberUpdatedState and use currentOnDragEndUp/currentOnDragEndDown instead of onDragEndUp/onDragEndDown
Copy code
onDragEndUp: () -> Unit,
    onDragEndDown: () -> Unit
) {
    val currentOnDragEndUp by rememberUpdatedState(onDragEndUp)
    val currentOnDragEndDown by rememberUpdatedState(onDragEndUp)
    ...
}
2. restart coroutine every time onDragEndUp/onDragEndDown changes (don't recommend, your loose state stored in coroutine)
Copy code
.pointerInput(onDragEndUp, onDragEndDown ) {
   detectDragGestures(
      onDrag
...
localize my problem
It is always difficult to the others to read not their own code, especially if the code is big. The most robust method to localize any issue in code - is to cut surrounding code / change data to stubs / remove unnecessary fancy decorations until the issue reproduces. If your code is small, then people would read it and can help. But if code is big then people usually will ignore it because it will take so much time to debug/find the issue.
d
To fix it there two ways:
1. use rememberUpdatedState
2. restart coroutine every time onDragEndUp/onDragEndDown changes
Thank you for the answer, but neither of these solutions solved my issue 😭 I edited the main file to make it a bit shorter.
o
the problem is that your reproducer has too much of custom logic unrelated to the problem. Please localize it to bugs in drag behavior or other Compose APIs behaving not intended and documented way. Trying to save your own time at expense of others is usually not considered friendly behavior in development community, so people will unlikely spend too much time on reports like that.
👍 1
d
Ok, I understand. I reworked my reproducer, it is now in one file only. I deleted my old code messages. The new reproducer can be found here https://github.com/GTZL1/TB-slack-short (or is it better to put it here in a block ?).
i
Try this fix:
Copy code
@Composable
fun DisplayCard(
    modifier: Modifier = Modifier,
    card: PlayCard,
    onDragEndUp: () -> Unit,
    onDragEndDown: () -> Unit
) = key(card) {
When Compose recomposes its content after we change order of the cards, it thinks that some other card in the bottom row is the same card that was dragged. To tell Compose that it isn't the same card we should use
key
d
Ok... it seems to work ! I'll try in the big project and mark the conversation as resolved if still the case.
It works fine, thanks for your help @Igor Demin 🙂
👍 1