This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-06-05
Channels
- # announcements (11)
- # architecture (22)
- # babashka (33)
- # beginners (15)
- # biff (8)
- # calva (7)
- # clj-otel (1)
- # cljs-dev (3)
- # cljsrn (5)
- # clojure (76)
- # clojure-art (1)
- # clojure-europe (36)
- # clojure-hamburg (3)
- # clojure-nl (1)
- # clojure-norway (7)
- # clojure-poland (12)
- # clojure-spec (2)
- # clojure-uk (7)
- # clojurescript (9)
- # cursive (22)
- # data-science (6)
- # datomic (7)
- # fulcro (9)
- # hoplon (14)
- # instaparse (2)
- # jobs-discuss (14)
- # london-clojurians (1)
- # matrix (32)
- # music (1)
- # nbb (8)
- # off-topic (18)
- # pathom (29)
- # pedestal (6)
- # portal (34)
- # reagent (2)
- # reitit (4)
- # releases (1)
- # sci (10)
- # shadow-cljs (7)
- # tools-deps (4)
- # vim (6)
I think I'm missing something:
(defn button [title action]
(fx/gesture-detector
{:onTap (fx/as-dart-callback [] (action))}
(fx/center
(m/Text title .style (m/TextStyle .fontSize 18 .fontWeight m/FontWeight.w800)))))
(defn make-app []
(let [title "Why Hello"]
(fx/material-app
{:title title}
(fx/scaffold
{:appBar (fx/app-bar {:title (fx/text title)})}
{:name :scaffo
:step (cI 1)}
(fx/center
(fx/column
(fx/text (str "current step: " (mget (fasc :scaffo) :step)))
(fx/elevated-button {:onPressed (dfn [] (with-cc :test (mset! (fasc :scaffo) :step 2)))}
(fx/text "Change to next step"))
(fx/elevated-button {:onPressed (dfn [] (with-cc :test (mset! (fasc :scaffo) :step 1)))}
(fx/text (str "Change to first step")))
(case (mget (fasc :scaffo) :step)
1 (fx/column (fx/text "hi -- ")
(button "you'd think this would change" (fn [] (mx/dp :button-1))))
2 (fx/column (fx/text "howdy -- ")
(button "but does it?" (fn [] (mx/dp :button-2)))))))))))
The regular text (IE. "hi -- " and "howdy -- ") Changes with the :step
prop, as I would expect. Yet somehow the (button ,,,,)
call does not?Hmm, works fine without the fx/guesture-detector
.
Gonna fire this up now....
Confirmed the issue.
Oh, btw, it should not matter (it's a NOP), but we only need to wrap state change in with-cc
in watches, when a state change is already underway. So the gesture-detector :onTap
is fine.
But I have those commented out in the elevated button onPresses and the problem is unchanged. I will leave them commented out while I explore, just to KISS.
I suspect I may be missing a setState
. Deep-diving...
Confirm it works without the gesture-detector -- good clue! Just realizing how strange is the behavior -- the text hi/howdy proves we are changing columns! Btw, eliminating the "but does it?" button altogether works in the sense that "you'd think" disappears. Good one! Wondering if we are looking at two issues... :thinking_face:
OK, the second column runs as expected, and as we can see from the text being pulled in. I have to crash, but methinks Flutter thinks the two GDs (gesture detectors) are the same, for some value of "same". More after a quick crash.
Sounds likely! Some bits in this thread are perhaps relevant: https://clojurians.slack.com/archives/C03A6GE8D32/p1675818632237609
Hmm, maybe it has something to do with GuestureDetector being a StatelessWidget ?
Since we're not dealing with a stateful widget, maybe we need to call markNeedsBuild directly?
Thx, I have been getting ready to explore which widgets were stateless and which not. I think I have experimented enough with widget juggling, I'll see where I can work markNeedsBuild
into things.
Ooh, wait, this might be a very simple fix, this deftag looks suspicious...
(deftag tiltontec.flutter-mx.factory/k1-child-stateful gesture-detector m/GestureDetector)
@U0PUGPSFR Aha, that's the culprit! swapped with k1-child-stateless
and now it works like a charm :)
Great catch, and the Flutter doc confirms I got that wrong. Now I have to cheak Ink
, because a center/ink/text is also broken, no GD at all.
Not sure about Ink
itself, but InkWell
is stateless, so probably same for Ink
? I wish flutter gave us a simpler way to find out :P
Oh, yeah, InkWell
is indeed stateful, (in accordence with the deftag), so something else must be at play.
Ink seems to be either. No inheritance (I scroll waaayyyyyyyy down to an inheritance list) and see neither Stateful nor Stateless.
Oh you're right, I got my pages mixed up for a sec.
ISTR Text is the same.
Hmm, (deftag tiltontec.flutter-mx.factory/k1-child-stateless ink m/Ink)
work?
With text I covered all the bases:
(deftagleaf tiltontec.flutter-mx.factory/konly-param1-stateless text m/Text)
(deftagleaf tiltontec.flutter-mx.factory/konly-param1-stateful text! m/Text)
And ISTR that was necessitated by sth not updating.
The Joy of Clojure Flutter :P
Maybe taking a more direct approach of markNeedsBuild
instead of setState
might work around the flutter dance?
Would need some extra guards in the mx internals, I'd guess, but might be a universal solution.
(I really have little context to work with here, this is just me stabbing in the dark)
So far I have found Flutter and Dart to be a PITA to get to work, but eventually sort it out in a way that makes sense. Then I get to look at mobile, desktop, and Web. 🙂 And f/mx can hide the nuisance. With other tools, the pain never ends, we just soldier on grumbling. Are you able to toggle back and forth OK. What if you hit the first button twice, then hit the second? I am seeing:
The following assertion was thrown while handling a gesture:
md-awaken> incoming md-state not= :nascent, it is:md-quiesced
re mNB vs setState, I felt ss might be more "within the system". But mnb is part of the API, and perhaps better than agonizing over stateful/stateless. I mean, after learning a bit more about native Flutter -- they go steful when they need to maintain the custom state f/mx handles at the CLJ level. Why does f/mx ever have to go there? :thinking_face:> Are you able to toggle back and forth OK. What if you hit the first button twice, then hit the second? Hmm, yes this works without incident on my end. Granted I've patched state-set awhile ago because my bluetooth callbacks were trying to set state while things were still building. Not sure if that why or not, but just in case it's relevant. :
(defn state-set
([^State state]
(state-set state nil))
([^State state me]
(if (.-mounted state)
(do (dpx :setting-state state (minfo me))
(try (.setState state (fn [] (do)))
(catch Exception e
(Future.delayed Duration.zero
(fn [] (if (.-mounted state)) (.setState state (fn [] (do))))))
#_ (finally (Future.delayed Duration.zero
(fn [] (if (.-mounted state)) (.setState state (fn [] (do))))))))
#_(dp :NOT_SETTING_STATE_NOT_MOUNTED state (cty/minfo me)))))
Ah, I had jazzed things up a little:
(button (str "but does it?" (* 10 (mget (fasc :scaffo) :step)))
(fn [] (mx/dp :button-2)))
I better see what's going on. :male-detective:Not able to recreate. Meanwhile, I broke the x03-physics-sim example which expects the GD to have state. Hopefully just need to work in that "nearest state" utility:
(cF (when-let [st (fx/my-state)]
(m/AnimationController .vsync st)))
So I changed the physics sim to search up to the nearest state, after making GD stateless, and got an error saying it was not a TickerProvider.
WTF?
A code search and I discover that, in desperation a year ago, I had splatted this line on exactly one factory variant, k1-child-stateful
:
^:mixin m/SingleTickerProviderStateMixin ;; todo make optional
Love the comment. When I made GD k1-child-stateless
, it lost the TickerProvider. The next state up was not a k1-child-stateful
. Boom.
I love this game!Not able to recreate. Meanwhile, I broke the x03-physics-sim example which expects the GD to have state. Hopefully just need to work in that "nearest state" utility:
(cF (when-let [st (fx/my-state)]
(m/AnimationController .vsync st)))
So I changed the physics sim to search up to the nearest state, after making GD stateless, and got an error saying it was not a TickerProvider.
WTF?
A code search and I discover that, in desperation a year ago, I had splatted this line on exactly one factory variant, k1-child-stateful
:
^:mixin m/SingleTickerProviderStateMixin ;; todo make optional
Love the comment. When I made GD k1-child-stateless
, it lost the TickerProvider. The next state up was not a k1-child-stateful
. Boom.
I love this game!