Mix.install([
{:kino, "~> 0.15.3"}
])
defmodule KinoSlides do
use GenServer
def new(slides) do
frame = Kino.Frame.new()
Kino.start_child({KinoSlides, %{slides: slides, layout_frame: frame}})
frame
end
def start_link(init_arg) do
GenServer.start_link(__MODULE__, init_arg, name: __MODULE__)
end
@impl true
def init(init_arg) do
prev_button = Kino.Control.button("<")
next_button = Kino.Control.button(">")
Kino.Control.subscribe(prev_button, :prev_button_clicked)
Kino.Control.subscribe(next_button, :next_button_clicked)
state = Map.merge(init_arg, %{current_slide: 0, buttons: [prev_button, next_button]})
{:ok, state |> render()}
end
defp render(state) do
slide = Enum.at(state.slides, state.current_slide)
layout =
Kino.Layout.grid([
Kino.Markdown.new(slide),
Kino.Layout.grid(state.buttons, columns: 8)
])
Kino.Frame.render(state.layout_frame, layout)
state
end
@impl true
def handle_info({:prev_button_clicked, _}, state) do
current_slide =
if(state.current_slide == 0) do
0
else
state.current_slide - 1
end
state = %{state | current_slide: current_slide}
{:noreply, state |> render()}
end
@impl true
def handle_info({:next_button_clicked, _}, state) do
max_slide = Enum.count(state.slides) - 1
current_slide =
if(state.current_slide == max_slide) do
max_slide
else
state.current_slide + 1
end
state = %{state | current_slide: current_slide}
{:noreply, state |> render()}
end
end
slides = [
"""
<div class="flex flex-col justify-center items-center p-8" style="height: 600px">
<div style="transform: scale(2)">
<h3>The Nx Stack</h3>
<p>Nx: Numerical Elixir</p>
</div>

</div>
""",
"""
<div class="flex flex-col justify-center items-center p-8" style="height: 600px">
<div style="transform: scale(2)">
<h3>Ferramentas para cada etapa</h3>
</div>

</div>
"""
]