                                                (dialog :content
                                                        (str "Successfully sent " (:value res) " posts"))))))))))))
 
-  (let [fa-stream (create-tap #(= :fa-post (:id %)))
-        fa-post-stream (create-tap #(and (= :fa-post (:id %)) (map? (:value %))))
-        posts-ready-stream (create-tap #(= :posts-ready (:id %)))
-        ]
-    ;; setup 'latest post' label and progressbar
-    (async/go-loop []
-      (let [e (async/<! fa-stream)]
-        (prn "fa-stream =>" e)
-        ;; TODO use cond
-        (if (= :wait (:value e))
-          (config! (select form [:#faprog]) :indeterminate? true)
-          (let [author (:author (:value e))
-                title (:title (:value e))]
-            (config! (select form [:#latest-fa-post :> :#author]) :text author)
-            (config! (select form [:#latest-fa-post :> :#title]) :text title)
-            (config! (select form [:#faprog]) :visible? false)
-            (config! (select form [:#latest-fa-post]) :visible? true)
-            )))
-      (recur))
-    ;; when fa post is retrived, start fetching aw posts
-    (async/go-loop []
-      (let [e (async/<! fa-post-stream)
-            c (async/chan)
-            content-chan (async/chan)
-            fa-post (:value e)]
-        (prn "fa-post-stream =>" e)
-        ;; FIXME if c will contain :error, dismiss all fetched so far and clear listbox
-        (posts/fetch-unpublished-aw-posts fa-post c)
-        ;; as posts arrive they get accumulated until it is known that there's no error.
-        ;; when :end is received, fetching of actual post content starts
-        (async/go-loop
-            [fetched []]
-          (let [post (async/<! c)]
-            (cond
-             (= :error post) (prn "ERROR!") ;; FIXME clear list from all fetched so far, do other cleanup stuff, disable buttons etc
-             (not= :end post) (do
-                                (add! (select form [:#aw-posts]) (make-post-widget post))
-                                (recur (conj fetched post)))
-             (= :end post) (posts/fetch-aw-posts-content fetched content-chan))))
-        ;; after above function started retrieving full content, let's wait for it to arrive and accumulate posts as they go
-        (async/go-loop
-            [full-posts []]
-          (let [post (async/<! content-chan)]
-            (cond
-             (= :error post) (prn "ERROR getting full post!")
-             (not= :end post) (do
-                                (prn "got full post fetched" (:title post) "by" (:author post))
-                                (config! (select form [(str "#" (:id post))]) :border (line-border :color "#8e80e4" :thickness 1))
-                                (recur (conj full-posts post)))
-             (= :end post) (do
-                             (prn "all posts fetched")
-                             (config! (select form [:#publish-btn]) :enabled? (not (empty? full-posts)))
-                             (config! (select form [:#publish-btn]) :user-data full-posts)
-                             )))))
-      (recur))
-    ))
+  ;; setup 'latest post' label and progressbar
+  (map-stream #(= :fa-post (:id %)) #(update-fa-post-widget % form))
+  ;; when fa post is retrived, start fetching aw posts
+  (map-stream #(and (= :fa-post (:id %)) (map? (:value %))) #(fetch-aw-posts % form)))
 
 (defn launch-tab [event-chan]
   (let [c (async/chan)]

   :border (line-border :color "#ccc" :thickness 1)
   :minimum-size [400 :by 60]))

(defn setup-events [form event-chan create-tap]
  (listen (select form [:#publish-btn])
          :mouse-clicked (fn [e]
                           (when-let [posts (config (select form [:#publish-btn]) :user-data)]

         :constraints ["fill,gap 18px,hidemode 3"])
        ev-chan (async/chan)
        ev-mult (async/mult ev-chan)
        tap-creator (fn [pred] (async/filter< pred (async/tap ev-mult (async/chan))))
        map-stream (fn [pred f]
                     (let [tap (tap-creator pred)]
                       (async/go-loop []
                         (let [ev (async/<! tap)]
                           (f ev)
                           (recur)))))

        ]
    (setup-events form ev-chan map-stream)
    (launch-tab ev-chan)
    form))
