70 lines
2.1 KiB
Elixir
70 lines
2.1 KiB
Elixir
defmodule WhispervadWeb.VadLive do
|
|
use WhispervadWeb, :live_view
|
|
alias Phoenix.PubSub
|
|
|
|
def mount(_, _, socket) do
|
|
PubSub.subscribe(Whispervad.PubSub, "transcription")
|
|
|
|
socket =
|
|
socket
|
|
|> assign(:transcription, "")
|
|
|> assign(:started, false)
|
|
|> assign(:transcriptions, [])
|
|
|
|
{:ok, socket}
|
|
end
|
|
|
|
def handle_event("start_vad", _params, socket) do
|
|
push_event(socket, "init-vad", %{})
|
|
{:noreply, assign(socket, started: true)}
|
|
end
|
|
|
|
def handle_event("stop_vad", _params, socket) do
|
|
push_event(socket, "stop-vad", %{})
|
|
{:noreply, assign(socket, started: false)}
|
|
end
|
|
|
|
def handle_info({:transcription, %{"received_at" => ts, "text" => %{"chunks" => chunks}}}, socket) do
|
|
text = Enum.map_join(chunks, " ", fn %{"text" => t} -> t end)
|
|
|
|
updated_transcriptions =
|
|
[%{received_at: ts, text: text} | socket.assigns.transcriptions]
|
|
|> Enum.sort_by(& &1.received_at)
|
|
|
|
final_text =
|
|
updated_transcriptions
|
|
|> Enum.map_join(" ", & &1.text)
|
|
|
|
socket =
|
|
socket
|
|
|> assign(:transcriptions, updated_transcriptions)
|
|
|> assign(:transcription, final_text)
|
|
|
|
{:noreply, socket}
|
|
end
|
|
|
|
def render(assigns) do
|
|
~H"""
|
|
<div id="vad-container" phx-hook="VadHook">
|
|
<%= if !@started do %>
|
|
<button phx-click="start_vad" class="btn btn-primary">🎙 Iniciar VAD</button>
|
|
<% end %>
|
|
|
|
<div id="vad-status" class="mt-4 text-sm text-gray-700"></div>
|
|
</div>
|
|
|
|
<div id="transcriptionContainer" class="w-full max-w-2xl space-y-4">
|
|
<%= if @transcription != "" do %>
|
|
<div class="p-4 bg-gray-100 rounded shadow-md">
|
|
<h2 class="text-sm font-semibold text-gray-700 mb-2">✅ Transcripción</h2>
|
|
<p class="text-green-600 whitespace-pre-wrap break-words text-sm leading-relaxed">
|
|
<%= @transcription %>
|
|
</p>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
"""
|
|
end
|
|
|
|
end
|