mirror of
https://github.com/heyarne/airsonic-ui.git
synced 2026-05-06 18:33:38 +02:00
Sketch out method to associate routes with api data
This commit is contained in:
parent
2ccf6b3f4c
commit
eb59e97e96
2 changed files with 38 additions and 41 deletions
|
|
@ -2,44 +2,18 @@
|
||||||
(:require [re-frame.core :as re-frame]
|
(:require [re-frame.core :as re-frame]
|
||||||
[ajax.core :as ajax]
|
[ajax.core :as ajax]
|
||||||
[airsonic-ui.routes :as routes]
|
[airsonic-ui.routes :as routes]
|
||||||
[airsonic-ui.config :as config]
|
|
||||||
[airsonic-ui.db :as db]
|
[airsonic-ui.db :as db]
|
||||||
[clojure.string :as string]))
|
[airsonic-ui.api :as api]))
|
||||||
|
|
||||||
;; TODO:
|
;; this is called with user and password to try and see if the credentials are
|
||||||
|
;; correct; if yes, ::auth-success will be fired
|
||||||
;; api related functions
|
|
||||||
|
|
||||||
(defn ^:private uri-escape [s]
|
|
||||||
(js/encodeURIComponent s))
|
|
||||||
|
|
||||||
(defn ^:private api-url [endpoint params]
|
|
||||||
(let [query (->> (assoc params
|
|
||||||
:f "json"
|
|
||||||
:c "airsonic-ui-cljs"
|
|
||||||
:v "1.15.0")
|
|
||||||
(map (fn [[k v]]
|
|
||||||
(str (uri-escape (name k)) "=" (uri-escape v))))
|
|
||||||
(string/join "&"))]
|
|
||||||
(str config/server "/rest/" endpoint "?" query)))
|
|
||||||
|
|
||||||
(defn ^:private api-error?
|
|
||||||
"We need to look at the message body because the subsonic api always responds
|
|
||||||
with status 200"
|
|
||||||
[response]
|
|
||||||
(= "failed" (-> response :subsonic-response :status)))
|
|
||||||
|
|
||||||
(defn ^:private error-message
|
|
||||||
[response]
|
|
||||||
(let [{:keys [code message]} (-> response :subsonic-response :error)]
|
|
||||||
(str "Code " code ": " message)))
|
|
||||||
|
|
||||||
(re-frame/reg-event-fx
|
(re-frame/reg-event-fx
|
||||||
::authenticate
|
::authenticate
|
||||||
(fn [{:keys [db]} [_ user pass]]
|
(fn [{:keys [db]} [_ user pass]]
|
||||||
{:db (update db :active-requests inc)
|
{:db (update db :active-requests inc)
|
||||||
:http-xhrio {:method :get
|
:http-xhrio {:method :get
|
||||||
:uri (api-url "ping" {:u user :p pass})
|
:uri (api/url "ping" {:u user :p pass})
|
||||||
:response-format (ajax/json-response-format {:keywords? true})
|
:response-format (ajax/json-response-format {:keywords? true})
|
||||||
:on-success [::auth-success user pass]
|
:on-success [::auth-success user pass]
|
||||||
:on-failure [::api-failure]}}))
|
:on-failure [::api-failure]}}))
|
||||||
|
|
@ -54,22 +28,23 @@
|
||||||
{::routes/set-credentials login
|
{::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-n (list [::start-page]
|
:dispatch [::logged-in]})))
|
||||||
[::api-request "getAlbumList2" :albumList2 {:type "recent"}])})))
|
|
||||||
|
|
||||||
;; we do this in two steps to make sure the credentials are set once we navigate
|
;; we do this in two steps to make sure the credentials are set once we navigate
|
||||||
(re-frame/reg-event-fx
|
(re-frame/reg-event-fx
|
||||||
::start-page
|
::logged-in
|
||||||
(fn [_ _]
|
(fn [_ _]
|
||||||
{::routes/navigate [::routes/main]}))
|
{::routes/navigate [::routes/main]}))
|
||||||
|
|
||||||
;; TODO: Test that credentials are actually taken
|
;; TODO: Test that credentials are actually taken
|
||||||
|
;; TODO: Move these in the future? events.cljs should just do wiring. We could
|
||||||
|
;; implement api.cljs as a completely independent module.
|
||||||
|
|
||||||
(re-frame/reg-event-fx
|
(re-frame/reg-event-fx
|
||||||
::api-request
|
:api-request
|
||||||
(fn [{:keys [db]} [_ endpoint k params]]
|
(fn [{:keys [db]} [_ endpoint k params]]
|
||||||
{:http-xhrio {:method :get
|
{:http-xhrio {:method :get
|
||||||
:uri (api-url endpoint (merge params (:login db)))
|
:uri (api/url endpoint (merge params (:login db)))
|
||||||
:response-format (ajax/json-response-format {:keywords? true})
|
:response-format (ajax/json-response-format {:keywords? true})
|
||||||
:on-success [::api-success k]
|
:on-success [::api-success k]
|
||||||
:on-failure [::api-failure]}}))
|
:on-failure [::api-failure]}}))
|
||||||
|
|
@ -89,18 +64,20 @@
|
||||||
|
|
||||||
;; routing
|
;; routing
|
||||||
|
|
||||||
(re-frame/reg-event-db
|
(re-frame/reg-event-fx
|
||||||
::routes/navigation
|
::routes/navigation
|
||||||
(fn [db [_ route params query]]
|
(fn [{:keys [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
|
||||||
(assoc db :current-route [route params query])))
|
(println "routes/route-data" (routes/data-for route params query))
|
||||||
|
{:db (assoc db :current-route [route params query])
|
||||||
|
:dispatch (routes/data-for route params query)}))
|
||||||
|
|
||||||
(re-frame/reg-event-fx
|
(re-frame/reg-event-fx
|
||||||
::routes/unauthorized
|
::routes/unauthorized
|
||||||
(fn [fx _]
|
(fn [fx _]
|
||||||
;; log out on 403
|
;; log out on 403
|
||||||
{:navigate [routes/default-route]
|
{::routes/navigate [routes/default-route]
|
||||||
::routes/unset-credentials nil
|
::routes/unset-credentials nil
|
||||||
:db db/default-db}))
|
:db db/default-db}))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,30 @@
|
||||||
["/album/:id" ::album-view]
|
["/album/:id" ::album-view]
|
||||||
["/artist/:id" ::artist-view]]))
|
["/artist/:id" ::artist-view]]))
|
||||||
|
|
||||||
(def protected-routes #{::main ::album-view})
|
; use this in views to construct a url
|
||||||
|
|
||||||
(defn url-for [k params]
|
(defn url-for [k params]
|
||||||
(str "#" (r/resolve router k params)))
|
(str "#" (r/resolve router k params)))
|
||||||
|
|
||||||
|
; which routes need valid login credentials?
|
||||||
|
(def protected-routes #{::main ::album-view})
|
||||||
|
|
||||||
|
; which data should be requested for which route? can either be a vector or a function returning a vector
|
||||||
|
(def route-data
|
||||||
|
{::main [:api-request "getAlbumList2" :albumList2 {:type "recent"}]
|
||||||
|
::album-view (fn [route-id params _]
|
||||||
|
[:api-request "getAlbum" :album {:id (:id params)}])})
|
||||||
|
|
||||||
|
|
||||||
|
(defn data-for
|
||||||
|
"Wrapper around route-data so we can call it like a function no matter whether
|
||||||
|
the value associated with the route key is a function or not."
|
||||||
|
[route params query]
|
||||||
|
(if-let [route-data' (route-data route)]
|
||||||
|
(if (vector? route-data')
|
||||||
|
route-data'
|
||||||
|
(route-data' route params query))
|
||||||
|
[]))
|
||||||
|
|
||||||
;; shouldn't need to change anything below
|
;; shouldn't need to change anything below
|
||||||
|
|
||||||
;; these are helper effects we can use to navigate; the first two manage an atom
|
;; these are helper effects we can use to navigate; the first two manage an atom
|
||||||
|
|
@ -36,6 +55,7 @@
|
||||||
(re-frame/reg-fx
|
(re-frame/reg-fx
|
||||||
::navigate
|
::navigate
|
||||||
(fn [[route-id params query]]
|
(fn [[route-id params query]]
|
||||||
|
(println "calling ::navigate with" route-id params query)
|
||||||
(r/navigate! router route-id params query)))
|
(r/navigate! router route-id params query)))
|
||||||
|
|
||||||
(defn can-access? [route]
|
(defn can-access? [route]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue