diff --git a/lib/philomena_web/controllers/image/random_controller.ex b/lib/philomena_web/controllers/image/random_controller.ex new file mode 100644 index 00000000..8f776a46 --- /dev/null +++ b/lib/philomena_web/controllers/image/random_controller.ex @@ -0,0 +1,54 @@ +defmodule PhilomenaWeb.Image.RandomController do + use PhilomenaWeb, :controller + + alias Philomena.Images.Query + alias Philomena.Images.Image + alias Philomena.ImageSorter + + def index(conn, params) do + user = conn.assigns.current_user + filter = conn.assigns.compiled_filter + + scope = Philomena.ImageScope.scope(conn) + query = query(user, params) + random_id = random_image_id(query, filter) + + if random_id do + redirect(conn, to: Routes.image_path(conn, :show, random_id, scope)) + else + redirect(conn, external: conn.assigns.referrer) + end + end + + defp query(user, %{"q" => q}) do + {:ok, query} = Query.compile(user, q) + + query + end + defp query(_user, _), do: %{match_all: %{}} + + defp random_image_id(query, filter) do + sort = ImageSorter.parse_sort(%{"sf" => "random"}) + + Image.search_records( + %{ + query: %{ + bool: %{ + must: List.flatten([sort.queries, query]), + must_not: [ + filter, + %{term: %{hidden_from_users: true}} + ] + } + }, + sort: sort.sorts + }, + %{page_size: 1} + ) + |> Enum.to_list() + |> unwrap() + end + + defp unwrap([image]), do: image.id + defp unwrap([]), do: nil +end \ No newline at end of file diff --git a/lib/philomena_web/router.ex b/lib/philomena_web/router.ex index 65352504..60161b06 100644 --- a/lib/philomena_web/router.ex +++ b/lib/philomena_web/router.ex @@ -91,6 +91,7 @@ defmodule PhilomenaWeb.Router do resources "/activity", ActivityController, only: [:index] scope "/images", Image, as: :image do resources "/scrape", ScrapeController, only: [:create] + resources "/random", RandomController, only: [:index] end resources "/images", ImageController, only: [:index, :show, :new, :create] do resources "/comments", Image.CommentController, only: [:index, :show, :create] diff --git a/lib/philomena_web/templates/image/_image_meta.html.slime b/lib/philomena_web/templates/image/_image_meta.html.slime index b0c30d9d..44e7b8a3 100644 --- a/lib/philomena_web/templates/image/_image_meta.html.slime +++ b/lib/philomena_web/templates/image/_image_meta.html.slime @@ -7,7 +7,7 @@ i.fa.fa-chevron-up a.js-next href=Routes.image_navigate_path(@conn, :index, @image, [rel: "next"] ++ scope(@conn)) title="Next Image (k)" i.fa.fa-chevron-right - a.js-rand href="/" title="Random (r)" + a.js-rand href=Routes.image_random_path(@conn, :index, scope(@conn)) title="Random (r)" i.fa.fa-random .stretched-mobile-links a.interaction--fave href="#" rel="nofollow" data-image-id=@image.id diff --git a/lib/philomena_web/templates/layout/_header_navigation.html.slime b/lib/philomena_web/templates/layout/_header_navigation.html.slime index 4e96d206..02217c8e 100644 --- a/lib/philomena_web/templates/layout/_header_navigation.html.slime +++ b/lib/philomena_web/templates/layout/_header_navigation.html.slime @@ -1,6 +1,12 @@ .hide-mobile - a.header__link href="/images" - | Images + .dropdown.header__dropdown + a.header__link href="/images" + | Images + span data-click-preventdefault="true" + i.fa.fa-caret-down< + .dropdown__content + a.header__link href="/images/random" + | Random .dropdown.header__dropdown a.header__link href="/activity" | Activity