mirror of
https://github.com/philomena-dev/philomena.git
synced 2024-11-27 13:47:58 +01:00
tentative comment editing
This commit is contained in:
parent
76de12d69d
commit
d22ab9aa58
9 changed files with 122 additions and 52 deletions
|
@ -11,6 +11,7 @@ defmodule Philomena.Comments do
|
|||
alias Philomena.Images.Image
|
||||
alias Philomena.Images
|
||||
alias Philomena.Notifications
|
||||
alias Philomena.Versions
|
||||
|
||||
@doc """
|
||||
Gets a single comment.
|
||||
|
@ -98,10 +99,23 @@ defmodule Philomena.Comments do
|
|||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def update_comment(%Comment{} = comment, attrs) do
|
||||
comment
|
||||
|> Comment.changeset(attrs)
|
||||
|> Repo.update()
|
||||
def update_comment(%Comment{} = comment, editor, attrs) do
|
||||
now = DateTime.utc_now() |> DateTime.truncate(:second)
|
||||
current_body = comment.body
|
||||
current_reason = comment.edit_reason
|
||||
|
||||
comment_changes =
|
||||
Comment.changeset(comment, attrs, now)
|
||||
|
||||
Multi.new
|
||||
|> Multi.update(:comment, comment_changes)
|
||||
|> Multi.run(:version, fn _repo, _changes ->
|
||||
Versions.create_version("Comment", comment.id, editor.id, %{
|
||||
"body" => current_body,
|
||||
"edit_reason" => current_reason
|
||||
})
|
||||
end)
|
||||
|> Repo.isolated_transaction(:serializable)
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
|
|
@ -23,6 +23,7 @@ defmodule Philomena.Comments.Comment do
|
|||
field :anonymous, :boolean, default: false
|
||||
field :hidden_from_users, :boolean, default: false
|
||||
field :edit_reason, :string
|
||||
field :edited_at, :utc_datetime
|
||||
field :deletion_reason, :string, default: ""
|
||||
field :destroyed_content, :boolean, default: false
|
||||
field :name_at_post_time, :string
|
||||
|
@ -40,9 +41,10 @@ defmodule Philomena.Comments.Comment do
|
|||
|> put_name_at_post_time(attribution[:user])
|
||||
end
|
||||
|
||||
def changeset(comment, attrs) do
|
||||
def changeset(comment, attrs, edited_at \\ nil) do
|
||||
comment
|
||||
|> cast(attrs, [:body, :edit_reason])
|
||||
|> put_change(:edited_at, edited_at)
|
||||
|> validate_required([:body])
|
||||
|> validate_length(:body, min: 1, max: 300_000, count: :bytes)
|
||||
|> validate_length(:edit_reason, max: 70, count: :bytes)
|
||||
|
|
|
@ -85,6 +85,14 @@ defimpl Canada.Can, for: [Atom, Philomena.Users.User] do
|
|||
# Comment on images where that is allowed
|
||||
def can?(_user, :create_comment, %Image{hidden_from_users: false, commenting_allowed: true}), do: true
|
||||
|
||||
# Edit comments on images
|
||||
def can?(%User{id: id}, :edit, %Comment{hidden_from_users: false, user_id: id} = comment) do
|
||||
# comment must have been made no later than 15 minutes ago
|
||||
time_ago = DateTime.utc_now() |> DateTime.add(-15 * 60)
|
||||
|
||||
DateTime.diff(comment.created_at, time_ago) > 0
|
||||
end
|
||||
|
||||
# Edit metadata on images where that is allowed
|
||||
def can?(_user, :edit_metadata, %Image{hidden_from_users: false, tag_editing_allowed: true}), do: true
|
||||
def can?(%User{id: id}, :edit_description, %Image{user_id: id, hidden_from_users: false, description_editing_allowed: true}), do: true
|
||||
|
@ -101,6 +109,9 @@ defimpl Canada.Can, for: [Atom, Philomena.Users.User] do
|
|||
def can?(_user, :show, %Topic{hidden_from_users: false}), do: true
|
||||
def can?(_user, :show, %Post{hidden_from_users: false}), do: true
|
||||
|
||||
# Edit posts
|
||||
def can?(%User{id: id}, :edit, %Post{hidden_from_users: false, user_id: id}), do: true
|
||||
|
||||
# View profile pages
|
||||
def can?(_user, :show, %User{}), do: true
|
||||
|
||||
|
|
|
@ -61,8 +61,12 @@ defmodule Philomena.Versions do
|
|||
|
||||
"""
|
||||
def create_version(item_type, item_id, whodunnit, attrs \\ %{}) do
|
||||
%Version{item_type: item_type, item_id: item_id, whodunnit: whodunnit}
|
||||
%Version{item_type: item_type, item_id: item_id, event: "update", whodunnit: whodunnit(whodunnit)}
|
||||
|> Version.changeset(attrs, item_id)
|
||||
|> Repo.insert()
|
||||
end
|
||||
|
||||
# revolver ocelot
|
||||
defp whodunnit(user_id) when is_integer(user_id), do: to_string(user_id)
|
||||
defp whodunnit(nil), do: nil
|
||||
end
|
||||
|
|
|
@ -12,8 +12,8 @@ defmodule PhilomenaWeb.Image.CommentController do
|
|||
plug :load_and_authorize_resource, model: Image, id_name: "image_id", persisted: true
|
||||
|
||||
# Undo the previous private parameter screwery
|
||||
plug PhilomenaWeb.CanaryMapPlug, create: :create, edit: :edit, update: :update
|
||||
plug :load_and_authorize_resource, model: Comment, only: [:show], preload: [:image, user: [awards: :badge]]
|
||||
plug PhilomenaWeb.CanaryMapPlug, create: :create, edit: :edit, update: :edit
|
||||
plug :load_and_authorize_resource, model: Comment, only: [:show, :edit, :update], preload: [:image, user: [awards: :badge]]
|
||||
|
||||
plug PhilomenaWeb.FilterBannedUsersPlug when action in [:create, :edit, :update]
|
||||
plug PhilomenaWeb.UserAttributionPlug when action in [:create]
|
||||
|
@ -92,11 +92,13 @@ defmodule PhilomenaWeb.Image.CommentController do
|
|||
end
|
||||
|
||||
def update(conn, %{"comment" => comment_params}) do
|
||||
case Comments.update_comment(conn.assigns.comment, comment_params) do
|
||||
{:ok, _comment} ->
|
||||
case Comments.update_comment(conn.assigns.comment, conn.assigns.current_user, comment_params) do
|
||||
{:ok, %{comment: comment}} ->
|
||||
Comments.reindex_comment(comment)
|
||||
|
||||
conn
|
||||
|> put_flash(:info, "Comment updated successfully.")
|
||||
|> redirect(to: Routes.image_path(conn, :show, conn.assigns.image) <> "#comment_#{conn.assigns.comment.id}")
|
||||
|> redirect(to: Routes.image_path(conn, :show, conn.assigns.image) <> "#comment_#{comment.id}")
|
||||
|
||||
_error ->
|
||||
conn
|
||||
|
|
|
@ -100,6 +100,7 @@ defmodule PhilomenaWeb.Router do
|
|||
resources "/hide", Image.HideController, only: [:create, :delete], singleton: true
|
||||
resources "/subscription", Image.SubscriptionController, only: [:create, :delete], singleton: true
|
||||
resources "/read", Image.ReadController, only: [:create], singleton: true
|
||||
resources "/comments", Image.CommentController, only: [:edit, :update]
|
||||
end
|
||||
|
||||
resources "/forums", ForumController, only: [] do
|
||||
|
|
|
@ -6,14 +6,16 @@ div
|
|||
i.fa.fa-flag>
|
||||
' Report
|
||||
|
||||
/- if comment.edited_at && can?(:read, comment)
|
||||
/ br
|
||||
/ a href=image_comment_history_path(comment.image, comment)
|
||||
/ | Edited
|
||||
/ =<> friendly_time(comment.edited_at)
|
||||
/ - if comment.edit_reason.present?
|
||||
/ | because:
|
||||
/ =<> comment.edit_reason
|
||||
= if not is_nil(@comment.edited_at) and can?(@conn, :read, @comment) do
|
||||
br
|
||||
a href=Routes.image_comment_history_path(@conn, :index, @comment.image, @comment)
|
||||
' Edited
|
||||
=> pretty_time(@comment.edited_at)
|
||||
|
||||
= if @comment.edit_reason not in [nil, ""] do
|
||||
' because:
|
||||
=> @comment.edit_reason
|
||||
|
||||
div
|
||||
- link_path = Routes.image_path(@conn, :show, @comment.image) <> "#comment_#{@comment.id}"
|
||||
- safe_author = PhilomenaWeb.PostView.textile_safe_author(@comment)
|
||||
|
@ -30,7 +32,10 @@ div
|
|||
a.communication__interaction.post-reply href=link_path data-reply-url=link_path data-author=safe_author
|
||||
i.fa.fa-reply>
|
||||
' Reply
|
||||
/span.owner-options.hidden
|
||||
/ strong =<> link_to edit_image_comment_path(comment.image, comment), class: 'communication__interaction' do
|
||||
/ i.fas.fa-edit
|
||||
/ ' Edit
|
||||
|
||||
= if can?(@conn, :edit, @comment) do
|
||||
span.owner-options
|
||||
strong
|
||||
a.communication__interaction href=Routes.image_comment_path(@conn, :edit, @comment.image, @comment)
|
||||
i.fa.fa-pencil>
|
||||
' Edit
|
||||
|
|
31
lib/philomena_web/templates/image/comment/edit.html.slime
Normal file
31
lib/philomena_web/templates/image/comment/edit.html.slime
Normal file
|
@ -0,0 +1,31 @@
|
|||
= form_for @changeset, Routes.image_comment_path(@conn, :update, @comment.image, @comment), fn f ->
|
||||
= if @changeset.action do
|
||||
.alert.alert-danger
|
||||
p Oops, something went wrong! Please check the errors below.
|
||||
|
||||
.block
|
||||
.block__header.block__header--js-tabbed
|
||||
a.selected href="#" data-click-tab="write"
|
||||
i.fa.fa-pencil>
|
||||
' Edit
|
||||
|
||||
a href="#" data-click-tab="preview"
|
||||
i.fa.fa-eye>
|
||||
' Preview
|
||||
|
||||
.block__tab.communication-edit__tab.selected data-tab="write"
|
||||
= render PhilomenaWeb.TextileView, "_help.html", conn: @conn
|
||||
= render PhilomenaWeb.TextileView, "_toolbar.html", conn: @conn
|
||||
|
||||
.field
|
||||
= textarea f, :body, class: "input input--wide input--text js-preview-input js-toolbar-input", placeholder: "Please read the site rules before posting and use [spoiler][/spoiler] for above-rating stuff.", required: true
|
||||
= error_tag f, :body
|
||||
|
||||
.field
|
||||
= text_input f, :edit_reason, class: "input input--wide", placeholder: "Reason for edit"
|
||||
|
||||
.block__tab.communication-edit__tab.hidden data-tab="preview"
|
||||
' [Loading preview...]
|
||||
|
||||
.block__content.communication-edit__actions
|
||||
=> submit "Edit", class: "button", data: [disable_with: raw("Posting…")]
|
|
@ -8,39 +8,39 @@ h1
|
|||
|
||||
= for version <- @versions do
|
||||
article.block.communication
|
||||
.block__content.flex.flex--no-wrap
|
||||
.flex__fixed.spacing-right
|
||||
= render PhilomenaWeb.UserAttributionView, "_anon_user_avatar.html", object: @comment, conn: @conn
|
||||
.block__content.flex.flex--no-wrap
|
||||
.flex__fixed.spacing-right
|
||||
= render PhilomenaWeb.UserAttributionView, "_anon_user_avatar.html", object: @comment, conn: @conn
|
||||
|
||||
.flex__grow.communication__body
|
||||
span.communication__body__sender-name = render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: @comment, awards: true, conn: @conn
|
||||
br
|
||||
.flex__grow.communication__body
|
||||
span.communication__body__sender-name = render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: @comment, awards: true, conn: @conn
|
||||
br
|
||||
|
||||
= render PhilomenaWeb.UserAttributionView, "_anon_user_title.html", object: @comment, conn: @conn
|
||||
= render PhilomenaWeb.UserAttributionView, "_anon_user_title.html", object: @comment, conn: @conn
|
||||
|
||||
.communication__body__text
|
||||
= for edit <- version.difference do
|
||||
= case edit do
|
||||
- {:eq, value} ->
|
||||
= escape_nl2br(value)
|
||||
.communication__body__text
|
||||
= for edit <- version.difference do
|
||||
= case edit do
|
||||
- {:eq, value} ->
|
||||
= escape_nl2br(value)
|
||||
|
||||
- {:ins, value} ->
|
||||
ins.differ = escape_nl2br(value)
|
||||
- {:ins, value} ->
|
||||
ins.differ = escape_nl2br(value)
|
||||
|
||||
- {:del, value} ->
|
||||
del.differ = escape_nl2br(value)
|
||||
- {:del, value} ->
|
||||
del.differ = escape_nl2br(value)
|
||||
|
||||
.block__content.communication__options
|
||||
.flex.flex--wrap.flex--spaced-out
|
||||
div
|
||||
= if version.edit_reason not in [nil, ""] do
|
||||
' Reason:
|
||||
= version.edit_reason
|
||||
- else
|
||||
' No reason given
|
||||
.block__content.communication__options
|
||||
.flex.flex--wrap.flex--spaced-out
|
||||
div
|
||||
= if version.edit_reason not in [nil, ""] do
|
||||
' Reason:
|
||||
= version.edit_reason
|
||||
- else
|
||||
' No reason given
|
||||
|
||||
.flex__right
|
||||
' Edited
|
||||
=> pretty_time(version.created_at)
|
||||
' by
|
||||
=> render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: version, conn: @conn
|
||||
.flex__right
|
||||
' Edited
|
||||
=> pretty_time(version.created_at)
|
||||
' by
|
||||
=> render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: version, conn: @conn
|
Loading…
Reference in a new issue