From 9ca116ee723e0bf24cd09b80949bda4a8899c3fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20Schl=C3=BCter?= Date: Fri, 20 Apr 2018 15:44:59 +0200 Subject: [PATCH] =?UTF-8?q?Login=20=E2=86=92=20Album=20List=20=E2=86=92=20?= =?UTF-8?q?Album=20Detail?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/airsonic_ui/api.cljs | 29 +++++++++++++++++++++++++ src/airsonic_ui/subs.cljs | 5 +++-- src/airsonic_ui/views.cljs | 43 ++++++++++++++++++++++++++++---------- 3 files changed, 64 insertions(+), 13 deletions(-) create mode 100644 src/airsonic_ui/api.cljs diff --git a/src/airsonic_ui/api.cljs b/src/airsonic_ui/api.cljs new file mode 100644 index 0000000..a9d13e0 --- /dev/null +++ b/src/airsonic_ui/api.cljs @@ -0,0 +1,29 @@ +(ns airsonic-ui.api + (:require [clojure.string :as string] + [airsonic-ui.config :as config])) + +(defn ^:private uri-escape [s] + (js/encodeURIComponent s)) + +(defn url + "Returns an absolute url to an API endpoint" + [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))) diff --git a/src/airsonic_ui/subs.cljs b/src/airsonic_ui/subs.cljs index 1cb680e..893c6e3 100644 --- a/src/airsonic_ui/subs.cljs +++ b/src/airsonic_ui/subs.cljs @@ -18,7 +18,8 @@ ;; --- ;; TODO: Make this nice and clean + (re-frame/reg-sub - ::current-album-list + ::current-content (fn [db] - (-> db :response :album))) + (-> db :response))) diff --git a/src/airsonic_ui/views.cljs b/src/airsonic_ui/views.cljs index aee5176..71cbe82 100644 --- a/src/airsonic_ui/views.cljs +++ b/src/airsonic_ui/views.cljs @@ -23,7 +23,7 @@ [:div [:button {:on-click #(re-frame/dispatch [::events/authenticate @user @pass])} "Submit"]]]))) -;; album list +;; album list (start page) (defn album-item [album] (let [{:keys [artist artistId name coverArt year id]} album] @@ -34,21 +34,42 @@ ;; link to album [:a {:href (routes/url-for ::routes/album-view {:id id})} name] (when year (str " (" year ")"))])) -(defn album-list [] - (let [albums @(re-frame/subscribe [::subs/current-album-list])] - [:ul - (map-indexed (fn [idx album] - [:li {:key idx} [album-item album]]) - albums)])) +;; TODO: album-list shouldn't know about the structure of content and should just get a list +(defn album-list [content] + [:div + [:h2 (str "Recently played")] + [:ul + (map-indexed + (fn [idx album] + [:li {:key idx} [album-item album]]) + (:album content))]]) + +;; single album + +(defn song-item [song] + [:div (str (:artist song) " - " (:title song))]) + +(defn song-list [songs] + [:ul + (map-indexed + (fn [idx song] [:li {:key idx} [song-item song]]) + songs)]) + +(defn album-detail [content] + [:div + [:h2 (str (:artist content) " - " (:name content))] + [song-list (:song content)]]) ;; putting everything together (defn app [route params query] - (let [login @(re-frame/subscribe [::subs/login])] + (let [login @(re-frame/subscribe [::subs/login]) + content @(re-frame/subscribe [::subs/current-content])] [:div - [:h2 (str "Currently logged in as " (:u login))] - [:h3 (str "Recently played")] - [album-list] + [:span (str "Currently logged in as " (:u login))] + (case route + ::routes/main [album-list content] + ::routes/album-view [album-detail content]) [:a {:on-click #(re-frame/dispatch [::events/initialize-db]) :href "#"} "Logout"]])) (defn main-panel []