mirror of
https://github.com/algora-io/tv.git
synced 2025-01-05 01:20:24 +02:00
enable admins to edit transcripts (#8)
This commit is contained in:
parent
dd1b31c4cd
commit
9259aff7aa
@ -326,4 +326,18 @@ defmodule Algora.Library do
|
||||
def change_subtitle(%Subtitle{} = subtitle, attrs \\ %{}) do
|
||||
Subtitle.changeset(subtitle, attrs)
|
||||
end
|
||||
|
||||
def save_subtitles(data) do
|
||||
{:ok, subs} = Jason.decode(data)
|
||||
|
||||
Enum.each(subs, fn sub ->
|
||||
%Subtitle{id: sub["id"]}
|
||||
|> Subtitle.changeset(%{
|
||||
start: sub["start"],
|
||||
end: sub["end"],
|
||||
body: sub["body"]
|
||||
})
|
||||
|> Repo.update!()
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
@ -697,6 +697,7 @@ defmodule AlgoraWeb.CoreComponents do
|
||||
attr :name, :any
|
||||
attr :label, :string, default: nil
|
||||
attr :value, :any
|
||||
attr :class, :string, default: nil
|
||||
|
||||
attr :type, :string,
|
||||
default: "text",
|
||||
@ -775,11 +776,12 @@ defmodule AlgoraWeb.CoreComponents do
|
||||
id={@id || @name}
|
||||
name={@name}
|
||||
class={[
|
||||
"mt-2 block min-h-[6rem] w-full rounded-lg border-gray-600 py-[7px] px-[11px]",
|
||||
"bg-gray-950 mt-2 block min-h-[6rem] w-full rounded-lg border-gray-600 py-[7px] px-[11px]",
|
||||
"text-gray-50 focus:border-gray-500 focus:outline-none focus:ring-4 focus:ring-gray-100/5 sm:text-sm sm:leading-6",
|
||||
"phx-no-feedback:border-gray-600 phx-no-feedback:focus:border-gray-500 phx-no-feedback:focus:ring-gray-100/5",
|
||||
"border-gray-600 focus:border-gray-500 focus:ring-gray-100/5",
|
||||
@errors != [] && "border-red-500 focus:border-red-500 focus:ring-red-500/10"
|
||||
@errors != [] && "border-red-500 focus:border-red-500 focus:ring-red-500/10",
|
||||
@class
|
||||
]}
|
||||
{@rest}
|
||||
><%= Phoenix.HTML.Form.normalize_value("textarea", @value) %></textarea>
|
||||
|
@ -40,19 +40,71 @@ defmodule AlgoraWeb.SidePanelLive do
|
||||
id={"side-panel-content-#{tab}"}
|
||||
class={["side-panel-content", i != 0 && "hidden"]}
|
||||
>
|
||||
<div
|
||||
:if={tab == :transcript}
|
||||
id="transcript-subtitles"
|
||||
class="text-sm break-words flex-1 overflow-y-auto h-[calc(100vh-11rem)]"
|
||||
>
|
||||
<div :for={subtitle <- @subtitles} id={"subtitle-#{subtitle.id}"}>
|
||||
<span class="font-semibold text-indigo-400">
|
||||
<%= Library.to_hhmmss(subtitle.start) %>
|
||||
</span>
|
||||
<span class="font-medium text-gray-100">
|
||||
<%= subtitle.body %>
|
||||
</span>
|
||||
<div :if={tab == :transcript}>
|
||||
<div
|
||||
id="show-transcript"
|
||||
phx-click={
|
||||
JS.hide(to: "#show-transcript")
|
||||
|> JS.show(to: "#edit-transcript")
|
||||
}
|
||||
>
|
||||
<div class={
|
||||
[
|
||||
"overflow-y-auto text-sm break-words flex-1",
|
||||
# HACK:
|
||||
if(@current_user.handle == "zaf",
|
||||
do: "h-[calc(100vh-11rem)]",
|
||||
else: "h-[calc(100vh-8.75rem)]"
|
||||
)
|
||||
]
|
||||
}>
|
||||
<div :for={subtitle <- @subtitles} id={"subtitle-#{subtitle.id}"}>
|
||||
<span class="font-semibold text-indigo-400">
|
||||
<%= Library.to_hhmmss(subtitle.start) %>
|
||||
</span>
|
||||
<span class="font-medium text-gray-100">
|
||||
<%= subtitle.body %>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button
|
||||
:if={@current_user.handle == "zaf"}
|
||||
class="mt-2 w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-purple-600 hover:bg-purple-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-purple-400"
|
||||
>
|
||||
Edit
|
||||
</button>
|
||||
</div>
|
||||
<.simple_form
|
||||
:if={@current_user.handle == "zaf"}
|
||||
id="edit-transcript"
|
||||
for={@form}
|
||||
phx-submit="save"
|
||||
class="hidden h-full"
|
||||
>
|
||||
<.input
|
||||
field={@form[:subtitles]}
|
||||
type="textarea"
|
||||
label="Edit transcript"
|
||||
class="font-mono h-[calc(100vh-14.75rem)]"
|
||||
/>
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<button
|
||||
name="save"
|
||||
value="naive"
|
||||
class="w-full flex justify-center z-10 py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-purple-600 hover:bg-purple-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-purple-400"
|
||||
>
|
||||
Save naive
|
||||
</button>
|
||||
<button
|
||||
name="save"
|
||||
value="fast"
|
||||
class="w-full flex justify-center z-10 py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-purple-600 hover:bg-purple-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-purple-400"
|
||||
>
|
||||
Save fast
|
||||
</button>
|
||||
</div>
|
||||
</.simple_form>
|
||||
</div>
|
||||
|
||||
<div :if={tab == :chat}>
|
||||
@ -96,15 +148,48 @@ defmodule AlgoraWeb.SidePanelLive do
|
||||
end
|
||||
|
||||
def handle_event("show", %{"video_id" => video_id}, socket) do
|
||||
subtitles = Library.list_subtitles(%Library.Video{id: video_id})
|
||||
|
||||
data = %{}
|
||||
|
||||
{:ok, encoded_subtitles} =
|
||||
subtitles
|
||||
|> Enum.map(&%{id: &1.id, start: &1.start, end: &1.end, body: &1.body})
|
||||
|> Jason.encode(pretty: true)
|
||||
|
||||
types = %{subtitles: :string}
|
||||
params = %{subtitles: encoded_subtitles}
|
||||
|
||||
changeset =
|
||||
{data, types}
|
||||
|> Ecto.Changeset.cast(params, Map.keys(types))
|
||||
|
||||
video = Library.get_video!(video_id)
|
||||
|
||||
socket =
|
||||
socket
|
||||
|> assign(subtitles: Library.list_subtitles(%Library.Video{id: video_id}))
|
||||
|> assign(messages: Chat.list_messages(%Library.Video{id: video_id}))
|
||||
|> assign(video: video)
|
||||
|> assign(subtitles: subtitles)
|
||||
|> assign(messages: Chat.list_messages(video))
|
||||
|> assign_form(changeset)
|
||||
|> push_event("join_chat", %{id: video_id})
|
||||
|
||||
{:noreply, socket}
|
||||
end
|
||||
|
||||
def handle_event("save", %{"data" => %{"subtitles" => subtitles}, "save" => save_type}, socket) do
|
||||
save(save_type, subtitles)
|
||||
{:noreply, socket}
|
||||
end
|
||||
|
||||
defp save("naive", subtitles) do
|
||||
Library.save_subtitles(subtitles)
|
||||
end
|
||||
|
||||
defp save("fast", subtitles) do
|
||||
Fly.Postgres.rpc_and_wait(Library, :save_subtitles, [subtitles])
|
||||
end
|
||||
|
||||
defp set_active_content(js \\ %JS{}, to) do
|
||||
js
|
||||
|> JS.hide(to: ".side-panel-content")
|
||||
@ -126,4 +211,8 @@ defmodule AlgoraWeb.SidePanelLive do
|
||||
defp append_if(list, cond, extra) do
|
||||
if cond, do: list ++ [extra], else: list
|
||||
end
|
||||
|
||||
defp assign_form(socket, %Ecto.Changeset{} = changeset) do
|
||||
assign(socket, :form, to_form(changeset, as: :data))
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user