Skip to content

Instantly share code, notes, and snippets.

@hugobarauna
Created April 1, 2025 14:37
Show Gist options
  • Save hugobarauna/882437a7ccc3f9f3061c76898fcf81b6 to your computer and use it in GitHub Desktop.
Save hugobarauna/882437a7ccc3f9f3061c76898fcf81b6 to your computer and use it in GitHub Desktop.
Kino Slides

KinoSlides

Mix.install([
  {:kino, "~> 0.15.3"}
])

Section

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>

  ![](https://dashbit.co/images/posts/2021/nx.png)

  </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>

  ![](https://i.imgur.com/b61BFWK.png)

  </div>
  """
]
KinoSlides.new(slides)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment