           true (on-success))))
     state))
 
-(reg-event-db
+(reg-event-fx
   :add-notification-rule
-  (fn [state [_ rule]]
+  (fn [{state :db :as cofx} [_ rule]]
     (let [current-rules (get (helpers/get-user-preferences state) :notification-rules [])]
-      ; TODO
-      (handler state [:set-preference [:notification-rules (conj current-rules rule)]]))))
+      {:dispatch [:set-preference [:notification-rules (conj current-rules rule)]]})))
 
 (reg-event-db
   :remove-notification-rule
-  (fn [state [_ rule]]
+  (fn [{state :db :as cofx} [_ rule]]
     (let [new-rules (->> (get (helpers/get-user-preferences state) :notification-rules [])
                          (into [] (remove (partial = rule))))]
-      ; TODO
-      (handler state [:set-preference [:notification-rules new-rules]]))))
+      {:dispatch [:set-preference [:notification-rules new-rules]]})))
 
 (reg-event-db
   :set-search-results

  :notify-if-client-out-of-date
  (fn [state [_ server-checksum]]
    (if (not= (aget js/window "checksum") server-checksum)
      ; TODO
      (handler state [:display-error [:client-out-of-date "Client out of date - please refresh" :info]])
      state)))

(reg-event-db
  :set-init-data

  (fn [state [_ thread-id]]
    (helpers/focus-thread state thread-id)))

(reg-event-fx
  :clear-inbox
  (fn [{state :db :as cofx} [_ _]]
    {:dispatch-n
     (into ()
           (comp (map :id)
                 (map (fn [id] [:hide-thread {:thread-id id :local-only? false}])))
           (helpers/get-open-threads state))}))

(reg-event-db
  :invite
