1module UI.Tracks.ContextMenu exposing (cacheAction, trackMenu, viewMenu)
2
3import Conditional exposing (ifThenElse)
4import ContextMenu exposing (..)
5import Coordinates exposing (Coordinates)
6import Material.Icons.Round as Icons
7import Maybe.Extra as Maybe
8import Playlists exposing (Playlist)
9import Queue
10import Sources exposing (Source)
11import Time
12import Tracks exposing (Grouping(..), IdentifiedTrack)
13import UI.Queue.Types as Queue
14import UI.Tracks.Types as Tracks
15import UI.Types exposing (Msg(..))
16
17
18
19-- TRACK MENU
20
21
22trackMenu :
23 { cached : List String
24 , cachingInProgress : List String
25 , currentTime : Time.Posix
26 , lastModifiedPlaylistName : Maybe { collection : Bool, name : String }
27 , selectedPlaylist : Maybe Playlist
28 , showAlternativeMenu : Bool
29 , sources : List Source
30 }
31 -> List IdentifiedTrack
32 -> Coordinates
33 -> ContextMenu Msg
34trackMenu { cached, cachingInProgress, currentTime, selectedPlaylist, lastModifiedPlaylistName, showAlternativeMenu, sources } tracks =
35 if showAlternativeMenu then
36 [ alternativeMenuActions
37 currentTime
38 sources
39 tracks
40 ]
41 |> List.concat
42 |> ContextMenu
43
44 else
45 [ queueActions
46 tracks
47
48 --
49 , playlistActions
50 { selectedPlaylist = selectedPlaylist
51 , lastModifiedPlaylistName = lastModifiedPlaylistName
52 }
53 tracks
54
55 --
56 , cacheAction
57 { cached = cached
58 , cachingInProgress = cachingInProgress
59 }
60 tracks
61 |> List.singleton
62 ]
63 |> List.concat
64 |> ContextMenu
65
66
67alternativeMenuActions :
68 Time.Posix
69 -> List Source
70 -> List IdentifiedTrack
71 -> List (ContextMenu.Item Msg)
72alternativeMenuActions timestamp sources tracks =
73 case tracks of
74 [ ( _, t ) ] ->
75 [ Item
76 { icon = Icons.link
77 , label = "Copy temporary url"
78 , msg = CopyToClipboard (Queue.makeTrackUrl timestamp sources t)
79 , active = False
80 }
81
82 --
83 , Item
84 { icon = Icons.sync
85 , label = "Sync tags"
86 , msg = TracksMsg (Tracks.SyncTags [ t ])
87 , active = False
88 }
89 ]
90
91 _ ->
92 []
93
94
95cacheAction :
96 { cached : List String, cachingInProgress : List String }
97 -> List IdentifiedTrack
98 -> ContextMenu.Item Msg
99cacheAction { cached, cachingInProgress } tracks =
100 case tracks of
101 [ ( _, t ) ] ->
102 if List.member t.id cached then
103 Item
104 { icon = Icons.offline_bolt
105 , label = "Remove from cache"
106 , msg =
107 tracks
108 |> List.map Tuple.second
109 |> Tracks.RemoveFromCache
110 |> TracksMsg
111
112 --
113 , active = False
114 }
115
116 else if List.member t.id cachingInProgress then
117 Item
118 { icon = Icons.offline_bolt
119 , label = "Downloading ..."
120 , msg = Bypass
121 , active = True
122 }
123
124 else
125 Item
126 { icon = Icons.offline_bolt
127 , label = "Store in cache"
128 , msg =
129 tracks
130 |> List.map Tuple.second
131 |> Tracks.StoreInCache
132 |> TracksMsg
133
134 --
135 , active = False
136 }
137
138 _ ->
139 Item
140 { icon = Icons.offline_bolt
141 , label = "Store in cache"
142 , msg =
143 tracks
144 |> List.map Tuple.second
145 |> Tracks.StoreInCache
146 |> TracksMsg
147
148 --
149 , active = False
150 }
151
152
153playlistActions :
154 { selectedPlaylist : Maybe Playlist
155 , lastModifiedPlaylistName : Maybe { collection : Bool, name : String }
156 }
157 -> List IdentifiedTrack
158 -> List (ContextMenu.Item Msg)
159playlistActions { selectedPlaylist, lastModifiedPlaylistName } tracks =
160 let
161 maybeCustomPlaylist =
162 Maybe.andThen
163 (\p ->
164 case p.autoGenerated of
165 Just _ ->
166 Nothing
167
168 Nothing ->
169 Just p
170 )
171 selectedPlaylist
172
173 maybeAddToLastModifiedPlaylist { collection } =
174 Maybe.andThen
175 (\l ->
176 if Maybe.map .name selectedPlaylist /= Just l.name && l.collection == collection then
177 justAnItem
178 { icon = Icons.waves
179 , label = "Add to \"" ++ l.name ++ "\""
180 , msg =
181 AddTracksToPlaylist
182 { collection = collection
183 , playlistName = l.name
184 , tracks = Tracks.toPlaylistTracks tracks
185 }
186
187 --
188 , active = False
189 }
190
191 else
192 Nothing
193 )
194 lastModifiedPlaylistName
195 in
196 case maybeCustomPlaylist of
197 -----------------------------------------
198 -- In a custom playlist
199 -----------------------------------------
200 Just playlist ->
201 Maybe.values
202 [ maybeAddToLastModifiedPlaylist { collection = True }
203 , justAnItem
204 { icon = Icons.waves
205 , label =
206 if playlist.collection then
207 "Remove from collection"
208
209 else
210 "Remove from playlist"
211 , msg = RemoveTracksFromPlaylist playlist tracks
212
213 --
214 , active = False
215 }
216 , justAnItem
217 { icon = Icons.waves
218 , label =
219 if playlist.collection then
220 "Add to another collection"
221
222 else
223 "Add to collection"
224 , msg = AssistWithAddingTracksToCollection tracks
225
226 --
227 , active = False
228 }
229 , maybeAddToLastModifiedPlaylist { collection = False }
230 , justAnItem
231 { icon = Icons.waves
232 , label =
233 if playlist.collection then
234 "Add to playlist"
235
236 else
237 "Add to another playlist"
238 , msg = AssistWithAddingTracksToPlaylist tracks
239
240 --
241 , active = False
242 }
243 ]
244
245 -----------------------------------------
246 -- Otherwise
247 -----------------------------------------
248 _ ->
249 Maybe.values
250 [ maybeAddToLastModifiedPlaylist { collection = True }
251 , justAnItem
252 { icon = Icons.waves
253 , label = "Add to collection"
254 , msg = AssistWithAddingTracksToCollection tracks
255 , active = False
256 }
257 , maybeAddToLastModifiedPlaylist { collection = False }
258 , justAnItem
259 { icon = Icons.waves
260 , label = "Add to playlist"
261 , msg = AssistWithAddingTracksToPlaylist tracks
262 , active = False
263 }
264 ]
265
266
267queueActions : List IdentifiedTrack -> List (ContextMenu.Item Msg)
268queueActions identifiedTracks =
269 [ Item
270 { icon = Icons.update
271 , label = "Play next"
272 , msg =
273 { inFront = True, tracks = identifiedTracks }
274 |> Queue.AddTracks
275 |> QueueMsg
276
277 --
278 , active = False
279 }
280 , Item
281 { icon = Icons.update
282 , label = "Add to queue"
283 , msg =
284 { inFront = False, tracks = identifiedTracks }
285 |> Queue.AddTracks
286 |> QueueMsg
287
288 --
289 , active = False
290 }
291 ]
292
293
294
295-- VIEW MENU
296
297
298viewMenu : Bool -> Maybe Grouping -> Coordinates -> ContextMenu Msg
299viewMenu onlyCachedTracks maybeGrouping =
300 ContextMenu
301 [ groupByDirectory (maybeGrouping == Just Directory)
302 , groupByFirstAlphaCharacter (maybeGrouping == Just FirstAlphaCharacter)
303 , groupByProcessingDate (maybeGrouping == Just AddedOn)
304 , groupByTrackYear (maybeGrouping == Just TrackYear)
305
306 --
307 , Item
308 { icon = Icons.filter_list
309 , label = "Cached tracks only"
310 , active = onlyCachedTracks
311 , msg = TracksMsg Tracks.ToggleCachedOnly
312 }
313 ]
314
315
316groupByDirectory isActive =
317 Item
318 { icon = ifThenElse isActive Icons.clear Icons.library_music
319 , label = "Group by directory"
320 , active = isActive
321
322 --
323 , msg =
324 if isActive then
325 TracksMsg Tracks.DisableGrouping
326
327 else
328 TracksMsg (Tracks.GroupBy Directory)
329 }
330
331
332groupByFirstAlphaCharacter isActive =
333 Item
334 { icon = ifThenElse isActive Icons.clear Icons.library_music
335 , label = "Group by first letter"
336 , active = isActive
337
338 --
339 , msg =
340 if isActive then
341 TracksMsg Tracks.DisableGrouping
342
343 else
344 TracksMsg (Tracks.GroupBy FirstAlphaCharacter)
345 }
346
347
348groupByProcessingDate isActive =
349 Item
350 { icon = ifThenElse isActive Icons.clear Icons.library_music
351 , label = "Group by processing date"
352 , active = isActive
353
354 --
355 , msg =
356 if isActive then
357 TracksMsg Tracks.DisableGrouping
358
359 else
360 TracksMsg (Tracks.GroupBy AddedOn)
361 }
362
363
364groupByTrackYear isActive =
365 Item
366 { icon = ifThenElse isActive Icons.clear Icons.library_music
367 , label = "Group by track year"
368 , active = isActive
369
370 --
371 , msg =
372 if isActive then
373 TracksMsg Tracks.DisableGrouping
374
375 else
376 TracksMsg (Tracks.GroupBy TrackYear)
377 }