From c3b045090dcfcb6cdf1943c39bfd7c79f245a4d0 Mon Sep 17 00:00:00 2001 From: Alexander Heldt Date: Fri, 14 Nov 2025 22:51:36 +0100 Subject: [PATCH] wip --- src/mpv/key.gleam | 7 ++++ src/mpv/mpv.gleam | 77 ++++++++++++++++++++++++++++++++++++++++--- src/musicplayer.gleam | 16 ++++----- 3 files changed, 87 insertions(+), 13 deletions(-) create mode 100644 src/mpv/key.gleam diff --git a/src/mpv/key.gleam b/src/mpv/key.gleam new file mode 100644 index 0000000..01f8d90 --- /dev/null +++ b/src/mpv/key.gleam @@ -0,0 +1,7 @@ +pub type Key { + Char(String) +} + +pub fn from_string(s: String) -> Key { + Char(s) +} diff --git a/src/mpv/mpv.gleam b/src/mpv/mpv.gleam index c5c9f8a..9759ad7 100644 --- a/src/mpv/mpv.gleam +++ b/src/mpv/mpv.gleam @@ -1,16 +1,83 @@ -import tcp/reason +import gleam/erlang/process.{type Subject} +import gleam/io +import gleam/otp/actor + +import gleam/string +import mpv/key.{type Key} +import tcp/reason.{type Reason} import tcp/tcp.{type Socket} -pub fn new() -> Result(Socket, String) { +pub type Message { + Tick + KeyPress(Key) + Shutdown +} + +type State(socket, exit) { + State(socket: Socket, exit: Subject(Nil)) +} + +pub fn new(exit: Subject(Nil)) -> Result(Subject(Message), String) { // TODO start up mvp here, currently hi-jacking `naviterm`s socket let socket_path = "/tmp/naviterm_mpv" case tcp.connect(socket_path) { - Error(r) -> Error("mpv - could not connect: " <> reason.to_string(r)) - Ok(socket) -> Ok(socket) + Error(r) -> Error("Could not connect to mpv: " <> reason.to_string(r)) + Ok(socket) -> { + case + actor.new(State(socket, exit)) + |> actor.on_message(handle_message) + |> actor.start + { + Error(start_error) -> + Error("Could not start actor: " <> string.inspect(start_error)) + Ok(actor.Started(data:, ..)) -> { + process.spawn(fn() { tick(data) }) + process.spawn(fn() { read_input(data) }) + Ok(data) + } + } + } } } -pub fn toggle_play_pause(socket: Socket) { +pub fn shutdown(subject: Subject(Message)) -> Nil { + actor.send(subject, Shutdown) +} + +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 { + Tick -> actor.continue(state) + KeyPress(key) -> { + io.println("key: " <> string.inspect(key)) + actor.continue(state) + } + Shutdown -> actor.continue(state) + } +} + +fn tick(subject: Subject(Message)) -> Nil { + process.send(subject, Tick) + process.sleep(1000) + tick(subject) +} + +fn read_input(subject: Subject(Message)) -> Nil { + io.println("reading input") + let key = io_get_line("") |> key.from_string + io.println("got key: " <> string.inspect(key)) + + key |> KeyPress |> process.send(subject, _) + read_input(subject) +} + +// https://www.erlang.org/doc/apps/stdlib/io.html#get_line/1 +@external(erlang, "io", "get_line") +fn io_get_line(prompt: String) -> String diff --git a/src/musicplayer.gleam b/src/musicplayer.gleam index 003672b..e900606 100644 --- a/src/musicplayer.gleam +++ b/src/musicplayer.gleam @@ -1,14 +1,14 @@ +import gleam/erlang/process import gleam/io import mpv/mpv pub fn main() -> Nil { - case mpv.new() { - Error(err) -> io.println("Could not create new mpv connection: " <> err) - Ok(socket) -> handle_key_events(socket) + let exit = process.new_subject() + case mpv.new(exit) { + Error(err) -> io.println("Could not start mpv: " <> err) + Ok(_) -> { + io.println("Started mpv") + } } -} - -fn handle_key_events(socket) -> Nil { - let _ = mpv.toggle_play_pause(socket) - Nil + exit |> process.receive_forever }