mirror of
https://github.com/algora-io/tv.git
synced 2025-04-17 06:57:04 +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
|
def change_subtitle(%Subtitle{} = subtitle, attrs \\ %{}) do
|
||||||
Subtitle.changeset(subtitle, attrs)
|
Subtitle.changeset(subtitle, attrs)
|
||||||
end
|
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
|
end
|
||||||
|
@ -697,6 +697,7 @@ defmodule AlgoraWeb.CoreComponents do
|
|||||||
attr :name, :any
|
attr :name, :any
|
||||||
attr :label, :string, default: nil
|
attr :label, :string, default: nil
|
||||||
attr :value, :any
|
attr :value, :any
|
||||||
|
attr :class, :string, default: nil
|
||||||
|
|
||||||
attr :type, :string,
|
attr :type, :string,
|
||||||
default: "text",
|
default: "text",
|
||||||
@ -775,11 +776,12 @@ defmodule AlgoraWeb.CoreComponents do
|
|||||||
id={@id || @name}
|
id={@id || @name}
|
||||||
name={@name}
|
name={@name}
|
||||||
class={[
|
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",
|
"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",
|
"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",
|
"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}
|
{@rest}
|
||||||
><%= Phoenix.HTML.Form.normalize_value("textarea", @value) %></textarea>
|
><%= Phoenix.HTML.Form.normalize_value("textarea", @value) %></textarea>
|
||||||
|
@ -40,19 +40,71 @@ defmodule AlgoraWeb.SidePanelLive do
|
|||||||
id={"side-panel-content-#{tab}"}
|
id={"side-panel-content-#{tab}"}
|
||||||
class={["side-panel-content", i != 0 && "hidden"]}
|
class={["side-panel-content", i != 0 && "hidden"]}
|
||||||
>
|
>
|
||||||
<div
|
<div :if={tab == :transcript}>
|
||||||
:if={tab == :transcript}
|
<div
|
||||||
id="transcript-subtitles"
|
id="show-transcript"
|
||||||
class="text-sm break-words flex-1 overflow-y-auto h-[calc(100vh-11rem)]"
|
phx-click={
|
||||||
>
|
JS.hide(to: "#show-transcript")
|
||||||
<div :for={subtitle <- @subtitles} id={"subtitle-#{subtitle.id}"}>
|
|> JS.show(to: "#edit-transcript")
|
||||||
<span class="font-semibold text-indigo-400">
|
}
|
||||||
<%= Library.to_hhmmss(subtitle.start) %>
|
>
|
||||||
</span>
|
<div class={
|
||||||
<span class="font-medium text-gray-100">
|
[
|
||||||
<%= subtitle.body %>
|
"overflow-y-auto text-sm break-words flex-1",
|
||||||
</span>
|
# 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>
|
</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>
|
||||||
|
|
||||||
<div :if={tab == :chat}>
|
<div :if={tab == :chat}>
|
||||||
@ -96,15 +148,48 @@ defmodule AlgoraWeb.SidePanelLive do
|
|||||||
end
|
end
|
||||||
|
|
||||||
def handle_event("show", %{"video_id" => video_id}, socket) do
|
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 =
|
||||||
socket
|
socket
|
||||||
|> assign(subtitles: Library.list_subtitles(%Library.Video{id: video_id}))
|
|> assign(video: video)
|
||||||
|> assign(messages: Chat.list_messages(%Library.Video{id: video_id}))
|
|> assign(subtitles: subtitles)
|
||||||
|
|> assign(messages: Chat.list_messages(video))
|
||||||
|
|> assign_form(changeset)
|
||||||
|> push_event("join_chat", %{id: video_id})
|
|> push_event("join_chat", %{id: video_id})
|
||||||
|
|
||||||
{:noreply, socket}
|
{:noreply, socket}
|
||||||
end
|
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
|
defp set_active_content(js \\ %JS{}, to) do
|
||||||
js
|
js
|
||||||
|> JS.hide(to: ".side-panel-content")
|
|> JS.hide(to: ".side-panel-content")
|
||||||
@ -126,4 +211,8 @@ defmodule AlgoraWeb.SidePanelLive do
|
|||||||
defp append_if(list, cond, extra) do
|
defp append_if(list, cond, extra) do
|
||||||
if cond, do: list ++ [extra], else: list
|
if cond, do: list ++ [extra], else: list
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp assign_form(socket, %Ecto.Changeset{} = changeset) do
|
||||||
|
assign(socket, :form, to_form(changeset, as: :data))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user