Fork me on GitHub
#biff
<
2022-06-13
>
jeffparker13:06:08

In Platypub I have the subscriber form and newsletter mailing lists setup and working with mailgun. One thing I ran into is the verify_address javascript function returning false for every address, so I disabled it.

jeffparker13:06:59

I'm guessing I may need to upgrade my Mailgun account for that feature to work?

Jacob O'Bryant01:06:50

Oh, maybe that is a paid feature... yep looks like you have to be on at least the $35/month plan (https://www.mailgun.com/pricing/). I'll comment that out, it's not that super important anyway.

👌 1
theeternalpulse13:06:43

I've been fiddling around with a devcards like feature that you can add to your app, allowing you to define card-like components for fast prototyping, with live-reloading via a websocket. I'm still figuring out a controls like mechanism so the card can be controlled in real time. Think I'm going to stop there and deal with things like history and mocking db calls later. Trying to figure out a smart way to just have the component live reload without loading the webpage

theeternalpulse14:06:40

Though I couldn't figure out how to signal from the on-save to be handled by the :on-text handler set up on the route controller. I had to create a little js that runs to refresh the page, but what I really want is for it to just reload the component in place since I'm loading it into the page via :hx-trigger load with a particular route element, since it's route based devcards.

theeternalpulse14:06:17

@U7YNGKDHA would love feedback. I hate that I used the name devcards because originally I was going to hook in the actual devcards project, but figured since htmx is relatively simpler I could try this

theeternalpulse16:06:41

One thing I'm wondering is that I initialize my websocket to an atom I put in the app config, then when I try to do (send! @myAtom "msg") in the on-save the :on-text handler I set up in the websocket routed doesn't get called. I had to do a roundabout thing where I handle the route in the javascript and just reload, which isn't what I eventually want

Jacob O'Bryant02:06:29

👀 I'll look at this soon!

theeternalpulse14:06:58

One of the final pieces that isn't in the snippet is

(defn on-save [sys]
  ...
  (let [{:keys [:example/devtools-ws]} sys]
    (when @devtools-ws
      (jetty/send! @devtools-ws "RELOAD"))))

👍 1
Jacob O'Bryant18:06:54

@U1CUUKHDL just looked over the snippet. Re: the :on-text handler--that function is only called when there's a message sent from the frontend, not the backend. e.g. at https://github.com/jacobobryant/biff/blob/master/example/src/com/example/feat/app.clj#L72-L73, this form being submitted will result in the form parameters getting passed to the :on-text handler (as a json string). For sending messages from the backend to the frontend, you're already doing it the right way, i.e. (jetty/send! @devtools-ws ...). There are a couple htmx techniques related to sending websocket messages from backend to frontend that might be handy. First (and I think this is what you'll want for reloading components in-place, without a page refresh) is doing an out-of-band swap. If you have htmx start the ws connection (as in the link above), then you can send html snippets and htmx will swap them into the dom. You just need to specify the id of the element that should be replaced with your snippet. Here for example (https://github.com/jacobobryant/biff/blob/master/example/src/com/example/feat/app.clj#L51-L55) we send a snippet that will replace* the <div id="messages" ... element. *or rather, we would've replaced that element, except since in that example we also set {:hx-swap-oob "afterbegin"}, the snippet just gets inserted into the div, it doesn't replace the div's current contents. another trick is if you do need to run arbitrary js, you can still initiate the ws connection with htmx, and from the backend send something like <div id="some-hidden-element" _="init call window.location.reload()"></div>" (in fact the previous example also does something like this: https://github.com/jacobobryant/biff/blob/master/example/src/com/example/feat/app.clj#L42).

🤯 1
theeternalpulse23:06:37

Yes, I just kind of wrapped my head around OOB when I saw it, and I definitely need to try that last trick trick. One of the latest things I'm trying to do is have a "create-card" so that it can store the card data so when I refetch the route, I can pass it the parameters (or last parameters whenever I look around to having a state. Thanks for the tips, I'm going to have some time to look it over.

👌 1
theeternalpulse11:06:50

Finally got it, had to wrap my head around some of the confusing routing I'm doing, need to simplify. I removed the JS ws stuff and am now just sending to the ws a static html with a reload div surrounding my original content that will load the devcard/card route into the container which will then be swapped oob

theeternalpulse11:06:59

(when @devtools-ws
      (let [html (rum/render-static-markup
                  [:#reload
                   (let [{:keys [route]} @devcards/current-card]
                     {:hx-trigger "load"
                      :hx-post (str "/devcards/card" route)
                      :hx-target "#devcard-container"})
                   [:#devcard-container.flex-1 {:hx-swap-oob "true"}]])]
        (jetty/send! @devtools-ws html)))

theeternalpulse11:06:19

took me a while to figure out that this would work as intended. Now I can go back to my main project 😆