From 4e5a29e6fb51b8b455c6723a5201b955ff4ae62f Mon Sep 17 00:00:00 2001 From: Luna D Date: Wed, 11 Dec 2019 18:58:00 -0500 Subject: [PATCH] post hiding, destroying, and a few fixes --- assets/css/common/global.scss | 2 +- assets/css/themes/dark.scss | 2 +- assets/css/themes/red.scss | 2 +- assets/css/views/comments.scss | 4 -- assets/css/views/communications.scss | 4 ++ lib/philomena/posts.ex | 18 ++++++ lib/philomena/posts/post.ex | 20 +++++++ .../topic/post/delete_controller.ex | 26 +++++++++ .../controllers/topic/post/hide_controller.ex | 44 ++++++++++++++ .../controllers/topic_controller.ex | 2 +- lib/philomena_web/router.ex | 5 +- .../templates/comment/_comment.html.slime | 6 +- .../comment/_comment_with_image.html.slime | 6 +- .../templates/post/_post.html.slime | 57 ++++++++++--------- .../templates/topic/show.html.slime | 2 +- lib/philomena_web/views/app_view.ex | 3 + lib/philomena_web/views/comment_view.ex | 3 - 17 files changed, 160 insertions(+), 46 deletions(-) create mode 100644 lib/philomena_web/controllers/topic/post/delete_controller.ex create mode 100644 lib/philomena_web/controllers/topic/post/hide_controller.ex diff --git a/assets/css/common/global.scss b/assets/css/common/global.scss index 60dd870c..b33377bd 100644 --- a/assets/css/common/global.scss +++ b/assets/css/common/global.scss @@ -30,7 +30,7 @@ $vote_up_color: #67af2b !default; $vote_down_color: #cf0001 !default; $hide_color: #cf0001 !default; -$destroyed_comment_color: #ffdcdc !default; +$destroyed_content_color: #ffdcdc !default; $assistant_color: #eeceed !default; diff --git a/assets/css/themes/dark.scss b/assets/css/themes/dark.scss index 0bd705aa..f1017115 100644 --- a/assets/css/themes/dark.scss +++ b/assets/css/themes/dark.scss @@ -17,7 +17,7 @@ $success_light_color: #144714 !default; $danger_light_color: #66211f !default; $warning_light_color: #7d4825 !default; -$destroyed_comment_color: #382c2f !default; +$destroyed_content_color: #382c2f !default; $meta_color: #191f2a !default; diff --git a/assets/css/themes/red.scss b/assets/css/themes/red.scss index bb672a6d..b3c7d138 100644 --- a/assets/css/themes/red.scss +++ b/assets/css/themes/red.scss @@ -22,7 +22,7 @@ $success_light_color: #2e4e2e !default; $danger_light_color: #7b3b00 !default; $warning_light_color: #5b5b00 !default; -$destroyed_comment_color: #412f2f !default; +$destroyed_content_color: #412f2f !default; $meta_color: #411d1d !default; diff --git a/assets/css/views/comments.scss b/assets/css/views/comments.scss index f2739171..e9f854a9 100644 --- a/assets/css/views/comments.scss +++ b/assets/css/views/comments.scss @@ -7,10 +7,6 @@ color: $vote_down_color; } -.comment--destroyed { - background-color: $destroyed_comment_color; -} - .comment_under_review { color: blue; } diff --git a/assets/css/views/communications.scss b/assets/css/views/communications.scss index d0a3b512..5809534f 100644 --- a/assets/css/views/communications.scss +++ b/assets/css/views/communications.scss @@ -97,3 +97,7 @@ span.communication__sender__stats, display: inline-block; margin-right: 2em; } + +.communication--destroyed { + background-color: $destroyed_content_color; +} diff --git a/lib/philomena/posts.ex b/lib/philomena/posts.ex index 2c39ca7c..35345ce7 100644 --- a/lib/philomena/posts.ex +++ b/lib/philomena/posts.ex @@ -160,6 +160,24 @@ defmodule Philomena.Posts do Repo.delete(post) end + def hide_post(%Post{} = post, attrs, user) do + post + |> Post.hide_changeset(attrs, user) + |> Repo.update() + end + + def unhide_post(%Post{} = post) do + post + |> Post.unhide_changeset() + |> Repo.update() + end + + def destroy_post(%Post{} = post) do + post + |> Post.destroy_changeset() + |> Repo.update() + end + @doc """ Returns an `%Ecto.Changeset{}` for tracking post changes. diff --git a/lib/philomena/posts/post.ex b/lib/philomena/posts/post.ex index 393906e7..f2df618d 100644 --- a/lib/philomena/posts/post.ex +++ b/lib/philomena/posts/post.ex @@ -64,6 +64,26 @@ defmodule Philomena.Posts.Post do |> put_name_at_post_time(attribution[:user]) end + def hide_changeset(post, attrs, user) do + post + |> cast(attrs, [:deletion_reason]) + |> put_change(:hidden_from_users, true) + |> put_change(:deleted_by_id, user.id) + |> validate_required([:deletion_reason]) + end + + def unhide_changeset(post) do + change(post) + |> put_change(:hidden_from_users, false) + |> put_change(:deletion_reason, "") + end + + def destroy_changeset(post) do + change(post) + |> put_change(:destroyed_content, true) + |> put_change(:body, "") + end + defp put_name_at_post_time(changeset, nil), do: changeset defp put_name_at_post_time(changeset, user), do: change(changeset, name_at_post_time: user.name) end diff --git a/lib/philomena_web/controllers/topic/post/delete_controller.ex b/lib/philomena_web/controllers/topic/post/delete_controller.ex new file mode 100644 index 00000000..64334018 --- /dev/null +++ b/lib/philomena_web/controllers/topic/post/delete_controller.ex @@ -0,0 +1,26 @@ +defmodule PhilomenaWeb.Topic.Post.DeleteController do + use PhilomenaWeb, :controller + + alias Philomena.Posts.Post + alias Philomena.Posts + + plug PhilomenaWeb.CanaryMapPlug, create: :hide, delete: :hide + plug :load_and_authorize_resource, model: Post, id_name: "post_id", persisted: true, preload: [:topic] + + def delete(conn, _params) do + post = conn.assigns.post + + case Posts.destroy_post(post) do + {:ok, post} -> + Posts.reindex_post(post) + + conn + |> put_flash(:info, "Post successfully destroyed!") + |> redirect(to: Routes.forum_topic_path(conn, :show, post.topic.forum_id, post.topic_id) <> "#post_#{post.id}") + {:error, _changeset} -> + conn + |> put_flash(:error, "Unable to destroy post!") + |> redirect(to: Routes.forum_topic_path(conn, :show, post.topic.forum_id, post.topic_id) <> "#post_#{post.id}") + end + end +end diff --git a/lib/philomena_web/controllers/topic/post/hide_controller.ex b/lib/philomena_web/controllers/topic/post/hide_controller.ex new file mode 100644 index 00000000..11b9b193 --- /dev/null +++ b/lib/philomena_web/controllers/topic/post/hide_controller.ex @@ -0,0 +1,44 @@ +defmodule PhilomenaWeb.Topic.Post.HideController do + use PhilomenaWeb, :controller + + alias Philomena.Posts.Post + alias Philomena.Posts + + plug PhilomenaWeb.CanaryMapPlug, create: :hide, delete: :hide + plug :load_and_authorize_resource, model: Post, id_name: "post_id", persisted: true, preload: [:topic] + + def create(conn, %{"post" => post_params}) do + post = conn.assigns.post + user = conn.assigns.current_user + + case Posts.hide_post(post, post_params, user) do + {:ok, post} -> + Posts.reindex_post(post) + + conn + |> put_flash(:info, "Post successfully hidden!") + |> redirect(to: Routes.forum_topic_path(conn, :show, post.topic.forum_id, post.topic_id) <> "#post_#{post.id}") + {:error, _changeset} -> + conn + |> put_flash(:error, "Unable to hide post!") + |> redirect(to: Routes.forum_topic_path(conn, :show, post.topic.forum_id, post.topic_id) <> "#post_#{post.id}") + end + end + + def delete(conn, _params) do + post = conn.assigns.post + + case Posts.unhide_post(post) do + {:ok, post} -> + Posts.reindex_post(post) + + conn + |> put_flash(:info, "Post successfully unhidden!") + |> redirect(to: Routes.forum_topic_path(conn, :show, post.topic.forum_id, post.topic_id) <> "#post_#{post.id}") + {:error, _changeset} -> + conn + |> put_flash(:error, "Unable to unhide post!") + |> redirect(to: Routes.forum_topic_path(conn, :show, post.topic.forum_id, post.topic_id) <> "#post_#{post.id}") + end + end +end diff --git a/lib/philomena_web/controllers/topic_controller.ex b/lib/philomena_web/controllers/topic_controller.ex index ccb7949f..99083c6a 100644 --- a/lib/philomena_web/controllers/topic_controller.ex +++ b/lib/philomena_web/controllers/topic_controller.ex @@ -49,7 +49,7 @@ defmodule PhilomenaWeb.TopicController do |> where(topic_id: ^conn.assigns.topic.id) |> where([p], p.topic_position >= ^(25 * (page - 1)) and p.topic_position < ^(25 * page)) |> order_by(asc: :created_at) - |> preload([topic: :forum, user: [awards: :badge]]) + |> preload([:deleted_by, :topic, topic: :forum, user: [awards: :badge]]) |> Repo.all() rendered = diff --git a/lib/philomena_web/router.ex b/lib/philomena_web/router.ex index af886282..7eef54a1 100644 --- a/lib/philomena_web/router.ex +++ b/lib/philomena_web/router.ex @@ -126,7 +126,10 @@ defmodule PhilomenaWeb.Router do resources "/topics", TopicController, only: [:new, :create] do resources "/subscription", Topic.SubscriptionController, only: [:create, :delete], singleton: true resources "/read", Topic.ReadController, only: [:create], singleton: true - resources "/posts", Topic.PostController, only: [:edit, :update] + resources "/posts", Topic.PostController, only: [:edit, :update] do + resources "/hide", Topic.Post.HideController, only: [:create, :delete], singleton: true + resources "/delete", Topic.Post.DeleteController, only: [:delete], singleton: true + end end resources "/subscription", Forum.SubscriptionController, only: [:create, :delete], singleton: true diff --git a/lib/philomena_web/templates/comment/_comment.html.slime b/lib/philomena_web/templates/comment/_comment.html.slime index 859eec30..1b61f1b1 100644 --- a/lib/philomena_web/templates/comment/_comment.html.slime +++ b/lib/philomena_web/templates/comment/_comment.html.slime @@ -1,5 +1,5 @@ article.block.communication id="comment_#{@comment.id}" - .block__content.flex.flex--no-wrap class=comment_body_class(@comment) + .block__content.flex.flex--no-wrap class=communication_body_class(@comment) .flex__fixed.spacing-right = render PhilomenaWeb.UserAttributionView, "_anon_user_avatar.html", object: @comment, conn: @conn .flex__grow.communication__body @@ -11,11 +11,11 @@ article.block.communication id="comment_#{@comment.id}" strong.comment_deleted ' Deletion reason: =<> @comment.deletion_reason - = if can?(@conn, :delete, @comment) do + = if can?(@conn, :hide, @comment) do | ( = @comment.deleted_by.name | ) - = if can?(@conn, :delete, @comment) do + = if can?(@conn, :hide, @comment) do = if @comment.destroyed_content do br strong.comment_deleted> diff --git a/lib/philomena_web/templates/comment/_comment_with_image.html.slime b/lib/philomena_web/templates/comment/_comment_with_image.html.slime index a91f5881..2339977e 100644 --- a/lib/philomena_web/templates/comment/_comment_with_image.html.slime +++ b/lib/philomena_web/templates/comment/_comment_with_image.html.slime @@ -1,5 +1,5 @@ article.block.communication id="comment_#{@comment.id}" - .block__content.flex.flex--no-wrap class=comment_body_class(@comment) + .block__content.flex.flex--no-wrap class=communication_body_class(@comment) .flex__fixed.spacing-right .post-image-container = render PhilomenaWeb.ImageView, "_image_container.html", image: @comment.image, size: :thumb_tiny, conn: @conn @@ -15,11 +15,11 @@ article.block.communication id="comment_#{@comment.id}" strong.comment_deleted ' Deletion reason: =<> @comment.deletion_reason - = if can?(@conn, :delete, @comment) do + = if can?(@conn, :hide, @comment) do | ( = @comment.deleted_by.name | ) - = if can?(@conn, :delete, @comment) do + = if can?(@conn, :hide, @comment) do = if @comment.destroyed_content do br strong.comment_deleted> diff --git a/lib/philomena_web/templates/post/_post.html.slime b/lib/philomena_web/templates/post/_post.html.slime index 721d5051..f2add634 100644 --- a/lib/philomena_web/templates/post/_post.html.slime +++ b/lib/philomena_web/templates/post/_post.html.slime @@ -1,5 +1,5 @@ article.block.communication id="post_#{@post.id}" - .block__content.flex.flex--no-wrap + .block__content.flex.flex--no-wrap class=communication_body_class(@post) .flex__fixed.spacing-right = render PhilomenaWeb.UserAttributionView, "_anon_user_avatar.html", object: @post, conn: @conn .flex__grow.communication__body @@ -11,40 +11,43 @@ article.block.communication id="post_#{@post.id}" strong.comment_deleted ' Deletion reason: => @post.deletion_reason + = if can?(@conn, :hide, @post) do + | ( + = @post.deleted_by.name + | ) + = if can?(@conn, :hide, @post) do + = if @post.destroyed_content do + br + strong.comment_deleted> + | This post's contents have been destroyed. + - else + br + ==<> @body - else ==<> @body .block__content.communication__options .flex.flex--wrap.flex--spaced-out = render PhilomenaWeb.PostView, "_post_options.html", conn: @conn, post: @post = if can?(@conn, :hide, @post) do - / todo: make post deletion work - a.communication__interaction.togglable-delete-form-link href="#" - i.fa.fa-times - =<> "Delete" + = cond do + - @post.hidden_from_users and not @post.destroyed_content -> + = link(to: Routes.forum_topic_post_hide_path(@conn, :delete, @post.topic.forum, @post.topic, @post), data: [confirm: "Are you sure?"], method: :delete, class: "communication__interaction") do + i.fas.fa-check> + ' Restore + = if can?(@conn, :delete, @post) do + = link(to: Routes.forum_topic_post_delete_path(@conn, :delete, @post.topic.forum, @post.topic, @post), data: [confirm: "Are you sure?"], method: :delete, class: "communication__interaction") do + i.fas.fa-times> + ' Delete Contents + - not @post.hidden_from_users and not @post.destroyed_content -> + a.communication__interaction.togglable-delete-form-link href="#" data-click-toggle="#inline-del-form-post-#{@post.id}" + i.fa.fa-times> + ' Delete + - true -> = if can?(@conn, :show, :ip_address) do .communication__info =<> link_to_ip(@conn, @post.ip) .communication__info =<> link_to_fingerprint(@conn, @post.fingerprint) - /- if can?(:hide, Post) - / .js-staff-action - / - if !post.hidden_from_users && !post.destroyed_content - / =<> link_to '#', class: 'communication__interaction togglable-delete-form-link', 'data-click-toggle': "#inline-del-form-post-#{post.id}" do - / i.fa.fa-times - / =<> 'Delete' - / - elsif post.hidden_from_users && !post.destroyed_content - / =<> link_to forum_topic_post_hide_path(post.topic.forum, post.topic, post), data: { confirm: t('are_you_sure') }, method: :delete, class: 'communication__interaction' do - / i.fa.fa-check - / =<> 'Restore' - / - if can?(:manage, Post) - / =<> link_to forum_topic_post_path(post.topic.forum, post.topic, post, deletion_reason: post.deletion_reason), method: :delete, data: { confirm: t('are_you_sure') }, class: 'communication__interaction' do - / i.fa.fa-times - / =<> 'Delete Contents' - / - if can?(:manage, Post) - / .communication__info - / =<> link_to_ip(post.ip) - / .communication__info - / =<> link_to_fingerprint(post.fingerprint, post.user_agent) - / = form_tag forum_topic_post_hide_path(post.topic.forum, post.topic, post), class: 'togglable-delete-form hidden flex', id: "inline-del-form-post-#{post.id}" - / = text_field_tag :deletion_reason, nil, class: 'input input--wide', placeholder: 'Deletion Reason', id: "inline-del-reason-post-#{post.id}", required: true - / = submit_tag 'Delete', class: 'button' + = form_for :post, Routes.forum_topic_post_hide_path(@conn, :create, @post.topic.forum, @post.topic, @post), [class: "togglable-delete-form hidden flex", id: "inline-del-form-post-#{@post.id}"], fn f -> + = text_input f, :deletion_reason, class: "input input--wide", placeholder: "Deletion Reason", id: "inline-del-reason-post-#{@post.id}", required: true + = submit "Delete", class: "button" diff --git a/lib/philomena_web/templates/topic/show.html.slime b/lib/philomena_web/templates/topic/show.html.slime index e912bcd6..8783a129 100644 --- a/lib/philomena_web/templates/topic/show.html.slime +++ b/lib/philomena_web/templates/topic/show.html.slime @@ -35,7 +35,7 @@ h1 = @topic.title / The actual posts .posts-area .post-list - = for {post, body} <- @posts, !post.destroyed_content do + = for {post, body} <- @posts, (!post.destroyed_content or can?(@conn, :hide, post)) do = render PhilomenaWeb.PostView, "_post.html", conn: @conn, post: post, body: body = if @conn.assigns.advert do diff --git a/lib/philomena_web/views/app_view.ex b/lib/philomena_web/views/app_view.ex index 86fb5a80..58537281 100644 --- a/lib/philomena_web/views/app_view.ex +++ b/lib/philomena_web/views/app_view.ex @@ -149,6 +149,9 @@ defmodule PhilomenaWeb.AppView do end end + def communication_body_class(%{destroyed_content: true}), do: "communication--destroyed" + def communication_body_class(_communication), do: nil + def blank?(nil), do: true def blank?(""), do: true def blank?([]), do: true diff --git a/lib/philomena_web/views/comment_view.ex b/lib/philomena_web/views/comment_view.ex index da9d88aa..fbe88c11 100644 --- a/lib/philomena_web/views/comment_view.ex +++ b/lib/philomena_web/views/comment_view.ex @@ -1,6 +1,3 @@ defmodule PhilomenaWeb.CommentView do use PhilomenaWeb, :view - - defp comment_body_class(%{destroyed_content: true}), do: "comment--destroyed" - defp comment_body_class(_comment), do: nil end