 (defn init [app-state]
   (let [{:keys [chsk ch-recv send-fn state] :as sente-state} (sente/make-channel-socket! "/chsk" {:type :auto})]
     (swap! app-state assoc :sente (assoc sente-state :ch-recv-mult (async/mult ch-recv)))
-    (subscribe-to-document (:sente @app-state) app-state (-> @app-state :document/id))
-    (fetch-subscribers (:sente @app-state) app-state (-> @app-state :document/id))
     (do-something app-state (:sente @app-state))))

(defn send-msg [sente-state message & [timeout-ms callback-fn :as rest]]
  (if (-> sente-state :state deref :open?)
    (apply (:send-fn sente-state) message rest)
    ;; wait for connection (this probably works)
    (let [tap (async/chan (async/sliding-buffer 1))]
      (async/tap (:ch-recv-mult sente-state) tap)
      (async/take! tap
                   (fn [val]
                     (apply (:send-fn sente-state) message rest))))))

(defn subscribe-to-document [sente-state app-state document-id]
  (send-msg sente-state [:frontend/subscribe {:document-id document-id}] 10000
            (fn [{:keys [document layers chats client-uuid]}]
              ;; TODO: if this is a good idea, then make it the default
              (put! (get-in @app-state [:comms :controls])
                    [:show-mouse-toggled {:client-uuid client-uuid
                                          :show-mouse? true}])
              (d/transact! (:db @app-state)
                           (concat layers chats)
                           {:server-update true}))))

(defn fetch-subscribers [sente-state app-state document-id]
  (send-msg sente-state [:frontend/fetch-subscribers {:document-id document-id}] 10000
            (fn [{:keys [subscribers]}]
              (swap! app-state update-in [:subscribers] (fn [s]
                                                          (merge-with merge
                                                                      subscribers
                                                                      s))))))

(defmulti handle-message (fn [app-state message data]
                           (utils/mlog "handle-message" message data)

(defmethod handle-message :frontend/update-subscriber [app-state message data]
  (swap! app-state update-in [:subscribers (:client-uuid data)] merge (:subscriber-data data)))

;; These are a little bit different, we're putting the message on the channel in a send-msg callback
(defmethod handle-message :frontend/subscribe [app-state message data]
  (let [{:keys [document layers chats client-uuid]} data]
    ;; TODO: if this is a good idea, then make it the default
    (put! (get-in @app-state [:comms :controls])
          [:show-mouse-toggled {:client-uuid client-uuid
                                :show-mouse? true}])
    (d/transact! (:db @app-state)
                 (concat layers chats)
                 {:server-update true})))

(defmethod handle-message :frontend/fetch-subscribers [app-state message {:keys [subscribers]}]
  (swap! app-state update-in [:subscribers] (fn [s]
                                              (merge-with merge
                                                          subscribers
                                                          s))))


(defn do-something [app-state sente-state]
  (let [tap (async/chan (async/sliding-buffer 10))
        mult (:ch-recv-mult sente-state)]
