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

Put on some lipgloss

commit 9fa1a611e2fa093819b332791c28783a4f92a6dc
Author: Arne Schlüter <arne@schlueter.is>
Date:   Fri May 18 00:00:31 2018 +0200

    Add album previews

commit 317a6632b898039e370e3f8d52627e08a8c8186c
Author: Arne Schlüter <arne@schlueter.is>
Date:   Fri May 18 00:00:06 2018 +0200

    Fix cover art url

commit 0ba09903b96f5241853f003f679c0f407243f12a
Author: Arne Schlüter <arne@schlueter.is>
Date:   Thu May 17 22:59:23 2018 +0200

    Add bulma breadcrumbs

commit d21c7c8acc802101ff8ec096d5c6fad90e4f8ea7
Author: Arne Schlüter <arne@schlueter.is>
Date:   Wed May 16 18:55:45 2018 +0200

    Add basic styling to bottom bar

commit 23b37984ca9e8af84767e073492a42bf6c5924ea
Author: Arne Schlüter <arne@schlueter.is>
Date:   Wed May 16 18:21:27 2018 +0200

    Add retina version of cover component

commit d86a44bc5f7b7472f0084c47b691b0f7d151f497
Author: Arne Schlüter <arne@schlueter.is>
Date:   Wed May 16 18:20:47 2018 +0200

    Add info about server address to README

commit 4114581c259e17e3d0342755124e4fa56cd5dd3a
Author: Arne Schlüter <arne@schlueter.is>
Date:   Tue May 8 11:51:07 2018 +0200

    Add cover image

commit e6cb0745b366cbce3c25f225d8e008f12fcaae8b
Author: Arne Schlüter <arne@schlueter.is>
Date:   Tue May 8 10:49:26 2018 +0200

    Move views to their own namespaces

commit 5c24a47cc07b347beedd972e32ec145348a82d65
Author: Arne Schlüter <arne@schlueter.is>
Date:   Mon May 7 18:10:00 2018 +0200

    Add login styling

commit e04e0505f684d99316bdb3e875c403af2c28c127
Author: Arne Schlüter <arne@schlueter.is>
Date:   Sun May 6 11:19:08 2018 +0200

    Add gh-pages deploy script

commit e1a4cb4bb646def28989100f2084990863160dd9
Author: Arne Schlüter <arne@schlueter.is>
Date:   Sun May 6 00:43:51 2018 +0200

    Add bulma
This commit is contained in:
Arne Schlüter 2018-05-28 12:29:42 +02:00
commit 8d24c1b42a
15 changed files with 2544 additions and 612 deletions

View file

@ -1,138 +1,32 @@
(ns airsonic-ui.views
(:require [re-frame.core :refer [dispatch subscribe]]
[reagent.core :as r]
[airsonic-ui.config :as config]
[airsonic-ui.routes :as routes :refer [url-for]]
[airsonic-ui.events :as events]
[airsonic-ui.subs :as subs]))
[airsonic-ui.subs :as subs]
(defn- >reset!
"Sends all target values to the given atom"
[atom]
#(reset! atom (.. % -target -value)))
[airsonic-ui.views.breadcrumbs :refer [breadcrumbs]]
[airsonic-ui.views.bottom-bar :refer [bottom-bar]]
[airsonic-ui.views.login :refer [login-form]]
[airsonic-ui.views.album :as album]
[airsonic-ui.views.song :as song]))
;; login form
(defn login-form []
(let [user (r/atom "")
pass (r/atom "")
server (r/atom config/server)]
(fn []
[:div
[:div
[:span "User"]
[:input {:type "text"
:name "user"
:on-change (>reset! user)}]]
[:div
[:span "Password"]
[:input {:type "password"
:name "pass"
:on-change (>reset! pass)}]]
[:div
[:span "Server"]
[:input {:type "text"
:name "server"
:on-change (>reset! server)
:value @server}]]
[:div
[:button {:on-click #(dispatch [::events/authenticate @user @pass @server])} "Submit"]]])))
;; single album
(defn song-item [songs song]
(let [artist-id (:artistId song)]
[:div
[:a
(when artist-id {:href (url-for ::routes/artist-view {:id artist-id})})
(:artist song)]
" - "
[:a
{:href "#" :on-click (fn [e]
(.preventDefault e)
(dispatch [::events/play-songs songs song]))}
(:title song)]]))
;; TODO: Find better names and places for these.
(defn album-detail [content]
[:div
[:h2 (str (:artist content) " - " (:name content))]
(let [songs (:song content)]
[:ul (for [[idx song] (map-indexed vector songs)]
[:li {:key idx} [song-item songs song]])])])
;; single artist
(defn album-item [album]
(let [{:keys [artist artistId name coverArt year id]} album]
[:div
;; link to artist page
[:a {:href (url-for ::routes/artist-view {:id artistId})} artist]
" - "
;; link to album
[:a {:href (url-for ::routes/album-view {:id id})} name] (when year (str " (" year ")"))]))
[:h2.title (str (:artist content) " - " (:name content))]
[song/listing (:song content)]])
(defn artist-detail [content]
[:div
[:h2 (:name content)]
[:ul (for [[idx album] (map-indexed vector (:album content))]
[:li {:key idx} [album-item album]])]])
;; TODO: album-list shouldn't know about the structure of content and should just get a list
[:h2.title (:name content)]
[album/listing (:album content)]])
(defn most-recent [content]
[:div
[:h2 "Recently played"]
[:ul (for [[idx album] (map-indexed vector (:album content))]
[:li {:key idx} [album-item album]])]])
;; top navigation
(defn content-type
"Helper to see what kind of server response"
[content]
(cond
(and (vector? (:album content)) (:id content)) :artist
(vector? (:song content)) :album
:else :unknown-content))
(defmulti breadcrumbs content-type)
(defmethod breadcrumbs :default [content]
[:div [:span "Start"]])
(defmethod breadcrumbs :artist [content]
[:div
[:span [:a {:href (url-for ::routes/main)} "Start"]]
[:span " · " (:name content)]])
(defmethod breadcrumbs :album [content]
[:div
[:span [:a {:href (url-for ::routes/main)} "Start"]]
[:span " · " [:a {:href (url-for ::routes/artist-view {:id (:artistId content)})} (:artist content)]]
[:span " · " (:name content)]])
;; currently playing / coming next / audio controls...
(defn current-song-info [{:keys [item status]}]
[:div
[:b "Currently playing: "]
[:div (:artist item) " - " (:title item)]
[:div (:current-time status) "s / " (:duration item) "s"]])
(defn playback-controls []
[:div
[:button {:on-click #(dispatch [::events/previous-song])} "previous"]
[:button {:on-click #(dispatch [::events/toggle-play-pause])} "play / pause"]
[:button {:on-click #(dispatch [::events/next-song])} "next"]
[:label [:input {:type "checkbox"}] "shuffle"]
[:label [:input {:type "checkbox"}] "repeat"]])
(defn bottom-bar []
[:div
(if-let [currently-playing @(subscribe [::subs/currently-playing])]
[current-song-info currently-playing]
[:span "Currently no song selected"])
[playback-controls]])
[:h2.title "Recently played"]
[album/listing (:album content)]])
;; putting everything together
@ -140,19 +34,19 @@
(let [login @(subscribe [::subs/login])
content @(subscribe [::subs/current-content])]
[:div
[:span (str "Currently logged in as " (:u login))]
[breadcrumbs content]
(case route
::routes/main [most-recent content]
::routes/artist-view [artist-detail content]
::routes/album-view [album-detail content])
[:a {:on-click #(dispatch [::events/initialize-db]) :href "#"} "Logout"]
[:section.section>div.container
[:div.level
[:div.level-left [:span (str "Currently logged in as " (:u login))]]
[:div.level-right [:a {:on-click #(dispatch [::events/initialize-db]) :href "#"} "Logout"]]]
[breadcrumbs content]
(case route
::routes/main [most-recent content]
::routes/artist-view [artist-detail content]
::routes/album-view [album-detail content])]
[bottom-bar]]))
(defn main-panel []
(let [[route params query] @(subscribe [::subs/current-route])]
[:div
[:h1 "Airsonic"]
(case route
::routes/login [login-form]
[app route params query])]))
(case route
::routes/login [login-form]
[app route params query])))