mirror of
https://github.com/philomena-dev/philomena.git
synced 2025-04-01 09:15:28 +02: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.Image
|
||||||
alias Philomena.Images
|
alias Philomena.Images
|
||||||
alias Philomena.Notifications
|
alias Philomena.Notifications
|
||||||
|
alias Philomena.Versions
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Gets a single comment.
|
Gets a single comment.
|
||||||
|
@ -98,10 +99,23 @@ defmodule Philomena.Comments do
|
||||||
{:error, %Ecto.Changeset{}}
|
{:error, %Ecto.Changeset{}}
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def update_comment(%Comment{} = comment, attrs) do
|
def update_comment(%Comment{} = comment, editor, attrs) do
|
||||||
comment
|
now = DateTime.utc_now() |> DateTime.truncate(:second)
|
||||||
|> Comment.changeset(attrs)
|
current_body = comment.body
|
||||||
|> Repo.update()
|
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
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
|
|
|
@ -23,6 +23,7 @@ defmodule Philomena.Comments.Comment do
|
||||||
field :anonymous, :boolean, default: false
|
field :anonymous, :boolean, default: false
|
||||||
field :hidden_from_users, :boolean, default: false
|
field :hidden_from_users, :boolean, default: false
|
||||||
field :edit_reason, :string
|
field :edit_reason, :string
|
||||||
|
field :edited_at, :utc_datetime
|
||||||
field :deletion_reason, :string, default: ""
|
field :deletion_reason, :string, default: ""
|
||||||
field :destroyed_content, :boolean, default: false
|
field :destroyed_content, :boolean, default: false
|
||||||
field :name_at_post_time, :string
|
field :name_at_post_time, :string
|
||||||
|
@ -40,9 +41,10 @@ defmodule Philomena.Comments.Comment do
|
||||||
|> put_name_at_post_time(attribution[:user])
|
|> put_name_at_post_time(attribution[:user])
|
||||||
end
|
end
|
||||||
|
|
||||||
def changeset(comment, attrs) do
|
def changeset(comment, attrs, edited_at \\ nil) do
|
||||||
comment
|
comment
|
||||||
|> cast(attrs, [:body, :edit_reason])
|
|> cast(attrs, [:body, :edit_reason])
|
||||||
|
|> put_change(:edited_at, edited_at)
|
||||||
|> validate_required([:body])
|
|> validate_required([:body])
|
||||||
|> validate_length(:body, min: 1, max: 300_000, count: :bytes)
|
|> validate_length(:body, min: 1, max: 300_000, count: :bytes)
|
||||||
|> validate_length(:edit_reason, max: 70, 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
|
# Comment on images where that is allowed
|
||||||
def can?(_user, :create_comment, %Image{hidden_from_users: false, commenting_allowed: true}), do: true
|
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
|
# 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, :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
|
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, %Topic{hidden_from_users: false}), do: true
|
||||||
def can?(_user, :show, %Post{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
|
# View profile pages
|
||||||
def can?(_user, :show, %User{}), do: true
|
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
|
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)
|
|> Version.changeset(attrs, item_id)
|
||||||
|> Repo.insert()
|
|> Repo.insert()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# revolver ocelot
|
||||||
|
defp whodunnit(user_id) when is_integer(user_id), do: to_string(user_id)
|
||||||
|
defp whodunnit(nil), do: nil
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,8 +12,8 @@ defmodule PhilomenaWeb.Image.CommentController do
|
||||||
plug :load_and_authorize_resource, model: Image, id_name: "image_id", persisted: true
|
plug :load_and_authorize_resource, model: Image, id_name: "image_id", persisted: true
|
||||||
|
|
||||||
# Undo the previous private parameter screwery
|
# Undo the previous private parameter screwery
|
||||||
plug PhilomenaWeb.CanaryMapPlug, create: :create, edit: :edit, update: :update
|
plug PhilomenaWeb.CanaryMapPlug, create: :create, edit: :edit, update: :edit
|
||||||
plug :load_and_authorize_resource, model: Comment, only: [:show], preload: [:image, user: [awards: :badge]]
|
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.FilterBannedUsersPlug when action in [:create, :edit, :update]
|
||||||
plug PhilomenaWeb.UserAttributionPlug when action in [:create]
|
plug PhilomenaWeb.UserAttributionPlug when action in [:create]
|
||||||
|
@ -92,11 +92,13 @@ defmodule PhilomenaWeb.Image.CommentController do
|
||||||
end
|
end
|
||||||
|
|
||||||
def update(conn, %{"comment" => comment_params}) do
|
def update(conn, %{"comment" => comment_params}) do
|
||||||
case Comments.update_comment(conn.assigns.comment, comment_params) do
|
case Comments.update_comment(conn.assigns.comment, conn.assigns.current_user, comment_params) do
|
||||||
{:ok, _comment} ->
|
{:ok, %{comment: comment}} ->
|
||||||
|
Comments.reindex_comment(comment)
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|> put_flash(:info, "Comment updated successfully.")
|
|> 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 ->
|
_error ->
|
||||||
conn
|
conn
|
||||||
|
|
|
@ -100,6 +100,7 @@ defmodule PhilomenaWeb.Router do
|
||||||
resources "/hide", Image.HideController, only: [:create, :delete], singleton: true
|
resources "/hide", Image.HideController, only: [:create, :delete], singleton: true
|
||||||
resources "/subscription", Image.SubscriptionController, only: [:create, :delete], singleton: true
|
resources "/subscription", Image.SubscriptionController, only: [:create, :delete], singleton: true
|
||||||
resources "/read", Image.ReadController, only: [:create], singleton: true
|
resources "/read", Image.ReadController, only: [:create], singleton: true
|
||||||
|
resources "/comments", Image.CommentController, only: [:edit, :update]
|
||||||
end
|
end
|
||||||
|
|
||||||
resources "/forums", ForumController, only: [] do
|
resources "/forums", ForumController, only: [] do
|
||||||
|
|
|
@ -6,14 +6,16 @@ div
|
||||||
i.fa.fa-flag>
|
i.fa.fa-flag>
|
||||||
' Report
|
' Report
|
||||||
|
|
||||||
/- if comment.edited_at && can?(:read, comment)
|
= if not is_nil(@comment.edited_at) and can?(@conn, :read, @comment) do
|
||||||
/ br
|
br
|
||||||
/ a href=image_comment_history_path(comment.image, comment)
|
a href=Routes.image_comment_history_path(@conn, :index, @comment.image, @comment)
|
||||||
/ | Edited
|
' Edited
|
||||||
/ =<> friendly_time(comment.edited_at)
|
=> pretty_time(@comment.edited_at)
|
||||||
/ - if comment.edit_reason.present?
|
|
||||||
/ | because:
|
= if @comment.edit_reason not in [nil, ""] do
|
||||||
/ =<> comment.edit_reason
|
' because:
|
||||||
|
=> @comment.edit_reason
|
||||||
|
|
||||||
div
|
div
|
||||||
- link_path = Routes.image_path(@conn, :show, @comment.image) <> "#comment_#{@comment.id}"
|
- link_path = Routes.image_path(@conn, :show, @comment.image) <> "#comment_#{@comment.id}"
|
||||||
- safe_author = PhilomenaWeb.PostView.textile_safe_author(@comment)
|
- 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
|
a.communication__interaction.post-reply href=link_path data-reply-url=link_path data-author=safe_author
|
||||||
i.fa.fa-reply>
|
i.fa.fa-reply>
|
||||||
' Reply
|
' Reply
|
||||||
/span.owner-options.hidden
|
|
||||||
/ strong =<> link_to edit_image_comment_path(comment.image, comment), class: 'communication__interaction' do
|
= if can?(@conn, :edit, @comment) do
|
||||||
/ i.fas.fa-edit
|
span.owner-options
|
||||||
/ ' Edit
|
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…")]
|
Loading…
Add table
Reference in a new issue