forked from
tokono.ma/diffuse
A music player that connects to your cloud/distributed storage.
1module Tracks.Favourites exposing (completeFavouritesList, completeTracksList, match, removeFromFavouritesList, removeFromTracksList, toggleInFavouritesList, toggleInTracksList)
2
3import List.Extra as List
4import Maybe.Extra as Maybe
5import Tracks exposing (Favourite, IdentifiedTrack, Track, fallbackArtist)
6
7
8
9-- 🔱
10
11
12completeFavouritesList : List IdentifiedTrack -> List Favourite -> List Favourite
13completeFavouritesList tracks favourites =
14 List.append
15 favourites
16 (List.filterMap
17 (\( i, t ) ->
18 if not i.isFavourite then
19 Just
20 { artist = t.tags.artist
21 , title = t.tags.title
22 }
23
24 else
25 Nothing
26 )
27 tracks
28 )
29
30
31completeTracksList : List IdentifiedTrack -> List IdentifiedTrack -> List IdentifiedTrack
32completeTracksList tracksToMakeFavourite tracks =
33 let
34 favs =
35 List.filterMap
36 (\( i, t ) ->
37 if not i.isFavourite then
38 Just ( lowercaseArtist t, lowercaseTitle t )
39
40 else
41 Nothing
42 )
43 tracksToMakeFavourite
44 in
45 List.map
46 (\( i, t ) ->
47 let
48 ( la, lt ) =
49 ( lowercaseArtist t, lowercaseTitle t )
50 in
51 List.foldr
52 (\( lartist, ltitle ) ( ai, at ) ->
53 if la == lartist && lt == ltitle && not ai.isFavourite then
54 ( { ai | isFavourite = True }, at )
55
56 else
57 ( ai, at )
58 )
59 ( i, t )
60 favs
61 )
62 tracks
63
64
65match : Favourite -> Favourite -> Bool
66match a b =
67 let
68 ( aa, at ) =
69 ( Maybe.unwrap "" String.toLower a.artist
70 , String.toLower a.title
71 )
72
73 ( ba, bt ) =
74 ( Maybe.unwrap "" String.toLower b.artist
75 , String.toLower b.title
76 )
77 in
78 aa == ba && at == bt
79
80
81removeFromFavouritesList : List IdentifiedTrack -> List Favourite -> List Favourite
82removeFromFavouritesList tracks favourites =
83 List.foldr
84 (\( i, t ) acc ->
85 if i.isFavourite then
86 List.filterNot
87 (match { artist = t.tags.artist, title = t.tags.title })
88 acc
89
90 else
91 acc
92 )
93 favourites
94 tracks
95
96
97removeFromTracksList : List IdentifiedTrack -> List IdentifiedTrack -> List IdentifiedTrack
98removeFromTracksList tracksToRemoveFromFavs tracks =
99 let
100 unfavs =
101 List.filterMap
102 (\( i, t ) ->
103 if i.isFavourite then
104 Just ( lowercaseArtist t, lowercaseTitle t )
105
106 else
107 Nothing
108 )
109 tracksToRemoveFromFavs
110 in
111 List.map
112 (\( i, t ) ->
113 let
114 ( la, lt ) =
115 ( lowercaseArtist t, lowercaseTitle t )
116 in
117 List.foldr
118 (\( lartist, ltitle ) ( ai, at ) ->
119 if la == lartist && lt == ltitle && ai.isFavourite then
120 ( { ai | isFavourite = False }, at )
121
122 else
123 ( ai, at )
124 )
125 ( i, t )
126 unfavs
127 )
128 tracks
129
130
131toggleInTracksList : Track -> List IdentifiedTrack -> List IdentifiedTrack
132toggleInTracksList track =
133 let
134 lartist =
135 lowercaseArtist track
136
137 ltitle =
138 lowercaseTitle track
139 in
140 List.map
141 (\( i, t ) ->
142 if lowercaseArtist t == lartist && lowercaseTitle t == ltitle then
143 ( { i | isFavourite = not i.isFavourite }, t )
144
145 else
146 ( i, t )
147 )
148
149
150toggleInFavouritesList : IdentifiedTrack -> List Favourite -> List Favourite
151toggleInFavouritesList ( i, t ) favourites =
152 let
153 favourite =
154 { artist = t.tags.artist
155 , title = t.tags.title
156 }
157 in
158 if i.isFavourite then
159 -- Remove from list
160 List.filterNot
161 (match favourite)
162 favourites
163
164 else
165 -- Add to list
166 List.append
167 favourites
168 [ favourite ]
169
170
171
172-- ⚗️
173
174
175lowercaseArtist : Track -> String
176lowercaseArtist =
177 -- NOTE: Not entirely sure this fallback is correct
178 .tags >> .artist >> Maybe.unwrap fallbackArtist String.toLower
179
180
181lowercaseTitle : Track -> String
182lowercaseTitle =
183 .tags >> .title >> String.toLower