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

Fix routing (r/navigate! was sometimes called twice)

This commit is contained in:
Arne Schlüter 2018-04-19 13:24:03 +02:00
commit 2ccf6b3f4c
3 changed files with 51 additions and 37 deletions

View file

@ -2,7 +2,6 @@
(:require [reagent.core :as reagent] (:require [reagent.core :as reagent]
[re-frame.core :as re-frame] [re-frame.core :as re-frame]
[day8.re-frame.http-fx] [day8.re-frame.http-fx]
[bide.core :as r]
[airsonic-ui.routes :as routes] [airsonic-ui.routes :as routes]
[airsonic-ui.events :as events] [airsonic-ui.events :as events]
[airsonic-ui.views :as views] [airsonic-ui.views :as views]
@ -13,18 +12,12 @@
(enable-console-print!) (enable-console-print!)
(println "dev mode"))) (println "dev mode")))
(defn on-navigate
[id params query]
(println "Route changed to " id 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] (.getElementById js/document "app"))) (reagent/render [views/main-panel] (.getElementById js/document "app")))
(defn ^:export init [] (defn ^:export init []
(routes/start-routing! {:default routes/default-route (routes/start-routing!)
:on-navigate on-navigate})
(re-frame/dispatch-sync [::events/initialize-db]) (re-frame/dispatch-sync [::events/initialize-db])
(dev-setup) (dev-setup)
(mount-root)) (mount-root))

View file

@ -1,7 +1,6 @@
(ns airsonic-ui.events (ns airsonic-ui.events
(:require [re-frame.core :as re-frame] (:require [re-frame.core :as re-frame]
[ajax.core :as ajax] [ajax.core :as ajax]
[bide.core :as r]
[airsonic-ui.routes :as routes] [airsonic-ui.routes :as routes]
[airsonic-ui.config :as config] [airsonic-ui.config :as config]
[airsonic-ui.db :as db] [airsonic-ui.db :as db]
@ -52,10 +51,17 @@
(fn [{:keys [db]} [_ user pass response]] (fn [{:keys [db]} [_ user pass response]]
;; TODO: Handle failures differently ;; TODO: Handle failures differently
(let [login {:u user :p pass}] (let [login {:u user :p pass}]
{:navigate [login ::routes/main] {::routes/set-credentials login
:db (-> (update db :active-requests #(max (dec %) 0)) :db (-> (update db :active-requests #(max (dec %) 0))
(assoc :login login)) (assoc :login login))
:dispatch [::api-request "getAlbumList2" :albumList2 {:type "recent"}]}))) :dispatch-n (list [::start-page]
[::api-request "getAlbumList2" :albumList2 {:type "recent"}])})))
;; we do this in two steps to make sure the credentials are set once we navigate
(re-frame/reg-event-fx
::start-page
(fn [_ _]
{::routes/navigate [::routes/main]}))
;; TODO: Test that credentials are actually taken ;; TODO: Test that credentials are actually taken
@ -83,20 +89,19 @@
;; routing ;; routing
(re-frame/reg-event-fx (re-frame/reg-event-db
::hash-change ::routes/navigation
(fn [{:keys [db]} [_ route params query]] (fn [db [_ route params query]]
;; all the naviagation logic is in routes.cljs; all we need to do here ;; all the naviagation logic is in routes.cljs; all we need to do here
;; is say what actually happens once we've navigated succesfully ;; is say what actually happens once we've navigated succesfully
;; FIXME: This is really bad and wonky actually (assoc db :current-route [route params query])))
{:navigate [(:login db) route params query]
:db (assoc db :current-route [route params query])}))
(re-frame/reg-event-fx (re-frame/reg-event-fx
::routes/forbidden-route ::routes/unauthorized
(fn [fx _] (fn [fx _]
;; log out on 403 ;; log out on 403
{:navigate [nil routes/default-route] {:navigate [routes/default-route]
::routes/unset-credentials nil
:db db/default-db})) :db db/default-db}))
;; database reset / init ;; database reset / init

View file

@ -12,27 +12,43 @@
(def protected-routes #{::main ::album-view}) (def protected-routes #{::main ::album-view})
(defn is-authorized? [login route]
(or (not (protected-routes route)) login))
(defn url-for [k params] (defn url-for [k params]
(str "#" (r/resolve router k params))) (str "#" (r/resolve router k params)))
;; shouldn't need to change this ;; shouldn't need to change anything below
;; TODO: This is kind of ugly because at the moment r/navigate! is called twice. ;; these are helper effects we can use to navigate; the first two manage an atom
;; the order is click -> hash-change -> {:navigate [bla] :db [bla]} -> (hash-change) -> ... ;; holding credentials, which is necessary to restrict certain routes, and the
;; last one is used for actual navigation
(def login (atom nil))
(re-frame/reg-fx
::set-credentials
(fn [credentials]
(reset! login credentials)))
(re-frame/reg-fx
::unset-credentials
(fn [credentials]
(reset! login nil)))
(re-frame/reg-fx
::navigate
(fn [[route-id params query]]
(r/navigate! router route-id params query)))
(defn can-access? [route]
(or (not (protected-routes route)) @login))
(defn on-navigate
[route-id params query]
(if (can-access? route-id)
(re-frame/dispatch [::navigation route-id params query])
(re-frame/dispatch [::unauthorized route-id params query])))
(defn start-routing! (defn start-routing!
"Registers a :navigate effect that can be used for navigation; opts will be "Initializes the router and makes sure the correct events get dispatched."
passed to bide.core/start!" []
[opts] (r/start! router {:default default-route
(re-frame/reg-fx :on-navigate on-navigate}))
: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))