Piggybacking off of :point_up_2: I see that `onRec...
# compose
e
Piggybacking off of 👆 I see that
onRectChanged
has throttle and debounce parameters. Is that something that will be coming to more modifiers?
r
Where would you like to see that?
e
Mostly on
clickable
type of modifiers. I came up with my own external system for handling it, but the devx for it isn't great, and I think it makes more sense to have it at the modifier layer.
s
What use cases do you have in mind? For click events I've found when I've needed to do such things it's always been for navigation. And we got dropUnlessResumed which is a 100% match for my needs there. Did you have anything else in mind instead?
e
Any user actions that can be done in quick succession can cause trouble, e.g. if a user clicks on a button I emit an event that causes a network request to get made. If the user clicks twice very quickly then 2 network requests would get made, which I don't want. I can write guards around it (which I do, and my current system moves the throttling to the event emission layer), but 99%+ of my use cases would be fully handled by throttling at the user input layer.
s
Sounds like not the job of the UI to fix tbh, since it's logic that happens in your VM, duplicate events should be handled by your VM as well. We use molecule presenters, so how this typically surfaces for us is that the click event sets some mutable state to something, and we key on that state on a LaunchedEffect to do some work. Clicking the button again sets the state again to the same thing, so the LaunchedEffect just gets the same key so nothing happens, the old coroutine still continues to do its work.
👆 1
👆🏾 1
2
e
I'm using MVI so it's a little more complicated. I put the logic in my event emitter which is passed to the Compose UI function, but it is very limited in what it could do (mostly just throttling, debouncing and friends would be difficult to implement), and requires the event to implement a marker interface (🤢). I know it technically isn't in the UI domain, but if you squint hard enough it could be, and would solve a lot of implementation issues.
I could solve it at the event handling layer, but that would come with a lot of duplication and boilerplate.
s
Do you have some code? What does it look like at the place where you receive the event to handle it?
e
Here's a simplified example. I could wrap the handling branch or the
login
function in a check to make sure there's nothing in flight, but I'd have to do that for each discrete event.
s
This is suspend as well. Does this mean if login takes time, you're blocking off new events from coming in?
My answer would be to not do side effects directly as a result of an event coming in. If you don't use molecule you could use a Channel. In your onEvent offer an object to the channel, and have someone collecting that channel and doing the network effects as a result. You can then debounce, distinctUntilChanged, and whatever else you wish at the place where you collect that channel.
e
The events are collected from a Flow, and are handed off to
onEvent
so that handling them doesn't block new events. There could be multiple types of events coming through so I can't use operators at the root of it. I could do something like you're suggesting (a separate channel or flow per type), but this is why I said it would be much simpler to handle it at the UI layer 😄
s
I wouldn't suggest using operations to the root of it anyway, each event will require separate handling in any case. Doing this on your UI layer would also mean your tests on your logic won't make a lot of sense if they're not UI tests. You'll be relying on the UI to "do the right thing" whatever that means, as opposed to just baking all of that into your presenter. What do you think about that?
e
I have event emission tests that run as UI tests, so I would be checking for that behavior there.
I don't have the concept of a "presenter" (I use my VICE framework) and my tests are very discrete in general. So when I test event handling I wouldn't expect to test what would happen if another event happens while handling the first one, just that the correct action happens in response to an event. I could also validate the whole flow e2e with a UI test, but I rarely feel the need to do that.