This commit is contained in:
Alexander Heldt
2025-11-14 22:51:36 +01:00
parent c395a5294d
commit c3b045090d
3 changed files with 87 additions and 13 deletions

7
src/mpv/key.gleam Normal file
View File

@@ -0,0 +1,7 @@
pub type Key {
Char(String)
}
pub fn from_string(s: String) -> Key {
Char(s)
}

View File

@@ -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} 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 // TODO start up mvp here, currently hi-jacking `naviterm`s socket
let socket_path = "/tmp/naviterm_mpv" let socket_path = "/tmp/naviterm_mpv"
case tcp.connect(socket_path) { case tcp.connect(socket_path) {
Error(r) -> Error("mpv - could not connect: " <> reason.to_string(r)) Error(r) -> Error("Could not connect to mpv: " <> reason.to_string(r))
Ok(socket) -> Ok(socket) 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") 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

View File

@@ -1,14 +1,14 @@
import gleam/erlang/process
import gleam/io import gleam/io
import mpv/mpv import mpv/mpv
pub fn main() -> Nil { pub fn main() -> Nil {
case mpv.new() { let exit = process.new_subject()
Error(err) -> io.println("Could not create new mpv connection: " <> err) case mpv.new(exit) {
Ok(socket) -> handle_key_events(socket) Error(err) -> io.println("Could not start mpv: " <> err)
Ok(_) -> {
io.println("Started mpv")
} }
} }
exit |> process.receive_forever
fn handle_key_events(socket) -> Nil {
let _ = mpv.toggle_play_pause(socket)
Nil
} }