From dd8ecd531cc32c6879180d9cc11357e11f74cf6c Mon Sep 17 00:00:00 2001 From: "byte[]" Date: Sun, 24 Nov 2019 21:16:22 -0500 Subject: [PATCH] controller/view for tag changes, source changes --- lib/philomena/attribution.ex | 6 ++ lib/philomena/comments/attribution.ex | 4 ++ lib/philomena/images.ex | 20 ++++++- lib/philomena/images/attribution.ex | 4 ++ lib/philomena/images/tag_differ.ex | 27 +++++++++ lib/philomena/posts/attribution.ex | 4 ++ lib/philomena/source_changes/attribution.ex | 13 ++++ lib/philomena/tag_changes/attribution.ex | 13 ++++ lib/philomena/tags.ex | 4 +- lib/philomena/tags/tag.ex | 15 +++++ lib/philomena/topics/attribution.ex | 4 ++ lib/philomena/users/ability.ex | 7 +++ .../controllers/image/comment_controller.ex | 2 +- .../image/source_change_controller.ex | 24 ++++++++ .../controllers/image/source_controller.ex | 6 +- .../image/tag_change_controller.ex | 32 ++++++++++ .../controllers/image/tag_controller.ex | 17 ++++-- .../controllers/image_controller.ex | 5 ++ lib/philomena_web/router.ex | 4 ++ .../templates/image/_source.html.slime | 40 +++++++++++++ .../templates/image/_tags.html.slime | 60 +++++++++++++++++++ .../templates/image/show.html.slime | 12 +--- .../image/source_change/index.html.slime | 46 ++++++++++++++ .../image/tag_change/index.html.slime | 58 ++++++++++++++++++ .../templates/tag/_tag_editor.html.slime | 9 ++- .../user_attribution/_anon_user.html.slime | 2 +- .../_anon_user_avatar.html.slime | 2 +- .../views/image/source_change_view.ex | 3 + .../views/image/tag_change_view.ex | 3 + lib/philomena_web/views/image_view.ex | 15 +---- .../views/user_attribution_view.ex | 4 ++ 31 files changed, 431 insertions(+), 34 deletions(-) create mode 100644 lib/philomena/source_changes/attribution.ex create mode 100644 lib/philomena/tag_changes/attribution.ex create mode 100644 lib/philomena_web/controllers/image/source_change_controller.ex create mode 100644 lib/philomena_web/controllers/image/tag_change_controller.ex create mode 100644 lib/philomena_web/templates/image/_source.html.slime create mode 100644 lib/philomena_web/templates/image/_tags.html.slime create mode 100644 lib/philomena_web/templates/image/source_change/index.html.slime create mode 100644 lib/philomena_web/templates/image/tag_change/index.html.slime create mode 100644 lib/philomena_web/views/image/source_change_view.ex create mode 100644 lib/philomena_web/views/image/tag_change_view.ex diff --git a/lib/philomena/attribution.ex b/lib/philomena/attribution.ex index 3fa0a843..c93ee739 100644 --- a/lib/philomena/attribution.ex +++ b/lib/philomena/attribution.ex @@ -14,4 +14,10 @@ defprotocol Philomena.Attribution do """ @spec best_user_identifier(struct()) :: String.t() def best_user_identifier(object) + + @doc """ + Return whether this object is considered to be anonymous. + """ + @spec anonymous?(struct()) :: true | false + def anonymous?(object) end \ No newline at end of file diff --git a/lib/philomena/comments/attribution.ex b/lib/philomena/comments/attribution.ex index 07c97467..5ac1a5fe 100644 --- a/lib/philomena/comments/attribution.ex +++ b/lib/philomena/comments/attribution.ex @@ -6,4 +6,8 @@ defimpl Philomena.Attribution, for: Philomena.Comments.Comment do def best_user_identifier(comment) do to_string(comment.user_id || comment.fingerprint || comment.ip) end + + def anonymous?(comment) do + !!comment.anonymous + end end \ No newline at end of file diff --git a/lib/philomena/images.ex b/lib/philomena/images.ex index 91a92b06..dc29d8e3 100644 --- a/lib/philomena/images.ex +++ b/lib/philomena/images.ex @@ -12,6 +12,7 @@ defmodule Philomena.Images do alias Philomena.SourceChanges.SourceChange alias Philomena.TagChanges.TagChange alias Philomena.Tags + alias Philomena.Tags.Tag @doc """ Gets a single image. @@ -118,11 +119,27 @@ defmodule Philomena.Images do {:ok, count} end) + |> Multi.run(:added_tag_count, fn repo, %{image: {_image, added_tags, _removed}} -> + tag_ids = added_tags |> Enum.map(& &1.id) + tags = Tag |> where([t], t.id in ^tag_ids) + + {count, nil} = repo.update_all(tags, inc: [images_count: 1]) + + {:ok, count} + end) + |> Multi.run(:removed_tag_count, fn repo, %{image: {_image, _added, removed_tags}} -> + tag_ids = removed_tags |> Enum.map(& &1.id) + tags = Tag |> where([t], t.id in ^tag_ids) + + {count, nil} = repo.update_all(tags, inc: [images_count: -1]) + + {:ok, count} + end) |> Repo.isolated_transaction(:serializable) end defp tag_change_attributes(attribution, image, tag, added, user) do - now = DateTime.utc_now() |> DateTime.truncate(:second) + now = NaiveDateTime.utc_now() |> NaiveDateTime.truncate(:second) user_id = case user do nil -> nil @@ -134,6 +151,7 @@ defmodule Philomena.Images do tag_id: tag.id, user_id: user_id, created_at: now, + updated_at: now, tag_name_cache: tag.name, ip: attribution[:ip], fingerprint: attribution[:fingerprint], diff --git a/lib/philomena/images/attribution.ex b/lib/philomena/images/attribution.ex index dd161b5b..b2695ccb 100644 --- a/lib/philomena/images/attribution.ex +++ b/lib/philomena/images/attribution.ex @@ -6,4 +6,8 @@ defimpl Philomena.Attribution, for: Philomena.Images.Image do def best_user_identifier(image) do to_string(image.user_id || image.fingerprint || image.ip) end + + def anonymous?(image) do + !!image.anonymous + end end \ No newline at end of file diff --git a/lib/philomena/images/tag_differ.ex b/lib/philomena/images/tag_differ.ex index 17dd0ea0..999c40f5 100644 --- a/lib/philomena/images/tag_differ.ex +++ b/lib/philomena/images/tag_differ.ex @@ -16,9 +16,14 @@ defmodule Philomena.Images.TagDiffer do {tags, actually_added, actually_removed} = apply_changes(tags, added_tags, removed_tags) + {tag_list_cache, tag_list_plus_alias_cache} = + create_caches(tags) + changeset |> put_change(:added_tags, actually_added) |> put_change(:removed_tags, actually_removed) + |> put_change(:tag_list_cache, tag_list_cache) + |> put_change(:tag_list_plus_alias_cache, tag_list_plus_alias_cache) |> put_assoc(:tags, tags) end @@ -88,4 +93,26 @@ defmodule Philomena.Images.TagDiffer do {tags, actually_added, actually_removed} end + + defp create_caches(tags) do + tag_list_cache = + tags + |> Tag.display_order() + |> Enum.map_join(", ", & &1.name) + + tag_ids = + tags |> Enum.map(& &1.id) + + aliases = + Tag + |> where([t], t.aliased_tag_id in ^tag_ids) + |> Repo.all() + + tag_list_plus_alias_cache = + (tags ++ aliases) + |> Tag.display_order() + |> Enum.map_join(", ", & &1.name) + + {tag_list_cache, tag_list_plus_alias_cache} + end end \ No newline at end of file diff --git a/lib/philomena/posts/attribution.ex b/lib/philomena/posts/attribution.ex index 8ac81c1a..0ee12d39 100644 --- a/lib/philomena/posts/attribution.ex +++ b/lib/philomena/posts/attribution.ex @@ -6,4 +6,8 @@ defimpl Philomena.Attribution, for: Philomena.Posts.Post do def best_user_identifier(post) do to_string(post.user_id || post.fingerprint || post.ip) end + + def anonymous?(post) do + !!post.anonymous + end end \ No newline at end of file diff --git a/lib/philomena/source_changes/attribution.ex b/lib/philomena/source_changes/attribution.ex new file mode 100644 index 00000000..dc97ff22 --- /dev/null +++ b/lib/philomena/source_changes/attribution.ex @@ -0,0 +1,13 @@ +defimpl Philomena.Attribution, for: Philomena.SourceChanges.SourceChange do + def object_identifier(source_change) do + to_string(source_change.image_id || source_change.id) + end + + def best_user_identifier(source_change) do + to_string(source_change.user_id || source_change.fingerprint || source_change.ip) + end + + def anonymous?(source_change) do + source_change.user_id == source_change.image.user_id and !!source_change.image.anonymous + end +end \ No newline at end of file diff --git a/lib/philomena/tag_changes/attribution.ex b/lib/philomena/tag_changes/attribution.ex new file mode 100644 index 00000000..4a686613 --- /dev/null +++ b/lib/philomena/tag_changes/attribution.ex @@ -0,0 +1,13 @@ +defimpl Philomena.Attribution, for: Philomena.TagChanges.TagChange do + def object_identifier(tag_change) do + to_string(tag_change.image_id || tag_change.id) + end + + def best_user_identifier(tag_change) do + to_string(tag_change.user_id || tag_change.fingerprint || tag_change.ip) + end + + def anonymous?(tag_change) do + tag_change.user_id == tag_change.image.user_id and !!tag_change.image.anonymous + end +end \ No newline at end of file diff --git a/lib/philomena/tags.ex b/lib/philomena/tags.ex index 6196742e..f724b2cc 100644 --- a/lib/philomena/tags.ex +++ b/lib/philomena/tags.ex @@ -15,8 +15,10 @@ defmodule Philomena.Tags do existent_tags = Tag |> where([t], t.name in ^tag_names) - |> preload(:implied_tags) + |> preload([:implied_tags, aliased_tag: :implied_tags]) |> Repo.all() + |> Enum.map(& &1.aliased_tag || &1) + |> Enum.uniq() existent_tag_names = existent_tags diff --git a/lib/philomena/tags/tag.ex b/lib/philomena/tags/tag.ex index 32fec576..17d99032 100644 --- a/lib/philomena/tags/tag.ex +++ b/lib/philomena/tags/tag.ex @@ -75,6 +75,21 @@ defmodule Philomena.Tags.Tag do |> Enum.reject(&"" == &1) end + def display_order(tags) do + tags + |> Enum.sort_by(&{ + &1.category != "rating", + &1.category != "origin", + &1.category != "character", + &1.category != "oc", + &1.category != "species", + &1.category != "content-fanmade", + &1.category != "content-official", + &1.category != "spoiler", + &1.name + }) + end + def clean_tag_name(name) do # Downcase, replace extra runs of spaces, replace unicode quotes # with ascii quotes, trim space from end diff --git a/lib/philomena/topics/attribution.ex b/lib/philomena/topics/attribution.ex index 171cd3a6..acb9d7fd 100644 --- a/lib/philomena/topics/attribution.ex +++ b/lib/philomena/topics/attribution.ex @@ -6,4 +6,8 @@ defimpl Philomena.Attribution, for: Philomena.Topics.Topic do def best_user_identifier(topic) do to_string(topic.user_id) end + + def anonymous?(topic) do + !!topic.anonymous + end end \ No newline at end of file diff --git a/lib/philomena/users/ability.ex b/lib/philomena/users/ability.ex index 49efcd64..a8f2c9e9 100644 --- a/lib/philomena/users/ability.ex +++ b/lib/philomena/users/ability.ex @@ -64,6 +64,13 @@ defimpl Canada.Can, for: [Atom, Philomena.Users.User] do when action in [:show, :index], do: true + # Comment on images where that is allowed + def can?(_user, :create_comment, %Image{hidden_from_users: false, commenting_allowed: true}), do: true + + # 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 + # Vote on images they can see def can?(user, :vote, image), do: can?(user, :show, image) diff --git a/lib/philomena_web/controllers/image/comment_controller.ex b/lib/philomena_web/controllers/image/comment_controller.ex index 750ef842..46e1a430 100644 --- a/lib/philomena_web/controllers/image/comment_controller.ex +++ b/lib/philomena_web/controllers/image/comment_controller.ex @@ -7,7 +7,7 @@ defmodule PhilomenaWeb.Image.CommentController do alias Philomena.Repo import Ecto.Query - plug PhilomenaWeb.CanaryMapPlug, create: :show, edit: :show, update: :show + plug PhilomenaWeb.CanaryMapPlug, create: :create_comment, edit: :create_comment, update: :create_comment plug :load_and_authorize_resource, model: Image, id_name: "image_id", persisted: true # Undo the previous private parameter screwery diff --git a/lib/philomena_web/controllers/image/source_change_controller.ex b/lib/philomena_web/controllers/image/source_change_controller.ex new file mode 100644 index 00000000..689253a8 --- /dev/null +++ b/lib/philomena_web/controllers/image/source_change_controller.ex @@ -0,0 +1,24 @@ +defmodule PhilomenaWeb.Image.SourceChangeController do + use PhilomenaWeb, :controller + + alias Philomena.Images.Image + alias Philomena.SourceChanges.SourceChange + alias Philomena.Repo + import Ecto.Query + + plug PhilomenaWeb.CanaryMapPlug, index: :show + plug :load_and_authorize_resource, model: Image, id_name: "image_id", persisted: true + + def index(conn, params) do + image = conn.assigns.image + + source_changes = + SourceChange + |> where(image_id: ^image.id) + |> preload([:user, image: [:user, :tags]]) + |> order_by(desc: :created_at) + |> Repo.paginate(conn.assigns.scrivener) + + render(conn, "index.html", image: image, source_changes: source_changes) + end +end \ No newline at end of file diff --git a/lib/philomena_web/controllers/image/source_controller.ex b/lib/philomena_web/controllers/image/source_controller.ex index 9a0586cd..60b6146f 100644 --- a/lib/philomena_web/controllers/image/source_controller.ex +++ b/lib/philomena_web/controllers/image/source_controller.ex @@ -7,7 +7,7 @@ defmodule PhilomenaWeb.Image.SourceController do plug PhilomenaWeb.FilterBannedUsersPlug plug PhilomenaWeb.CaptchaPlug plug PhilomenaWeb.UserAttributionPlug - plug PhilomenaWeb.CanaryMapPlug, update: :show + plug PhilomenaWeb.CanaryMapPlug, update: :edit_metadata plug :load_and_authorize_resource, model: Image, id_name: "image_id" def update(conn, %{"image" => image_params}) do @@ -21,12 +21,12 @@ defmodule PhilomenaWeb.Image.SourceController do conn |> put_view(PhilomenaWeb.ImageView) - |> render("_source.html", image: image, changeset: changeset) + |> render("_source.html", layout: false, image: image, changeset: changeset) {:error, :image, changeset, _} -> conn |> put_view(PhilomenaWeb.ImageView) - |> render("_source.html", image: image, changeset: changeset) + |> render("_source.html", layout: false, image: image, changeset: changeset) end end end \ No newline at end of file diff --git a/lib/philomena_web/controllers/image/tag_change_controller.ex b/lib/philomena_web/controllers/image/tag_change_controller.ex new file mode 100644 index 00000000..903a7051 --- /dev/null +++ b/lib/philomena_web/controllers/image/tag_change_controller.ex @@ -0,0 +1,32 @@ +defmodule PhilomenaWeb.Image.TagChangeController do + use PhilomenaWeb, :controller + + alias Philomena.Images.Image + alias Philomena.TagChanges.TagChange + alias Philomena.Repo + import Ecto.Query + + plug PhilomenaWeb.CanaryMapPlug, index: :show + plug :load_and_authorize_resource, model: Image, id_name: "image_id", persisted: true + + def index(conn, params) do + image = conn.assigns.image + + tag_changes = + TagChange + |> where(image_id: ^image.id) + |> added_filter(params) + |> preload([:tag, :user, image: [:user, :tags]]) + |> order_by(desc: :created_at) + |> Repo.paginate(conn.assigns.scrivener) + + render(conn, "index.html", image: image, tag_changes: tag_changes) + end + + defp added_filter(query, %{"added" => "1"}), + do: where(query, added: true) + defp added_filter(query, %{"added" => "0"}), + do: where(query, added: false) + defp added_filter(query, _params), + do: query +end \ No newline at end of file diff --git a/lib/philomena_web/controllers/image/tag_controller.ex b/lib/philomena_web/controllers/image/tag_controller.ex index a9339d10..9f0c9a89 100644 --- a/lib/philomena_web/controllers/image/tag_controller.ex +++ b/lib/philomena_web/controllers/image/tag_controller.ex @@ -3,11 +3,13 @@ defmodule PhilomenaWeb.Image.TagController do alias Philomena.Images alias Philomena.Images.Image + alias Philomena.Tags + alias Philomena.Repo plug PhilomenaWeb.FilterBannedUsersPlug plug PhilomenaWeb.CaptchaPlug plug PhilomenaWeb.UserAttributionPlug - plug PhilomenaWeb.CanaryMapPlug, update: :show + plug PhilomenaWeb.CanaryMapPlug, update: :edit_metadata plug :load_and_authorize_resource, model: Image, id_name: "image_id" def update(conn, %{"image" => image_params}) do @@ -15,18 +17,25 @@ defmodule PhilomenaWeb.Image.TagController do image = conn.assigns.image case Images.update_tags(image, attributes, image_params) do - {:ok, %{image: image}} -> + {:ok, %{image: {image, added_tags, removed_tags}}} -> + Images.reindex_image(image) + Tags.reindex_tags(added_tags ++ removed_tags) + + image = + image + |> Repo.preload(:tags, force: true) + changeset = Images.change_image(image) conn |> put_view(PhilomenaWeb.ImageView) - |> render("_tags.html", image: image, changeset: changeset) + |> render("_tags.html", layout: false, image: image, changeset: changeset) {:error, :image, changeset, _} -> conn |> put_view(PhilomenaWeb.ImageView) - |> render("_tags.html", image: image, changeset: changeset) + |> render("_tags.html", layout: false, image: image, changeset: changeset) end end end \ No newline at end of file diff --git a/lib/philomena_web/controllers/image_controller.ex b/lib/philomena_web/controllers/image_controller.ex index af9a1303..ecd1c8c6 100644 --- a/lib/philomena_web/controllers/image_controller.ex +++ b/lib/philomena_web/controllers/image_controller.ex @@ -57,6 +57,10 @@ defmodule PhilomenaWeb.ImageController do %Comment{} |> Comments.change_comment() + image_changeset = + image + |> Images.change_image() + watching = Images.subscribed?(image, conn.assigns.current_user) @@ -65,6 +69,7 @@ defmodule PhilomenaWeb.ImageController do "show.html", image: image, comments: comments, + image_changeset: image_changeset, comment_changeset: comment_changeset, description: description, interactions: interactions, diff --git a/lib/philomena_web/router.ex b/lib/philomena_web/router.ex index 7b22c813..904dfa7f 100644 --- a/lib/philomena_web/router.ex +++ b/lib/philomena_web/router.ex @@ -85,6 +85,10 @@ defmodule PhilomenaWeb.Router do resources "/activity", ActivityController, only: [:index] resources "/images", ImageController, only: [:index, :show] do resources "/comments", Image.CommentController, only: [:index, :show, :create] + resources "/tags", Image.TagController, only: [:update], singleton: true + resources "/sources", Image.SourceController, only: [:update], singleton: true + resources "/tag_changes", Image.TagChangeController, only: [:index] + resources "/source_changes", Image.SourceChangeController, only: [:index] end resources "/tags", TagController, only: [:index, :show] resources "/search", SearchController, only: [:index] diff --git a/lib/philomena_web/templates/image/_source.html.slime b/lib/philomena_web/templates/image/_source.html.slime new file mode 100644 index 00000000..8c9bd0e2 --- /dev/null +++ b/lib/philomena_web/templates/image/_source.html.slime @@ -0,0 +1,40 @@ +.block + = form_for @changeset, Routes.image_source_path(@conn, :update, @image), [method: "put", class: "hidden", id: "source-form", data: [remote: true]], fn f -> + = if can?(@conn, :update_metadata, @image) and !@conn.assigns.current_ban do + + = if @changeset.action do + .alert.alert-danger + p Oops, something went wrong! Please check the errors below. + + .flex + = url_input f, :source_url, id: "source-field", class: "input input--wide", autocomplete: "off", placeholder: "Source URL" + = submit "Save source", class: "button button--separate-left" + button.button.button--separate-left type="reset" data-click-hide="#source-form" data-click-show="#image-source" + ' Cancel + + = if !@conn.assigns.current_user do + = checkbox f, :captcha, class: "js-captcha", value: 0 + = label f, :captcha, "I am not a robot!" + + - else + p + ' You can't edit the source on this image. + + .flex.flex--wrap#image-source + p + a.button.button--separate-right#edit-source data-click-focus="#source-field" data-click-hide="#image-source" data-click-show="#source-form" title="Edit source" accessKey="s" + i.fa.fa-pencil> + ' Source: + + p + = if @image.source_url not in [nil, ""] do + a.js-source-link href=@image.source_url + strong + = @image.source_url + + - else + em> not provided yet + + a.button.button--link.button--separate-left href=Routes.image_source_change_path(@conn, :index, @image) title="Source history" + i.fa.fa-history> + ' History \ No newline at end of file diff --git a/lib/philomena_web/templates/image/_tags.html.slime b/lib/philomena_web/templates/image/_tags.html.slime new file mode 100644 index 00000000..7677f854 --- /dev/null +++ b/lib/philomena_web/templates/image/_tags.html.slime @@ -0,0 +1,60 @@ +- form_class = if @changeset.action, do: "", else: "hidden" + +.js-tagsauce#image_tags_and_source + = if can?(@conn, :update_metadata, @image) and !@conn.assigns.current_ban do + + .js-imageform class=form_class + + = form_for @changeset, Routes.image_tag_path(@conn, :update, @image), [id: "tags-form", method: "put", data: [remote: true]], fn f -> + = if @changeset.action do + .alert.alert-danger + p Oops, something went wrong! Please check the errors below. + + = hidden_input f, :old_tag_input, value: @image.tag_list_cache + + .field + = label f, :tag_input do + ' Separate tags with commas. Use 'artist:name' tags to identify artists. Got questions? Check the + a> href="/pages/tags" tag guidelines + ' or the + a href="/pages/spoilers" spoiler guidelines + ' . + + = render PhilomenaWeb.TagView, "_tag_editor.html", f: f, name: :tag_input, type: :edit, extra: [value: @image.tag_list_cache] + + = if !@conn.assigns.current_user do + .block.block--fixed.block--warning + strong + em Hang on a sec… + br + ' Make sure you have read and understood our + a> href="/pages/tags" tagging guidelines + ' before editing tags. + + .field + = checkbox f, :captcha, class: "js-captcha", value: 0 + = label f, :captcha, "I am not a robot!" + + ul.horizontal-list + li + .actions + = submit "Save tags", class: "button", id: "edit_save_button", data: [disable_with: raw("Saving…")] + li + button.button.js-tag-sauce-toggle data-click-toggle=".tagsauce, .js-imageform" data-click-focus=".js-taginput-plain:not(.hidden), .js-taginput-input" + ' Cancel + + - else + p + ' You can't edit the tags on this image. + + .tagsauce + .block + a.button.js-tag-sauce-toggle#edit-tags data-click-toggle=".tagsauce, .js-imageform" data-click-focus=".js-taginput-plain:not(.hidden), .js-taginput-input" title="Edit tags" accessKey="t" + i.fa.fa-pencil> + ' Tags: + + a.button.button--link.button--separate-left href=Routes.image_tag_change_path(@conn, :index, @image) title="Tag history" + i.fa.fa-history> + ' History + + = render PhilomenaWeb.TagView, "_tag_list.html", tags: display_order(@image.tags), conn: @conn \ No newline at end of file diff --git a/lib/philomena_web/templates/image/show.html.slime b/lib/philomena_web/templates/image/show.html.slime index e57f7bdd..67d79e82 100644 --- a/lib/philomena_web/templates/image/show.html.slime +++ b/lib/philomena_web/templates/image/show.html.slime @@ -8,15 +8,9 @@ | Description: .image-description__text == @description - .js-tagsauce id="image_tags_and_source_#{@image.id}" - .tagsauce - = render PhilomenaWeb.TagView, "_tag_list.html", tags: display_order(@image.tags), conn: @conn - .block - .flex.flex--wrap#image-source - = if !!@image.source_url and @image.source_url != "" do - a href=@image.source_url = @image.source_url - - else - em> no source provided yet + + = render PhilomenaWeb.ImageView, "_tags.html", image: @image, changeset: @image_changeset, conn: @conn + = render PhilomenaWeb.ImageView, "_source.html", image: @image, changeset: @image_changeset, conn: @conn h4 Comments = cond do diff --git a/lib/philomena_web/templates/image/source_change/index.html.slime b/lib/philomena_web/templates/image/source_change/index.html.slime new file mode 100644 index 00000000..4cedd025 --- /dev/null +++ b/lib/philomena_web/templates/image/source_change/index.html.slime @@ -0,0 +1,46 @@ +h1 + ' Source changes for + a href=Routes.image_path(@conn, :show, @image) + | image # + = @image.id + +- route = fn p -> Routes.image_source_change_path(@conn, :index, @image, p) end +- pagination = render PhilomenaWeb.PaginationView, "_pagination.html", page: @source_changes, route: route, conn: @conn + +.block + .block__header + = pagination + + .block__content + table.table + thead + tr + th colspan=2 Image + th New Source + th Timestamp + th User + th Initial? + + tbody + = for source_change <- @source_changes do + tr + td.center + = link source_change.image_id, to: Routes.image_path(@conn, :show, source_change.image) + td.center + = render PhilomenaWeb.ImageView, "_image_container.html", image: source_change.image, size: :thumb_tiny, conn: @conn + + td + = source_change.new_value + + td + = pretty_time(source_change.created_at) + + td + = render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: source_change, conn: @conn + + td + = if source_change.initial do + ' ✓ + + .block__header + = pagination \ No newline at end of file diff --git a/lib/philomena_web/templates/image/tag_change/index.html.slime b/lib/philomena_web/templates/image/tag_change/index.html.slime new file mode 100644 index 00000000..f23f2b3a --- /dev/null +++ b/lib/philomena_web/templates/image/tag_change/index.html.slime @@ -0,0 +1,58 @@ +h1 + ' Tag changes for + a href=Routes.image_path(@conn, :show, @image) + | image # + = @image.id + +- route = fn p -> Routes.image_tag_change_path(@conn, :index, @image, p) end +- pagination = render PhilomenaWeb.PaginationView, "_pagination.html", page: @tag_changes, route: route, conn: @conn + +.block + .block__header + span.block__header_title + | Display only: + + = link "Removed", to: Routes.image_tag_change_path(@conn, :index, @image, added: 0) + = link "Added", to: Routes.image_tag_change_path(@conn, :index, @image, added: 1) + = link "All", to: Routes.image_tag_change_path(@conn, :index, @image) + + .block__header + = pagination + + .block__content + table.table + thead + tr + th colspan=2 Image + th Tag + th Action + th Timestamp + th User + + tbody + = for tag_change <- @tag_changes do + tr + td.center + = link tag_change.image_id, to: Routes.image_path(@conn, :show, tag_change.image) + td.center + = render PhilomenaWeb.ImageView, "_image_container.html", image: tag_change.image, size: :thumb_tiny, conn: @conn + + td + = if tag_change.tag do + = render PhilomenaWeb.TagView, "_tag.html", tag: tag_change.tag, conn: @conn + - else + = tag_change.tag_name_cache || "Unknown tag" + + = if tag_change.added do + td.success Added + - else + td.danger Removed + + td + = pretty_time(tag_change.created_at) + + td + = render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: tag_change, conn: @conn + + .block__header + = pagination \ No newline at end of file diff --git a/lib/philomena_web/templates/tag/_tag_editor.html.slime b/lib/philomena_web/templates/tag/_tag_editor.html.slime index 8ea139d0..ab818bc1 100644 --- a/lib/philomena_web/templates/tag/_tag_editor.html.slime +++ b/lib/philomena_web/templates/tag/_tag_editor.html.slime @@ -1,5 +1,12 @@ +elixir: + textarea_options = [ + class: "input input--wide tagsinput js-image-input js-taginput js-taginput-plain js-taginput-#{@name}", + placeholder: "Add tags separated with commas" + ] + html_options = Keyword.merge(textarea_options, assigns[:extra] || []) + .js-tag-block class="fancy-tag-#{@type}" - = textarea @f, @name, class: "input input--wide tagsinput js-image-input js-taginput js-taginput-plain js-taginput-#{@name}", placeholder: "Add tags separated with commas" + = textarea @f, @name, html_options .js-taginput.input.input--wide.tagsinput.hidden class="js-taginput-fancy" data-click-focus=".js-taginput-input.js-taginput-#{@name}" input.input class="js-taginput-input js-taginput-#{@name}" id="taginput-fancy-#{@name}" type="text" placeholder="add a tag" autocapitalize="none" data-ac="true" data-ac-min-length="3" data-ac-source='/tags/autocomplete.json?term=' button.button.button--state-primary.button--bold class="js-taginput-show" data-click-show=".js-taginput-fancy,.js-taginput-hide" data-click-hide=".js-taginput-plain,.js-taginput-show" data-click-focus=".js-taginput-input.js-taginput-#{@name}" diff --git a/lib/philomena_web/templates/user_attribution/_anon_user.html.slime b/lib/philomena_web/templates/user_attribution/_anon_user.html.slime index f5747320..39e72379 100644 --- a/lib/philomena_web/templates/user_attribution/_anon_user.html.slime +++ b/lib/philomena_web/templates/user_attribution/_anon_user.html.slime @@ -1,4 +1,4 @@ -= if !!@object.user and !@object.anonymous do += if !!@object.user and !anonymous?(@object) do strong<> = link(@object.user.name, to: Routes.profile_path(@conn, :show, @object.user)) = if assigns[:awards] do diff --git a/lib/philomena_web/templates/user_attribution/_anon_user_avatar.html.slime b/lib/philomena_web/templates/user_attribution/_anon_user_avatar.html.slime index 7ba3d1c5..d411abaa 100644 --- a/lib/philomena_web/templates/user_attribution/_anon_user_avatar.html.slime +++ b/lib/philomena_web/templates/user_attribution/_anon_user_avatar.html.slime @@ -1,4 +1,4 @@ -= if !!@object.user and !@object.anonymous do += if !!@object.user and !anonymous?(@object) do = user_avatar(@object, assigns[:class] || "avatar--100px") - else = anonymous_avatar(@object, assigns[:class] || "avatar--100px") \ No newline at end of file diff --git a/lib/philomena_web/views/image/source_change_view.ex b/lib/philomena_web/views/image/source_change_view.ex new file mode 100644 index 00000000..dc95602d --- /dev/null +++ b/lib/philomena_web/views/image/source_change_view.ex @@ -0,0 +1,3 @@ +defmodule PhilomenaWeb.Image.SourceChangeView do + use PhilomenaWeb, :view +end diff --git a/lib/philomena_web/views/image/tag_change_view.ex b/lib/philomena_web/views/image/tag_change_view.ex new file mode 100644 index 00000000..91d8e052 --- /dev/null +++ b/lib/philomena_web/views/image/tag_change_view.ex @@ -0,0 +1,3 @@ +defmodule PhilomenaWeb.Image.TagChangeView do + use PhilomenaWeb, :view +end diff --git a/lib/philomena_web/views/image_view.ex b/lib/philomena_web/views/image_view.ex index 2c446ca4..3e65388c 100644 --- a/lib/philomena_web/views/image_view.ex +++ b/lib/philomena_web/views/image_view.ex @@ -1,6 +1,8 @@ defmodule PhilomenaWeb.ImageView do use PhilomenaWeb, :view + alias Philomena.Tags.Tag + def thumb_urls(image, show_hidden) do %{ thumb_tiny: thumb_url(image, show_hidden, :thumb_tiny), @@ -76,18 +78,7 @@ defmodule PhilomenaWeb.ImageView do end def display_order(tags) do - tags - |> Enum.sort_by(&{ - &1.category != "rating", - &1.category != "origin", - &1.category != "character", - &1.category != "oc", - &1.category != "species", - &1.category != "content-fanmade", - &1.category != "content-official", - &1.category != "spoiler", - &1.name - }) + Tag.display_order(tags) end defp thumb_format("svg"), do: "png" diff --git a/lib/philomena_web/views/user_attribution_view.ex b/lib/philomena_web/views/user_attribution_view.ex index acb39f9f..d639b66b 100644 --- a/lib/philomena_web/views/user_attribution_view.ex +++ b/lib/philomena_web/views/user_attribution_view.ex @@ -3,6 +3,10 @@ defmodule PhilomenaWeb.UserAttributionView do use Bitwise use PhilomenaWeb, :view + def anonymous?(object) do + Attribution.anonymous?(object) + end + def anonymous_name(object) do salt = anonymous_name_salt() id = Attribution.object_identifier(object)