Add Search section

This commit is contained in:
Alexander Heldt
2025-11-25 20:50:13 +01:00
parent 91eab4e454
commit 34ff51881f
4 changed files with 37 additions and 9 deletions

View File

@@ -2,13 +2,16 @@ import musicplayer/input/key.{type Key}
pub type Control { pub type Control {
TogglePlayPause TogglePlayPause
Search
Input(String)
Search(List(String))
Exit Exit
} }
pub fn from_key(key: Key) -> Result(Control, Nil) { pub fn from_key(key: Key) -> Result(Control, Nil) {
case key { case key {
key.Input(content) -> Ok(Input(content))
key.Char(char) -> char_control(char) key.Char(char) -> char_control(char)
_ -> Error(Nil) _ -> Error(Nil)
} }
@@ -17,7 +20,7 @@ pub fn from_key(key: Key) -> Result(Control, Nil) {
fn char_control(char: String) -> Result(Control, Nil) { fn char_control(char: String) -> Result(Control, Nil) {
case char { case char {
" " -> Ok(TogglePlayPause) " " -> Ok(TogglePlayPause)
"/" -> Ok(Search) "/" -> Ok(Search([]))
"q" -> Ok(Exit) "q" -> Ok(Exit)
_ -> Error(Nil) _ -> Error(Nil)
} }

View File

@@ -1,4 +1,4 @@
import gleam/erlang/process.{type Name, type Subject} import gleam/erlang/process.{type Name}
import musicplayer/input/key.{type Key} import musicplayer/input/key.{type Key}

View File

@@ -54,11 +54,20 @@ fn handle_message(
control: Control, control: Control,
) -> actor.Next(State(ui, mpv, input_inject, exit), Control) { ) -> actor.Next(State(ui, mpv, input_inject, exit), Control) {
case control { case control {
control.Search -> { control.Search([]) -> {
process.send(state.input_inject, key.Continue([key.input_introducer])) process.send(state.input_inject, key.Continue([key.input_introducer]))
update_search(state.ui, "searching: ")
actor.continue(state) actor.continue(state)
} }
control.Search(content) -> {
update_search(state.ui, "searching: " <> string.join(content, ""))
actor.continue(state)
}
control.Input(_) -> {
update_search(state.ui, "")
actor.continue(state)
}
control.TogglePlayPause -> { control.TogglePlayPause -> {
echo "toggling play/pause" echo "toggling play/pause"
@@ -120,13 +129,26 @@ fn update_playback_time(
} }
} }
fn update_search(ui: Subject(ui_control.Control), content: String) -> Nil {
process.send(ui, ui_control.UpdateState(layout.Search, content))
}
/// `handle_key` listens to a subject onto which `input` will send messages with /// `handle_key` listens to a subject onto which `input` will send messages with
/// parsed `Key`s which will be mapped to `Control`s (if possible) /// parsed `Key`s which will be mapped to `Control`s (if possible)
fn handle_key(musicplayer: Subject(Control), input_keys: Subject(Key)) -> Nil { fn handle_key(musicplayer: Subject(Control), input_keys: Subject(Key)) -> Nil {
let _ = let _ = case
process.receive_forever(input_keys) process.new_selector()
|> process.select(input_keys)
|> process.selector_receive_forever
{
key.Continue(buffer:) ->
Ok(process.send(musicplayer, control.Search(buffer)))
key ->
key
|> control.from_key |> control.from_key
|> result.map(process.send(musicplayer, _)) |> result.map(process.send(musicplayer, _))
}
handle_key(musicplayer, input_keys) handle_key(musicplayer, input_keys)
} }

View File

@@ -7,6 +7,7 @@ pub type Layout {
pub type Section { pub type Section {
Root Root
Header Header
Search
PlaybackTime PlaybackTime
} }
@@ -21,10 +22,12 @@ pub fn new() -> Layout {
Root, Root,
Node(content: "", x: 0, y: 0, children: [ Node(content: "", x: 0, y: 0, children: [
Header, Header,
Search,
PlaybackTime, PlaybackTime,
]), ]),
), ),
#(Header, Node(content: "Music Player", x: 1, y: 1, children: [])), #(Header, Node(content: "Music Player", x: 1, y: 1, children: [])),
#(Search, Node(content: "", x: 30, y: 1, children: [])),
#(PlaybackTime, Node(content: "00:00", x: 1, y: 2, children: [])), #(PlaybackTime, Node(content: "00:00", x: 1, y: 2, children: [])),
]) ])