hide/spoiler/watch from tag dropdown

This commit is contained in:
byte[] 2019-12-06 12:12:55 -05:00
parent 90bb70a527
commit 6329b01e38
19 changed files with 241 additions and 17 deletions

View file

@ -142,4 +142,36 @@ defmodule Philomena.Filters do
end end
) )
end end
def hide_tag(filter, tag) do
hidden_tag_ids = Enum.uniq([tag.id | filter.hidden_tag_ids])
filter
|> Filter.hidden_tags_changeset(hidden_tag_ids)
|> Repo.update()
end
def unhide_tag(filter, tag) do
hidden_tag_ids = filter.hidden_tag_ids -- [tag.id]
filter
|> Filter.hidden_tags_changeset(hidden_tag_ids)
|> Repo.update()
end
def spoiler_tag(filter, tag) do
spoilered_tag_ids = Enum.uniq([tag.id | filter.spoilered_tag_ids])
filter
|> Filter.spoilered_tags_changeset(spoilered_tag_ids)
|> Repo.update()
end
def unspoiler_tag(filter, tag) do
spoilered_tag_ids = filter.spoilered_tag_ids -- [tag.id]
filter
|> Filter.spoilered_tags_changeset(spoilered_tag_ids)
|> Repo.update()
end
end end

View file

@ -45,6 +45,14 @@ defmodule Philomena.Filters.Filter do
|> unsafe_validate_unique([:user_id, :name], Repo) |> unsafe_validate_unique([:user_id, :name], Repo)
end end
def hidden_tags_changeset(filter, hidden_tag_ids) do
change(filter, hidden_tag_ids: hidden_tag_ids)
end
def spoilered_tags_changeset(filter, spoilered_tag_ids) do
change(filter, spoilered_tag_ids: spoilered_tag_ids)
end
defp validate_my_downvotes(changeset, field) do defp validate_my_downvotes(changeset, field) do
value = get_field(changeset, field) || "" value = get_field(changeset, field) || ""

View file

@ -95,6 +95,22 @@ defmodule Philomena.Users do
|> Repo.update() |> Repo.update()
end end
def watch_tag(%User{} = user, tag) do
watched_tag_ids = Enum.uniq([tag.id | user.watched_tag_ids])
user
|> User.watched_tags_changeset(watched_tag_ids)
|> Repo.update()
end
def unwatch_tag(%User{} = user, tag) do
watched_tag_ids = user.watched_tag_ids -- [tag.id]
user
|> User.watched_tags_changeset(watched_tag_ids)
|> Repo.update()
end
@doc """ @doc """
Returns an `%Ecto.Changeset{}` for tracking user changes. Returns an `%Ecto.Changeset{}` for tracking user changes.

View file

@ -193,6 +193,10 @@ defmodule Philomena.Users.User do
|> validate_format(:personal_title, ~r/\A((?!site|admin|moderator|assistant|developer|\p{C}).)*\z/iu) |> validate_format(:personal_title, ~r/\A((?!site|admin|moderator|assistant|developer|\p{C}).)*\z/iu)
end end
def watched_tags_changeset(user, watched_tag_ids) do
change(user, watched_tag_ids: watched_tag_ids)
end
def create_totp_secret_changeset(user) do def create_totp_secret_changeset(user) do
secret = :crypto.strong_rand_bytes(15) |> Base.encode32() secret = :crypto.strong_rand_bytes(15) |> Base.encode32()
data = Philomena.Users.Encryptor.encrypt_model(secret) data = Philomena.Users.Encryptor.encrypt_model(secret)

View file

@ -0,0 +1,56 @@
defmodule PhilomenaWeb.Filter.HideController do
use PhilomenaWeb, :controller
alias Philomena.Filters
alias Philomena.Tags.Tag
alias Philomena.Repo
plug :authorize_filter
plug :load_tag
def create(conn, _params) do
case Filters.hide_tag(conn.assigns.current_filter, conn.assigns.tag) do
{:ok, _filter} ->
conn
|> put_status(:ok)
|> text("")
{:error, _changeset} ->
conn
|> put_status(:internal_server_error)
|> text("")
end
end
def delete(conn, _params) do
case Filters.unhide_tag(conn.assigns.current_filter, conn.assigns.tag) do
{:ok, _filter} ->
conn
|> put_status(:ok)
|> text("")
{:error, _changeset} ->
conn
|> put_status(:internal_server_error)
|> text("")
end
end
defp authorize_filter(conn, _opts) do
case Canada.Can.can?(conn.assigns.current_user, :edit, conn.assigns.current_filter) do
true ->
conn
false ->
conn
|> put_status(:forbidden)
|> text("")
end
end
def load_tag(conn, _opts) do
tag = Repo.get_by!(Tag, slug: URI.encode(conn.params["tag"]))
assign(conn, :tag, tag)
end
end

View file

@ -0,0 +1,56 @@
defmodule PhilomenaWeb.Filter.SpoilerController do
use PhilomenaWeb, :controller
alias Philomena.Filters
alias Philomena.Tags.Tag
alias Philomena.Repo
plug :authorize_filter
plug :load_tag
def create(conn, _params) do
case Filters.spoiler_tag(conn.assigns.current_filter, conn.assigns.tag) do
{:ok, _filter} ->
conn
|> put_status(:ok)
|> text("")
{:error, _changeset} ->
conn
|> put_status(:internal_server_error)
|> text("")
end
end
def delete(conn, _params) do
case Filters.unspoiler_tag(conn.assigns.current_filter, conn.assigns.tag) do
{:ok, _filter} ->
conn
|> put_status(:ok)
|> text("")
{:error, _changeset} ->
conn
|> put_status(:internal_server_error)
|> text("")
end
end
defp authorize_filter(conn, _opts) do
case Canada.Can.can?(conn.assigns.current_user, :edit, conn.assigns.current_filter) do
true ->
conn
false ->
conn
|> put_status(:forbidden)
|> text("")
end
end
def load_tag(conn, _opts) do
tag = Repo.get_by!(Tag, slug: URI.encode(conn.params["tag"]))
assign(conn, :tag, tag)
end
end

View file

@ -0,0 +1,43 @@
defmodule PhilomenaWeb.Tag.WatchController do
use PhilomenaWeb, :controller
alias Philomena.Tags.Tag
alias Philomena.Users
alias Philomena.Repo
plug :load_tag
def create(conn, _params) do
case Users.watch_tag(conn.assigns.current_user, conn.assigns.tag) do
{:ok, _user} ->
conn
|> put_status(:ok)
|> text("")
{:error, _changeset} ->
conn
|> put_status(:internal_server_error)
|> text("")
end
end
def delete(conn, _params) do
case Users.unwatch_tag(conn.assigns.current_user, conn.assigns.tag) do
{:ok, _user} ->
conn
|> put_status(:ok)
|> text("")
{:error, _changeset} ->
conn
|> put_status(:internal_server_error)
|> text("")
end
end
def load_tag(conn, _opts) do
tag = Repo.get_by!(Tag, slug: URI.encode(conn.params["tag_id"]))
assign(conn, :tag, tag)
end
end

View file

@ -124,6 +124,12 @@ defmodule PhilomenaWeb.Router do
scope "/filters", Filter, as: :filter do scope "/filters", Filter, as: :filter do
resources "/spoiler_type", SpoilerTypeController, only: [:update], singleton: true resources "/spoiler_type", SpoilerTypeController, only: [:update], singleton: true
resources "/hide", HideController, only: [:create, :delete], singleton: true
resources "/spoiler", SpoilerController, only: [:create, :delete], singleton: true
end
resources "/tags", TagController, only: [] do
resources "/watch", Tag.WatchController, only: [:create, :delete], singleton: true
end end
resources "/reports", ReportController, only: [:index] resources "/reports", ReportController, only: [:index]

View file

@ -11,6 +11,7 @@
' This is a friendly name for this filter - it should be short and descriptive. ' This is a friendly name for this filter - it should be short and descriptive.
.field .field
= textarea f, :description, class: "input input--wide", placeholder: "Description" = textarea f, :description, class: "input input--wide", placeholder: "Description"
= error_tag f, :description
.fieldlabel .fieldlabel
' Here you can describe your filter in a bit more detail. ' Here you can describe your filter in a bit more detail.
@ -19,6 +20,7 @@
= label f, :spoilered_tag_list, "Spoilered Tags" = label f, :spoilered_tag_list, "Spoilered Tags"
br br
= render PhilomenaWeb.TagView, "_tag_editor.html", f: f, name: :spoilered_tag_list, type: "edit" = render PhilomenaWeb.TagView, "_tag_editor.html", f: f, name: :spoilered_tag_list, type: "edit"
= error_tag f, :spoilered_tag_list
.fieldlabel .fieldlabel
' These tags will spoiler the images they're associated with. ' These tags will spoiler the images they're associated with.
.field .field
@ -43,6 +45,7 @@
= label f, :hidden_tag_list, "Hidden Tags" = label f, :hidden_tag_list, "Hidden Tags"
br br
= render PhilomenaWeb.TagView, "_tag_editor.html", f: f, name: :hidden_tag_list, type: "edit" = render PhilomenaWeb.TagView, "_tag_editor.html", f: f, name: :hidden_tag_list, type: "edit"
= error_tag f, :hidden_tag_list
.fieldlabel .fieldlabel
' These tags will hide images entirely from the site; if you go directly to an image, it will spoiler it. ' These tags will hide images entirely from the site; if you go directly to an image, it will spoiler it.
.field .field

View file

@ -31,7 +31,6 @@ h1
p.filter-maintainer p.filter-maintainer
' This filter is maintained by ' This filter is maintained by
= render PhilomenaWeb.UserAttributionView, "_user.html", object: @filter, conn: @conn = render PhilomenaWeb.UserAttributionView, "_user.html", object: @filter, conn: @conn
' .
p.filter-description p.filter-description
= @filter.description = @filter.description
@ -40,7 +39,7 @@ h1
h5 This filter spoilers... h5 This filter spoilers...
= for tag <- @spoilered_tags do = for tag <- @spoilered_tags do
= render PhilomenaWeb.TagView, "_tag.html", tag: tag = render PhilomenaWeb.TagView, "_tag.html", tag: tag, conn: @conn
pre.spoiler-filter-code pre.spoiler-filter-code
= @filter.spoilered_complex_str = @filter.spoilered_complex_str
@ -52,7 +51,7 @@ h1
h5 This filter hides... h5 This filter hides...
= for tag <- @hidden_tags do = for tag <- @hidden_tags do
= render PhilomenaWeb.TagView, "_tag.html", tag: tag = render PhilomenaWeb.TagView, "_tag.html", tag: tag, conn: @conn
pre.spoiler-filter-code pre.spoiler-filter-code
= @filter.hidden_complex_str = @filter.hidden_complex_str

View file

@ -1,6 +1,6 @@
.center--layout--flex .center--layout--flex
= if @image.thumbnails_generated do = if @image.thumbnails_generated do
= render PhilomenaWeb.ImageView, "_image_target.html", image: @image = render PhilomenaWeb.ImageView, "_image_target.html", image: @image, conn: @conn
- else - else
#thumbnails-not-yet-generated.block.block--fixed.block--warning.layout--narrow #thumbnails-not-yet-generated.block.block--fixed.block--warning.layout--narrow
h3 Just a moment h3 Just a moment

View file

@ -5,7 +5,8 @@
p p
= img_tag(Routes.static_path(PhilomenaWeb.Endpoint, "/images/tagblocked.svg"), width: 250, height: 250, data: [click_unfilter: @image.id]) = img_tag(Routes.static_path(PhilomenaWeb.Endpoint, "/images/tagblocked.svg"), width: 250, height: 250, data: [click_unfilter: @image.id])
span.filter-explanation span.filter-explanation
=< link("your current filter", to: "#", class: "filter-link") =< link("your current filter", to: Routes.filter_path(@conn, :show, @conn.assigns.current_filter), class: "filter-link")
' .
#image_target.hidden.image-show data-scaled="true" data-uris=Jason.encode!(thumb_urls(@image, false)) data-width=@image.image_width data-height=@image.image_height #image_target.hidden.image-show data-scaled="true" data-uris=Jason.encode!(thumb_urls(@image, false)) data-width=@image.image_width data-height=@image.image_height
= if @image.image_mime_type == "video/webm" do = if @image.image_mime_type == "video/webm" do

View file

@ -49,7 +49,7 @@
.block__content.alternating-color.break-word .block__content.alternating-color.break-word
.center .center
= if link.tag do = if link.tag do
.tag_list = render PhilomenaWeb.TagView, "_tag.html", tag: link.tag .tag_list = render PhilomenaWeb.TagView, "_tag.html", tag: link.tag, conn: @conn
= link(link.uri, to: link.uri) = link(link.uri, to: link.uri)
.block .block

View file

@ -66,7 +66,7 @@ h1 Reverse Search
=> round(match.image_size / 1024) => round(match.image_size / 1024)
' KiB ' KiB
= render PhilomenaWeb.TagView, "_tag_list.html", tags: Tag.display_order(match.tags) = render PhilomenaWeb.TagView, "_tag_list.html", tags: Tag.display_order(match.tags), conn: @conn
- true -> - true ->
h2 Results h2 Results

View file

@ -15,14 +15,14 @@ span.tag.dropdown data-tag-category="#{@tag.category}" data-tag-id="#{@tag.id}"
span.tag__state.hidden title="Hidden" span.tag__state.hidden title="Hidden"
| H | H
span.dropdown__content span.dropdown__content
a.tag__dropdown__link.hidden data-method="delete" data-remote="true" data-tag-action="unwatch" href="/tags/#{@tag.slug}/watch" Unwatch a.tag__dropdown__link.hidden data-method="delete" data-remote="true" data-tag-action="unwatch" href=Routes.tag_watch_path(@conn, :delete, @tag) Unwatch
a.tag__dropdown__link.hidden data-method="post" data-remote="true" data-tag-action="watch" href="/tags/#{@tag.slug}/watch" Watch a.tag__dropdown__link.hidden data-method="post" data-remote="true" data-tag-action="watch" href=Routes.tag_watch_path(@conn, :create, @tag) Watch
a.tag__dropdown__link.hidden data-method="delete" data-remote="true" data-tag-action="unspoiler" href="/filters/spoiler?tagname=#{@tag.slug}" Unspoiler a.tag__dropdown__link.hidden data-method="delete" data-remote="true" data-tag-action="unspoiler" href=Routes.filter_spoiler_path(@conn, :delete, tag: @tag) Unspoiler
a.tag__dropdown__link.hidden data-method="post" data-remote="true" data-tag-action="spoiler" href="/filters/spoiler?tagname=#{@tag.slug}" Spoiler a.tag__dropdown__link.hidden data-method="post" data-remote="true" data-tag-action="spoiler" href=Routes.filter_spoiler_path(@conn, :create, tag: @tag) Spoiler
a.tag__dropdown__link.hidden data-method="delete" data-remote="true" data-tag-action="unhide" href="/filters/hide?tagname=#{@tag.slug}" Unhide a.tag__dropdown__link.hidden data-method="delete" data-remote="true" data-tag-action="unhide" href=Routes.filter_hide_path(@conn, :delete, tag: @tag) Unhide
a.tag__dropdown__link.hidden data-method="post" data-remote="true" data-tag-action="hide" href="/filters/hide?tagname=#{@tag.slug}" Hide a.tag__dropdown__link.hidden data-method="post" data-remote="true" data-tag-action="hide" href=Routes.filter_hide_path(@conn, :create, tag: @tag) Hide
a.tag__dropdown__link.hidden href="/users/sign_in" Sign in to Watch a.tag__dropdown__link.hidden href="/users/sign_in" Sign in to Watch
a.tag__dropdown__link.hidden href="/filters" Filter a.tag__dropdown__link.hidden href="/filters" Filter

View file

@ -6,7 +6,7 @@
| no spoiler image | no spoiler image
.flex__grow .flex__grow
= render PhilomenaWeb.TagView, "_tag.html", tag: @tag = render PhilomenaWeb.TagView, "_tag.html", tag: @tag, conn: @conn
= link "Tag changes", to: Routes.tag_tag_change_path(@conn, :index, @tag), class: "detail-link" = link "Tag changes", to: Routes.tag_tag_change_path(@conn, :index, @tag), class: "detail-link"
br br

View file

@ -1,3 +1,3 @@
.tag-list .tag-list
= for tag <- @tags do = for tag <- @tags do
= render PhilomenaWeb.TagView, "_tag.html", tag: tag = render PhilomenaWeb.TagView, "_tag.html", tag: tag, conn: @conn

View file

@ -18,7 +18,7 @@ h2 Search Results
- route = fn p -> Routes.tag_path(@conn, :index, p) end - route = fn p -> Routes.tag_path(@conn, :index, p) end
- pagination = render PhilomenaWeb.PaginationView, "_pagination.html", page: @tags, route: route - pagination = render PhilomenaWeb.PaginationView, "_pagination.html", page: @tags, route: route
= render PhilomenaWeb.TagView, "_tag_list.html", tags: @tags = render PhilomenaWeb.TagView, "_tag_list.html", tags: @tags, conn: @conn
.block .block
.block__header.block__header--light.flex .block__header.block__header--light.flex

View file

@ -52,7 +52,7 @@ h3 Visibility
h3 Associated tag h3 Associated tag
= if @user_link.tag do = if @user_link.tag do
p p
= render PhilomenaWeb.TagView, "_tag.html", tag: @user_link.tag = render PhilomenaWeb.TagView, "_tag.html", tag: @user_link.tag, conn: @conn
- else - else
p There is no tag associated with this link. p There is no tag associated with this link.