2020-05-08 04:10:54 +02:00
|
|
|
defmodule PhilomenaWeb.ImageNavigator do
|
|
|
|
alias PhilomenaWeb.ImageSorter
|
2020-08-13 17:32:35 +02:00
|
|
|
alias Philomena.Images.Image
|
2024-05-25 20:03:45 +02:00
|
|
|
alias PhilomenaQuery.Search
|
2019-11-30 03:33:15 +01:00
|
|
|
|
|
|
|
@order_for_dir %{
|
2020-08-13 17:32:35 +02:00
|
|
|
"next" => %{"asc" => "asc", "desc" => "desc"},
|
|
|
|
"prev" => %{"asc" => "desc", "desc" => "asc"}
|
2019-11-30 03:33:15 +01:00
|
|
|
}
|
|
|
|
|
2020-08-13 17:32:35 +02:00
|
|
|
def find_consecutive(conn, image, compiled_query, compiled_filter) do
|
2022-03-25 17:02:19 +01:00
|
|
|
conn = update_in(conn.params, &Map.put_new(&1, "sf", "id"))
|
|
|
|
|
2020-08-13 17:32:35 +02:00
|
|
|
%{query: compiled_query, sorts: sorts} = ImageSorter.parse_sort(conn.params, compiled_query)
|
2019-11-30 03:33:15 +01:00
|
|
|
|
2020-08-13 17:32:35 +02:00
|
|
|
sorts =
|
|
|
|
sorts
|
|
|
|
|> Enum.flat_map(&Enum.to_list/1)
|
|
|
|
|> Enum.map(&apply_direction(&1, conn.params["rel"]))
|
2019-11-30 03:33:15 +01:00
|
|
|
|
2020-08-13 17:32:35 +02:00
|
|
|
search_after =
|
|
|
|
conn.params["sort"]
|
|
|
|
|> permit_list()
|
|
|
|
|> Enum.flat_map(&permit_value/1)
|
|
|
|
|> default_value(image.id)
|
2019-11-30 03:33:15 +01:00
|
|
|
|
2020-08-13 17:32:35 +02:00
|
|
|
maybe_search_after(
|
2019-12-24 22:14:42 +01:00
|
|
|
Image,
|
2019-11-30 03:33:15 +01:00
|
|
|
%{
|
|
|
|
query: %{
|
|
|
|
bool: %{
|
2020-08-13 17:32:35 +02:00
|
|
|
must: compiled_query,
|
2019-11-30 03:33:15 +01:00
|
|
|
must_not: [
|
|
|
|
compiled_filter,
|
2020-05-08 05:58:21 +02:00
|
|
|
%{term: %{hidden_from_users: true}},
|
2020-08-13 17:32:35 +02:00
|
|
|
%{term: %{id: image.id}},
|
2020-05-08 05:58:21 +02:00
|
|
|
hidden_filter(conn.assigns.current_user, conn.params["hidden"])
|
2019-11-30 03:33:15 +01:00
|
|
|
]
|
|
|
|
}
|
|
|
|
},
|
2020-08-13 17:32:35 +02:00
|
|
|
sort: sorts,
|
|
|
|
search_after: search_after
|
2019-11-30 03:33:15 +01:00
|
|
|
},
|
2019-12-24 22:44:58 +01:00
|
|
|
%{page_size: 1},
|
2020-08-13 17:32:35 +02:00
|
|
|
Image,
|
|
|
|
length(sorts) == length(search_after)
|
2019-11-30 03:33:15 +01:00
|
|
|
)
|
|
|
|
|> Enum.to_list()
|
|
|
|
|> case do
|
2020-08-13 17:32:35 +02:00
|
|
|
[] -> nil
|
2019-11-30 03:33:15 +01:00
|
|
|
[next_image] -> next_image
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-08-13 17:32:35 +02:00
|
|
|
defp maybe_search_after(module, body, options, queryable, true) do
|
2020-08-23 21:47:42 +02:00
|
|
|
module
|
2024-05-25 20:03:45 +02:00
|
|
|
|> Search.search_definition(body, options)
|
|
|
|
|> Search.search_records_with_hits(queryable)
|
2019-11-30 03:33:15 +01:00
|
|
|
end
|
|
|
|
|
2020-08-13 17:32:35 +02:00
|
|
|
defp maybe_search_after(_module, _body, _options, _queryable, _false) do
|
|
|
|
[]
|
|
|
|
end
|
2019-11-30 03:33:15 +01:00
|
|
|
|
2020-08-13 17:32:35 +02:00
|
|
|
defp apply_direction({"galleries.position", sort_body}, rel) do
|
|
|
|
sort_body = update_in(sort_body.order, fn direction -> @order_for_dir[rel][direction] end)
|
2019-11-30 03:33:15 +01:00
|
|
|
|
2020-08-13 17:32:35 +02:00
|
|
|
%{"galleries.position" => sort_body}
|
2019-11-30 03:33:15 +01:00
|
|
|
end
|
|
|
|
|
2020-08-13 17:32:35 +02:00
|
|
|
defp apply_direction({field, direction}, rel) do
|
|
|
|
%{field => @order_for_dir[rel][direction]}
|
2019-11-30 03:33:15 +01:00
|
|
|
end
|
|
|
|
|
2020-08-13 17:32:35 +02:00
|
|
|
defp permit_list(value) when is_list(value), do: value
|
|
|
|
defp permit_list(_value), do: []
|
2019-11-30 03:33:15 +01:00
|
|
|
|
2020-08-13 17:32:35 +02:00
|
|
|
defp permit_value(value) when is_binary(value) or is_number(value), do: [value]
|
|
|
|
defp permit_value(_value), do: []
|
2020-01-11 05:20:19 +01:00
|
|
|
|
2020-08-13 17:32:35 +02:00
|
|
|
defp default_value([], term), do: [term]
|
|
|
|
defp default_value(list, _term), do: list
|
2019-11-30 03:33:15 +01:00
|
|
|
|
2020-05-08 05:58:21 +02:00
|
|
|
defp hidden_filter(%{id: id}, param) when param != "1", do: %{term: %{hidden_by_user_ids: id}}
|
|
|
|
defp hidden_filter(_user, _param), do: %{match_none: %{}}
|
2019-12-24 22:14:42 +01:00
|
|
|
end
|