diff --git a/lib/philomena/users/user.ex b/lib/philomena/users/user.ex index 654b4e4f..e3eea07f 100644 --- a/lib/philomena/users/user.ex +++ b/lib/philomena/users/user.ex @@ -201,7 +201,7 @@ defmodule Philomena.Users.User do :fancy_tag_field_on_edit, :anonymous_by_default, :scale_large_images, :comments_per_page, :theme, :watched_images_query_str, :no_spoilered_in_watched, :watched_images_exclude_str, - :use_centered_layout, :hide_vote_counts + :use_centered_layout, :hide_vote_counts, :comments_newest_first ]) |> validate_required([ :images_per_page, :fancy_tag_field_on_upload, :fancy_tag_field_on_edit, diff --git a/lib/philomena_web/comment_loader.ex b/lib/philomena_web/comment_loader.ex new file mode 100644 index 00000000..66f4fd86 --- /dev/null +++ b/lib/philomena_web/comment_loader.ex @@ -0,0 +1,46 @@ +defmodule PhilomenaWeb.CommentLoader do + alias Philomena.Comments.Comment + alias Philomena.Repo + import Ecto.Query + + def load_comments(conn, image) do + pref = load_direction(conn.assigns.current_user) + + Comment + |> where(image_id: ^image.id) + |> order_by([{^pref, :created_at}]) + |> preload([:image, :deleted_by, user: [awards: :badge]]) + |> Repo.paginate(conn.assigns.comment_scrivener) + end + + def find_page(conn, image, comment_id) do + user = conn.assigns.current_user + + comment = + Comment + |> where(image_id: ^image.id) + |> where(id: ^comment_id) + |> Repo.one!() + + offset = + Comment + |> where(image_id: ^image.id) + |> filter_direction(comment.created_at, user) + |> Repo.aggregate(:count, :id) + |> IO.inspect() + + page_size = conn.assigns.comment_scrivener[:page_size] + + # Pagination starts at page 1 + div(offset, page_size) + 1 + end + + defp load_direction(%{comments_newest_first: false}), do: :asc + defp load_direction(_user), do: :desc + + defp filter_direction(query, time, %{comments_newest_first: false}), + do: where(query, [c], c.created_at <= ^time) + + defp filter_direction(query, time, _user), + do: where(query, [c], c.created_at >= ^time) +end diff --git a/lib/philomena_web/controllers/image/comment_controller.ex b/lib/philomena_web/controllers/image/comment_controller.ex index 4f9de241..665d2d63 100644 --- a/lib/philomena_web/controllers/image/comment_controller.ex +++ b/lib/philomena_web/controllers/image/comment_controller.ex @@ -1,6 +1,7 @@ defmodule PhilomenaWeb.Image.CommentController do use PhilomenaWeb, :controller + alias PhilomenaWeb.CommentLoader alias Philomena.{Images.Image, Comments.Comment, Textile.Renderer} alias Philomena.UserStatistics alias Philomena.Comments @@ -20,36 +21,15 @@ defmodule PhilomenaWeb.Image.CommentController do plug :authorize_resource, model: Comment, only: [:show, :edit, :update], preload: [:image, user: [awards: :badge]] def index(conn, %{"comment_id" => comment_id}) do - comment = - Comment - |> where(image_id: ^conn.assigns.image.id) - |> where(id: ^comment_id) - |> Repo.one!() + page = CommentLoader.find_page(conn, conn.assigns.image, comment_id) - offset = - Comment - |> where(image_id: ^conn.assigns.image.id) - |> where([c], c.created_at > ^comment.created_at) - |> Repo.aggregate(:count, :id) - - %{page_size: page_size} = conn.assigns.pagination - page = div(offset, page_size) - - conn - |> redirect(to: Routes.image_comment_path(conn, :index, conn.assigns.image, page: page)) + redirect(conn, to: Routes.image_comment_path(conn, :index, conn.assigns.image, page: page)) end def index(conn, _params) do - comments = - Comment - |> where(image_id: ^conn.assigns.image.id) - |> order_by(desc: :created_at) - |> preload([:image, user: [awards: :badge]]) - |> Repo.paginate(conn.assigns.comment_scrivener) + comments = CommentLoader.load_comments(conn, conn.assigns.image) - rendered = - comments.entries - |> Renderer.render_collection(conn) + rendered = Renderer.render_collection(comments.entries, conn) comments = %{comments | entries: Enum.zip(comments.entries, rendered)} diff --git a/lib/philomena_web/controllers/image_controller.ex b/lib/philomena_web/controllers/image_controller.ex index eb94676c..642738a0 100644 --- a/lib/philomena_web/controllers/image_controller.ex +++ b/lib/philomena_web/controllers/image_controller.ex @@ -2,6 +2,7 @@ defmodule PhilomenaWeb.ImageController do use PhilomenaWeb, :controller alias PhilomenaWeb.ImageLoader + alias PhilomenaWeb.CommentLoader alias PhilomenaWeb.NotificationCountPlug alias Philomena.{Images, Images.Image, Comments.Comment, Galleries.Gallery, Galleries.Interaction, Textile.Renderer} alias Philomena.Servers.ImageProcessor @@ -38,17 +39,9 @@ defmodule PhilomenaWeb.ImageController do # Update the notification ticker in the header conn = NotificationCountPlug.call(conn) - comments = - Comment - |> where(image_id: ^image.id) - |> preload([:image, :deleted_by, user: [awards: :badge]]) - |> order_by(desc: :created_at) - |> limit(25) - |> Repo.paginate(conn.assigns.comment_scrivener) + comments = CommentLoader.load_comments(conn, image) - rendered = - comments.entries - |> Renderer.render_collection(conn) + rendered = Renderer.render_collection(comments.entries, conn) comments = %{comments | entries: Enum.zip(comments.entries, rendered)} diff --git a/lib/philomena_web/controllers/profile_controller.ex b/lib/philomena_web/controllers/profile_controller.ex index c160b5bd..a563f56c 100644 --- a/lib/philomena_web/controllers/profile_controller.ex +++ b/lib/philomena_web/controllers/profile_controller.ex @@ -33,14 +33,14 @@ defmodule PhilomenaWeb.ProfileController do ImageLoader.search_string( conn, "uploader_id:#{user.id}", - pagination: %{page_number: 1, page_size: 6} + pagination: %{page_number: 1, page_size: 8} ) {:ok, {recent_faves, _tags}} = ImageLoader.search_string( conn, "faved_by_id:#{user.id}", - pagination: %{page_number: 1, page_size: 6} + pagination: %{page_number: 1, page_size: 8} ) tags = tags(conn.assigns.user.public_links) @@ -195,7 +195,7 @@ defmodule PhilomenaWeb.ProfileController do ImageLoader.query( conn, %{terms: %{tag_ids: Enum.map(tags, & &1.id)}}, - pagination: %{page_number: 1, page_size: 6} + pagination: %{page_number: 1, page_size: 8} ) images diff --git a/lib/philomena_web/templates/image/show.html.slime b/lib/philomena_web/templates/image/show.html.slime index 476dd745..631563dd 100644 --- a/lib/philomena_web/templates/image/show.html.slime +++ b/lib/philomena_web/templates/image/show.html.slime @@ -23,5 +23,5 @@ - true -> - #comments data-current-url=Routes.image_comment_path(@conn, :index, @image, page: 1) data-loaded="true" + #comments data-current-url=Routes.image_comment_path(@conn, :index, @image) data-loaded="true" = render PhilomenaWeb.Image.CommentView, "index.html", image: @image, comments: @comments, conn: @conn diff --git a/lib/philomena_web/templates/setting/edit.html.slime b/lib/philomena_web/templates/setting/edit.html.slime index 6f548d61..ee5c9795 100644 --- a/lib/philomena_web/templates/setting/edit.html.slime +++ b/lib/philomena_web/templates/setting/edit.html.slime @@ -59,6 +59,10 @@ h1 Content Settings => label f, :hide_vote_counts => checkbox f, :hide_vote_counts, class: "checkbox" .fieldlabel: i Hide upvote and downvote counts on images, showing only the overall score + .field + => label f, :comments_newest_first, "Newest comments first" + => checkbox f, :comments_newest_first + .fieldlabel: i Display the newest comments at the top of the page. .field => label f, :images_per_page => number_input f, :images_per_page, min: 15, max: 50, step: 1, class: "input" @@ -129,4 +133,4 @@ h1 Content Settings br = submit "Save My Settings", class: "button" - br \ No newline at end of file + br