Search v1 (#19)
* Adds description to media items; hooks it up to indexing/media downloading * Added a search method using postgres fulltext search * Hooked up search functionality to the search form * Added persistence to the search form when on search page
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
defmodule PinchflatWeb.Searches.SearchController do
|
||||
use PinchflatWeb, :controller
|
||||
|
||||
alias Pinchflat.Media
|
||||
|
||||
def show(conn, params) do
|
||||
search_term = Map.get(params, "q", "")
|
||||
search_results = Media.search(search_term)
|
||||
|
||||
render(conn, :show, search_term: search_term, search_results: search_results)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,25 @@
|
||||
defmodule PinchflatWeb.Searches.SearchHTML do
|
||||
use PinchflatWeb, :html
|
||||
|
||||
embed_templates "search_html/*"
|
||||
|
||||
@doc """
|
||||
Highlight search terms in a string of text based on `[PF_HIGHLIGHT]` and `[/PF_HIGHLIGHT]` tags
|
||||
"""
|
||||
attr :text, :string, required: true
|
||||
|
||||
def highlight_search_terms(assigns) do
|
||||
split_string = String.split(assigns.text, ~r{\[PF_HIGHLIGHT\]|\[/PF_HIGHLIGHT\]}, include_captures: true)
|
||||
assigns = assign(assigns, split_string: split_string)
|
||||
|
||||
~H"""
|
||||
<%= for fragment <- @split_string do %>
|
||||
<%= render_fragment(fragment) %>
|
||||
<% end %>
|
||||
"""
|
||||
end
|
||||
|
||||
defp render_fragment("[PF_HIGHLIGHT]"), do: raw(~s(<span class="font-bold italic">))
|
||||
defp render_fragment("[/PF_HIGHLIGHT]"), do: raw("</span>")
|
||||
defp render_fragment(text), do: text
|
||||
end
|
||||
@@ -0,0 +1,29 @@
|
||||
<div class="mb-6 flex gap-3 flex-row items-center justify-between">
|
||||
<h2 class="text-title-md2 font-bold text-black dark:text-white">
|
||||
<span class="hidden sm:inline">Search </span>Results for "<%= StringUtils.truncate(@search_term, 50) %>"
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div class="rounded-sm border border-stroke bg-white px-5 py-5 shadow-default dark:border-strokedark dark:bg-boxdark sm:px-7.5">
|
||||
<div class="max-w-full overflow-x-auto">
|
||||
<div class="flex flex-col gap-10 dark:text-white">
|
||||
<%= if match?([_|_], @search_results) do %>
|
||||
<.table rows={@search_results} table_class="text-black dark:text-white">
|
||||
<:col :let={result} label="Title">
|
||||
<%= StringUtils.truncate(result.title, 40) %>
|
||||
</:col>
|
||||
<:col :let={result} label="Excerpt">
|
||||
<.highlight_search_terms text={result.matching_search_term} />
|
||||
</:col>
|
||||
<:col :let={result} label="" class="flex place-content-evenly">
|
||||
<.link navigate={~p"/media/#{result.id}"} class="hover:text-secondary duration-200 ease-in-out mx-0.5">
|
||||
<.icon name="hero-eye" />
|
||||
</.link>
|
||||
</:col>
|
||||
</.table>
|
||||
<% else %>
|
||||
<p class="font-bold text-lg text-center text-black dark:text-white">No results found</p>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user