From 8b6fef83e2f7a63b184edf5d3be79e50fe0da906 Mon Sep 17 00:00:00 2001 From: "byte[]" Date: Thu, 5 Dec 2019 16:57:59 -0500 Subject: [PATCH] better tag info row --- .../controllers/activity_controller.ex | 6 +- .../controllers/api/json/search_controller.ex | 2 +- .../controllers/gallery_controller.ex | 2 +- .../controllers/image_controller.ex | 2 +- .../controllers/profile_controller.ex | 4 +- .../controllers/search_controller.ex | 4 +- .../controllers/tag_controller.ex | 4 +- lib/philomena_web/image_loader.ex | 66 +++++++++++++++---- .../templates/image/index.html.slime | 3 + .../templates/search/index.html.slime | 2 +- .../templates/tag/_tags_row.html.slime | 3 + .../templates/tag/show.html.slime | 5 +- lib/philomena_web/views/image_view.ex | 8 +++ lib/philomena_web/views/tag_view.ex | 5 ++ 14 files changed, 90 insertions(+), 26 deletions(-) create mode 100644 lib/philomena_web/templates/tag/_tags_row.html.slime diff --git a/lib/philomena_web/controllers/activity_controller.ex b/lib/philomena_web/controllers/activity_controller.ex index 996825c5..665d9317 100644 --- a/lib/philomena_web/controllers/activity_controller.ex +++ b/lib/philomena_web/controllers/activity_controller.ex @@ -10,14 +10,14 @@ defmodule PhilomenaWeb.ActivityController do def index(conn, _params) do user = conn.assigns.current_user - {:ok, images} = + {:ok, {images, _tags}} = ImageLoader.search_string( conn, "created_at.lte:3 minutes ago", pagination: %{conn.assigns.image_pagination | page_number: 1} ) - top_scoring = + {top_scoring, _tags} = ImageLoader.query( conn, %{range: %{first_seen_at: %{gt: "now-3d"}}}, @@ -46,7 +46,7 @@ defmodule PhilomenaWeb.ActivityController do ) watched = if !!user do - {:ok, watched_images} = + {:ok, {watched_images, _tags}} = ImageLoader.search_string( conn, "my:watched", diff --git a/lib/philomena_web/controllers/api/json/search_controller.ex b/lib/philomena_web/controllers/api/json/search_controller.ex index adf0eea7..12c44fe9 100644 --- a/lib/philomena_web/controllers/api/json/search_controller.ex +++ b/lib/philomena_web/controllers/api/json/search_controller.ex @@ -14,7 +14,7 @@ defmodule PhilomenaWeb.Api.Json.SearchController do sort = ImageSorter.parse_sort(params) case ImageLoader.search_string(conn, params["q"], sorts: sort.sorts, queries: sort.queries, queryable: queryable) do - {:ok, images} -> + {:ok, {images, _tags}} -> interactions = Interactions.user_interactions(images, user) diff --git a/lib/philomena_web/controllers/gallery_controller.ex b/lib/philomena_web/controllers/gallery_controller.ex index 71739234..a79c2ba4 100644 --- a/lib/philomena_web/controllers/gallery_controller.ex +++ b/lib/philomena_web/controllers/gallery_controller.ex @@ -37,7 +37,7 @@ defmodule PhilomenaWeb.GalleryController do params = Map.put(conn.params, "q", query) sort = ImageSorter.parse_sort(%{"sf" => "gallery_id:#{gallery.id}", "sd" => position_order(gallery)}) - {:ok, images} = ImageLoader.search_string(conn, query, queries: sort.queries, sorts: sort.sorts) + {:ok, {images, _tags}} = ImageLoader.search_string(conn, query, queries: sort.queries, sorts: sort.sorts) interactions = Interactions.user_interactions(images, user) watching = Galleries.subscribed?(gallery, user) diff --git a/lib/philomena_web/controllers/image_controller.ex b/lib/philomena_web/controllers/image_controller.ex index 87a95246..b64b29d7 100644 --- a/lib/philomena_web/controllers/image_controller.ex +++ b/lib/philomena_web/controllers/image_controller.ex @@ -21,7 +21,7 @@ defmodule PhilomenaWeb.ImageController do plug PhilomenaWeb.AdvertPlug when action in [:show] def index(conn, _params) do - images = ImageLoader.query(conn, %{match_all: %{}}) + {images, _tags} = ImageLoader.query(conn, %{match_all: %{}}) interactions = Interactions.user_interactions(images, conn.assigns.current_user) diff --git a/lib/philomena_web/controllers/profile_controller.ex b/lib/philomena_web/controllers/profile_controller.ex index 5f24ecbe..7162f49c 100644 --- a/lib/philomena_web/controllers/profile_controller.ex +++ b/lib/philomena_web/controllers/profile_controller.ex @@ -18,14 +18,14 @@ defmodule PhilomenaWeb.ProfileController do current_user = conn.assigns.current_user user = conn.assigns.user - {:ok, recent_uploads} = + {:ok, {recent_uploads, _tags}} = ImageLoader.search_string( conn, "uploader_id:#{user.id}", pagination: %{page_number: 1, page_size: 6} ) - {:ok, recent_faves} = + {:ok, {recent_faves, _tags}} = ImageLoader.search_string( conn, "faved_by_id:#{user.id}", diff --git a/lib/philomena_web/controllers/search_controller.ex b/lib/philomena_web/controllers/search_controller.ex index c582f2b8..07bd656b 100644 --- a/lib/philomena_web/controllers/search_controller.ex +++ b/lib/philomena_web/controllers/search_controller.ex @@ -10,12 +10,12 @@ defmodule PhilomenaWeb.SearchController do sort = ImageSorter.parse_sort(params) case ImageLoader.search_string(conn, params["q"], sorts: sort.sorts, queries: sort.queries) do - {:ok, images} -> + {:ok, {images, tags}} -> interactions = Interactions.user_interactions(images, user) conn - |> render("index.html", images: images, search_query: params["q"], interactions: interactions, layout_class: "layout--wide") + |> render("index.html", images: images, tags: tags, search_query: params["q"], interactions: interactions, layout_class: "layout--wide") {:error, msg} -> render(conn, "index.html", images: [], error: msg, search_query: params["q"]) diff --git a/lib/philomena_web/controllers/tag_controller.ex b/lib/philomena_web/controllers/tag_controller.ex index dca8d326..2ba26d7f 100644 --- a/lib/philomena_web/controllers/tag_controller.ex +++ b/lib/philomena_web/controllers/tag_controller.ex @@ -39,7 +39,7 @@ defmodule PhilomenaWeb.TagController do |> preload([:aliases, :implied_tags, :implied_by_tags, :dnp_entries, public_links: :user]) |> Repo.one() - images = + {images, _tags} = ImageLoader.query(conn, %{term: %{"namespaced_tags.name" => tag.name}}) interactions = @@ -55,6 +55,8 @@ defmodule PhilomenaWeb.TagController do Enum.zip(dnp_bodies, tag.dnp_entries) search_query = escape_name(tag) + params = Map.put(conn.params, "q", search_query) + conn = Map.put(conn, :params, params) render( conn, diff --git a/lib/philomena_web/image_loader.ex b/lib/philomena_web/image_loader.ex index d19f48b4..acf1c34f 100644 --- a/lib/philomena_web/image_loader.ex +++ b/lib/philomena_web/image_loader.ex @@ -1,5 +1,8 @@ defmodule PhilomenaWeb.ImageLoader do alias Philomena.Images.{Image, Query} + alias Philomena.Textile.Renderer + alias Philomena.Tags.Tag + alias Philomena.Repo import Ecto.Query def search_string(conn, search_string, options \\ []) do @@ -23,19 +26,28 @@ defmodule PhilomenaWeb.ImageLoader do filter = conn.assigns.compiled_filter filters = create_filters(user, filter) - Image.search_records( - %{ - query: %{ - bool: %{ - must: List.flatten([body, sort_queries]), - must_not: filters - } + records = + Image.search_records( + %{ + query: %{ + bool: %{ + must: List.flatten([body, sort_queries]), + must_not: filters + } + }, + sort: sort_sorts }, - sort: sort_sorts - }, - pagination, - queryable - ) + pagination, + queryable + ) + + tags = + body + |> search_tag_names() + |> load_tags() + |> render_dnp_entries(conn) + + {records, tags} end defp create_filters(user, filter) do @@ -51,4 +63,34 @@ defmodule PhilomenaWeb.ImageLoader do defp maybe_custom_hide(filters, _user), do: filters + + # TODO: the search parser should try to optimize queries + defp search_tag_name(%{term: %{"namespaced_tags.name" => tag_name}}), do: [tag_name] + defp search_tag_name(_other_query), do: [] + + defp search_tag_names(%{bool: %{must: musts}}), do: Enum.flat_map(musts, &search_tag_name(&1)) + defp search_tag_names(%{bool: %{should: shoulds}}), do: Enum.flat_map(shoulds, &search_tag_name(&1)) + defp search_tag_names(%{term: %{"namespaced_tags.name" => tag_name}}), do: [tag_name] + defp search_tag_names(_other_query), do: [] + + defp load_tags([]), do: [] + defp load_tags(tags) do + Tag + |> join(:left, [t], at in Tag, on: t.id == at.aliased_tag_id) + |> where([t, at], t.name in ^tags or at.name in ^tags) + |> preload([:aliases, :implied_tags, :implied_by_tags, :dnp_entries, public_links: :user]) + |> Repo.all() + end + + defp render_dnp_entries([], _conn), do: [] + defp render_dnp_entries([tag], conn) do + dnp_bodies = + Renderer.render_collection(Enum.map(tag.dnp_entries, &%{body: &1.conditions || ""}), conn) + + dnp_entries = + Enum.zip(dnp_bodies, tag.dnp_entries) + + [{tag, dnp_entries}] + end + defp render_dnp_entries(tags, _conn), do: tags end \ No newline at end of file diff --git a/lib/philomena_web/templates/image/index.html.slime b/lib/philomena_web/templates/image/index.html.slime index 73274bd4..b9bad496 100644 --- a/lib/philomena_web/templates/image/index.html.slime +++ b/lib/philomena_web/templates/image/index.html.slime @@ -2,6 +2,7 @@ elixir: header = assigns[:header] || "" params = assigns[:params] || assigns[:scope] || [] scope = assigns[:scope] || [] + tags = assigns[:tags] || [] route = assigns[:route] || fn p -> Routes.image_path(@conn, :index, p) end image_url = fn image -> Routes.image_path(@conn, :show, image, scope) end pagination = render PhilomenaWeb.PaginationView, "_pagination.html", page: @images, route: route, params: params @@ -13,6 +14,8 @@ elixir: => header = pagination + = info_row @conn, tags + .block__content.js-resizable-media-container = for image <- @images do = render PhilomenaWeb.ImageView, "_image_box.html", image: image, link: image_url.(image), size: assigns[:size] || :thumb, conn: @conn diff --git a/lib/philomena_web/templates/search/index.html.slime b/lib/philomena_web/templates/search/index.html.slime index 5ed08e72..0a965648 100644 --- a/lib/philomena_web/templates/search/index.html.slime +++ b/lib/philomena_web/templates/search/index.html.slime @@ -1,6 +1,6 @@ = cond do - Enum.any?(@images) -> - = render PhilomenaWeb.ImageView, "index.html", conn: @conn, images: @images, route: fn p -> Routes.search_path(@conn, :index, p) end, scope: scope(@conn) + = render PhilomenaWeb.ImageView, "index.html", conn: @conn, tags: @tags, images: @images, route: fn p -> Routes.search_path(@conn, :index, p) end, scope: scope(@conn) - assigns[:error] -> p ' Oops, there was an error evaluating your query: diff --git a/lib/philomena_web/templates/tag/_tags_row.html.slime b/lib/philomena_web/templates/tag/_tags_row.html.slime new file mode 100644 index 00000000..1d32520a --- /dev/null +++ b/lib/philomena_web/templates/tag/_tags_row.html.slime @@ -0,0 +1,3 @@ +.block__content.js-imagelist-info.flex class=tags_row_class(@conn) + .flex__grow + = render PhilomenaWeb.TagView, "_tag_list.html", tags: @tags, conn: @conn \ No newline at end of file diff --git a/lib/philomena_web/templates/tag/show.html.slime b/lib/philomena_web/templates/tag/show.html.slime index 210a405c..8fa78b65 100644 --- a/lib/philomena_web/templates/tag/show.html.slime +++ b/lib/philomena_web/templates/tag/show.html.slime @@ -1,2 +1,3 @@ -= render PhilomenaWeb.TagView, "_tag_info_row.html", tag: @tag, body: @body, dnp_entries: @dnp_entries, conn: @conn -= render PhilomenaWeb.ImageView, "index.html", conn: @conn, images: @images, scope: [q: @search_query] \ No newline at end of file += render PhilomenaWeb.ImageView, "index.html", conn: @conn, tags: [{@tag, @dnp_entries}], images: @images, scope: [q: @search_query] + += render PhilomenaWeb.SearchView, "_form.html", conn: @conn \ No newline at end of file diff --git a/lib/philomena_web/views/image_view.ex b/lib/philomena_web/views/image_view.ex index 0a9c136d..528e3961 100644 --- a/lib/philomena_web/views/image_view.ex +++ b/lib/philomena_web/views/image_view.ex @@ -136,6 +136,14 @@ defmodule PhilomenaWeb.ImageView do conn.assigns.current_user.anonymous_by_default end + def info_row(_conn, []), do: [] + def info_row(conn, [{tag, dnp_entries}]) do + render PhilomenaWeb.TagView, "_tag_info_row.html", conn: conn, tag: tag, dnp_entries: dnp_entries + end + def info_row(conn, tags) do + render PhilomenaWeb.TagView, "_tags_row.html", conn: conn, tags: tags + end + defp thumb_format("svg", _name), do: "png" defp thumb_format(_, :rendered), do: "png" defp thumb_format(format, _name), do: format diff --git a/lib/philomena_web/views/tag_view.ex b/lib/philomena_web/views/tag_view.ex index 077445d8..b84ad2c0 100644 --- a/lib/philomena_web/views/tag_view.ex +++ b/lib/philomena_web/views/tag_view.ex @@ -41,6 +41,11 @@ defmodule PhilomenaWeb.TagView do link tag_name, to: "#", title: title, data: [tag_name: tag_name, click_addtag: tag_name] end + def tags_row_class(%{params: %{"page" => "0"}}), do: nil + def tags_row_class(%{params: %{"page" => "1"}}), do: nil + def tags_row_class(%{params: %{"page" => _page}}), do: "hidden" + def tags_row_class(_conn), do: nil + defp implications(%{implied_tags: []}), do: [] defp implications(%{implied_tags: it}) do names =