Deduplicate player controls

This commit is contained in:
Mikko Ahlroth 2024-03-01 14:19:06 +02:00
parent 4b9c81d24c
commit afa9125546
4 changed files with 99 additions and 97 deletions

View file

@ -0,0 +1,73 @@
import lustre/element/html.{div}
import lustre/attribute
import lustre/event
import elekf/web/components/icon.{Alt, icon}
import elekf/web/components/button_group
import elekf/web/components/button
import elekf/web/components/link
import elekf/web/components/player/actions.{NextTrack, Pause, Play, PrevTrack}
import elekf/web/components/player/model.{type Model}
import elekf/web/components/player/track
import elekf/web/router
pub fn view(model: Model) {
let is_playing = model.state == model.Playing
let toggle_link = case model.view_mode {
model.Small ->
router.to_hash(router.current_with_query(router.fullscreen_player()))
model.FullScreen -> "javascript:history.back()"
}
let toggle_icon = case model.view_mode {
model.Small -> icon("arrows-angle-expand", Alt("Full screen player"))
model.FullScreen -> icon("arrows-angle-contract", Alt("Small player"))
}
div([attribute.id("player-controls")], [
button_group.view("", [attribute.id("player-controls-buttons")], [
button.view(
"",
[attribute.id("player-previous"), event.on("click", on_prev_track)],
[icon("skip-backward-fill", Alt("Previous"))],
),
case is_playing {
True ->
button.view(
"",
[attribute.id("player-play-pause"), event.on("click", on_pause)],
[icon("pause-fill", Alt("Pause"))],
)
False ->
button.view(
"",
[attribute.id("player-play-pause"), event.on("click", on_play)],
[icon("play-fill", Alt("Play"))],
)
},
button.view(
"",
[attribute.id("player-next"), event.on("click", on_next_track)],
[icon("skip-forward-fill", Alt("Next"))],
),
link.button(toggle_link, "", [attribute.id("player-fullscreen-toggle")], [
toggle_icon,
]),
]),
..track.view(model)
])
}
fn on_pause(_) {
Ok(Pause)
}
fn on_play(_) {
Ok(Play)
}
fn on_prev_track(_) {
Ok(PrevTrack)
}
fn on_next_track(_) {
Ok(NextTrack)
}

View file

@ -4,20 +4,12 @@ import gleam/option
import lustre/element.{text}
import lustre/element/html.{div, p}
import lustre/attribute
import lustre/event
import elekf/utils/lustre
import elekf/web/components/icon.{Alt, icon}
import elekf/web/components/button_group
import elekf/web/components/button
import elekf/web/components/link
import elekf/web/components/thumbnail
import elekf/web/components/player/actions.{NextTrack, Pause, Play, PrevTrack}
import elekf/web/components/player/model.{type Model}
import elekf/web/components/player/track
import elekf/web/components/player/controls
pub fn view(model: Model) {
let is_playing = model.state == model.Playing
div(
[
attribute.id("full-player-wrapper"),
@ -56,41 +48,7 @@ pub fn view(model: Model) {
}),
meta("full-player-plays", "Plays", int.to_string(model.track.plays)),
]),
div([attribute.id("player-controls")], [
button_group.view("", [attribute.id("player-controls-buttons")], [
button.view(
"",
[attribute.id("player-previous"), event.on_click(PrevTrack)],
[icon("skip-backward-fill", Alt("Previous"))],
),
case is_playing {
True ->
button.view(
"",
[attribute.id("player-play-pause"), event.on_click(Pause)],
[icon("pause-fill", Alt("Pause"))],
)
False ->
button.view(
"",
[attribute.id("player-play-pause"), event.on_click(Play)],
[icon("play-fill", Alt("Play"))],
)
},
button.view(
"",
[attribute.id("player-next"), event.on_click(NextTrack)],
[icon("skip-forward-fill", Alt("Next"))],
),
link.button(
"javascript:history.back()",
"",
[attribute.id("player-fullscreen-toggle")],
[icon("arrows-angle-contract", Alt("Small player"))],
),
]),
..track.view(model)
]),
controls.view(model),
],
)
}

View file

@ -2,20 +2,11 @@ import gleam/option
import lustre/element.{text}
import lustre/element/html.{div, p}
import lustre/attribute
import lustre/event
import elekf/web/components/icon.{Alt, icon}
import elekf/web/components/button_group
import elekf/web/components/button
import elekf/web/components/link
import elekf/web/components/thumbnail
import elekf/web/components/player/actions.{NextTrack, Pause, Play, PrevTrack}
import elekf/web/components/player/model.{type Model}
import elekf/web/components/player/track
import elekf/web/router
import elekf/web/components/player/controls
pub fn view(model: Model) {
let is_playing = model.state == model.Playing
div(
[
attribute.id("small-player-wrapper"),
@ -35,43 +26,7 @@ pub fn view(model: Model) {
p([attribute.id("small-player-track-name")], [text(model.track.title)]),
p([attribute.id("small-player-artist-name")], [text(model.artist.name)]),
p([attribute.id("small-player-album-name")], [text(model.album.name)]),
div([attribute.id("player-controls")], [
button_group.view("", [attribute.id("player-controls-buttons")], [
button.view(
"",
[attribute.id("player-previous"), event.on_click(PrevTrack)],
[icon("skip-backward-fill", Alt("Previous"))],
),
case is_playing {
True ->
button.view(
"",
[attribute.id("player-play-pause"), event.on_click(Pause)],
[icon("pause-fill", Alt("Pause"))],
)
False ->
button.view(
"",
[attribute.id("player-play-pause"), event.on_click(Play)],
[icon("play-fill", Alt("Play"))],
)
},
button.view(
"",
[attribute.id("player-next"), event.on_click(NextTrack)],
[icon("skip-forward-fill", Alt("Next"))],
),
link.button(
router.to_hash(
router.current_with_query(router.fullscreen_player()),
),
"",
[attribute.id("player-fullscreen-toggle")],
[icon("arrows-angle-expand", Alt("Full screen player"))],
),
]),
..track.view(model)
]),
controls.view(model),
],
)
}

View file

@ -44,12 +44,28 @@ pub fn view(model: model.Model) {
attribute.max(int.to_string(model.track.length)),
attribute.value(track_pos),
attribute.attribute("aria-label", "Track position"),
event.on("change", fn(_) { Ok(SelectPosition(Commit)) }),
event.on_mouse_down(StartUserSkip),
event.on_mouse_up(EndUserSkip),
event.on("touchstart", fn(_) { Ok(StartUserSkip) }),
event.on("touchend", fn(_) { Ok(EndUserSkip) }),
event.on_input(fn(_) { SelectPosition(Ephemeral) }),
event.on("input", input_handler),
event.on("change", change_handler),
event.on("mousedown", touch_start_handler),
event.on("touchstart", touch_start_handler),
event.on("mouseup", touch_end_handler),
event.on("touchend", touch_end_handler),
]),
]
}
fn input_handler(_) {
Ok(SelectPosition(Ephemeral))
}
fn change_handler(_) {
Ok(SelectPosition(Commit))
}
fn touch_start_handler(_) {
Ok(StartUserSkip)
}
fn touch_end_handler(_) {
Ok(EndUserSkip)
}