Cleanup
This commit is contained in:
parent
830918c344
commit
773627bd5d
7 changed files with 42 additions and 149 deletions
|
@ -1,15 +1,15 @@
|
||||||
//// The library stores the music library retrieved from iBroadcast.
|
//// The library stores the music library retrieved from iBroadcast.
|
||||||
|
|
||||||
import gleam/map.{type Map}
|
import gleam/dict.{type Dict}
|
||||||
import elekf/library/track.{type Track}
|
import elekf/library/track.{type Track}
|
||||||
import elekf/library/album.{type Album}
|
import elekf/library/album.{type Album}
|
||||||
import elekf/library/artist.{type Artist}
|
import elekf/library/artist.{type Artist}
|
||||||
|
|
||||||
pub type Library {
|
pub type Library {
|
||||||
Library(
|
Library(
|
||||||
albums: Map(Int, Album),
|
albums: Dict(Int, Album),
|
||||||
artists: Map(Int, Artist),
|
artists: Dict(Int, Artist),
|
||||||
tracks: Map(Int, Track),
|
tracks: Dict(Int, Track),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,38 +18,38 @@ pub const invalid_id = -1
|
||||||
|
|
||||||
/// Gets an empty library for use as a default value.
|
/// Gets an empty library for use as a default value.
|
||||||
pub fn empty() {
|
pub fn empty() {
|
||||||
Library(albums: map.new(), artists: map.new(), tracks: map.new())
|
Library(albums: dict.new(), artists: dict.new(), tracks: dict.new())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets an album from the library based on ID.
|
/// Gets an album from the library based on ID.
|
||||||
pub fn get_album(library: Library, id: Int) {
|
pub fn get_album(library: Library, id: Int) {
|
||||||
map.get(library.albums, id)
|
dict.get(library.albums, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets an artist from the library based on ID.
|
/// Gets an artist from the library based on ID.
|
||||||
pub fn get_artist(library: Library, id: Int) {
|
pub fn get_artist(library: Library, id: Int) {
|
||||||
map.get(library.artists, id)
|
dict.get(library.artists, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a track from the library based on ID.
|
/// Gets a track from the library based on ID.
|
||||||
pub fn get_track(library: Library, id: Int) {
|
pub fn get_track(library: Library, id: Int) {
|
||||||
map.get(library.tracks, id)
|
dict.get(library.tracks, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets an album from the library, asserting that it exists.
|
/// Gets an album from the library, asserting that it exists.
|
||||||
pub fn assert_album(library: Library, id: Int) {
|
pub fn assert_album(library: Library, id: Int) {
|
||||||
let assert Ok(album) = map.get(library.albums, id)
|
let assert Ok(album) = dict.get(library.albums, id)
|
||||||
album
|
album
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets an artist from the library, asserting that it exists.
|
/// Gets an artist from the library, asserting that it exists.
|
||||||
pub fn assert_artist(library: Library, id: Int) {
|
pub fn assert_artist(library: Library, id: Int) {
|
||||||
let assert Ok(artist) = map.get(library.artists, id)
|
let assert Ok(artist) = dict.get(library.artists, id)
|
||||||
artist
|
artist
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a track from the library, asserting that it exists.
|
/// Gets a track from the library, asserting that it exists.
|
||||||
pub fn assert_track(library: Library, id: Int) {
|
pub fn assert_track(library: Library, id: Int) {
|
||||||
let assert Ok(track) = map.get(library.tracks, id)
|
let assert Ok(track) = dict.get(library.tracks, id)
|
||||||
track
|
track
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,10 +16,7 @@ import lustre/event
|
||||||
import elekf/utils/order.{type Sorter}
|
import elekf/utils/order.{type Sorter}
|
||||||
import elekf/library.{type Library}
|
import elekf/library.{type Library}
|
||||||
import elekf/library/track.{type Track}
|
import elekf/library/track.{type Track}
|
||||||
import elekf/library/artist.{type Artist}
|
|
||||||
import elekf/library/album.{type Album}
|
|
||||||
import elekf/web/events/start_play
|
import elekf/web/events/start_play
|
||||||
import elekf/web/events/show_artist
|
|
||||||
import elekf/web/components/search
|
import elekf/web/components/search
|
||||||
import elekf/web/components/library_item.{type LibraryItem}
|
import elekf/web/components/library_item.{type LibraryItem}
|
||||||
import elekf/web/components/shuffle_all
|
import elekf/web/components/shuffle_all
|
||||||
|
@ -70,9 +67,7 @@ pub type Msg {
|
||||||
SettingsUpdated(option.Option(common.Settings))
|
SettingsUpdated(option.Option(common.Settings))
|
||||||
ShuffleAll
|
ShuffleAll
|
||||||
StartPlay(List(LibraryItem(Track)), Int)
|
StartPlay(List(LibraryItem(Track)), Int)
|
||||||
ShowArtist(LibraryItem(Artist))
|
|
||||||
Search(search.Msg)
|
Search(search.Msg)
|
||||||
AlbumExpandToggled(LibraryItem(Album))
|
|
||||||
FilterUpdated
|
FilterUpdated
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,15 +163,11 @@ pub fn update(model, msg) {
|
||||||
)
|
)
|
||||||
ShuffleAll -> #(model, shuffle_all(model))
|
ShuffleAll -> #(model, shuffle_all(model))
|
||||||
StartPlay(tracks, position) -> #(model, start_play.emit(tracks, position))
|
StartPlay(tracks, position) -> #(model, start_play.emit(tracks, position))
|
||||||
ShowArtist(artist) -> #(model, show_artist.emit(artist))
|
|
||||||
Search(search_msg) -> {
|
Search(search_msg) -> {
|
||||||
let search_model = search.update(model.search, search_msg)
|
let search_model = search.update(model.search, search_msg)
|
||||||
#(Model(..model, search: search_model), effect.none())
|
#(Model(..model, search: search_model), effect.none())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Base case, this should be handled in an implementing view
|
|
||||||
AlbumExpandToggled(_album) -> #(model, effect.none())
|
|
||||||
|
|
||||||
FilterUpdated -> #(update_data(model, model.library), effect.none())
|
FilterUpdated -> #(update_data(model, model.library), effect.none())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,20 +3,14 @@
|
||||||
import gleam/list
|
import gleam/list
|
||||||
import gleam/option
|
import gleam/option
|
||||||
import gleam/int
|
import gleam/int
|
||||||
import lustre/element/html.{div, h3, p}
|
import lustre/element/html.{h3, p}
|
||||||
import lustre/element.{text}
|
import lustre/element.{text}
|
||||||
import lustre/attribute
|
import lustre/attribute
|
||||||
import lustre/event
|
|
||||||
import elekf/library.{type Library}
|
import elekf/library.{type Library}
|
||||||
import elekf/library/album.{type Album}
|
import elekf/library/album.{type Album}
|
||||||
import elekf/library/track.{type Track}
|
|
||||||
import elekf/library/album_utils
|
import elekf/library/album_utils
|
||||||
import elekf/library/track_utils
|
|
||||||
import elekf/web/components/library_view.{AlbumExpandToggled, ShuffleAll}
|
|
||||||
import elekf/web/components/library_item.{type LibraryItem}
|
import elekf/web/components/library_item.{type LibraryItem}
|
||||||
import elekf/web/components/library_views/track_item
|
|
||||||
import elekf/web/components/thumbnail
|
import elekf/web/components/thumbnail
|
||||||
import elekf/web/components/shuffle_all
|
|
||||||
import elekf/web/components/link
|
import elekf/web/components/link
|
||||||
import elekf/web/common.{type Settings}
|
import elekf/web/common.{type Settings}
|
||||||
import elekf/web/router
|
import elekf/web/router
|
||||||
|
@ -25,7 +19,6 @@ pub fn view(
|
||||||
library: Library,
|
library: Library,
|
||||||
settings: option.Option(Settings),
|
settings: option.Option(Settings),
|
||||||
item: LibraryItem(Album),
|
item: LibraryItem(Album),
|
||||||
show_tracks: Bool,
|
|
||||||
) {
|
) {
|
||||||
let #(album_id, album) = item
|
let #(album_id, album) = item
|
||||||
let tracks = album_utils.get_tracks(library, album)
|
let tracks = album_utils.get_tracks(library, album)
|
||||||
|
@ -35,7 +28,6 @@ pub fn view(
|
||||||
}
|
}
|
||||||
let assert Ok(first_track) = list.first(tracks)
|
let assert Ok(first_track) = list.first(tracks)
|
||||||
|
|
||||||
list.append(
|
|
||||||
[
|
[
|
||||||
link.link(
|
link.link(
|
||||||
router.to_hash(router.Album(album_id)),
|
router.to_hash(router.Album(album_id)),
|
||||||
|
@ -54,30 +46,5 @@ pub fn view(
|
||||||
]),
|
]),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
]
|
||||||
case show_tracks {
|
|
||||||
True -> [view_tracks(library, tracks)]
|
|
||||||
False -> []
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
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(
|
|
||||||
"library-item-expanded-contents album-item-expanded-tracks",
|
|
||||||
),
|
|
||||||
],
|
|
||||||
list.flatten([
|
|
||||||
[shuffle_all.view([event.on_click(ShuffleAll)])],
|
|
||||||
list.index_map(tracks, fn(track_item, index) {
|
|
||||||
track_item.view(library, tracks, index, track_item, "album-tracks-list")
|
|
||||||
})
|
|
||||||
|> list.flatten(),
|
|
||||||
]),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
import gleam/string
|
import gleam/string
|
||||||
import gleam/list
|
import gleam/list
|
||||||
import gleam/map
|
import gleam/dict
|
||||||
import gleam/option
|
import gleam/option
|
||||||
import gleam/dynamic
|
import gleam/dynamic
|
||||||
import gleam/result
|
import gleam/result
|
||||||
|
@ -10,11 +10,10 @@ import lustre
|
||||||
import lustre/effect
|
import lustre/effect
|
||||||
import lustre/attribute
|
import lustre/attribute
|
||||||
import lustre/element
|
import lustre/element
|
||||||
import elekf/utils/misc
|
|
||||||
import elekf/library.{type Library}
|
import elekf/library.{type Library}
|
||||||
import elekf/library/album.{type Album}
|
import elekf/library/album.{type Album}
|
||||||
import elekf/library/album_utils
|
import elekf/library/album_utils
|
||||||
import elekf/web/components/library_view.{AlbumExpandToggled}
|
import elekf/web/components/library_view
|
||||||
import elekf/web/components/library_item.{type LibraryItem}
|
import elekf/web/components/library_item.{type LibraryItem}
|
||||||
import elekf/web/components/library_views/album_item
|
import elekf/web/components/library_views/album_item
|
||||||
import elekf/web/common
|
import elekf/web/common
|
||||||
|
@ -22,7 +21,7 @@ import elekf/web/common
|
||||||
const component_name = "albums-view"
|
const component_name = "albums-view"
|
||||||
|
|
||||||
type Model {
|
type Model {
|
||||||
Model(library_view: library_view.Model(Album), expanded_album: Int)
|
Model(library_view: library_view.Model(Album))
|
||||||
}
|
}
|
||||||
|
|
||||||
type Msg {
|
type Msg {
|
||||||
|
@ -37,7 +36,7 @@ pub fn register() {
|
||||||
update,
|
update,
|
||||||
generate_view(search_filter),
|
generate_view(search_filter),
|
||||||
library_view.generic_attributes()
|
library_view.generic_attributes()
|
||||||
|> map.map_values(fn(_key, decoder) {
|
|> dict.map_values(fn(_key, decoder) {
|
||||||
fn(data: dynamic.Dynamic) {
|
fn(data: dynamic.Dynamic) {
|
||||||
data
|
data
|
||||||
|> decoder()
|
|> decoder()
|
||||||
|
@ -66,36 +65,20 @@ fn init() {
|
||||||
album_utils.sort_by_name,
|
album_utils.sort_by_name,
|
||||||
)
|
)
|
||||||
|
|
||||||
#(
|
#(Model(library_view: lib_m), effect.map(lib_e, LibraryViewMsg))
|
||||||
Model(library_view: lib_m, expanded_album: library.invalid_id),
|
|
||||||
effect.map(lib_e, LibraryViewMsg),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(model: Model, msg) {
|
fn update(model: Model, msg) {
|
||||||
case msg {
|
case msg {
|
||||||
LibraryViewMsg(AlbumExpandToggled(album)) -> {
|
|
||||||
#(
|
|
||||||
Model(
|
|
||||||
..model,
|
|
||||||
expanded_album: misc.toggle(
|
|
||||||
model.expanded_album,
|
|
||||||
album.0,
|
|
||||||
library.invalid_id,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
effect.none(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
LibraryViewMsg(lib_msg) -> {
|
LibraryViewMsg(lib_msg) -> {
|
||||||
let #(lib_m, lib_e) = library_view.update(model.library_view, lib_msg)
|
let #(lib_m, lib_e) = library_view.update(model.library_view, lib_msg)
|
||||||
#(Model(..model, library_view: lib_m), effect.map(lib_e, LibraryViewMsg))
|
#(Model(library_view: lib_m), effect.map(lib_e, LibraryViewMsg))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn data_getter(library: Library) {
|
fn data_getter(library: Library) {
|
||||||
map.to_list(library.albums)
|
dict.to_list(library.albums)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shuffler(library, items: List(LibraryItem(Album))) {
|
fn shuffler(library, items: List(LibraryItem(Album))) {
|
||||||
|
@ -121,10 +104,5 @@ fn generate_view(search_filter: library_view.SearchFilter(Album)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn view(model: Model, item: LibraryItem(Album)) {
|
fn view(model: Model, item: LibraryItem(Album)) {
|
||||||
album_item.view(
|
album_item.view(model.library_view.library, model.library_view.settings, item)
|
||||||
model.library_view.library,
|
|
||||||
model.library_view.settings,
|
|
||||||
item,
|
|
||||||
item.0 == model.expanded_album,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -189,12 +189,7 @@ fn view(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn album_view(model: Model, item: LibraryItem(Album)) {
|
fn album_view(model: Model, item: LibraryItem(Album)) {
|
||||||
album_item.view(
|
album_item.view(model.library_view.library, model.library_view.settings, item)
|
||||||
model.library_view.library,
|
|
||||||
model.library_view.settings,
|
|
||||||
item,
|
|
||||||
False,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn id_decode(data: dynamic.Dynamic) {
|
fn id_decode(data: dynamic.Dynamic) {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
import gleam/string
|
import gleam/string
|
||||||
import gleam/list
|
import gleam/list
|
||||||
import gleam/map
|
import gleam/dict
|
||||||
import gleam/option
|
import gleam/option
|
||||||
import lustre/attribute
|
import lustre/attribute
|
||||||
import elekf/library.{type Library}
|
import elekf/library.{type Library}
|
||||||
|
@ -37,7 +37,7 @@ pub fn render(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn data_getter(library: Library) {
|
fn data_getter(library: Library) {
|
||||||
map.to_list(library.tracks)
|
dict.to_list(library.tracks)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shuffler(_library, items) {
|
fn shuffler(_library, items) {
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
import gleam/result
|
|
||||||
import gleam/dynamic
|
|
||||||
import lustre/event
|
|
||||||
import elekf/library/artist.{type Artist}
|
|
||||||
import elekf/web/components/library_item.{type LibraryItem}
|
|
||||||
import elekf/utils/custom_event.{type CustomEvent}
|
|
||||||
|
|
||||||
const event_name = "show-artist"
|
|
||||||
|
|
||||||
pub type EventData {
|
|
||||||
EventData(artist: LibraryItem(Artist))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn emit(artist) {
|
|
||||||
event.emit(event_name, EventData(artist))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn on(msg: fn(LibraryItem(Artist)) -> b) {
|
|
||||||
event.on(
|
|
||||||
event_name,
|
|
||||||
fn(data) {
|
|
||||||
data
|
|
||||||
|> decoder
|
|
||||||
|> result.map(fn(e) { msg(e.artist) })
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn decoder(data: dynamic.Dynamic) {
|
|
||||||
let e: CustomEvent = dynamic.unsafe_coerce(data)
|
|
||||||
let detail = custom_event.get_detail(e)
|
|
||||||
let event_data: EventData =
|
|
||||||
detail
|
|
||||||
|> dynamic.from()
|
|
||||||
|> dynamic.unsafe_coerce()
|
|
||||||
|
|
||||||
Ok(event_data)
|
|
||||||
}
|
|
Loading…
Reference in a new issue