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

Move all source files to src folder

This commit is contained in:
Arne Schlüter 2018-05-28 13:24:15 +02:00
commit 47c37e198c
20 changed files with 24 additions and 9 deletions

View file

@ -0,0 +1,147 @@
(ns airsonic-ui.events
(:require [re-frame.core :as re-frame]
[ajax.core :as ajax]
[airsonic-ui.routes :as routes]
[airsonic-ui.db :as db]
[airsonic-ui.api :as api]
[day8.re-frame.tracing :refer-macros [fn-traced]])) ; <- useful to debug handlers
;; this is where all of the event handling takes place; the names put the events into
;; the following categories:
;; ::events/something-happening -> relevant to only this app
;; :single-colon/something -> coming from external sources (e.g. :audio/... or :routes/...) that are potentially reusable
;; database reset / init
(re-frame/reg-event-db
::initialize-db
(fn [_]
db/default-db))
;; this is called with user and password to try and see if the credentials are
;; correct; if yes, ::auth-success will be fired
(re-frame/reg-event-fx
::authenticate
(fn [{:keys [db]} [_ user pass server]]
{:db (-> (update db :active-requests inc)
(assoc :server server))
:http-xhrio {:method :get
:uri (api/url server "ping" {:u user :p pass})
:response-format (ajax/json-response-format {:keywords? true})
:on-success [::auth-success user pass]
:on-failure [::api-failure]}}))
;; TODO: Test that credentials are associated
(re-frame/reg-event-fx
::auth-success
(fn [{:keys [db]} [_ user pass response]]
;; TODO: Handle failures differently
(let [login {:u user :p pass}]
{:routes/set-credentials login
:db (-> (update db :active-requests #(max (dec %) 0))
(assoc :login login))
:dispatch [::logged-in]})))
;; TODO: We have to find another solution for this once we have routes that
;; don't require a login but have the bottom controls
(re-frame/reg-fx
:show-nav-bar
(fn [_]
(.. js/document -documentElement -classList (add "has-navbar-fixed-bottom"))))
;; we do this in two steps to make sure the credentials are set once we navigate
(re-frame/reg-event-fx
::logged-in
(fn [_ _]
{:routes/navigate [::routes/main]
:show-nav-bar nil}))
;; 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
:api-request
(fn [{:keys [db]} [_ endpoint k params]]
{:http-xhrio {:method :get
:uri (api/url (:server db) endpoint (merge params (:login db)))
:response-format (ajax/json-response-format {:keywords? true})
:on-success [::api-success k]
:on-failure [::api-failure]}}))
(re-frame/reg-event-db
::api-success
(fn [db [_ k response]]
; we "unwrap" the responses
(assoc db :response (-> response :subsonic-response k))))
(re-frame/reg-event-db
::api-failure
(fn [db event]
(println "api call gone bad; CORS headers missing? check for :status 0" event)
db))
;; musique
; TODO: Make play, next and previous a bit prettier and more DRY
(re-frame/reg-event-fx
; sets up the db, starts to play a song and adds the rest to a playlist
::play-songs
(fn [{:keys [db]} [_ songs song]]
{:play-song (api/song-url (:server db) (:login db) song)
:db (-> db
(assoc-in [:currently-playing :item] song)
(assoc-in [:currently-playing :playlist] songs))}))
(re-frame/reg-event-fx
::next-song
(fn [{:keys [db]} _]
(let [playlist (-> db :currently-playing :playlist)
current (-> db :currently-playing :item)
next (first (rest (drop-while #(not= % current) playlist)))]
(when next
{:play-song (api/song-url (:server db) (:login db) next)
:db (assoc-in db [:currently-playing :item] next)}))))
(re-frame/reg-event-fx
::previous-song
(fn [{:keys [db]} _]
(let [playlist (-> db :currently-playing :playlist)
current (-> db :currently-playing :item)
previous (last (take-while #(not= % current) playlist))]
(when previous
{:play-song (api/song-url (:server db) (:login db) previous)
:db (assoc-in db [:currently-playing :item] previous)}))))
(re-frame/reg-event-fx
::toggle-play-pause
(fn [_ _]
{:toggle-play-pause nil}))
(re-frame/reg-event-db
:audio/update
(fn [db [_ status]]
; we receive this from the player once it's playing
(assoc-in db [:currently-playing :status] status)))
;; routing
(re-frame/reg-event-fx
:routes/navigation
(fn [{:keys [db]} [_ route params query]]
;; all the naviagation logic is in routes.cljs; all we need to do here
;; is say what actually happens once we've navigated succesfully
{:db (assoc db :current-route [route params query])
:dispatch (routes/route-data route params query)}))
(re-frame/reg-event-fx
:routes/unauthorized
(fn [fx _]
;; log out on 403
{:routes/navigate [routes/default-route]
:routes/unset-credentials nil
:db db/default-db}))