This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-01-11
Channels
- # announcements (16)
- # aws (17)
- # babashka (25)
- # beginners (60)
- # calva (40)
- # cider (3)
- # clara (4)
- # clj-kondo (24)
- # clojure (16)
- # clojure-austin (3)
- # clojure-dev (23)
- # clojure-europe (33)
- # clojure-nl (2)
- # clojure-norway (7)
- # clojure-uk (4)
- # clojurescript (39)
- # clr (108)
- # conjure (10)
- # cursive (12)
- # datalevin (7)
- # editors (2)
- # events (1)
- # fulcro (24)
- # graalvm (3)
- # introduce-yourself (8)
- # london-clojurians (2)
- # malli (18)
- # meander (6)
- # missionary (10)
- # nbb (16)
- # off-topic (19)
- # polylith (1)
- # portal (4)
- # rdf (1)
- # reitit (4)
- # remote-jobs (3)
- # shadow-cljs (10)
- # xtdb (12)
new problem: I have a discrete flow (DOM "copy"
event listener). On every event I have to use the async Clipboard API to retrieve the contents of the clipboard. the goal is to have a p/def
that represents the current clipboard contents at all time
(m/reductions {} ""
(m/ap
(m/?> (m/relieve {} (m/observe copy-events)))
(let [text (m/dfv)]
(-> (.-clipboard js/Navigator)
(.readText)
(.then text))
(m/? text))))
great, both of these work, the latter being a version of yours:
(p/def clipboard2
#?(:cljs
(->> (m/observe
(fn [!]
(let [handler (fn [e] (sdom/read-clipboard !))]
(.addEventListener js/document "copy" handler)
#(.removeEventListener js/document "copy" handler))))
(m/reductions {} nil))))
(p/def clipboard3
#?(:cljs
(->>
(m/ap
(m/?> (m/relieve {} (m/observe
(fn [!]
(.addEventListener js/document "copy" !)
#(.removeEventListener js/document "copy" !)))))
(m/? (doto (m/dfv) sdom/read-clipboard)))
(m/reductions {} ""))))
can two flows be merged into one? for example, the app should read the clipboard a) when the user copies something b) when the user focuses the window
(p/def clipboard+focus
#?(:cljs
(->>
(m/ap
(m/?> (m/relieve {}
(m/observe
(fn [!]
(.addEventListener js/document "copy" !)
#(.removeEventListener js/document "copy" !)))))
(m/?> (m/relieve {}
(m/observe
(fn [!]
(let [handler (fn [e]
(println :running (j/call js/document :hasFocus))
(when (j/call js/document :hasFocus)
(! e)))]
(.addEventListener js/window "focus" handler)
#(.removeEventListener js/window "focus" handler))))))
(m/? (doto (m/dfv) sdom/read-clipboard)))
(m/reductions {} ""))))
that works!
(p/def clipboard+focus2
#?(:cljs
(->>
(m/ap
(m/?> #_(m/relieve {})
(m/amb=
(m/observe
(fn [!]
(.addEventListener js/document "copy" !)
#(.removeEventListener js/document "copy" !)))
(m/observe
(fn [!]
(let [handler (fn [e]
(println :running (j/call js/document :hasFocus))
(when (j/call js/document :hasFocus)
(! e)))]
(.addEventListener js/window "focus" handler)
#(.removeEventListener js/window "focus" handler))))))
(m/? (doto (m/dfv) sdom/read-clipboard)))
(m/reductions {} "")
new)))
it also appears that m/relieve
is not needed in this case?relieve
covers the case of two consecutive events where the former is still being processed when the latter occurs. relieve {}
explicitly says we want to keep the latest, without it observe
would complain about backpressure in the form of errors in the console.