timgremore
commited on
Commit
•
83105f7
1
Parent(s):
79bf54b
feat: HomeLive.Index LiveView
Browse files
lib/medical_transcription_web/live/home_live/index.ex
ADDED
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
defmodule MedicalTranscriptionWeb.HomeLive.Index do
|
2 |
+
use MedicalTranscriptionWeb, :live_view
|
3 |
+
|
4 |
+
@impl Phoenix.LiveView
|
5 |
+
def mount(_params, _session, socket) do
|
6 |
+
{:ok,
|
7 |
+
socket
|
8 |
+
|> assign(:uploaded_files, [])
|
9 |
+
|> assign_async(:audio_text, fn -> {:ok, %{audio_text: []}} end)
|
10 |
+
|> allow_upload(:audio, accept: ~w(.mp3), max_entries: 1)}
|
11 |
+
end
|
12 |
+
|
13 |
+
@impl Phoenix.LiveView
|
14 |
+
def render(assigns) do
|
15 |
+
~H"""
|
16 |
+
<form id="audio-form" phx-submit="save" phx-change="validate">
|
17 |
+
<div class="flex flex-col space-y-4">
|
18 |
+
<h1>Upload Transcription Audio</h1>
|
19 |
+
<.live_file_input upload={@uploads.audio} />
|
20 |
+
<button name="submit-btn" class="rounded-full bg-slate-200 py-4 px-8 text-slate-800 w-48">
|
21 |
+
Upload Audio
|
22 |
+
</button>
|
23 |
+
|
24 |
+
<%= for entry <- @uploads.audio.entries do %>
|
25 |
+
<p>Submitted: <%= entry.client_name %></p>
|
26 |
+
<% end %>
|
27 |
+
|
28 |
+
<.async_result :let={text} assign={@audio_text}>
|
29 |
+
<:loading>Transcribing audio...</:loading>
|
30 |
+
<:failed :let={_reason}>Transcription failed</:failed>
|
31 |
+
<%= for entry <- text do %>
|
32 |
+
<p><%= entry %></p>
|
33 |
+
<% end %>
|
34 |
+
</.async_result>
|
35 |
+
</div>
|
36 |
+
</form>
|
37 |
+
"""
|
38 |
+
end
|
39 |
+
|
40 |
+
@impl true
|
41 |
+
def handle_event("save", _params, socket) do
|
42 |
+
uploaded_files =
|
43 |
+
consume_uploaded_entries(socket, :audio, fn %{path: path}, _entry ->
|
44 |
+
dest = Path.join("priv/static/uploads", Path.basename(path))
|
45 |
+
File.cp!(path, dest)
|
46 |
+
{:ok, "audio.mp3"}
|
47 |
+
end)
|
48 |
+
|
49 |
+
# Task async -> Audio Tagger -> get transcribed audio
|
50 |
+
|
51 |
+
socket =
|
52 |
+
socket
|
53 |
+
|> assign_async(:audio_text, fn -> {:ok, %{audio_text: ["Hello", "Hi"]}} end)
|
54 |
+
|> update(:uploaded_files, &(&1 ++ uploaded_files))
|
55 |
+
|
56 |
+
{:noreply, socket}
|
57 |
+
end
|
58 |
+
|
59 |
+
@impl true
|
60 |
+
def handle_event("validate", _params, socket) do
|
61 |
+
{:noreply, socket}
|
62 |
+
end
|
63 |
+
|
64 |
+
def error_to_string(:too_large), do: "Too large"
|
65 |
+
def error_to_string(:not_accepted), do: "You have selected an unacceptable file type"
|
66 |
+
end
|
lib/medical_transcription_web/router.ex
CHANGED
@@ -17,7 +17,7 @@ defmodule MedicalTranscriptionWeb.Router do
|
|
17 |
scope "/", MedicalTranscriptionWeb do
|
18 |
pipe_through :browser
|
19 |
|
20 |
-
|
21 |
end
|
22 |
|
23 |
# Other scopes may use custom stacks.
|
|
|
17 |
scope "/", MedicalTranscriptionWeb do
|
18 |
pipe_through :browser
|
19 |
|
20 |
+
live "/", HomeLive.Index
|
21 |
end
|
22 |
|
23 |
# Other scopes may use custom stacks.
|
test/medical_transcription_web/live/home_live_test.exs
ADDED
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
defmodule MedicalTranscriptionWeb.HomeLiveTest do
|
2 |
+
use MedicalTranscriptionWeb.ConnCase, async: true
|
3 |
+
|
4 |
+
import Phoenix.LiveViewTest
|
5 |
+
|
6 |
+
alias MedicalTranscriptionWeb.HomeLive.Index
|
7 |
+
|
8 |
+
describe "/" do
|
9 |
+
test "renders upload screen", %{conn: conn} do
|
10 |
+
conn = get(conn, "/")
|
11 |
+
assert html_response(conn, 200) =~ "<h1>Upload Transcription Audio</h1>"
|
12 |
+
|
13 |
+
{:ok, view, html} = live(conn)
|
14 |
+
assert html =~ "<h1>Upload Transcription Audio</h1>"
|
15 |
+
|
16 |
+
sample_file =
|
17 |
+
__DIR__
|
18 |
+
|> Path.join("../../../medasrdemo-Paul.mp3")
|
19 |
+
|> Path.expand()
|
20 |
+
|
21 |
+
audio =
|
22 |
+
file_input(view, "#audio-form", :audio, [
|
23 |
+
%{
|
24 |
+
last_modified: 1_594_171_879_000,
|
25 |
+
name: "sample.mp3",
|
26 |
+
content: File.read!(sample_file),
|
27 |
+
size: 992_980,
|
28 |
+
type: "audio/mp3"
|
29 |
+
}
|
30 |
+
])
|
31 |
+
|
32 |
+
assert audio
|
33 |
+
|> render_upload("sample.mp3") =~ "Submitted: sample.mp3"
|
34 |
+
|
35 |
+
refute view
|
36 |
+
|> form("#audio-form")
|
37 |
+
|> render_submit() =~ "Submitted: sample.mp3"
|
38 |
+
|
39 |
+
# |> render_async() =~ "Hello"
|
40 |
+
|
41 |
+
# |> render_submit() =~ "Submitted: sample.mp3"
|
42 |
+
|
43 |
+
# assert render_upload(audio, "sample.mp3") |> dbg() =~ "100%"
|
44 |
+
|
45 |
+
# 1. Find file input
|
46 |
+
# 2. Upload file
|
47 |
+
# 3. Click submit
|
48 |
+
# 4. Assert we see text
|
49 |
+
# 5. Assert we see codes alongside text
|
50 |
+
end
|
51 |
+
end
|
52 |
+
end
|