Skip to content
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

Refresh events for individual frames #1215

Open
rbclark opened this issue Mar 1, 2024 · 6 comments
Open

Refresh events for individual frames #1215

rbclark opened this issue Mar 1, 2024 · 6 comments

Comments

@rbclark
Copy link

rbclark commented Mar 1, 2024

Full page morphing is very useful in a lot of situations, but for more complicated pages it would be awesome to be able to trigger refreshing for individual frames on the page. I realize this sounds very similar to what turbo streams already do, however the distinction is that everything would be loaded with the current users context since the client is triggering the refresh, something that isn't possible currently when doing a turbo broadcast.

My use case is that I have multiple pages which have very different content based on a users permissions within turbo frames. Currently it isn't possible for me to broadcast updates to these frames since they look very different for different users and I have no context of the users permissions when rendering the content when using turbo stream broadcasts.

Having the ability to specify a <turbo-stream action="refresh" target="some_frame"></turbo-stream> would be awesome and would make things much more possible for my use case. With the work in #1192 it seems like what I am requesting is already pretty close to possible.

@krschacht
Copy link

@rbclark That seems off to me because the refresh action which is broadcast is tied to a specific model and then views simply subscribe to refreshes from that model. The model does blind broadcasts_refreshes and any pages which are subscribed to it refresh. It does not seem proper for the backend model to consider which particular frame to send a refresh to.

What happens now if you put a <%= turbo_stream_from :model %> inside a turbo frame and then have the backend do it's usual broadcasts_refreshes`?

I know for sure that if the turbo_stream_from is outside of the turbo-frame, that will trigger a refreshing morph of the full page, which subsequently triggers a morphing refresh to each individual turbo-frame on the page (provided that those turbo frames have refresh=morph. It sounds like this alone would get you what you want.

But it may be the case that if you put the turbo_stream_from inside of a turbo frame it might only refresh that frame, without having to do a special refresh broadcast which targets that frame. Give it a shot and see what happens. And if that doesn't work then maybe the base-case will still work for you to just trigger a refresh of the full page.

@rbclark
Copy link
Author

rbclark commented Mar 2, 2024

@krschacht Thank you for your reply! I appreciate your perspective on this, it seems I've used broadcast_replace_to(dom_id(...)) one too many times and seem to still be thinking in that paradigm. Putting a refresh inside a turbo frame makes a lot more sense. I tried out what you said, I placed a turbo_stream_from @model and added broadcasts_refreshes inside of that model inside of a turbo_frame to test it out and unfortunately it just went ahead and triggered a full page morph instead of a targeted frame morph.

For the page in question, it already heavily utilizes turbo streams and stimulus controllers. I spent most of the week investigating converting it over to morphing and came to the conclusion that it would be a significant undertaking to get it all to morph properly since the page consists of filtering, sorting, cross-page-multi-select, and expandable sections each with their own trix editor. I'm also a bit worried about the performance of this page after a full morph since I had to apply a decent amount of logic in before-morph actions to preserve existing state during my testing. Overall in my case I think there would be a lot less strange edge cases and an overall faster user experience in my application if I could easily trigger refreshes of compartmentalized frames.

@krschacht
Copy link

Conceptually, the idea behind broadcast_refresh is "I don't want to think about what parts of the page need to be updated. Please update any parts of the page that ought to change now that I've made an update to this particular model." So the idea that it always triggers a full page morph feels appropriate. Because a full page morph may result in zero dom nodes being updates or lots of dom nodes updating.

I would be surprised that morphing would mess things up. Maybe you simply need to add some "permanent" tags in the right places.

But I'm still new to moprhing as well so I don't know all the edge cases with it. My app is pretty simple so far (https://github.com/the-dot-bot/hostedgpt)

@krschacht
Copy link

Oh, but note that once The 1192 PR gets merged in you will be able to use javascript to target any individual turbo-frame you want and call a .refresh() on it. So it would be a bit hacky, but you could wire up your own special turbo stream action which exists solely to trigger the morphing refresh of specific turbo frames.

@rbclark
Copy link
Author

rbclark commented Mar 2, 2024

@krschacht I tried to document some of the gotcha’s that I think are bugs in a few of the issues I opened on this repository. A lot of the issues revolved around keeping stimulus state and things like that. There’s also some stuff that I want to be permanent in some situations and temporary in others, the app I’m working on has one very complex page in particular that is causing issues.

Regarding implementing a custom turbo action, that’s my plan next week. I just figured I’d float the idea to the project as a whole since I think it’ll be useful for people other than just me!

@tonywok
Copy link

tonywok commented Mar 29, 2024

So it would be a bit hacky, but you could wire up your own special turbo stream action which exists solely to trigger the morphing refresh of specific turbo frames.

I think I have a similar issue as the one described by OP. Unfortunately I also needed to solve it prior to the release of turbo 8. Fwiw, I'm doing almost exactly this. It's been kinda nice!

I have a custom turbo steam action called "custom_event". Then, a stimulus controller with a url value. Upon receiving the event, the controller requests the url, and the response is free to do whatever contextual thing it wants.

What's nice about this is the broadcast is tiny and different parts of the page -- or other pages entirely can request different responses that perform different actions.

In my case, I respond with a morph turbo stream action to update very specific parts of the page.

As I mentioned, because it was prior to turbo 8, I was using the idiomorph library directly. It sounds like once #1192 lands I might be able to delete some code.

For context, I really wanted the response to be as slim as possible because it's quite chatty for this near real time application.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants