mirror of
https://github.com/heyarne/airsonic-ui.git
synced 2026-05-07 02:33:39 +02:00
Make song-table more reusable
This commit is contained in:
parent
60a4b41371
commit
0eec1df70f
3 changed files with 98 additions and 53 deletions
|
|
@ -54,29 +54,36 @@
|
|||
[dropdown {:items [{:label "Play next" :event [:audio-player/enqueue-next song]}
|
||||
{:label "Play last" :event [:audio-player/enqueue-last song]}]}])
|
||||
|
||||
(defn song-table [songs]
|
||||
(defn default-thead []
|
||||
[:thead>tr
|
||||
[:td.is-narrow]
|
||||
[:td.song-artist "Artist"]
|
||||
[:td.song-title "Title"]
|
||||
[:td.song-duration "Duration"]
|
||||
[:td.is-narrow]])
|
||||
|
||||
(defn default-tbody [{:keys [songs current-song]}]
|
||||
[:tbody
|
||||
(for [[idx song] (map-indexed vector songs)]
|
||||
^{:key idx}
|
||||
[(if (= (:id song) (:id current-song)) :tr.is-playing :tr)
|
||||
[:td.song-tracknr.is-narrow (:track song)]
|
||||
[:td.song-artist [artist-link song]]
|
||||
[:td.song-title [song-link {:songs songs
|
||||
:song song
|
||||
:idx idx}]]
|
||||
[:td.song-duration (h/format-duration (:duration song) :brief? true)]
|
||||
[:td.song-actions.is-narrow [song-actions song]]])])
|
||||
|
||||
(defn song-table [{:keys [songs thead tbody]
|
||||
:or {thead default-thead, tbody default-tbody}}]
|
||||
;; we subscribe here instead of one level higher up to make this a more
|
||||
;; reusable component; this way we can for example get a list of all songs
|
||||
;; in a search result and easily highlight the currently playing track
|
||||
(let [current-song @(subscribe [:audio/current-song])]
|
||||
[:table.song-listing-table.table.is-fullwidth
|
||||
[:thead>tr
|
||||
[:td.is-narrow]
|
||||
[:td.song-artist "Artist"]
|
||||
[:td.song-title "Title"]
|
||||
[:td.song-duration "Duration"]
|
||||
[:td.is-narrow]]
|
||||
[:tbody
|
||||
(for [[idx song] (map-indexed vector songs)]
|
||||
^{:key idx}
|
||||
[(if (= (:id song) (:id current-song)) :tr.is-playing :tr)
|
||||
[:td.song-tracknr.is-narrow (:track song)]
|
||||
[:td.song-artist [artist-link song]]
|
||||
[:td.song-title [song-link {:songs songs
|
||||
:song song
|
||||
:idx idx}]]
|
||||
[:td.song-duration (h/format-duration (:duration song) :brief? true)]
|
||||
[:td.song-actions.is-narrow [song-actions song]]])]]))
|
||||
[thead]
|
||||
[tbody {:songs songs, :current-song current-song}]]))
|
||||
|
||||
(defn detail
|
||||
"Shows a detail view of a single album, listing all "
|
||||
|
|
@ -91,4 +98,4 @@
|
|||
[:h3.subtitle (:artist album)]
|
||||
[collection-info album]]]]]
|
||||
[:section.section>div.container
|
||||
[song-table (:song album)]]])
|
||||
[song-table {:songs (:song album)}]]])
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
[bulma.icon :refer [icon]]
|
||||
[bulma.dropdown.views :refer [dropdown]]
|
||||
[airsonic-ui.helpers :as helpers]
|
||||
[airsonic-ui.components.collection.views :as collection]
|
||||
[airsonic-ui.components.sortable.views :as sortable]
|
||||
[airsonic-ui.routes :as routes]
|
||||
|
||||
|
|
@ -38,35 +39,45 @@
|
|||
:on-click (helpers/muted-dispatch [:audio-player/set-current-song idx])}
|
||||
(:title song)])
|
||||
|
||||
(defn song-table-head []
|
||||
[:thead>tr
|
||||
[:td.is-narrow]
|
||||
[:td.song-artist "Artist"]
|
||||
[:td.song-title "Title"]
|
||||
[:td.song-duration "Duration"]
|
||||
[:td.song-actions.is-narrow]])
|
||||
|
||||
(defn song-table-sortable-tbdoy [{:keys [songs current-song-idx]}]
|
||||
;; we need this closure to pass in custom arguments (current-song-idx)
|
||||
(fn []
|
||||
[sortable/sortable-component
|
||||
{:items songs
|
||||
:container [:tbody]
|
||||
:helper-class "sortable-is-moving"
|
||||
|
||||
:render-item
|
||||
(fn [{[idx song] :value}]
|
||||
[(if (= idx current-song-idx) :tr.is-playing :tr)
|
||||
[:td.sortable-handle.is-narrow [:> SortHandle]]
|
||||
[:td.song-artist [artist-link song]]
|
||||
[:td.song-title [song-link song idx]]
|
||||
[:td.song-duration (helpers/format-duration (:duration song) :brief? true)]
|
||||
[:td.song-actions.is-narrow [song-actions]]])
|
||||
|
||||
:on-sort-end
|
||||
(fn [{:keys [old-idx new-idx]}]
|
||||
;; if we don't dispatch-sync, the UI sometimes places the row back and
|
||||
;; resorts it a litle later
|
||||
(dispatch-sync [:audio-player/move-song old-idx new-idx]))}]))
|
||||
|
||||
(defn song-table [{:keys [songs current-song-idx]}]
|
||||
[:table.song-listing-table.table.is-fullwidth
|
||||
[:thead>tr
|
||||
[:td.is-narrow]
|
||||
[:td.song-artist "Artist"]
|
||||
[:td.song-title "Title"]
|
||||
[:td.song-duration "Duration"]
|
||||
[:td.song-actions.is-narrow]]
|
||||
[sortable/sortable-component
|
||||
{:items songs
|
||||
:container [:tbody]
|
||||
:helper-class "sortable-is-moving"
|
||||
[collection/song-table
|
||||
{:songs songs
|
||||
:thead song-table-head
|
||||
:tbody (song-table-sortable-tbdoy {:songs songs
|
||||
:current-song-idx current-song-idx})}])
|
||||
|
||||
:render-item
|
||||
(fn [{[idx song] :value}]
|
||||
[(if (= idx current-song-idx) :tr.is-playing :tr)
|
||||
[:td.sortable-handle.is-narrow [:> SortHandle]]
|
||||
[:td.song-artist [artist-link song]]
|
||||
[:td.song-title [song-link song idx]]
|
||||
[:td.song-duration (helpers/format-duration (:duration song) :brief? true)]
|
||||
[:td.song-actions.is-narrow [song-actions]]])
|
||||
|
||||
:on-sort-end
|
||||
(fn [{:keys [old-idx new-idx]}]
|
||||
;; if we don't dispatch-sync, the UI sometimes places the row back and
|
||||
;; resorts it a litle later
|
||||
(dispatch-sync [:audio-player/move-song old-idx new-idx]))}]])
|
||||
|
||||
(defn collection-info [{:keys [playlist-info]}]
|
||||
(defn queue-info [{:keys [playlist-info]}]
|
||||
[:ul.is-smaller.collection-info
|
||||
[:li [icon :audio-spectrum] (str (:count playlist-info)
|
||||
(if (pos? (:count playlist-info))
|
||||
|
|
@ -76,7 +87,7 @@
|
|||
|
||||
(defn playlist [props]
|
||||
[:div
|
||||
[collection-info props]
|
||||
[queue-info props]
|
||||
[song-table {:songs (get-in props [:current-playlist :items])
|
||||
:current-song-idx (get-in props [:current-playlist :current-idx])}]])
|
||||
|
||||
|
|
|
|||
|
|
@ -2,13 +2,15 @@
|
|||
(:require [re-frame.core :refer [dispatch subscribe]]
|
||||
[goog.functions :refer [debounce]]
|
||||
[airsonic-ui.routes :as routes :refer [url-for]]
|
||||
[airsonic-ui.components.collection.views :refer [song-table]]
|
||||
[airsonic-ui.components.debug :refer [debug]]
|
||||
[airsonic-ui.helpers :as h]
|
||||
[airsonic-ui.components.collection.views :as collection]
|
||||
[airsonic-ui.views.cover :refer [card]]))
|
||||
|
||||
(def search
|
||||
(debounce #(dispatch [:search/do-search (.. % -target -value)]) 100))
|
||||
|
||||
(defn form []
|
||||
(let [search-term @(subscribe [:search/current-term])
|
||||
throttled-search (debounce #(dispatch [:search/do-search (.. % -target -value)]) 100)]
|
||||
(let [search-term @(subscribe [:search/current-term])]
|
||||
(fn []
|
||||
[:form {:on-submit #(.preventDefault %)}
|
||||
[:div.feld>p.control
|
||||
|
|
@ -16,7 +18,7 @@
|
|||
;; the event might be gone when we the dispatched
|
||||
;; function is fired, we need to persist it
|
||||
(.persist e)
|
||||
(throttled-search e))
|
||||
(search e))
|
||||
:default-value search-term
|
||||
:placeholder "Search"}]]])))
|
||||
|
||||
|
|
@ -42,9 +44,34 @@
|
|||
(defn album-results [{:keys [album]}]
|
||||
[result-cards (map (juxt album-url identity) album)])
|
||||
|
||||
(defn song-table-thead []
|
||||
[:thead
|
||||
[:td.song-artist "Artist"]
|
||||
[:td.song-album "Album"]
|
||||
[:td.song-title "Title"]
|
||||
[:td.song-duration "Duration"]
|
||||
[:td.song-actions.is-narrow]])
|
||||
|
||||
(defn album-link [{id :albumId :as song}]
|
||||
[:a {:href (routes/url-for ::routes/album.detail {:id id})} (:album song)])
|
||||
|
||||
(defn song-table-tbody [{:keys [songs current-song]}]
|
||||
[:tbody
|
||||
(for [[idx song] (map-indexed vector songs)]
|
||||
^{:key idx}
|
||||
[(if (= (:id song) (:id current-song)) :tr.is-playing :tr)
|
||||
[:td.song-artist [collection/artist-link song]]
|
||||
[:td.song-album [album-link song]]
|
||||
[:td.song-title [collection/song-link {:songs songs
|
||||
:song song
|
||||
:idx idx}]]
|
||||
[:td.song-duration (h/format-duration (:duration song) :brief? true)]
|
||||
[:td.song-actions.is-narrow [collection/song-actions song]]])])
|
||||
|
||||
(defn song-results [{songs :song}]
|
||||
[]
|
||||
[song-table songs])
|
||||
[collection/song-table {:songs songs
|
||||
:thead song-table-thead
|
||||
:tbody song-table-tbody}])
|
||||
|
||||
(defn results [{:keys [search]}]
|
||||
(let [term @(subscribe [:search/current-term])]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue