mirror of
https://github.com/philomena-dev/philomena.git
synced 2025-01-19 14:17:59 +01:00
primitive history viewing
This commit is contained in:
parent
2a338d86c7
commit
9fc04b9b71
9 changed files with 139 additions and 71 deletions
|
@ -7,35 +7,47 @@ defmodule Philomena.Versions do
|
|||
alias Philomena.Repo
|
||||
|
||||
alias Philomena.Versions.Version
|
||||
alias Philomena.Users.User
|
||||
|
||||
@doc """
|
||||
Returns the list of versions.
|
||||
def load_data_and_associations(versions, parent) do
|
||||
user_ids =
|
||||
versions
|
||||
|> Enum.map(& &1.whodunnit)
|
||||
|> Enum.reject(&is_nil/1)
|
||||
|
||||
## Examples
|
||||
users =
|
||||
User
|
||||
|> where([u], u.id in ^user_ids)
|
||||
|> preload(awards: :badge)
|
||||
|> Repo.all()
|
||||
|> Map.new(&{to_string(&1.id), &1})
|
||||
|
||||
iex> list_versions()
|
||||
[%Version{}, ...]
|
||||
{versions, _last_body} =
|
||||
versions
|
||||
|> Enum.reverse()
|
||||
|> Enum.map_reduce(nil, fn version, previous_body ->
|
||||
yaml = YamlElixir.read_from_string!(version.object || "")
|
||||
body = yaml["body"] || ""
|
||||
edit_reason = yaml["edit_reason"]
|
||||
|
||||
"""
|
||||
def list_versions do
|
||||
Repo.all(Version)
|
||||
v =
|
||||
%{
|
||||
version |
|
||||
parent: parent,
|
||||
user: users[version.whodunnit],
|
||||
body: body,
|
||||
edit_reason: edit_reason,
|
||||
difference: difference(previous_body, body)
|
||||
}
|
||||
|
||||
{v, body}
|
||||
end)
|
||||
|
||||
Enum.reverse(versions)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Gets a single version.
|
||||
|
||||
Raises `Ecto.NoResultsError` if the Version does not exist.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> get_version!(123)
|
||||
%Version{}
|
||||
|
||||
iex> get_version!(456)
|
||||
** (Ecto.NoResultsError)
|
||||
|
||||
"""
|
||||
def get_version!(id), do: Repo.get!(Version, id)
|
||||
defp difference(nil, next), do: [eq: next]
|
||||
defp difference(previous, next), do: String.myers_difference(previous, next)
|
||||
|
||||
@doc """
|
||||
Creates a version.
|
||||
|
@ -54,51 +66,4 @@ defmodule Philomena.Versions do
|
|||
|> Version.changeset(attrs)
|
||||
|> Repo.insert()
|
||||
end
|
||||
|
||||
@doc """
|
||||
Updates a version.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> update_version(version, %{field: new_value})
|
||||
{:ok, %Version{}}
|
||||
|
||||
iex> update_version(version, %{field: bad_value})
|
||||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def update_version(%Version{} = version, attrs) do
|
||||
version
|
||||
|> Version.changeset(attrs)
|
||||
|> Repo.update()
|
||||
end
|
||||
|
||||
@doc """
|
||||
Deletes a Version.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> delete_version(version)
|
||||
{:ok, %Version{}}
|
||||
|
||||
iex> delete_version(version)
|
||||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def delete_version(%Version{} = version) do
|
||||
Repo.delete(version)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Returns an `%Ecto.Changeset{}` for tracking version changes.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> change_version(version)
|
||||
%Ecto.Changeset{source: %Version{}}
|
||||
|
||||
"""
|
||||
def change_version(%Version{} = version) do
|
||||
Version.changeset(version, %{})
|
||||
end
|
||||
end
|
||||
|
|
16
lib/philomena/versions/attribution.ex
Normal file
16
lib/philomena/versions/attribution.ex
Normal file
|
@ -0,0 +1,16 @@
|
|||
defimpl Philomena.Attribution, for: Philomena.Versions.Version do
|
||||
def object_identifier(version) do
|
||||
to_string(version.parent.id)
|
||||
end
|
||||
|
||||
def best_user_identifier(version) do
|
||||
to_string(version.user.id)
|
||||
end
|
||||
|
||||
def anonymous?(version) do
|
||||
same_user?(version.user, version.parent) and !!version.parent.anonymous
|
||||
end
|
||||
|
||||
defp same_user?(%{id: id}, %{user_id: id}), do: true
|
||||
defp same_user?(_user, _parent), do: false
|
||||
end
|
|
@ -11,6 +11,12 @@ defmodule Philomena.Versions.Version do
|
|||
field :item_id, :integer
|
||||
field :item_type, :string
|
||||
|
||||
field :user, :any, virtual: true
|
||||
field :parent, :any, virtual: true
|
||||
field :body, :string, virtual: true
|
||||
field :edit_reason, :string, virtual: true
|
||||
field :difference, :any, virtual: true
|
||||
|
||||
timestamps(inserted_at: :created_at, updated_at: false)
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
defmodule PhilomenaWeb.Image.Comment.HistoryController do
|
||||
use PhilomenaWeb, :controller
|
||||
|
||||
alias Philomena.Versions.Version
|
||||
alias Philomena.Versions
|
||||
alias Philomena.Comments.Comment
|
||||
alias Philomena.Images.Image
|
||||
alias Philomena.Repo
|
||||
import Ecto.Query
|
||||
|
||||
plug PhilomenaWeb.CanaryMapPlug, index: :show
|
||||
plug :load_and_authorize_resource, model: Image, id_name: "image_id", persisted: true
|
||||
plug :load_and_authorize_resource, model: Comment, id_name: "comment_id", persisted: true, preload: [:user, :image]
|
||||
|
||||
def index(conn, _params) do
|
||||
comment = conn.assigns.comment
|
||||
|
||||
versions =
|
||||
Version
|
||||
|> where(item_type: "Comment", item_id: ^comment.id)
|
||||
|> order_by(desc: :created_at)
|
||||
|> limit(25)
|
||||
|> Repo.all()
|
||||
|> Versions.load_data_and_associations(comment)
|
||||
|
||||
render(conn, "index.html", versions: versions)
|
||||
end
|
||||
end
|
|
@ -152,6 +152,7 @@ defmodule PhilomenaWeb.Router do
|
|||
resources "/images", ImageController, only: [:index, :show, :new, :create] do
|
||||
resources "/comments", Image.CommentController, only: [:index, :show, :create] do
|
||||
resources "/reports", Image.Comment.ReportController, only: [:new, :create]
|
||||
resources "/history", Image.Comment.HistoryController, only: [:index]
|
||||
end
|
||||
resources "/tags", Image.TagController, only: [:update], singleton: true
|
||||
resources "/sources", Image.SourceController, only: [:update], singleton: true
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
h1
|
||||
' Viewing last 25 versions of comment by
|
||||
= render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: @comment, conn: @conn
|
||||
' on image
|
||||
a href=Routes.image_path(@conn, :show, @comment.image)
|
||||
| #
|
||||
= @comment.image_id
|
||||
|
||||
= 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
|
||||
|
||||
.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
|
||||
|
||||
.communication__body__text
|
||||
= for edit <- version.difference do
|
||||
= case edit do
|
||||
- {:eq, value} ->
|
||||
= text_to_html(value)
|
||||
|
||||
- {:ins, value} ->
|
||||
ins.differ = text_to_html(value)
|
||||
|
||||
- {:del, value} ->
|
||||
del.differ = text_to_html(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
|
||||
|
||||
.flex__right
|
||||
' Edited
|
||||
= pretty_time(version.created_at)
|
||||
' by
|
||||
= render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: @version, conn: @conn
|
3
lib/philomena_web/views/image/comment/history_view.ex
Normal file
3
lib/philomena_web/views/image/comment/history_view.ex
Normal file
|
@ -0,0 +1,3 @@
|
|||
defmodule PhilomenaWeb.Image.Comment.HistoryView do
|
||||
use PhilomenaWeb, :view
|
||||
end
|
3
mix.exs
3
mix.exs
|
@ -60,7 +60,8 @@ defmodule Philomena.MixProject do
|
|||
{:bamboo_smtp, "~> 1.7"},
|
||||
{:remote_ip, "~> 0.2.0"},
|
||||
{:briefly, "~> 0.3.0"},
|
||||
{:phoenix_mtm, "~> 1.0.0"}
|
||||
{:phoenix_mtm, "~> 1.0.0"},
|
||||
{:yaml_elixir, "~> 2.4.0"}
|
||||
]
|
||||
end
|
||||
|
||||
|
|
2
mix.lock
2
mix.lock
|
@ -61,4 +61,6 @@
|
|||
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.5", "6eaf7ad16cb568bb01753dbbd7a95ff8b91c7979482b95f38443fe2c8852a79b", [:make, :mix, :rebar3], [], "hexpm"},
|
||||
"telemetry": {:hex, :telemetry, "0.4.1", "ae2718484892448a24470e6aa341bc847c3277bfb8d4e9289f7474d752c09c7f", [:rebar3], [], "hexpm"},
|
||||
"unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm"},
|
||||
"yamerl": {:hex, :yamerl, "0.7.0", "e51dba652dce74c20a88294130b48051ebbbb0be7d76f22de064f0f3ccf0aaf5", [:rebar3], [], "hexpm"},
|
||||
"yaml_elixir": {:hex, :yaml_elixir, "2.4.0", "2f444abc3c994c902851fde56b6a9cb82895c291c05a0490a289035c2e62ae71", [:mix], [{:yamerl, "~> 0.7", [hex: :yamerl, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue