Packages

fnord

0.4.18

AI code archaeology

Current section

Files

Jump to
fnord lib ui.ex
Raw

lib/ui.ex

defmodule UI do
use GenServer
defstruct [
:id_counter,
:statuses
]
# -----------------------------------------------------------------------------
# Client API
# -----------------------------------------------------------------------------
def start_link() do
GenServer.start_link(__MODULE__, nil, name: __MODULE__)
end
def add_status(msg, detail \\ nil) do
GenServer.call(__MODULE__, {:add_status, msg, detail})
end
def complete_status(status_id, resolution) do
GenServer.cast(__MODULE__, {:complete_status, status_id, resolution})
end
def complete_status(status_id, resolution, append) do
GenServer.cast(__MODULE__, {:complete_status, status_id, resolution, append})
end
def puts(msg) do
Owl.IO.puts(msg)
Owl.LiveScreen.await_render()
end
# -----------------------------------------------------------------------------
# Server callbacks
# -----------------------------------------------------------------------------
@impl true
def init(_) do
state = %__MODULE__{
id_counter: 0,
statuses: %{}
}
{:ok, state}
end
@impl true
def handle_call({:add_status, msg, detail}, _from, state) do
{state, status_id} = do_add_status(state, msg, detail)
{:reply, status_id, state}
end
@impl true
def handle_cast({:complete_status, status_id, resolution}, state) do
{:noreply, do_complete_status(state, status_id, resolution)}
end
@impl true
def handle_cast({:complete_status, status_id, resolution, msg}, state) do
{:noreply, do_complete_status(state, status_id, resolution, msg)}
end
# -----------------------------------------------------------------------------
# Private functions
# -----------------------------------------------------------------------------
defp interactive?(), do: IO.ANSI.enabled?()
defp do_add_status(state, msg, detail) do
msg =
if is_nil(detail) do
msg
else
Owl.Data.tag(
["#{msg}: ", Owl.Data.tag(detail, :green)],
:default_color
)
|> Owl.Data.to_chardata()
end
counter = state.id_counter + 1
status_id = String.to_atom("status_#{counter}")
statuses = Map.put(state.statuses, status_id, msg)
if interactive?() do
Owl.Spinner.start(id: status_id)
Owl.Spinner.update_label(id: status_id, label: msg)
Owl.LiveScreen.await_render()
end
{
%__MODULE__{state | id_counter: counter, statuses: statuses},
status_id
}
end
defp do_complete_status(state, status_id, resolution, msg \\ nil) do
status = Map.get(state.statuses, status_id)
state = %{state | statuses: Map.delete(state.statuses, status_id)}
msg =
if is_nil(msg) do
status
else
status <> ": " <> msg
end
if interactive?() do
Owl.Spinner.stop(id: status_id, resolution: resolution, label: msg)
Owl.LiveScreen.await_render()
end
state
end
end