1module Tracks.Sorting exposing (sort)
2
3import Maybe.Extra as Maybe
4import Tracks exposing (..)
5
6
7
8-- 🔱
9
10
11sort : SortBy -> SortDirection -> List IdentifiedTrack -> List IdentifiedTrack
12sort property direction list =
13 let
14 sortFn =
15 case property of
16 Album ->
17 sortByAlbum
18
19 Artist ->
20 sortByArtist
21
22 PlaylistIndex ->
23 sortByPlaylistIndex
24
25 Title ->
26 sortByTitle
27
28 dirFn =
29 if direction == Desc then
30 List.reverse
31
32 else
33 identity
34 in
35 list
36 |> List.sortWith sortFn
37 |> dirFn
38
39
40
41-- BY
42
43
44sortByAlbum : IdentifiedTrack -> IdentifiedTrack -> Order
45sortByAlbum ( x, a ) ( y, b ) =
46 EQ
47 |> andThenCompareBools isMissing x y
48 |> andThenCompare album a b
49 |> andThenCompare parentDir x y
50 |> andThenCompare disc a b
51 |> andThenCompare nr a b
52 |> andThenCompare artist a b
53 |> andThenCompare title a b
54
55
56sortByArtist : IdentifiedTrack -> IdentifiedTrack -> Order
57sortByArtist ( x, a ) ( y, b ) =
58 EQ
59 |> andThenCompareBools isMissing x y
60 |> andThenCompare artist a b
61 |> andThenCompare album a b
62 |> andThenCompare parentDir x y
63 |> andThenCompare disc a b
64 |> andThenCompare nr a b
65 |> andThenCompare title a b
66
67
68sortByTitle : IdentifiedTrack -> IdentifiedTrack -> Order
69sortByTitle ( _, a ) ( _, b ) =
70 EQ
71 |> andThenCompare title a b
72 |> andThenCompare artist a b
73 |> andThenCompare album a b
74
75
76sortByPlaylistIndex : IdentifiedTrack -> IdentifiedTrack -> Order
77sortByPlaylistIndex ( a, _ ) ( b, _ ) =
78 andThenCompare (.indexInPlaylist >> Maybe.withDefault 0) a b EQ
79
80
81
82-- TAGS
83
84
85album : Track -> String
86album =
87 .tags >> .album >> Maybe.unwrap fallbackAlbum low
88
89
90artist : Track -> String
91artist =
92 .tags >> .artist >> Maybe.unwrap fallbackArtist low
93
94
95title : Track -> String
96title =
97 .tags >> .title >> low
98
99
100disc : Track -> Int
101disc =
102 .tags >> .disc
103
104
105nr : Track -> Int
106nr =
107 .tags >> .nr
108
109
110isMissing : Identifiers -> Bool
111isMissing =
112 .isMissing
113
114
115parentDir : Identifiers -> String
116parentDir =
117 .parentDirectory >> low
118
119
120
121-- COMMON
122
123
124andThenCompare : (ctx -> comparable) -> ctx -> ctx -> Order -> Order
125andThenCompare fn a b order =
126 if order == EQ then
127 compare (fn a) (fn b)
128
129 else
130 order
131
132
133andThenCompareBools : (ctx -> Bool) -> ctx -> ctx -> Order -> Order
134andThenCompareBools fn a b order =
135 if order == EQ then
136 let
137 af =
138 fn a
139
140 bf =
141 fn b
142 in
143 if af == bf then
144 EQ
145
146 else if af == False then
147 GT
148
149 else
150 LT
151
152 else
153 order
154
155
156low : String -> String
157low =
158 String.trim >> String.toLower