Add sorting
This commit is contained in:
parent
ee70f6742c
commit
ccecb20aea
10 changed files with 105 additions and 5 deletions
|
@ -1,7 +1,12 @@
|
|||
import gleam/list
|
||||
import gleam/string
|
||||
import gleam/int
|
||||
import elekf/utils/order
|
||||
import elekf/library.{type Library}
|
||||
import elekf/library/album.{type Album}
|
||||
|
||||
const year_sorters = [year_compare, name_compare]
|
||||
|
||||
/// Get the individual tracks in an album.
|
||||
pub fn get_tracks(library: Library, album: Album) {
|
||||
list.map(
|
||||
|
@ -9,3 +14,21 @@ pub fn get_tracks(library: Library, album: Album) {
|
|||
fn(track_id) { #(track_id, library.assert_track(library, track_id)) },
|
||||
)
|
||||
}
|
||||
|
||||
/// Sort given albums by their lowercased names.
|
||||
pub fn sort_by_name(a: Album, b: Album) {
|
||||
name_compare(a, b)
|
||||
}
|
||||
|
||||
/// Sort given albums by their publishing year first, then lowercased names.
|
||||
pub fn sort_by_year(a: Album, b: Album) {
|
||||
order.compare_by_multiple(year_sorters, a, b)
|
||||
}
|
||||
|
||||
fn name_compare(a: Album, b: Album) {
|
||||
string.compare(a.name_lower, b.name_lower)
|
||||
}
|
||||
|
||||
fn year_compare(a: Album, b: Album) {
|
||||
int.compare(a.year, b.year)
|
||||
}
|
||||
|
|
7
src/elekf/library/artist_utils.gleam
Normal file
7
src/elekf/library/artist_utils.gleam
Normal file
|
@ -0,0 +1,7 @@
|
|||
import gleam/string
|
||||
import elekf/library/artist.{type Artist}
|
||||
|
||||
/// Sort given artists by their lowercased names.
|
||||
pub fn sort_by_name(a: Artist, b: Artist) {
|
||||
string.compare(a.name_lower, b.name_lower)
|
||||
}
|
24
src/elekf/library/track_utils.gleam
Normal file
24
src/elekf/library/track_utils.gleam
Normal file
|
@ -0,0 +1,24 @@
|
|||
import gleam/string
|
||||
import gleam/int
|
||||
import elekf/utils/order
|
||||
import elekf/library/track.{type Track}
|
||||
|
||||
const track_number_sorters = [order_compare, name_compare]
|
||||
|
||||
/// Sort given tracks by their lowercased names.
|
||||
pub fn sort_by_name(a: Track, b: Track) {
|
||||
name_compare(a, b)
|
||||
}
|
||||
|
||||
/// Sort given tracks by their track number first, lowercased title second.
|
||||
pub fn sort_by_track_number(a: Track, b: Track) {
|
||||
order.compare_by_multiple(track_number_sorters, a, b)
|
||||
}
|
||||
|
||||
fn order_compare(a: Track, b: Track) {
|
||||
int.compare(a.number, b.number)
|
||||
}
|
||||
|
||||
fn name_compare(a: Track, b: Track) {
|
||||
string.compare(a.title_lower, b.title_lower)
|
||||
}
|
21
src/elekf/utils/order.gleam
Normal file
21
src/elekf/utils/order.gleam
Normal file
|
@ -0,0 +1,21 @@
|
|||
import gleam/order
|
||||
import gleam/list
|
||||
|
||||
/// A function that sorts two values.
|
||||
pub type Sorter(a) =
|
||||
fn(a, a) -> order.Order
|
||||
|
||||
/// Compare two values by using multiple sorters. The comparison will stop after
|
||||
/// the first sorter that returns something other than `order.Eq`.
|
||||
pub fn compare_by_multiple(sorters: List(Sorter(a)), a: a, b: a) {
|
||||
list.fold_until(
|
||||
sorters,
|
||||
order.Eq,
|
||||
fn(prev, sorter) {
|
||||
case prev {
|
||||
order.Eq -> list.Continue(sorter(a, b))
|
||||
other -> list.Stop(other)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
|
@ -12,6 +12,7 @@ import lustre/element.{text}
|
|||
import lustre/element/html.{div, h3}
|
||||
import lustre/attribute
|
||||
import lustre/event
|
||||
import elekf/utils/order.{type Sorter} as order_utils
|
||||
import elekf/library.{type Library}
|
||||
import elekf/library/track.{type Track}
|
||||
import elekf/library/artist.{type Artist}
|
||||
|
@ -78,6 +79,7 @@ pub type Model(a) {
|
|||
data: List(LibraryItem(a)),
|
||||
data_getter: DataGetter(a),
|
||||
shuffler: Shuffler(a),
|
||||
sorter: Sorter(a),
|
||||
search: search.Model,
|
||||
settings: option.Option(common.Settings),
|
||||
)
|
||||
|
@ -97,11 +99,12 @@ pub fn register(
|
|||
data_getter: DataGetter(a),
|
||||
item_view: ItemView(a),
|
||||
shuffler: Shuffler(a),
|
||||
sorter: Sorter(a),
|
||||
search_filter: SearchFilter(a),
|
||||
) {
|
||||
lustre.component(
|
||||
name,
|
||||
fn() { init(library.empty(), data_getter, shuffler) },
|
||||
fn() { init(library.empty(), data_getter, shuffler, sorter) },
|
||||
update,
|
||||
generate_view(item_view, search_filter),
|
||||
generic_attributes(),
|
||||
|
@ -134,13 +137,14 @@ pub fn render(
|
|||
)
|
||||
}
|
||||
|
||||
pub fn init(library, data_getter, shuffler) {
|
||||
pub fn init(library, data_getter, shuffler, sorter) {
|
||||
#(
|
||||
Model(
|
||||
library,
|
||||
data_getter(library),
|
||||
data_getter,
|
||||
shuffler,
|
||||
sorter,
|
||||
search.init(),
|
||||
option.None,
|
||||
),
|
||||
|
@ -151,7 +155,13 @@ pub fn init(library, data_getter, shuffler) {
|
|||
pub fn update(model, msg) {
|
||||
case msg {
|
||||
LibraryUpdated(library) -> #(
|
||||
Model(..model, library: library, data: model.data_getter(library)),
|
||||
Model(
|
||||
..model,
|
||||
library: library,
|
||||
data: library
|
||||
|> model.data_getter()
|
||||
|> list.sort(fn(a, b) { model.sorter(a.1, b.1) }),
|
||||
),
|
||||
effect.none(),
|
||||
)
|
||||
SettingsUpdated(settings) -> #(
|
||||
|
|
|
@ -11,6 +11,7 @@ import elekf/library.{type Library}
|
|||
import elekf/library/album.{type Album}
|
||||
import elekf/library/track.{type Track}
|
||||
import elekf/library/album_utils
|
||||
import elekf/library/track_utils
|
||||
import elekf/web/components/library_view.{AlbumExpandToggled}
|
||||
import elekf/web/components/library_item.{type LibraryItem}
|
||||
import elekf/web/components/library_views/track_item
|
||||
|
@ -94,6 +95,9 @@ pub fn view(
|
|||
}
|
||||
|
||||
pub fn view_tracks(library: Library, tracks: List(LibraryItem(Track))) {
|
||||
let tracks =
|
||||
list.sort(tracks, fn(a, b) { track_utils.sort_by_track_number(a.1, b.1) })
|
||||
|
||||
div(
|
||||
[
|
||||
attribute.class(
|
||||
|
|
|
@ -58,7 +58,12 @@ pub fn render(
|
|||
|
||||
fn init() {
|
||||
let #(lib_m, lib_e) =
|
||||
library_view.init(library.empty(), data_getter, shuffler)
|
||||
library_view.init(
|
||||
library.empty(),
|
||||
data_getter,
|
||||
shuffler,
|
||||
album_utils.sort_by_name,
|
||||
)
|
||||
|
||||
#(
|
||||
Model(library_view: lib_m, expanded_album: library.invalid_id),
|
||||
|
|
|
@ -11,6 +11,7 @@ import lustre/attribute
|
|||
import lustre/event
|
||||
import elekf/library.{type Library}
|
||||
import elekf/library/artist.{type Artist}
|
||||
import elekf/library/artist_utils
|
||||
import elekf/web/components/library_view.{type Model, ShowArtist}
|
||||
import elekf/web/components/library_item.{type LibraryItem}
|
||||
import elekf/web/components/library_views/thumbnail
|
||||
|
@ -25,6 +26,7 @@ pub fn register() {
|
|||
data_getter,
|
||||
item_view,
|
||||
shuffler,
|
||||
artist_utils.sort_by_name,
|
||||
search_filter,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -81,6 +81,7 @@ fn init() {
|
|||
library.empty(),
|
||||
fn(_) -> List(LibraryItem(Album)) { [] },
|
||||
shuffler,
|
||||
album_utils.sort_by_year,
|
||||
)
|
||||
|
||||
#(
|
||||
|
@ -101,7 +102,8 @@ fn update(model: Model, msg) {
|
|||
expanded_album: library.invalid_id,
|
||||
library_view: library_view.Model(
|
||||
..model.library_view,
|
||||
data: data_getter(model.library_view.library, artist),
|
||||
data: data_getter(model.library_view.library, artist)
|
||||
|> list.sort(fn(a, b) { model.library_view.sorter(a.1, b.1) }),
|
||||
),
|
||||
),
|
||||
effect.none(),
|
||||
|
|
|
@ -7,6 +7,7 @@ import gleam/option
|
|||
import lustre/attribute
|
||||
import elekf/library.{type Library}
|
||||
import elekf/library/track.{type Track}
|
||||
import elekf/library/track_utils
|
||||
import elekf/web/components/library_view.{type Model}
|
||||
import elekf/web/components/library_item.{type LibraryItem}
|
||||
import elekf/web/components/library_views/track_item
|
||||
|
@ -21,6 +22,7 @@ pub fn register() {
|
|||
data_getter,
|
||||
item_view,
|
||||
shuffler,
|
||||
track_utils.sort_by_name,
|
||||
search_filter,
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue