From b38c1b5123682d242885a38295c08b7a800f8a24 Mon Sep 17 00:00:00 2001 From: ks0m1c_dharma Date: Fri, 26 Jul 2024 01:12:26 +0800 Subject: [PATCH] Sangh Comments Preview --- assets/js/hooks/hoverune.js | 86 +++++++++-------- lib/vyasa/written/verse.ex | 1 + .../controllers/og_image_controller.ex | 1 - .../live/source_live/chapter/index.ex | 74 ++++++++++----- .../live/source_live/chapter/index.html.heex | 7 +- mix.exs | 8 +- mix.lock | 92 ++++++++++--------- 7 files changed, 155 insertions(+), 114 deletions(-) diff --git a/assets/js/hooks/hoverune.js b/assets/js/hooks/hoverune.js index 7dc6baa6..0aba28e1 100644 --- a/assets/js/hooks/hoverune.js +++ b/assets/js/hooks/hoverune.js @@ -1,4 +1,4 @@ -import { computePosition, offset, inline } from "floating-ui.dom.umd.min"; +import { computePosition, offset, inline, autoUpdate } from "floating-ui.dom.umd.min"; const findParent = (el, attr, stopper) => { // need identifier for marginoted content @@ -8,27 +8,62 @@ const findParent = (el, attr, stopper) => { return findParent(el.parentElement, attr, stopper) } +function floatHoveRune({clientX, clientY}) { + + console.log("sting like a bees") + const selection = window.getSelection() + var getSelectRect = selection.getRangeAt(0).getBoundingClientRect() + const virtualEl = { + getBoundingClientRect() { + return getSelectRect + }, + contextElement: document.querySelector('#verses'), + }; + const hoverune = document.getElementById("hoverune"); + + computePosition(virtualEl, hoverune, {placement: 'top-end', middleware: [inline(getSelectRect.x, getSelectRect.y), offset(5)]}).then(({x, y}) => { + // Position the floating element relative to the click + hoverune.classList.remove("hidden") + Object.assign(hoverune.style, { + left: `${getSelectRect.x}px`, + top: `${y}px`, + }) + }); + + // computePosition(virtualEl, hoverune, {placement: 'top-end', middleware: [inline(getSelectRect.x, getSelectRect.y), offset(5)]}).then(({x, y}) => { + // hoverune.classList.remove("hidden") + // Object.assign(hoverune.style, { + // left: `${getSelectRect.x}px`, + // top: `${y}px`, + // }); + // }) +} + const findHook = el => findParent(el, "phx-hook", "HoveRune") const findMarginote = el => findParent(el, "phx-hook", "MargiNote") const findNode = el => el && el.getAttribute('node') -const forgeBinding = (el, attrs) => attrs.reduce((acc, attr) => {return acc.set(attr, el.getAttribute(attr))}, new Map()) +const forgeBinding = (el, attrs) => attrs.reduce((acc, attr) => { + acc[attr] = el.getAttribute(attr) + return acc +}, {}) // const marginoteParent = el => findParent(el, "data-marginote", "parent") export default HoveRune = { mounted() { const t = this.el - const hoverune = document.querySelector('#hoverune'); window.addEventListener('click', ({ target }) => { - const selection = window.getSelection() + var selection = window.getSelection() var getSelectRect = selection.getRangeAt(0).getBoundingClientRect(); + const getSelectText = selection.toString() //const validElem = findHook(target) // const isMarginote = findMarginote(target) const isNode = findNode(target) if (isNode) { - binding = forgeBinding(target, ["node", "node_id", "field"]) - binding = binding.set("selection", selection.toString()) - console.log(binding) + binding = forgeBinding(target, ["node", "node_id", "field", "verse_id"]) + binding["selection"] = getSelectText + this.pushEvent("bindHoveRune", {"binding": binding}) + computePosition(target, hoverune, {placement: 'top-end', middleware: [inline(getSelectRect.x, getSelectRect.y), offset(5)]}).then(({x, y}) => { hoverune.classList.remove("hidden") @@ -37,42 +72,13 @@ export default HoveRune = { top: `${y}px`, }); }) - } - else - { - hoverune.classList.add("hidden") - } - // if (marginoteParent(target)) return - - // if (!isMarginote) { - // console.log("not marginote yet") - // //this.pushEvent("hide-quoted-comment") - // } - if (!selection || selection == "") return - - // t.classList.remove("hidden") - // if (t.parentElement.classList.contains("popover__content")) { - // this.pushEvent("quoted-text", {quoted: selection}, () => { - // t.parentElement.classList.add("popover--visible") - // }) - // } + } + else { + hoverune.classList.remove("hidden") + } })}, updated() { - // const marginoteParent = document.querySelector("[data-marginote='parent']") - // const id = marginoteParent.getAttribute("data-marginote-id") - // const marginote = document.getElementById(`marginote-id-${id}`) - - // if (!marginoteParent) return - // if (marginote) { - // this.pushEvent("show-quoted-comment", {id: `marginote-id-${id}`}, () => { - // computePosition(marginote, marginoteParent, { - // middleware: [offset(10), autoPlacement()], - // }).then(({ x, y}) => { - // this.pushEvent("adjust-marginote", {top: `${y}px`, left: `${x}px`}) - // }) - // }) - // } } } diff --git a/lib/vyasa/written/verse.ex b/lib/vyasa/written/verse.ex index 364eed45..fb122d5a 100644 --- a/lib/vyasa/written/verse.ex +++ b/lib/vyasa/written/verse.ex @@ -8,6 +8,7 @@ defmodule Vyasa.Written.Verse do schema "verses" do field :no, :integer field :body, :string + field :binding, :any, virtual: true belongs_to :source, Source, type: Ecto.UUID belongs_to :chapter, Chapter, type: :integer, references: :no, foreign_key: :chapter_no diff --git a/lib/vyasa_web/controllers/og_image_controller.ex b/lib/vyasa_web/controllers/og_image_controller.ex index dc644f60..89a127d8 100644 --- a/lib/vyasa_web/controllers/og_image_controller.ex +++ b/lib/vyasa_web/controllers/og_image_controller.ex @@ -126,7 +126,6 @@ defmodule VyasaWeb.OgImageController do text_fill_color: caption_text_color, x: :right, y: :top, - autofit: true, width: caption_width, height: caption_height, font: font, diff --git a/lib/vyasa_web/live/source_live/chapter/index.ex b/lib/vyasa_web/live/source_live/chapter/index.ex index 7ce62bc3..1a237c68 100644 --- a/lib/vyasa_web/live/source_live/chapter/index.ex +++ b/lib/vyasa_web/live/source_live/chapter/index.ex @@ -11,8 +11,7 @@ defmodule VyasaWeb.SourceLive.Chapter.Index do @impl true def mount(_params, _session, socket) do - {:ok, socket - |> stream_configure(:verses, dom_id: &("verse-#{&1.id}"))} + {:ok, socket} end @@ -40,7 +39,9 @@ defmodule VyasaWeb.SourceLive.Chapter.Index do %{verses: verses, translations: [ts | _]} = chap <- Written.get_chapter(chap_no, sid, @default_lang) do socket + |> stream_configure(:verses, dom_id: &("verse-#{&1.id}")) |> stream(:verses, verses) + |> assign(:kv_verses, Enum.into(verses, %{}, &({&1.id, &1}))) |> assign(:src, source) |> assign(:lang, @default_lang) |> assign(:chap, chap) @@ -55,8 +56,13 @@ defmodule VyasaWeb.SourceLive.Chapter.Index do @impl true @doc """ + events + + "clickVersetoSeek" -> Handles the action of clicking to seek by emitting the verse_id to the live player via the pubsub system. + + "binding" """ def handle_event("clickVerseToSeek", %{"verse_id" => verse_id} = _payload, @@ -64,9 +70,32 @@ defmodule VyasaWeb.SourceLive.Chapter.Index do IO.inspect("handle_event::clickVerseToSeek", label: "checkpoint") Vyasa.PubSub.publish(%{verse_id: verse_id}, :playback_sync, "media:session:" <> sess_id) - {:noreply, socket} + {:noreply, socket } end + @impl true + def handle_event("bindHoveRune", + %{ + "binding" => %{ + "field" => field, + "node" => node, + "node_id" => node_id, + "verse_id" => verse_id, + "selection" => selection}} = _payload, + %{assigns: %{kv_verses: verses}} = socket) do + # bind = %{node => %{node_id => %{field => %{"selection" => selection}}}} + + {:noreply, socket + |> stream_insert(:verses, + %{verses[verse_id] | binding: %{node: node, + node_id: node_id, + field: field, + selection: selection}}) + |> push_event("genHoveRune", %{}) + } + end + + @doc """ Upon rcv of :media_handshake, which indicates an intention to sync by the player, returns a message containing %Voice{} info that can be used to generate a playback. @@ -148,7 +177,7 @@ defmodule VyasaWeb.SourceLive.Chapter.Index do assigns = assigns |> assign(:marginote_id, "marginote-#{Map.get(assigns, :id)}-#{Ecto.UUID.generate()}") ~H""" -
+
-
Enum.join("::")} class={"text-zinc-700 #{verse_class(elem.verseup)}"}> +
+
Enum.join("::")} class={"text-zinc-700 #{verse_class(elem.verseup)}"}> <%= Struct.get_in(Map.get(elem, :node, @verse), elem.field)%>
-
+ <.comment_binding :if={@verse.binding} class={(@verse.binding.node_id == Map.get(elem, :node, @verse).id && @verse.binding.field == elem.field |> Enum.join("::")) && "" || "hidden"} /> +
+
""" @@ -180,25 +212,25 @@ defmodule VyasaWeb.SourceLive.Chapter.Index do do: "font-dn text-m" - attr :current_user, :map, required: true + attr :class, :string, default: nil - def comment_information(assigns) do + def comment_binding(assigns) do assigns = assigns |> assign(:elem_id, "comment-modal-#{Ecto.UUID.generate()}") ~H""" - +
+ + + Sangh comment here + +
""" end diff --git a/lib/vyasa_web/live/source_live/chapter/index.html.heex b/lib/vyasa_web/live/source_live/chapter/index.html.heex index 81645265..a02e0945 100644 --- a/lib/vyasa_web/live/source_live/chapter/index.html.heex +++ b/lib/vyasa_web/live/source_live/chapter/index.html.heex @@ -1,4 +1,4 @@ -
+
<.header class="p-4 pb-0">
<%= @selected_transl.target.translit_title %> | <%= @chap.title%> @@ -13,7 +13,7 @@
- +
<.verse_matrix id={dom_id} verse={verse} :for={{dom_id, %Written.Verse{} = verse} <- @streams.verses}> <:edge title={"#{verse.chapter_no}.#{verse.no}"} @@ -34,10 +34,11 @@ field={[:target, :body]} verseup={:mid}/> +
<.back navigate={~p"/explore/#{@src.title}"}>Back to <%= to_title_case(@src.title)%> Chapters
-