Drats — accidentally deleted my message. Reposting. Ever want to write a simple application, but writing a CLJS front end and a CLJ backend just seem like overkill? And the idea of having to learn Java Swing or JavaFX seems too daunting, but so too does the idea of writing a curses/terminal app (which doesn't even have an event loop)? @smith.adriane wrote something so cool, the membrane library — it lets you write a curses/terminal app that runs in your terminal or in a Swing application, but on top of re-frame. He helped me write a simple app yesterday that captures and displays keystrokes (hacked into the membrane sample app, which is the canonical TODO MVC app.) I'm so excited by this, because there's a whole class of simple applications that this seems perfect for! Thank you, @smith.adriane and @mikethompson !
Here was his announcement of the project yesterday — so fun!!! https://clojurians.slack.com/archives/C073DKH9P/p1594229800342600
And a screenshot of the ridiculous simple app I'm so happy about! :) https://clojurians.slack.com/archives/C073DKH9P/p1594623576408700?thread_ts=1594229800.342600&channel=C073DKH9P&message_ts=1594623576.408700
Further discussions in #membrane!
Thanks for the kind words @genekim and also thanks to @mikethompson for re-frame. If this is something people are interested in, I could use some help designing re-frame compatible versions of basic reusable components like textboxes
I'm struggling with a design question.
In my app I have a concept of "actions" that the user can take, which are determined dynamically based on things like selections made in the UI and data fetched from remote services. I have a network of subscriptions which aggregates this nicely into a single list of actions, and a UI which can show the user a searchable list of these actions. Subscriptions mean that the list updates dynamically, as it should.
I also want to provide keyboard shortcuts for actions, and I've been looking at re-pressed as a library for this. Problem is that re-pressed requires me to "declare" the active keyboard shortcuts via an event (`set-keydown-rules`). So instead of having a data-driven reactive workflow as I do with the action list UI, I have to trigger events when the relevant data changes, if the change means that a new keyboard shortcut is now valid (or an old one is not).
My ideal solution is simply to be able to trigger an event when a subscription changes. It seems like the easiest way to do this is to have a Reagent form-3 component which subscribes to the relevant subscription, and triggers an event in the :component-did-update
handler, while returning nil
from the render function. Is there a better design pattern for this?
I have not used it (yet), but I think you want track!
https://reagent-project.github.io/docs/master/reagent.core.html#var-track.21
removes the need of a react component and is more explicit in intent
Oh, that makes sense. Thanks! I was starting from the JS React-ish concept of renderless components, which felt like an un-Reagent/Re-frameish way of doing things.
Regarding re-pressed, yeah, the recommended approach is to dispatch the set-keydown-rules
event anytime the rules change. There is no limit to how frequent you can dispatch that even, so I think you can achieve the dynamic effect you want.
Yes, absolutely! My problem was just that I wanted to re-use the work I had already done in generating the action list, which is bundled up in a subscription, so I needed to figure out the right way of triggering an event on a subscription change.
Does track!
work with re-frame subscriptions? I'm trying it but not seeing the results I would expect.
re-frame subscriptions are reagent reactions, so yes, it should work
just make sure to deref the subscription inside the function
Yeah, that's what I'm doing.
(defn active-tracker []
(let [active (re-frame/subscribe [::active])]
(prn @active)))
(defonce tracker (r/track! active-tracker))
It prints once, but doesn't do anything when the subscription updates.
hmmm... my guess is it doesn't work because you are creating the reaction inside the tracking function
Oh, hmm. Where else am I supposed to create it?
(let [active (re-frame/subscribe [::active])
tracker (fn [] (println @active))]
(r/track! tracker))
that should work
Thanks, I'll try that
you will need to keep a reference of the result of track!
for later disposal though... the example I gave you will leak the reference
This seems to behave the same way as the original version 😞
maybe something like:
(defonce tracker (let [active (re-frame/subscribe [::active])] (r/track! (fn [] (println @active))))
although probably an atom would be more appropriate to hold the reference
I'm doing that, but the basic functionality just doesn't seem to work. I must be missing something obvious but I can't work out what.
Ah, during re-frame setup/auto-reload I have a call to re-frame/clear-subscription-cache!
and this breaks the subscription. As it's not part of a view/component, it doesn't get recreated. That was the problem.
Any good open source re-frame project to get idea about to to properly structure the components, etc?
@genekim suggested https://github.com/day8/re-com to me yesterday and it looks pretty good and has lots of examples: https://github.com/day8/re-com/blob/master/src/re_com/misc.cljs
for specifically flexible and re-usable components
Thanks @smith.adriane