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

Immediately render reordered tracks, reimplement actions in album view

This commit is contained in:
heyarne 2019-03-10 10:21:05 +01:00
commit 21b00dbd6b
5 changed files with 86 additions and 46 deletions

View file

@ -109,15 +109,6 @@
:<- [:audio/summary] :<- [:audio/summary]
current-playlist) current-playlist)
(defn current-queue
[playlist _]
(vals (:items playlist)))
(rf/reg-sub
:audio/current-queue
:<- [:audio/current-playlist]
current-queue)
(defn current-song (defn current-song
"Gives us information about the currently played song as presented by "Gives us information about the currently played song as presented by
the airsonic api" the airsonic api"

View file

@ -1,30 +1,36 @@
(ns airsonic-ui.components.collection.views (ns airsonic-ui.components.collection.views
"A collection is a list of audio files that belong together (e.g. an album or "A collection is a list of audio files that belong together (e.g. an album or
a podcast's overview)" a podcast's overview)"
(:require [airsonic-ui.helpers :refer [format-duration]] (:require [re-frame.core :refer [subscribe]]
[airsonic-ui.routes :as routes :refer [url-for]] [bulma.icon :refer [icon]]
[airsonic-ui.views.cover :refer [cover card]] [bulma.dropdown.views :refer [dropdown]]
[bulma.icon :refer [icon]])) [airsonic-ui.helpers :as h]
[airsonic-ui.routes :as routes]
[airsonic-ui.views.cover :refer [cover card]]))
(defn collection-info [{:keys [songCount duration year]}] (defn collection-info [{:keys [songCount duration year]}]
(vec (cond-> [:ul.is-smaller.collection-info (vec (cond-> [:ul.is-smaller.collection-info
[:li [icon :audio-spectrum] (str songCount (if (= 1 songCount) [:li [icon :audio-spectrum] (str songCount (if (= 1 songCount)
" track" " tracks"))] " track" " tracks"))]
[:li [icon :clock] (format-duration duration)]] [:li [icon :clock] (h/format-duration duration)]]
year (conj [:li [icon :calendar] (str "Released in " year)])))) year (conj [:li [icon :calendar] (str "Released in " year)]))))
(defn album-card [album] ;; TODO: Maybe this view belongs somewhere else?
(let [{:keys [artist artistId name id]} album] ;; Something like a collection-grid component?
[card album
:url-fn #(url-for ::routes/album.detail {:id id}) (defn album-card
:content [:div "A single element in a grid of albums. Shows the cover, artist and album name."
;; link to album [{:keys [artist artistId name id] :as album}]
[:div.title.is-5 [card album
[:a {:href (url-for ::routes/album.detail {:id id}) :url-fn #(routes/url-for ::routes/album.detail {:id id})
:title name} name]] :content [:div
;; link to artist page ;; link to album
[:div.subtitle.is-6 [:a {:href (url-for ::routes/artist.detail {:id artistId}) [:div.title.is-5
:title artist} artist]]]])) [:a {:href (routes/url-for ::routes/album.detail {:id id})
:title name} name]]
;; link to artist page
[:div.subtitle.is-6 [:a {:href (routes/url-for ::routes/artist.detail {:id artistId})
:title artist} artist]]]])
(defn listing [albums] (defn listing [albums]
;; always show 5 in a row ;; always show 5 in a row
@ -33,8 +39,49 @@
^{:key idx} [:div.column.is-one-fifth-desktop.is-one-quarter-tablet.is-half-mobile ^{:key idx} [:div.column.is-one-fifth-desktop.is-one-quarter-tablet.is-half-mobile
[album-card album]])]) [album-card album]])])
;; TODO: Avoid duplication
(defn artist-link [{id :artistId, artist :artist}]
(if id
[:a {:href (routes/url-for ::routes/artist.detail {:id id})} artist]
artist))
(defn song-link [{:keys [song album idx]}]
[:a
{:href "#" :on-click (h/muted-dispatch [:audio-player/play-all (:song album) idx] :sync? true)}
(:title song)])
(defn song-actions [{:keys [song album idx]}]
[dropdown {:items [{:label "Play next" :event [:audio-player/enqueue-next song]}
{:label "Play last" :event [:audio-player/enqueue-last song]}]}])
(defn song-table [{:keys [album]}]
;; 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 (:song album))]
^{: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 {:album album
:song song
:idx idx}]]
[:td.song-duration (h/format-duration (:duration song) :brief? true)]
[:td.song-actions.is-narrow [song-actions {:album album
:song song
:idx idx}]]])]]))
(defn detail (defn detail
"Lists all songs in an album" "Shows a detail view of a single album, listing all "
[{:keys [album]}] [{:keys [album]}]
[:div [:div
[:section.hero.is-small>div.hero-body [:section.hero.is-small>div.hero-body
@ -45,4 +92,5 @@
[:h2.title (:name album)] [:h2.title (:name album)]
[:h3.subtitle (:artist album)] [:h3.subtitle (:artist album)]
[collection-info album]]]]] [collection-info album]]]]]
[:section.section>div.container [song/listing (:song album)]]]) [:section.section>div.container
[song-table {:album album}]]])

View file

@ -1,5 +1,5 @@
(ns airsonic-ui.components.current-queue.views (ns airsonic-ui.components.current-queue.views
(:require [re-frame.core :refer [subscribe dispatch]] (:require [re-frame.core :refer [subscribe dispatch-sync]]
[reagent.core :as r] [reagent.core :as r]
["react-sortable-hoc" :refer [SortableHandle]] ["react-sortable-hoc" :refer [SortableHandle]]
[bulma.icon :refer [icon]] [bulma.icon :refer [icon]]
@ -7,6 +7,8 @@
[airsonic-ui.helpers :as helpers] [airsonic-ui.helpers :as helpers]
[airsonic-ui.components.sortable.views :as sortable] [airsonic-ui.components.sortable.views :as sortable]
[airsonic-ui.routes :as routes] [airsonic-ui.routes :as routes]
;; ↓ registers subscription handlers ↓
[airsonic-ui.components.current-queue.subs])) [airsonic-ui.components.current-queue.subs]))
(def SortHandle (def SortHandle
@ -60,7 +62,9 @@
:on-sort-end :on-sort-end
(fn [{:keys [old-idx new-idx]}] (fn [{:keys [old-idx new-idx]}]
(dispatch [:audio-player/move-song 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 collection-info [{:keys [playlist-info]}]
[:ul.is-smaller.collection-info [:ul.is-smaller.collection-info

View file

@ -5,12 +5,10 @@
[bulma.dropdown.events :as ev] [bulma.dropdown.events :as ev]
[bulma.dropdown.subs :as sub])) [bulma.dropdown.subs :as sub]))
;; there's "muted-dispatch" in airsonic-ui.helpers which does the same thing (defn choose-action [event-vector]
;; it's not used here because all the bulma.*-components should work independently
(defn muted-dispatch [event-vector]
(fn [e] (fn [e]
(.preventDefault e) (.preventDefault e)
(dispatch [::ev/hide])
(dispatch event-vector))) (dispatch event-vector)))
(defn generate-id [] (defn generate-id []
@ -42,4 +40,4 @@
(for [[idx {:keys [label event]}] (map-indexed vector items)] (for [[idx {:keys [label event]}] (map-indexed vector items)]
^{:key (str dropdown-id "-" idx)} ^{:key (str dropdown-id "-" idx)}
[:a.dropdown-item {:href "#" [:a.dropdown-item {:href "#"
:on-click (muted-dispatch event)} label])]]])))) :on-click (choose-action event)} label])]]]))))

View file

@ -298,17 +298,6 @@
margin-right: 1rem margin-right: 1rem
margin-bottom: 0 margin-bottom: 0
.collection-info
list-style: none
li
display: inline-block
margin-left: 0.75rem
&:first-child
margin-left: 0
.song-list .song-list
counter-reset: track counter-reset: track
@ -323,6 +312,16 @@
display: inline display: inline
padding-right: 0.375rem padding-right: 0.375rem
.collection-info
list-style: none
li
display: inline-block
margin-left: 0.75rem
&:first-child
margin-left: 0
.song-listing-table .song-listing-table
tr.is-playing tr.is-playing
background-color: $table-row-active-background-color background-color: $table-row-active-background-color