From e20f8e33ee3539984cd483d8a7ba6744dfa5afe9 Mon Sep 17 00:00:00 2001 From: Thelonius Kort Date: Sun, 5 Mar 2023 20:56:19 +0100 Subject: [PATCH] Add selecting next/previous tunit and highlight it --- assets/css/article.css | 8 ++++ assets/js/app.js | 5 ++- assets/js/translation-form.js | 38 +++++++++++++++++++ .../components/tunit_editor_component.ex | 2 +- .../live/translation_live/form_component.ex | 37 ++++++++++++++---- 5 files changed, 81 insertions(+), 9 deletions(-) create mode 100644 assets/js/translation-form.js diff --git a/assets/css/article.css b/assets/css/article.css index d9a2fa2..d6a7029 100644 --- a/assets/css/article.css +++ b/assets/css/article.css @@ -15,6 +15,14 @@ @apply hover:bg-gray-700; } +.article .tunit[current="yes"] { + @apply bg-amber-300 text-stone-700 hover:bg-amber-200 hover:text-red-900; +} + +.dark .article .tunit[current="yes"] { + @apply bg-amber-500/70 text-white hover:bg-amber-500/70 hover:text-red-900; +} + .article a.hide-link { display: none; } diff --git a/assets/js/app.js b/assets/js/app.js index 9fee884..6f8953d 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -23,11 +23,14 @@ import {LiveSocket} from "phoenix_live_view" import topbar from "../vendor/topbar" import {DarkModeHook} from './dark-mode-widget' +import {TranslationFormHook} from "./translation-form" let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content") let liveSocket = new LiveSocket("/live", Socket, { params: {_csrf_token: csrfToken}, - hooks: {dark_mode_widget: DarkModeHook}, + hooks: {translation_form: TranslationFormHook, + // tunit_editor: TunitEditorHook, + dark_mode_widget: DarkModeHook}, }) // Show progress bar on live navigation and form submits diff --git a/assets/js/translation-form.js b/assets/js/translation-form.js new file mode 100644 index 0000000..cfc0b5a --- /dev/null +++ b/assets/js/translation-form.js @@ -0,0 +1,38 @@ +let TranslationFormHook = { + + mounted() { + this.el.addEventListener("keyup", this.keyupHandler.bind(this)) + this.title_input = this.el.querySelector("#translation-form_title") + this.tunit_editor = this.el.querySelector("#tunit-editor-content") + }, + keyupHandler(e) { + var preaction = () => { } + var postaction = () => { } + var payload = {} + if (e.altKey){ + if (e.key == "ArrowDown"){ + preaction = () => { this.title_input.focus() } + postaction = () => { this.tunit_editor.focus() } + var handler = "select_next_tunit" + } else if (e.key == "ArrowUp"){ + preaction = () => { this.title_input.focus() } + postaction = () => { this.tunit_editor.focus() } + var handler = "select_previous_tunit" + } else if (e.key == "u") { + var handler = "tunit_status" + payload = {status: "untranslated"} + } else if (e.key == "p") { + var handler = "tunit_status" + payload = {status: "passable"} + } else if (e.key == "o") { + var handler = "tunit_status" + payload = {status: "done"} + } + preaction.call() + this.pushEventTo(this.el, handler, payload, postaction) + } + // console.info(["keyupHandler", e, this]) + }, +} + +export {TranslationFormHook} diff --git a/lib/outlook_web/components/tunit_editor_component.ex b/lib/outlook_web/components/tunit_editor_component.ex index ab7c630..202dddf 100644 --- a/lib/outlook_web/components/tunit_editor_component.ex +++ b/lib/outlook_web/components/tunit_editor_component.ex @@ -14,7 +14,7 @@ defmodule OutlookWeb.TunitEditorComponent do <%= @current_tunit.content |> raw %> --%>
-
<.status_selector target={@target} disabled={!@current_tunit.status} tunit={@current_tunit} /> diff --git a/lib/outlook_web/live/translation_live/form_component.ex b/lib/outlook_web/live/translation_live/form_component.ex index c79ce1d..b183d68 100644 --- a/lib/outlook_web/live/translation_live/form_component.ex +++ b/lib/outlook_web/live/translation_live/form_component.ex @@ -8,7 +8,7 @@ defmodule OutlookWeb.TranslationLive.FormComponent do def render(assigns) do ~H"""
-
+
<.header> <%= @title %> <:subtitle>Use this form to manage translation records in your database. @@ -63,6 +63,7 @@ defmodule OutlookWeb.TranslationLive.FormComponent do socket |> assign(assigns) |> assign(:current_tunit, %TranslationUnit{status: nil}) + |> assign(:tunit_ids, InternalTree.get_tunit_ids(translation.article.content)) |> assign(:changeset, changeset) |> assign_article_tree(translation) |> assign(:deepl_progress, nil)} @@ -118,11 +119,33 @@ defmodule OutlookWeb.TranslationLive.FormComponent do {:noreply, socket |> assign(:current_tunit, tunit)} end - def handle_event("select_current_tunit", %{"nid" => nid}, socket) do - {:noreply, - socket - |> update_translation_with_current_tunit(socket.assigns.current_tunit.status) - |> assign(:current_tunit, socket.assigns.translation_content[nid])} + def handle_event("select_tunit_by_nid", %{"nid" => nid}, socket) do + {:noreply, change_tunit(socket, nid)} + end + + def handle_event("select_next_tunit", _, socket) do + {:noreply, select_next_tunit(socket, &Kernel.+/2)} + end + + def handle_event("select_previous_tunit", _, socket) do + {:noreply, select_next_tunit(socket, &Kernel.-/2)} + end + + defp select_next_tunit(socket, direction) do + tunit_ids = socket.assigns.tunit_ids + current_tunit_nid = socket.assigns.current_tunit.status && socket.assigns.current_tunit.nid || List.last(tunit_ids) + index_current = Enum.find_index(tunit_ids, fn nid -> nid == current_tunit_nid end) + index_next = direction.(index_current, 1) |> Integer.mod(length(tunit_ids)) + next_nid = Enum.at(tunit_ids, index_next) + change_tunit(socket, next_nid) + end + + defp change_tunit(socket, nid) do + fun = fn n -> n.nid == nid && "yes" || "no" end + socket + |> assign(:article_tree, InternalTree.garnish(socket.assigns.article_tree, %{tunits: %{current: fun}})) + |> update_translation_with_current_tunit(socket.assigns.current_tunit.status) + |> assign(:current_tunit, socket.assigns.translation_content[nid]) end @doc "updating on browser events" @@ -146,7 +169,7 @@ defmodule OutlookWeb.TranslationLive.FormComponent do :article_tree, InternalTree.add_phx_click_event(translation.article.content, nodes: :tunits, - click: "select_current_tunit", + click: "select_tunit_by_nid", target: socket.assigns.myself) |> InternalTree.garnish(%{tunits: %{class: "tunit"}})) end