···2233## 3.4.0
4455+- **Improved audio metadata parsing**. Now uses [mediainfo.js](https://github.com/buzz/mediainfo.js).
56- **Removed native builds.** I no longer want to maintain native builds for Diffuse. I personally use it straight in the browser or install it as a PWA. Alternatively, there's software like [Multi](https://github.com/kofigumbs/multi) that allow you to package web applications into native apps. There are icons in the [src](/src/Static/Images) folder that you can use as the app icon.
67- Adjusted search behaviour, now searches while typing (with a small delay).
78- Allows you to make playlists public when using Fission/ODD SDK.
89- Fixes issue with Safari where reloading after a search caused the loader to be shown indefinitely.
1010+- Fixes some issues with cover grouping.
911- Fixes syncing issues with Fission/ODD SDK (was called Webnative before)
1012- Made the project easier to build.
1313+- Reduced unnecessary error messages.
1114- Removes support for older browsers.
12151316
···6060 , title "Scroll to track"
6161 ]
6262 [ "cursor-pointer" ]
6363- [ text (tags.artist ++ " - " ++ tags.title) ]
6363+ [ case tags.artist of
6464+ Just artist ->
6565+ text (artist ++ " - " ++ tags.title)
6666+6767+ Nothing ->
6868+ text tags.title
6969+ ]
64706571 Nothing ->
6672 text "Diffuse"
+15-15
src/Applications/UI/Demo.elm
···29293030favourites : List Favourite
3131favourites =
3232- [ { artist = "James Blake"
3232+ [ { artist = Just "James Blake"
3333 , title = "Essential Mix (09-17-2011)"
3434 }
3535 ]
···7676 , nr = 1
77777878 --
7979- , album = "Soulection White Label: 013"
8080- , artist = "oriJanus"
7979+ , album = Just "Soulection White Label: 013"
8080+ , artist = Just "oriJanus"
8181 , title = "Bonita"
82828383 --
···9595 , nr = 2
96969797 --
9898- , album = "Soulection White Label: 013"
9999- , artist = "oriJanus"
9898+ , album = Just "Soulection White Label: 013"
9999+ , artist = Just "oriJanus"
100100 , title = "6"
101101102102 --
···114114 , nr = 3
115115116116 --
117117- , album = "Soulection White Label: 013"
118118- , artist = "oriJanus"
117117+ , album = Just "Soulection White Label: 013"
118118+ , artist = Just "oriJanus"
119119 , title = "Hot Remix ft. Tek.Lun & Zikomo"
120120121121 --
···133133 , nr = 9
134134135135 --
136136- , album = "Adult Swim Singles Project 2012"
137137- , artist = "Com Truise"
136136+ , album = Just "Adult Swim Singles Project 2012"
137137+ , artist = Just "Com Truise"
138138 , title = "Chemical Legs"
139139140140 --
···152152 , nr = 4
153153154154 --
155155- , album = "The Miyazaki Tour EP"
156156- , artist = "Manuele Atzeni"
155155+ , album = Just "The Miyazaki Tour EP"
156156+ , artist = Just "Manuele Atzeni"
157157 , title = "Little Star"
158158159159 --
···171171 , nr = 2
172172173173 --
174174- , album = "The Last Thing"
175175- , artist = "Patrick Lee"
174174+ , album = Just "The Last Thing"
175175+ , artist = Just "Patrick Lee"
176176 , title = "Quittin' Time"
177177178178 --
···190190 , nr = 1
191191192192 --
193193- , album = "Essential Mix-SAT-09-17"
194194- , artist = "James Blake"
193193+ , album = Just "Essential Mix-SAT-09-17"
194194+ , artist = Just "James Blake"
195195 , title = "Essential Mix (09-17-2011)"
196196197197 --
+12-2
src/Applications/UI/Queue/View.elm
···165165 , "text-xs"
166166 ]
167167 [ text (String.fromInt <| idx + 1), text "." ]
168168- , text (track.tags.artist ++ " - " ++ track.tags.title)
168168+ , case track.tags.artist of
169169+ Just artist ->
170170+ text (artist ++ " - " ++ track.tags.title)
171171+172172+ Nothing ->
173173+ text track.tags.title
169174 ]
170175 , actions =
171176 [ -- Remove
···285290 [ inline
286291 [ "inline-block", "text-xs", "mr-2" ]
287292 [ text (String.fromInt <| idx + 1), text "." ]
288288- , text (track.tags.artist ++ " - " ++ track.tags.title)
293293+ , case track.tags.artist of
294294+ Just artist ->
295295+ text (artist ++ " - " ++ track.tags.title)
296296+297297+ Nothing ->
298298+ text track.tags.title
289299 ]
290300 , actions =
291301 [ { icon = Icons.more_vert
···673673 |> .album
674674675675 missingTracks =
676676- album == Tracks.missingAlbumPlaceholder
676676+ List.any
677677+ (Tuple.first >> .isMissing)
678678+ cover.tracks
677679678680 maybeBlobUrlFromCache =
679681 cachedCovers
···800802 identifiedTrackCover
801803802804 missingTracks =
803803- track.tags.album == Tracks.missingAlbumPlaceholder
805805+ List.any
806806+ (Tuple.first >> .isMissing)
807807+ cover.tracks
804808 in
805809 brick
806810 (if clickable then
···827831 , "pt-px"
828832 , "truncate"
829833 ]
830830- [ case sortBy of
831831- Album ->
832832- text track.tags.album
834834+ [
835835+ case sortBy of
836836+ Album ->
837837+ if missingTracks then
838838+ text "Missing tracks"
839839+840840+ else
841841+ text (Maybe.withDefault "Unknown album" track.tags.album)
833842834834- Artist ->
835835- text track.tags.artist
843843+ Artist ->
844844+ if missingTracks then
845845+ text "Missing tracks"
836846837837- _ ->
838838- nothing
847847+ else
848848+ text (Maybe.withDefault "Unknown artist" track.tags.artist)
849849+850850+ _ ->
851851+ nothing
839852 ]
840853841854 --
···848861 ]
849862 [ case sortBy of
850863 Album ->
851851- if missingTracks then
852852- text "Missing tracks"
853853-854854- else if cover.variousArtists then
864864+ if cover.variousArtists then
855865 text "Various Artists"
856866867867+ else if not missingTracks && Maybe.isJust track.tags.artist then
868868+ text (Maybe.withDefault "" track.tags.artist)
857869 else
858858- text track.tags.artist
870870+ case List.length cover.trackIds of
871871+ 1 ->
872872+ text "1 track"
873873+874874+ n ->
875875+ text (String.fromInt n ++ " tracks")
876876+859877860878 Artist ->
861879 case List.length cover.trackIds of
862880 1 ->
863863- Html.text "1 track"
881881+ text "1 track"
864882865883 n ->
866866- Html.text (String.fromInt n ++ " tracks")
884884+ text (String.fromInt n ++ " tracks")
867885868886 _ ->
869887 nothing
···66import String.Ext as String
77import Time
88import Time.Ext as Time
99+import Maybe.Extra as Maybe
91010111112···3031 , nr : Int
31323233 -- Main
3333- , album : String
3434- , artist : String
3434+ , album : Maybe String
3535+ , artist : Maybe String
3536 , title : String
36373738 -- Extra
···585959606061type alias Favourite =
6161- { artist : String
6262+ { artist : Maybe String
6263 , title : String
6364 }
6465···177178emptyTags =
178179 { disc = 1
179180 , nr = 0
180180- , album = "Empty"
181181- , artist = "Empty"
181181+ , album = Nothing
182182+ , artist = Nothing
182183 , title = "Empty"
183184 , genre = Nothing
184185 , picture = Nothing
···219220 , scrollContext = ""
220221 }
221222223223+{-| If a track doesn't fit into a group, where does it go?
224224+-}
225225+fallbackCoverGroup : String
226226+fallbackCoverGroup =
227227+ "MISSING_TRACK_INFO"
228228+229229+{-| This value is used as a fallback in the UI if the album is missing.
230230+-}
231231+fallbackAlbum : String
232232+fallbackAlbum =
233233+ ""
234234+235235+{-| This value is used as a fallback in the UI if the artist is missing.
236236+-}
237237+fallbackArtist : String
238238+fallbackArtist =
239239+ ""
222240223241224242-- MORE STUFF
···226244227245coverGroup : SortBy -> IdentifiedTrack -> String
228246coverGroup sort ( identifiers, { tags } as track ) =
247247+ if identifiers.isMissing then
248248+ "MISSING_TRACKS"
249249+ else
229250 (case sort of
230251 Artist ->
231231- tags.artist
252252+ Maybe.unwrap fallbackCoverGroup (String.trim >> String.toLower) tags.artist
232253233254 Album ->
234255 -- There is the possibility of albums with the same name,
235256 -- such as "Greatests Hits".
236257 -- To make sure we treat those as different albums,
237258 -- we prefix the album by its parent directory.
238238- identifiers.parentDirectory ++ tags.album
259259+260260+ case tags.album of
261261+ Just album ->
262262+ (identifiers.parentDirectory ++ album)
263263+ |> String.trim
264264+ |> String.toLower
265265+ Nothing ->
266266+ fallbackCoverGroup
239267240268 PlaylistIndex ->
241269 ""
···243271 Title ->
244272 tags.title
245273 )
246246- |> String.trim
247247- |> String.toLower
274274+248275249276250277coverKey : Bool -> Track -> String
251278coverKey isVariousArtists { tags } =
252252- if isVariousArtists then
253253- tags.album
279279+ if isVariousArtists then
280280+ Maybe.withDefault "?" tags.album
254281255255- else
256256- tags.artist ++ " --- " ++ tags.album
282282+ else
283283+ Maybe.withDefault "?" tags.artist ++ " --- " ++ Maybe.withDefault "?" tags.album
257284258285259286isNowPlaying : IdentifiedTrack -> IdentifiedTrack -> Bool
···281308 |> List.head
282309 |> (==) (Just playlist.name)
283310 |> (&&) playlist.autoGenerated
284284-285285-286286-missingAlbumPlaceholder : String
287287-missingAlbumPlaceholder =
288288- "⌁"
289311290312291313missingId : String
···7878 |> List.foldl
7979 (\( i, t ) ( dict, ( idx, prevIdentifiers ), acc ) ->
8080 let
8181+ -- Identifier used to distinguish duplicates
8182 s =
8282- String.toLower (t.tags.artist ++ t.tags.title)
8383+ case t.tags.artist of
8484+ Just artist ->
8585+ String.toLower (artist ++ t.tags.title)
8686+8787+ Nothing ->
8888+ String.toLower t.tags.title
8389 in
8490 if theFilter ( i, t ) == False then
8591 ( dict, ( idx, prevIdentifiers ), acc )
···11module Tracks.Sorting exposing (sort)
2233+import Maybe.Extra as Maybe
34import Tracks exposing (..)
4556···4344sortByAlbum : IdentifiedTrack -> IdentifiedTrack -> Order
4445sortByAlbum ( x, a ) ( y, b ) =
4546 EQ
4747+ |> andThenCompareBools isMissing x y
4648 |> andThenCompare album a b
4749 |> andThenCompare parentDir x y
4850 |> andThenCompare disc a b
···5456sortByArtist : IdentifiedTrack -> IdentifiedTrack -> Order
5557sortByArtist ( x, a ) ( y, b ) =
5658 EQ
5959+ |> andThenCompareBools isMissing x y
5760 |> andThenCompare artist a b
5861 |> andThenCompare album a b
5962 |> andThenCompare parentDir x y
···81848285album : Track -> String
8386album =
8484- .tags >> .album >> low
8787+ .tags >> .album >> Maybe.unwrap fallbackAlbum low
858886898790artist : Track -> String
8891artist =
8989- .tags >> .artist >> low
9292+ .tags >> .artist >> Maybe.unwrap fallbackArtist low
909391949295title : Track -> String
···103106nr =
104107 .tags >> .nr
105108109109+isMissing : Identifiers -> Bool
110110+isMissing =
111111+ .isMissing
112112+106113107114parentDir : Identifiers -> String
108115parentDir =
···117124andThenCompare fn a b order =
118125 if order == EQ then
119126 compare (fn a) (fn b)
127127+128128+ else
129129+ order
130130+131131+andThenCompareBools : (ctx -> Bool) -> ctx -> ctx -> Order -> Order
132132+andThenCompareBools fn a b order =
133133+ if order == EQ then
134134+ let
135135+ af = fn a
136136+ bf = fn b
137137+ in
138138+ if af == bf then
139139+ EQ
140140+ else if af == False then
141141+ GT
142142+ else
143143+ LT
144144+120145121146 else
122147 order