From 4c7324478712a72d147b95d296aef67ab50c03c3 Mon Sep 17 00:00:00 2001 From: Alexander Heldt Date: Sat, 15 Nov 2025 17:47:59 +0100 Subject: [PATCH] Map `Key` to `Control` --- src/mpv/control.gleam | 27 ++++++++++++++++++++++++++ src/mpv/internal.gleam | 1 - src/mpv/mpv.gleam | 44 +++++++++++++++++++++++------------------- 3 files changed, 51 insertions(+), 21 deletions(-) create mode 100644 src/mpv/control.gleam diff --git a/src/mpv/control.gleam b/src/mpv/control.gleam new file mode 100644 index 0000000..328cb6b --- /dev/null +++ b/src/mpv/control.gleam @@ -0,0 +1,27 @@ +import mpv/internal.{type Key} +import tcp/reason.{type Reason} +import tcp/tcp.{type Socket} + +pub type Control { + TogglePlayPause + Exit +} + +pub fn from_key(key: Key) -> Result(Control, Nil) { + case key { + internal.Char(char) -> char_control(char) + _ -> Error(Nil) + } +} + +fn char_control(char: String) -> Result(Control, Nil) { + case char { + " " -> Ok(TogglePlayPause) + "q" -> Ok(Exit) + _ -> Error(Nil) + } +} + +pub fn toggle_play_pause(socket: Socket) -> Result(Nil, Reason) { + tcp.send(socket, "{\"command\":[\"cycle\",\"pause\"]}\n") +} diff --git a/src/mpv/internal.gleam b/src/mpv/internal.gleam index 36c3ae9..fb4d0c5 100644 --- a/src/mpv/internal.gleam +++ b/src/mpv/internal.gleam @@ -41,7 +41,6 @@ pub fn start_raw_shell() { shell_start_interactive(#(no_shell, raw)) } -// TODO map key to something like Control, to not leak `Continue` etc. pub fn read_input_until_key(l: List(String)) -> Key { let l = read_input() |> list.wrap |> list.append(l, _) diff --git a/src/mpv/mpv.gleam b/src/mpv/mpv.gleam index 403f195..3379b9f 100644 --- a/src/mpv/mpv.gleam +++ b/src/mpv/mpv.gleam @@ -1,15 +1,13 @@ import gleam/erlang/process.{type Subject} import gleam/otp/actor +import gleam/result import gleam/string -import mpv/internal.{type Key, Char} -import tcp/reason.{type Reason} +import mpv/control.{type Control} +import mpv/internal +import tcp/reason import tcp/tcp.{type Socket} -pub type Message { - KeyPress(Key) -} - type State(socket, exit) { State(socket: Socket, exit: Subject(Nil)) } @@ -39,28 +37,34 @@ pub fn new(exit: Subject(Nil)) -> Result(Nil, String) { } } -pub fn toggle_play_pause(socket: Socket) -> Result(Nil, Reason) { - tcp.send(socket, "{\"command\":[\"cycle\",\"pause\"]}\n") -} - fn handle_message( state: State(socket, exit), - message: Message, -) -> actor.Next(State(socket, exit), Message) { - case message { - KeyPress(Char("q")) -> { + control: Control, +) -> actor.Next(State(socket, exit), Control) { + case control { + control.TogglePlayPause -> { + echo "toggling play/pause" + let _ = + result.map_error(control.toggle_play_pause(state.socket), fn(r) { + echo "Could not toggle play/pause: " <> reason.to_string(r) + }) + actor.continue(state) + } + control.Exit -> { process.send(state.exit, Nil) actor.stop() } - KeyPress(key) -> { - echo "key: " <> string.inspect(key) - actor.continue(state) - } } } -fn read_input(subject: Subject(Message)) -> Nil { - internal.read_input_until_key([]) |> KeyPress |> process.send(subject, _) +fn read_input(subject: Subject(Control)) -> Nil { + case + internal.read_input_until_key([]) + |> control.from_key + { + Error(_) -> Nil + Ok(control) -> process.send(subject, control) + } read_input(subject) }