Skip to content

Commit 5a89632

Browse files
committed
Support theme provided by asciicast compatible (JSON) live stream parser
1 parent 8444b00 commit 5a89632

File tree

5 files changed

+58
-15
lines changed

5 files changed

+58
-15
lines changed

lib/asciinema/colors.ex

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
defmodule Asciinema.Colors do
22
def mix(c1, c2, ratio) do
3-
{r1, g1, b1} = parse_color(c1)
4-
{r2, g2, b2} = parse_color(c2)
3+
{r1, g1, b1} = parse(c1)
4+
{r2, g2, b2} = parse(c2)
55
r = hex(floor(r1 * ratio + r2 * (1 - ratio)))
66
g = hex(floor(g1 * ratio + g2 * (1 - ratio)))
77
b = hex(floor(b1 * ratio + b2 * (1 - ratio)))
@@ -19,11 +19,11 @@ defmodule Asciinema.Colors do
1919
|> String.downcase()
2020
end
2121

22-
defp parse_color(<<"#", r::binary-size(2), g::binary-size(2), b::binary-size(2)>>) do
22+
def parse(<<"#", r::binary-size(2), g::binary-size(2), b::binary-size(2)>>) do
2323
{String.to_integer(r, 16), String.to_integer(g, 16), String.to_integer(b, 16)}
2424
end
2525

26-
defp parse_color("rgb(" <> rest) do
26+
def parse("rgb(" <> rest) do
2727
rest
2828
|> String.slice(0, String.length(rest) - 1)
2929
|> String.split(",", parts: 3)

lib/asciinema/streaming/live_stream_server.ex

+5-7
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ defmodule Asciinema.Streaming.LiveStreamServer do
22
use GenServer, restart: :temporary
33
alias Asciinema.Recordings.Snapshot
44
alias Asciinema.Streaming.ViewerTracker
5-
alias Asciinema.{Colors, PubSub, Streaming, Vt}
5+
alias Asciinema.{PubSub, Streaming, Vt}
66
require Logger
77

88
defmodule Update do
@@ -295,13 +295,11 @@ defmodule Asciinema.Streaming.LiveStreamServer do
295295

296296
defp theme_fields(nil), do: [theme_fg: nil, theme_bg: nil, theme_palette: nil]
297297

298-
defp theme_fields(theme) when byte_size(theme) == 18 * 3 do
299-
colors = for <<r::8, g::8, b::8 <- theme>>, do: Colors.hex(r, g, b)
300-
298+
defp theme_fields(theme) do
301299
[
302-
theme_fg: Enum.at(colors, 0),
303-
theme_bg: Enum.at(colors, 1),
304-
theme_palette: Enum.join(Enum.slice(colors, 2..-1), ":")
300+
theme_fg: theme.fg,
301+
theme_bg: theme.bg,
302+
theme_palette: Enum.join(theme.palette, ":")
305303
]
306304
end
307305

lib/asciinema/streaming/parser/alis.ex

+14
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
defmodule Asciinema.Streaming.Parser.Alis do
2+
alias Asciinema.Colors
3+
24
@behaviour Asciinema.Streaming.Parser
35

46
@theme_absent 0x00
@@ -50,6 +52,8 @@ defmodule Asciinema.Streaming.Parser.Alis do
5052
%{status: status} = state
5153
)
5254
when status in [:init, :offline] do
55+
theme = parse_theme(theme)
56+
5357
{:ok, [reset: %{size: {cols, rows}, init: init, time: time, theme: theme}],
5458
%{state | status: :online}}
5559
end
@@ -91,4 +95,14 @@ defmodule Asciinema.Streaming.Parser.Alis do
9195
def parse({_type, _payload}, _state) do
9296
{:error, :message_invalid}
9397
end
98+
99+
defp parse_theme(theme) do
100+
colors = for <<r::8, g::8, b::8 <- theme>>, do: Colors.hex(r, g, b)
101+
102+
%{
103+
fg: Enum.at(colors, 0),
104+
bg: Enum.at(colors, 1),
105+
palette: Enum.slice(colors, 2..-1)
106+
}
107+
end
94108
end

lib/asciinema/streaming/parser/json.ex

+25-3
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,26 @@ defmodule Asciinema.Streaming.Parser.Json do
1717

1818
def handle_message(%{"cols" => cols, "rows" => rows} = header, state)
1919
when is_integer(cols) and is_integer(rows) do
20-
commands = [reset: %{size: {cols, rows}, init: header["init"], time: header["time"]}]
20+
commands = [
21+
reset: %{
22+
size: {cols, rows},
23+
init: header["init"],
24+
time: header["time"],
25+
theme: parse_theme(header["theme"])
26+
}
27+
]
2128

2229
{:ok, commands, %{state | first: false}}
2330
end
2431

25-
def handle_message(%{"width" => cols, "height" => rows}, state)
32+
def handle_message(%{"width" => cols, "height" => rows} = header, state)
2633
when is_integer(cols) and is_integer(rows) do
27-
commands = [reset: %{size: {cols, rows}}]
34+
commands = [
35+
reset: %{
36+
size: {cols, rows},
37+
theme: parse_theme(header["theme"])
38+
}
39+
]
2840

2941
{:ok, commands, %{state | first: false}}
3042
end
@@ -53,4 +65,14 @@ defmodule Asciinema.Streaming.Parser.Json do
5365
def handle_message(_message, _state) do
5466
{:error, :message_invalid}
5567
end
68+
69+
defp parse_theme(nil), do: nil
70+
71+
defp parse_theme(%{"fg" => fg, "bg" => bg, "palette" => palette}) do
72+
%{
73+
fg: fg,
74+
bg: bg,
75+
palette: String.split(palette, ":")
76+
}
77+
end
5678
end

lib/asciinema_web/live_stream_consumer_socket.ex

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
defmodule AsciinemaWeb.LiveStreamConsumerSocket do
2-
alias Asciinema.{Accounts, Authorization, Streaming}
2+
alias Asciinema.{Accounts, Authorization, Colors, Streaming}
33
alias Asciinema.Streaming.{LiveStreamServer, ViewerTracker}
44
alias AsciinemaWeb.Endpoint
55
require Logger
@@ -174,6 +174,7 @@ defmodule AsciinemaWeb.LiveStreamConsumerSocket do
174174
defp reset_message({vt_size, init, time, theme}) do
175175
{cols, rows} = vt_size
176176
theme_presence = 1
177+
theme = encode_theme(theme)
177178
init = init || ""
178179
init_len = byte_size(init)
179180

@@ -221,4 +222,12 @@ defmodule AsciinemaWeb.LiveStreamConsumerSocket do
221222
defp offline_message do
222223
{:binary, <<@msg_type_offline>>}
223224
end
225+
226+
defp encode_theme(%{fg: fg, bg: bg, palette: palette}) do
227+
for color <- [fg, bg | palette], into: <<>> do
228+
{r, g, b} = Colors.parse(color)
229+
230+
<<r::8, g::8, b::8>>
231+
end
232+
end
224233
end

0 commit comments

Comments
 (0)