From c6c05c0fa19da060c8c00728e55361f766552e29 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Mon, 28 Mar 2022 18:05:19 -0400 Subject: [PATCH] WIP: trying to figure out flickering --- assets/css/app.css | 1 - assets/js/app.js | 19 +- assets/tailwind.config.js | 2 +- .../changes/render_markdown.ex | 1 + .../extensions/render_markdown/highlighter.ex | 55 +++++ .../docs/resources/extension/extension.ex | 18 +- lib/ash_hq_web/components/doc_sidebar.ex | 148 +++++++++++++ lib/ash_hq_web/components/search.ex | 5 +- lib/ash_hq_web/pages/docs.ex | 207 +++++++----------- lib/ash_hq_web/views/app_view_live.ex | 39 ++-- mix.exs | 7 + mix.lock | 6 + .../20220328162643_add_tsvector_indices.exs | 3 +- .../20220328204638_migrate_resources9.exs | 23 ++ .../repo/extensions/20220328204638.json | 130 +++++++++++ 15 files changed, 507 insertions(+), 157 deletions(-) create mode 100644 lib/ash_hq/docs/extensions/render_markdown/highlighter.ex create mode 100644 lib/ash_hq_web/components/doc_sidebar.ex create mode 100644 priv/repo/migrations/20220328204638_migrate_resources9.exs create mode 100644 priv/resource_snapshots/repo/extensions/20220328204638.json diff --git a/assets/css/app.css b/assets/css/app.css index f367515..446a849 100644 --- a/assets/css/app.css +++ b/assets/css/app.css @@ -4,7 +4,6 @@ @import "tailwindcss/utilities"; @import "syntax.css"; -@import "markdown.css"; .search-hit { color: #fb923c diff --git a/assets/js/app.js b/assets/js/app.js index 0b7e692..3299652 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -71,10 +71,23 @@ let liveSocket = new LiveSocket("/live", Socket, { } }); -// Show progress bar on live navigation and form submits +// Show progress bar on live navigation and form submits. Only displays if still +// loading after 120 msec topbar.config({barColors: {0: "#29d"}, shadowColor: "rgba(0, 0, 0, .3)"}) -window.addEventListener("phx:page-loading-start", info => topbar.show()) -window.addEventListener("phx:page-loading-stop", info => topbar.hide()) + +let topBarScheduled = undefined; +window.addEventListener("phx:page-loading-start", () => { + if(!topBarScheduled) { + topBarScheduled = setTimeout(() => topbar.show(), 120); + }; +}); +window.addEventListener("phx:page-loading-stop", () => { + clearTimeout(topBarScheduled); + topBarScheduled = undefined; + topbar.hide(); +}); + + window.addEventListener("js:focus", e => e.target.focus()) window.addEventListener("js:noscroll-main", e => { if(e.target.style.display === "none") { diff --git a/assets/tailwind.config.js b/assets/tailwind.config.js index ec0f682..9bc3f67 100644 --- a/assets/tailwind.config.js +++ b/assets/tailwind.config.js @@ -2,7 +2,7 @@ const colors = require('tailwindcss/colors') module.exports = { mode: "jit", - purge: ["./js/**/*.js", "../lib/*_web/**/*.*ex"], + content: ["./js/**/*.js", "../lib/*_web/**/*.*ex"], darkMode: "class", theme: { extend: { diff --git a/lib/ash_hq/docs/extensions/render_markdown/changes/render_markdown.ex b/lib/ash_hq/docs/extensions/render_markdown/changes/render_markdown.ex index 85dad24..cf64361 100644 --- a/lib/ash_hq/docs/extensions/render_markdown/changes/render_markdown.ex +++ b/lib/ash_hq/docs/extensions/render_markdown/changes/render_markdown.ex @@ -17,6 +17,7 @@ defmodule AshHq.Docs.Extensions.RenderMarkdown.Changes.RenderMarkdown do ) {:ok, html_doc, _} -> + html_doc = AshHq.Docs.Extensions.RenderMarkdown.Highlighter.highlight(html_doc) Ash.Changeset.force_change_attribute(changeset, opts[:destination], html_doc) end else diff --git a/lib/ash_hq/docs/extensions/render_markdown/highlighter.ex b/lib/ash_hq/docs/extensions/render_markdown/highlighter.ex new file mode 100644 index 0000000..f45f81f --- /dev/null +++ b/lib/ash_hq/docs/extensions/render_markdown/highlighter.ex @@ -0,0 +1,55 @@ +defmodule AshHq.Docs.Extensions.RenderMarkdown.Highlighter do + @moduledoc false + # Copied *directly* from nimble_publisher + # https://github.com/dashbitco/nimble_publisher/blob/v0.1.2/lib/nimble_publisher/highlighter.ex + + @doc """ + Highlights all code block in an already generated HTML document. + """ + def highlight(html) do + Regex.replace( + ~r/
([^<]*)<\/code><\/pre>/,
+      html,
+      &highlight_code_block(&1, &2, &3)
+    )
+  end
+
+  defp highlight_code_block(full_block, lang, code) do
+    case pick_language_and_lexer(lang) do
+      {_language, nil, _opts} -> full_block
+      {language, lexer, opts} -> render_code(language, lexer, opts, code)
+    end
+  end
+
+  defp pick_language_and_lexer(""), do: {"text", nil, []}
+
+  defp pick_language_and_lexer(lang) do
+    case Makeup.Registry.fetch_lexer_by_name(lang) do
+      {:ok, {lexer, opts}} -> {lang, lexer, opts}
+      :error -> {lang, nil, []}
+    end
+  end
+
+  defp render_code(lang, lexer, lexer_opts, code) do
+    highlighted =
+      code
+      |> unescape_html()
+      |> IO.iodata_to_binary()
+      |> Makeup.highlight_inner_html(
+        lexer: lexer,
+        lexer_options: lexer_opts,
+        formatter_options: [highlight_tag: "span"]
+      )
+
+    ~s(
#{highlighted}
) + end + + entities = [{"&", ?&}, {"<", ?<}, {">", ?>}, {""", ?"}, {"'", ?'}] + + for {encoded, decoded} <- entities do + defp unescape_html(unquote(encoded) <> rest), do: [unquote(decoded) | unescape_html(rest)] + end + + defp unescape_html(<>), do: [c | unescape_html(rest)] + defp unescape_html(<<>>), do: [] +end diff --git a/lib/ash_hq/docs/resources/extension/extension.ex b/lib/ash_hq/docs/resources/extension/extension.ex index f314e64..e2900f9 100644 --- a/lib/ash_hq/docs/resources/extension/extension.ex +++ b/lib/ash_hq/docs/resources/extension/extension.ex @@ -1,6 +1,15 @@ defmodule AshHq.Docs.Extension do use AshHq.Resource, - data_layer: AshPostgres.DataLayer + data_layer: AshPostgres.DataLayer, + extensions: [AshHq.Docs.Extensions.Search, AshHq.Docs.Extensions.RenderMarkdown] + + render_markdown do + render_attributes doc: :html_doc + end + + # search :load_for_search do + + # end postgres do table "extensions" @@ -50,6 +59,13 @@ defmodule AshHq.Docs.Extension do attribute :doc, :string do allow_nil? false + constraints trim?: false, allow_empty?: true + default "" + end + + attribute :doc_html, :string do + constraints trim?: false, allow_empty?: true + writable? false end attribute :type, :string do diff --git a/lib/ash_hq_web/components/doc_sidebar.ex b/lib/ash_hq_web/components/doc_sidebar.ex new file mode 100644 index 0000000..f0c7fba --- /dev/null +++ b/lib/ash_hq_web/components/doc_sidebar.ex @@ -0,0 +1,148 @@ +defmodule AshHqWeb.Components.DocSidebar do + use Surface.Component + + alias AshHqWeb.Routes + alias Surface.Components.LiveRedirect + + prop class, :css_class, default: "" + prop libraries, :list, required: true + prop extension, :any, default: nil + prop guide, :any, default: nil + prop library, :any, default: nil + prop library_version, :any, default: nil + prop selected_versions, :map, default: %{} + prop id, :string, required: true + + def render(assigns) do + ~F""" + + """ + end + + def render_icon(assigns, "Resource") do + ~F""" + + """ + end + + def render_icon(assigns, "Api") do + ~F""" + + """ + end + + def render_icon(assigns, "DataLayer") do + ~F""" + + """ + end + + def render_icon(assigns, "Flow") do + ~F""" + + """ + end + + def render_icon(assigns, "Notifier") do + ~F""" + + """ + end + + def render_icon(assigns, "Registry") do + ~F""" + + """ + end + + def render_icon(assigns, _) do + ~F""" + + """ + end + + defp selected_version_name(library, selected_versions) do + case Enum.find(library.versions, &(&1.id == selected_versions[library.id])) do + nil -> + nil + + version -> + version.version + end + end + + defp get_extensions(library, selected_versions) do + case Enum.find(library.versions, &(&1.id == selected_versions[library.id])) do + nil -> + [] + + version -> + version.extensions + end + end +end diff --git a/lib/ash_hq_web/components/search.ex b/lib/ash_hq_web/components/search.ex index e57e2a3..17e005a 100644 --- a/lib/ash_hq_web/components/search.ex +++ b/lib/ash_hq_web/components/search.ex @@ -23,7 +23,7 @@ defmodule AshHqWeb.Components.Search do