defmodule Kanta.DeepL.Plugin.FormComponent do @moduledoc """ Phoenix LiveComponent for Kanta translation form """ use Phoenix.LiveComponent alias Kanta.DeepL.Adapter alias KantaWeb.Components.Shared.Select alias Kanta.Translations alias Kanta.Translations.Message alias Kanta.Translations.Locale.Finders.ListLocalesWithTranslatedMessage alias Kanta.Translations.SingularTranslations.Finders.GetSingularTranslation alias Kanta.Translations.PluralTranslations.Finders.GetPluralTranslation def render(assigns) do ~H"""
DeepL Translator
<.form :let={form} for={@form} phx-change="change" phx-submit="submit" phx-target={@myself} class="space-y-4"> <.live_component form={form} module={Select} id={"source_id"} label="Source" field={form["source_id"]} options={[%{color: "#c3c3c3", label: "Message ID", value: nil}] ++ Enum.map(@locales, & %{color: "#c3c3c3", label: &1.name, value: &1.id})} />
""" end def update(assigns, socket) do locales_with_translation = ListLocalesWithTranslatedMessage.find(assigns.message) socket = socket |> assign_new(:form, fn -> %{ "source_text" => assigns.message.msgid, "source_id" => nil } end) |> assign(:locales, locales_with_translation) {:ok, assign(socket, assigns)} end def handle_event("change", %{"source_id" => source_locale_id}, socket) do source_iso_code = unless is_nil(source_locale_id) do Enum.find(socket.assigns.locales, &(&1.id == String.to_integer(source_locale_id))).iso639_code end source_text = get_message_source_text( socket.assigns.message, String.to_integer(source_locale_id), socket.assigns.translation ) {:noreply, update( socket, :form, &Map.merge(&1, %{ "source_id" => source_locale_id, "source_text" => source_text, "source_iso_code" => source_iso_code }) )} end def handle_event( "submit", %{"translated_text" => translated}, %{assigns: %{message: %Message{message_type: :singular}}} = socket ) do locale = socket.assigns.locale translation = socket.assigns.translation Translations.update_singular_translation(translation, %{"translated_text" => translated}) {:noreply, socket} end def handle_event( "submit", %{"translated_text" => translated}, %{assigns: %{message: %Message{message_type: :plural}}} = socket ) do locale = socket.assigns.locale translation = socket.assigns.translation Translations.update_plural_translation(translation, %{"translated_text" => translated}) {:noreply, socket} end def handle_event("translate_via_deep_l", _, socket) do message = socket.assigns.message source_locale = (socket.assigns.form["source_iso_code"] || "en") |> String.upcase() source_text = socket.assigns.form["source_text"] || message.msgid translate_locale = socket.assigns.locale case Adapter.request_translation( source_locale, String.upcase(translate_locale.iso639_code), source_text ) do {:ok, translations} -> %{"text" => translated_text} = List.first(translations) {:noreply, update(socket, :form, &Map.merge(&1, %{"translated_text" => translated_text}))} _ -> {:noreply, socket} end end defp get_message_source_text( %Message{id: message_id, message_type: :singular}, locale_id, _translation ) do {:ok, translation} = GetSingularTranslation.find(filter: [message_id: message_id, locale_id: locale_id]) translation.translated_text || translation.original_text end defp get_message_source_text( %Message{id: message_id, message_type: :plural}, locale_id, translation ) do {:ok, translation} = GetPluralTranslation.find( filter: [ message_id: message_id, locale_id: locale_id, nplural_index: translation.nplural_index ] ) translation.translated_text || translation.original_text end end