topic hiding / restoring

This commit is contained in:
Luna D 2019-12-14 13:03:11 -05:00
parent 37be32f2b2
commit 782baba324
No known key found for this signature in database
GPG key ID: D0F46C94720BAA4B
6 changed files with 186 additions and 88 deletions

View file

@ -235,6 +235,16 @@ defmodule Philomena.Topics do
|> Repo.isolated_transaction(:serializable) |> Repo.isolated_transaction(:serializable)
end end
def hide_topic(topic, deletion_reason, user) do
Topic.hide_changeset(topic, deletion_reason, user)
|> Repo.update()
end
def unhide_topic(topic) do
Topic.unhide_changeset(topic)
|> Repo.update()
end
def clear_notification(nil, _user), do: nil def clear_notification(nil, _user), do: nil
def clear_notification(_topic, nil), do: nil def clear_notification(_topic, nil), do: nil
def clear_notification(topic, user) do def clear_notification(topic, user) do

View file

@ -96,6 +96,21 @@ defmodule Philomena.Topics.Topic do
|> put_change(:forum_id, new_forum_id) |> put_change(:forum_id, new_forum_id)
end end
def hide_changeset(topic, deletion_reason, user) do
change(topic)
|> put_change(:hidden_from_users, true)
|> put_change(:deleted_by_id, user.id)
|> put_change(:deletion_reason, deletion_reason)
|> validate_required([:deletion_reason])
end
def unhide_changeset(topic) do
change(topic)
|> put_change(:hidden_from_users, false)
|> put_change(:deleted_by_id, nil)
|> put_change(:deletion_reason, "")
end
def put_slug(changeset) do def put_slug(changeset) do
slug = slug =
changeset changeset

View file

@ -0,0 +1,54 @@
defmodule PhilomenaWeb.Topic.HideController do
import Plug.Conn
use PhilomenaWeb, :controller
alias Philomena.Topics.Topic
alias Philomena.Topics
alias Philomena.Repo
import Ecto.Query
plug :load_topic
plug PhilomenaWeb.CanaryMapPlug, create: :hide, delete: :hide
plug :authorize_resource, model: Topic, id_name: "topic_id", persisted: true
def create(conn, %{"topic" => topic_params}) do
topic = conn.assigns.topic
deletion_reason = topic_params["deletion_reason"]
user = conn.assigns.current_user
case Topics.hide_topic(topic, deletion_reason, user) do
{:ok, topic} ->
conn
|> put_flash(:info, "Topic successfully hidden!")
|> redirect(to: Routes.forum_topic_path(conn, :show, topic.forum, topic))
{:error, _changeset} ->
conn
|> put_flash(:error, "Unable to hide the topic!")
|> redirect(to: Routes.forum_topic_path(conn, :show, topic.forum, topic))
end
end
def delete(conn, _opts) do
topic = conn.assigns.topic
case Topics.unhide_topic(topic) do
{:ok, topic} ->
conn
|> put_flash(:info, "Topic successfully restored!")
|> redirect(to: Routes.forum_topic_path(conn, :show, topic.forum, topic))
{:error, _changeset} ->
conn
|> put_flash(:error, "Unable to restore the topic!")
|> redirect(to: Routes.forum_topic_path(conn, :show, topic.forum, topic))
end
end
defp load_topic(conn, _opts) do
topic = Topic
|> where(forum_id: ^conn.params["forum_id"], slug: ^conn.params["topic_id"])
|> preload([:forum])
|> Repo.one()
Plug.Conn.assign(conn, :topic, topic)
end
end

View file

@ -19,8 +19,8 @@ defmodule PhilomenaWeb.TopicController do
forum = conn.assigns.forum forum = conn.assigns.forum
topic = topic =
Topic Topic
|> where(forum_id: ^forum.id, slug: ^slug, hidden_from_users: false) |> where(forum_id: ^forum.id, slug: ^slug)
|> preload([:user, poll: :options]) |> preload([:deleted_by, :user, poll: :options])
|> Repo.one() |> Repo.one()
user = conn.assigns.current_user user = conn.assigns.current_user

View file

@ -129,6 +129,7 @@ defmodule PhilomenaWeb.Router do
resources "/move", Topic.MoveController, only: [:create], singleton: true resources "/move", Topic.MoveController, only: [:create], singleton: true
resources "/stick", Topic.StickController, only: [:create, :delete], singleton: true resources "/stick", Topic.StickController, only: [:create, :delete], singleton: true
resources "/lock", Topic.LockController, only: [:create, :delete], singleton: true resources "/lock", Topic.LockController, only: [:create, :delete], singleton: true
resources "/hide", Topic.HideController, only: [:create, :delete], singleton: true
resources "/posts", Topic.PostController, only: [:edit, :update] do resources "/posts", Topic.PostController, only: [:edit, :update] do
resources "/hide", Topic.Post.HideController, only: [:create, :delete], singleton: true resources "/hide", Topic.Post.HideController, only: [:create, :delete], singleton: true
resources "/delete", Topic.Post.DeleteController, only: [:create], singleton: true resources "/delete", Topic.Post.DeleteController, only: [:create], singleton: true

View file

@ -3,6 +3,23 @@ elixir:
pagination = render PhilomenaWeb.PaginationView, "_pagination.html", page: @posts, route: route, last: true pagination = render PhilomenaWeb.PaginationView, "_pagination.html", page: @posts, route: route, last: true
h1 = @topic.title h1 = @topic.title
= if @topic.hidden_from_users do
.block.block--fixed.block--danger
h4 This topic has been deleted by a moderator.
p
strong> Reason:
em
= @topic.deletion_reason
= if can?(@conn, :unhide, @topic) do
p
strong> Deleted by:
em
strong
= link(@topic.deleted_by.name, to: Routes.profile_path(@conn, :show, @topic.deleted_by))
p
= link(to: Routes.forum_topic_hide_path(@conn, :delete, @forum.id, @topic), method: :delete, class: "button") do
i.fas.fa-check>
' Restore
/ Header section / Header section
.block .block
.block__header .block__header
@ -11,6 +28,7 @@ h1 = @topic.title
=> link(@forum.name, to: Routes.forum_path(@conn, :show, @forum)) => link(@forum.name, to: Routes.forum_path(@conn, :show, @forum))
' » ' »
=> link(@topic.title, to: Routes.forum_topic_path(@conn, :show, @forum, @topic)) => link(@topic.title, to: Routes.forum_topic_path(@conn, :show, @forum, @topic))
= if not @topic.hidden_from_users or can?(@conn, :hide, @topic) do
a href=Routes.post_path(@conn, :index, pq: "topic_id:#{@topic.id}") a href=Routes.post_path(@conn, :index, pq: "topic_id:#{@topic.id}")
i.fa.fa-fw.fa-search> i.fa.fa-fw.fa-search>
' Search Posts ' Search Posts
@ -26,8 +44,10 @@ h1 = @topic.title
.flex--fixed.block__header__item .flex--fixed.block__header__item
=> @topic.post_count - 1 => @topic.post_count - 1
' replies ' replies
= if not @topic.hidden_from_users do
= render PhilomenaWeb.Topic.SubscriptionView, "_subscription.html", forum: @forum, topic: @topic, watching: @watching, conn: @conn = render PhilomenaWeb.Topic.SubscriptionView, "_subscription.html", forum: @forum, topic: @topic, watching: @watching, conn: @conn
= if not @topic.hidden_from_users or can?(@conn, :hide, @topic) do
/ Display the poll, if any / Display the poll, if any
= if @topic.poll do = if @topic.poll do
= render PhilomenaWeb.Topic.PollView, "_display.html", poll: @topic.poll, conn: @conn = render PhilomenaWeb.Topic.PollView, "_display.html", poll: @topic.poll, conn: @conn
@ -59,12 +79,15 @@ h1 = @topic.title
p p
' Lock reason: ' Lock reason:
em = @topic.lock_reason em = @topic.lock_reason
/ Post form / Post form
= cond do = cond do
- @conn.assigns.current_ban -> - @conn.assigns.current_ban ->
= render PhilomenaWeb.BanView, "_ban_reason.html", conn: @conn = render PhilomenaWeb.BanView, "_ban_reason.html", conn: @conn
- @topic.hidden_from_users ->
.block.block--fixed.block--danger
h4 Cannot reply to a deleted topic.
- @topic.post_count < 200_000 and can?(@conn, :create_post, @topic) -> - @topic.post_count < 200_000 and can?(@conn, :create_post, @topic) ->
= render PhilomenaWeb.Topic.PostView, "_form.html", conn: @conn, forum: @forum, topic: @topic, changeset: @changeset = render PhilomenaWeb.Topic.PostView, "_form.html", conn: @conn, forum: @forum, topic: @topic, changeset: @changeset
@ -81,47 +104,42 @@ h1 = @topic.title
.toggle-box-container .toggle-box-container
.toggle-box-container__content .toggle-box-container__content
p p
= if not @topic.hidden_from_users do
= cond do = cond do
- can?(@conn, :lock, @topic) and is_nil(@topic.locked_at) -> - can?(@conn, :lock, @topic) and is_nil(@topic.locked_at) ->
= form_for :topic, Routes.forum_topic_lock_path(@conn, :create, @topic.forum_id, @topic), [method: :post, class: "hform"], fn f -> = form_for :topic, Routes.forum_topic_lock_path(@conn, :create, @forum.id, @topic), [method: :post, class: "hform"], fn f ->
= text_input f, :lock_reason, class: "input hform__text", placeholder: "Lock reason" = text_input f, :lock_reason, class: "input hform__text", placeholder: "Lock reason", required: true
= submit class: "hform__button button" do = submit class: "hform__button button" do
i.fas.fa-lock> i.fas.fa-lock>
' Lock ' Lock
- can?(@conn, :unlock, @topic) and not is_nil(@topic.locked_at) -> - can?(@conn, :unlock, @topic) and not is_nil(@topic.locked_at) ->
= link(to: Routes.forum_topic_lock_path(@conn, :delete, @topic.forum_id, @topic), method: :delete, class: "button") do = link(to: Routes.forum_topic_lock_path(@conn, :delete, @forum.id, @topic), method: :delete, class: "button") do
i.fas.fa-unlock> i.fas.fa-unlock>
' Unlock ' Unlock
- true -> - true ->
= cond do = cond do
- can?(@conn, :stick, @topic) and @topic.sticky -> - can?(@conn, :stick, @topic) and @topic.sticky ->
= link(to: Routes.forum_topic_stick_path(@conn, :delete, @topic.forum_id, @topic), method: :delete, class: "button") do = link(to: Routes.forum_topic_stick_path(@conn, :delete, @forum.id, @topic), method: :delete, class: "button") do
i.fas.fa-thumbtack> i.fas.fa-thumbtack>
' Unstick ' Unstick
- can?(@conn, :stick, @topic) and not @topic.sticky -> - can?(@conn, :stick, @topic) and not @topic.sticky ->
= link(to: Routes.forum_topic_stick_path(@conn, :create, @topic.forum_id, @topic), method: :post, class: "button") do = link(to: Routes.forum_topic_stick_path(@conn, :create, @forum.id, @topic), method: :post, class: "button") do
i.fas.fa-thumbtack> i.fas.fa-thumbtack>
' Stick ' Stick
- true -> - true ->
= if can?(@conn, :move, @topic) do = if can?(@conn, :move, @topic) do
= form_for :topic, Routes.forum_topic_move_path(@conn, :create, @topic.forum_id, @topic), [method: :post, class: "hform"], fn f -> = form_for :topic, Routes.forum_topic_move_path(@conn, :create, @forum.id, @topic), [method: :post, class: "hform"], fn f ->
.field .field
= select f, :target_forum_id, @conn.assigns.forums |> Enum.map(fn forum -> {forum.name, forum.id} end), class: "input hform__text" = select f, :target_forum_id, @conn.assigns.forums |> Enum.map(fn forum -> {forum.name, forum.id} end), class: "input hform__text"
= submit class: "hform__button button" do = submit class: "hform__button button" do
i.fas.fa-truck> i.fas.fa-truck>
' Move ' Move
/ Mod tools = if can?(@conn, :hide, @topic) do
/- if can? :assist, Topic = form_for :topic, Routes.forum_topic_hide_path(@conn, :create, @forum.id, @topic), [method: :post, class: "hform"], fn f ->
/ .block__content .field
/ input.toggle-box id="administrator_tools" type="checkbox" checked=false = text_input f, :deletion_reason, class: "input hform__text", placeholder: "Deletion reason", required: true
/ label for="administrator_tools" Topic Admin Tools = submit class: "hform__button button" do
/ .toggle-box-container i.fas.fa-trash>
/ .toggle-box-container__content ' Delete
/ p - else
/ - if can?(:destroy, @topic) && !@topic.hidden_from_users | Moderation tools unavailable for deleted topics.
/ = form_tag forum_topic_hide_path(@forum, @topic), method: :post, class: 'hform' do
/ .field
/ => text_field_tag :deletion_reason, '', placeholder: 'Deletion reason', required: true, class: 'input hform__text'
/ => button_tag class: 'hform__button button' do
/ i.fa.fa-trash>
/ | Delete