1
0
Fork 0
mirror of https://github.com/heyarne/airsonic-ui.git synced 2026-05-06 18:33:38 +02:00

Move navigation to effect

This commit is contained in:
Arne Schlüter 2018-04-18 16:21:21 +02:00
commit 6117b921a6
6 changed files with 63 additions and 46 deletions

View file

@ -14,18 +14,17 @@
(println "dev mode"))) (println "dev mode")))
(defn on-navigate (defn on-navigate
[name params query] [id params query]
(println "Route changed to " name params query) (println "Route changed to " id params query)
(re-frame/dispatch [::events/navigate name params query])) (re-frame/dispatch [::events/hash-change id params query]))
(defn mount-root [] (defn mount-root []
(re-frame/clear-subscription-cache!) (re-frame/clear-subscription-cache!)
(reagent/render [views/main-panel] (reagent/render [views/main-panel] (.getElementById js/document "app")))
(.getElementById js/document "app")))
(defn ^:export init [] (defn ^:export init []
(re-frame/dispatch-sync [::events/initialize-db]) (routes/start-routing! {:default routes/default-route
(r/start! routes/router {:default ::routes/login
:on-navigate on-navigate}) :on-navigate on-navigate})
(re-frame/dispatch-sync [::events/initialize-db])
(dev-setup) (dev-setup)
(mount-root)) (mount-root))

View file

@ -4,4 +4,4 @@
(def default-db (def default-db
{:active-requests 0 {:active-requests 0
;; because navigate! executes asynchronously we force to display the login screen first ;; because navigate! executes asynchronously we force to display the login screen first
:route routes/default}) :current-route [routes/default-route]})

View file

@ -46,15 +46,14 @@
:on-success [::auth-successful user pass] :on-success [::auth-successful user pass]
:on-failure [::api-failure]}})) :on-failure [::api-failure]}}))
(re-frame/reg-event-db (re-frame/reg-event-fx
::auth-successful ::auth-successful
(fn [db [_ user pass response]] (fn [{:keys [db]} [_ user pass response]]
;; TODO: Handle failures differently ;; TODO: Handle failures differently
;; TODO: Refactor navigation into effect (let [login {:u user :p pass}]
(r/navigate! routes/router ::routes/main) {:navigate [login ::routes/main]
(-> (update db :active-requests dec) :db (-> (update db :active-requests dec)
(assoc :login {:u user (assoc :login login))})))
:p pass}))))
(re-frame/reg-event-db (re-frame/reg-event-db
::api-failure ::api-failure
@ -62,25 +61,24 @@
(println "api call gone bad; CORS headers missing? check for :status 0" event) (println "api call gone bad; CORS headers missing? check for :status 0" event)
db)) db))
;; app interface ;; routing
(defn authed? (re-frame/reg-event-fx
"Predicate to determine whether we can access a specific route." ::hash-change
[route credentials] (fn [{:keys [db]} [_ route params query]]
(or (not (routes/protected route)) credentials)) ;; all the naviagation logic is in routes.cljs; all we need to do here
;; is say what actually happens once we've navigated succesfully
{:navigate [(:login db) route params query]
:db (assoc db :current-route [route params query])}))
(re-frame/reg-event-db (re-frame/reg-event-fx
::navigate ::routes/forbidden-route
(fn [db [_ route]] (fn [fx _]
(println "authed?" route (authed? route (:login db))) ;; log out on 403
(if (authed? route (:login db)) {:db db/default-db
;; continue to correct page :navigate [nil routes/default-route]}))
;; TODO: Fetch data based on route
(assoc db :route route) ;; database reset / init
;; logout and redirect to login
(do (re-frame/dispatch [::initialize-db])
(r/navigate! routes/router routes/default)
db))))
(re-frame/reg-event-db (re-frame/reg-event-db
::initialize-db ::initialize-db

View file

@ -1,14 +1,34 @@
(ns airsonic-ui.routes (ns airsonic-ui.routes
(:require [bide.core :as r])) (:require [bide.core :as r]
[re-frame.core :as re-frame]))
;; routing is started in core.cljs (def default-route ::login)
(def default ::login) (def routes
[["/" ::login]
["/hello" ::main]])
(def router (def protected-routes #{::main})
(r/router [["/" ::login]
["/hello" ::main]]))
;; routes that need valid credentials (defn is-authorized? [login route]
(or (not (protected-routes route)) login))
(def protected #{::main}) ;; shouldn't need to change this
;; TODO: This is kind of ugly because at the moment r/navigate! is called twice.
;; the order is click -> hash-change -> {:navigate [bla] :db [bla]} -> (hash-change) -> ...
(defn start-routing!
"Registers a :navigate effect that can be used for navigation; opts will be
passed to bide.core/start!"
[opts]
(let [router (r/router routes)]
(re-frame/reg-fx
:navigate
(fn [[login route-id params query]]
(if (is-authorized? login route-id)
(r/navigate! router route-id params query)
(do ;; 403 gets a special event
(println "Not authorized to navigate to " route-id)
(re-frame/dispatch [::forbidden-route])))))
(r/start! router opts)))

View file

@ -11,6 +11,6 @@
;; --- ;; ---
(re-frame/reg-sub (re-frame/reg-sub
::current-page ::current-route
(fn [db] (fn [db]
(:route db))) (:current-route db)))

View file

@ -21,16 +21,16 @@
[:div [:div
[:button {:on-click #(re-frame/dispatch [::events/authenticate @user @pass])} "Submit"]]]))) [:button {:on-click #(re-frame/dispatch [::events/authenticate @user @pass])} "Submit"]]])))
(defn app [current-page] (defn app [route]
(let [login @(re-frame/subscribe [::subs/login])] (let [login @(re-frame/subscribe [::subs/login])]
[:div [:div
[:h2 (str "Currently logged in as " (:u login))] [:h2 (str "Currently logged in as " (:u login))]
[:a {:on-click #(re-frame/dispatch [::events/initialize-db]) :href "#"} "Logout"]])) [:a {:on-click #(re-frame/dispatch [::events/initialize-db]) :href "#"} "Logout"]]))
(defn main-panel [] (defn main-panel []
(let [current-page @(re-frame/subscribe [::subs/current-page])] (let [[route params query] @(re-frame/subscribe [::subs/current-route])]
[:div [:div
[:h1 "Airsonic"] [:h1 "Airsonic"]
(case current-page (case route
::routes/login [login-form] ::routes/login [login-form]
[app current-page])])) [app route])]))