diff --git a/lib/philomena_web.ex b/lib/philomena_web.ex index 24c39e3b..7b33057f 100644 --- a/lib/philomena_web.ex +++ b/lib/philomena_web.ex @@ -25,6 +25,7 @@ defmodule PhilomenaWeb do import PhilomenaWeb.Gettext import Canary.Plugs alias PhilomenaWeb.Router.Helpers, as: Routes + alias PhilomenaWeb.Plugs.RequireUser end end diff --git a/lib/philomena_web/controllers/filter_controller.ex b/lib/philomena_web/controllers/filter_controller.ex index 9f1f15a8..e4aabab0 100644 --- a/lib/philomena_web/controllers/filter_controller.ex +++ b/lib/philomena_web/controllers/filter_controller.ex @@ -1,10 +1,13 @@ defmodule PhilomenaWeb.FilterController do use PhilomenaWeb, :controller - alias Philomena.Filters.Filter + alias Philomena.{Filters, Filters.Filter, Tags.Tag} alias Philomena.Repo import Ecto.Query + plug :load_and_authorize_resource, model: Filter, except: [:index], preload: :user + plug RequireUser when action not in [:index, :show] + def index(conn, _params) do user = conn.assigns.current_user @@ -26,4 +29,71 @@ defmodule PhilomenaWeb.FilterController do render(conn, "index.html", my_filters: my_filters, system_filters: system_filters) end + + def show(conn, _params) do + filter = conn.assigns.filter + + spoilered_tags = + Tag + |> where([t], t.id in ^filter.spoilered_tag_ids) + |> order_by(asc: :name) + |> Repo.all() + + hidden_tags = + Tag + |> where([t], t.id in ^filter.hidden_tag_ids) + |> order_by(asc: :name) + |> Repo.all() + + render(conn, "show.html", filter: filter, spoilered_tags: spoilered_tags, hidden_tags: hidden_tags) + end + + def new(conn, _params) do + changeset = Filters.change_filter(%Filter{}) + + render(conn, "new.html", changeset: changeset) + end + + def create(conn, %{"filter" => filter_params}) do + case Filters.create_filter(conn.assigns.current_user, filter_params) do + {:ok, filter} -> + conn + |> put_flash(:info, "Filter created successfully.") + |> redirect(to: Routes.filter_path(conn, :show, filter)) + + {:error, %Ecto.Changeset{} = changeset} -> + render(conn, "new.html", changeset: changeset) + end + end + + def edit(conn, _params) do + filter = conn.assigns.filter + changeset = Filters.change_filter(filter) + + render(conn, "edit.html", filter: filter, changeset: changeset) + end + + def update(conn, %{"filter" => filter_params}) do + filter = conn.assigns.filter + + case Filters.update_filter(filter, filter_params) do + {:ok, filter} -> + conn + |> put_flash(:info, "Filter updated successfully.") + |> redirect(to: Routes.filter_path(conn, :show, filter)) + + {:error, %Ecto.Changeset{} = changeset} -> + render(conn, "edit.html", filter: filter, changeset: changeset) + end + end + + def delete(conn, _params) do + filter = conn.assigns.filter + + {:ok, _filter} = Filters.delete_filter(filter) + + conn + |> put_flash(:info, "Filter deleted successfully.") + |> redirect(to: Routes.filter_path(conn, :index)) + end end diff --git a/lib/philomena_web/plugs/current_filter.ex b/lib/philomena_web/plugs/current_filter.ex index f26fb1c0..e9b6d659 100644 --- a/lib/philomena_web/plugs/current_filter.ex +++ b/lib/philomena_web/plugs/current_filter.ex @@ -5,7 +5,6 @@ defmodule PhilomenaWeb.Plugs.CurrentFilter do alias Philomena.{Filters, Filters.Filter} alias Philomena.Repo alias Pow.Plug - # No options def init([]), do: false diff --git a/lib/philomena_web/plugs/require_user.ex b/lib/philomena_web/plugs/require_user.ex new file mode 100644 index 00000000..88aac28a --- /dev/null +++ b/lib/philomena_web/plugs/require_user.ex @@ -0,0 +1,22 @@ +defmodule PhilomenaWeb.Plugs.RequireUser do + import Phoenix.Controller + import Plug.Conn + import Pow.Plug + + # No options + def init([]), do: false + + # Redirect if not logged in + def call(conn, _opts) do + user = conn |> current_user() + + if user do + conn + else + conn + |> put_flash(:error, "You must be signed in to see this page.") + |> redirect(to: "/") + |> halt() + end + end +end diff --git a/lib/philomena_web/router.ex b/lib/philomena_web/router.ex index 2cbeba00..8f960520 100644 --- a/lib/philomena_web/router.ex +++ b/lib/philomena_web/router.ex @@ -38,7 +38,7 @@ defmodule PhilomenaWeb.Router do scope "/filters", Filter, as: :filter do resources "/current", CurrentController, only: [:update], singular: true end - resources "/filters", FilterController, only: [:index, :show] + resources "/filters", FilterController get "/:id", ImageController, :show end diff --git a/lib/philomena_web/templates/filter/_filter.html.slime b/lib/philomena_web/templates/filter/_filter.html.slime index b4a9583b..13cf0f93 100644 --- a/lib/philomena_web/templates/filter/_filter.html.slime +++ b/lib/philomena_web/templates/filter/_filter.html.slime @@ -24,15 +24,7 @@ strong Your current filter - else li - = form_for nil, Routes.filter_current_path(@conn, :update, @filter), [method: "put", class: "button_to"], fn f -> - = submit "Use this filter", class: "button" - - /- if can?(:edit, filter) && current_user && filter.user_id == current_user.id - / li = link_to 'Edit this filter', edit_filter_path(filter), class: 'button' - / - if can?(:delete, filter) && current_user && filter.user_id == current_user.id - / li = button_to 'Delete this filter', filter_path(filter), data: { confirm: 'Are you sure you want to delete this filter?' }, method: :delete, class: 'button' - /- elsif can? :create, Filter - / li = link_to 'Copy and Customize this filter', new_filter_path(based_on_filter_id: filter.id), class: 'button' + = button_to "Use this filter", Routes.filter_current_path(@conn, :update, @filter), method: "put", class: "button" p em = @filter.description diff --git a/lib/philomena_web/templates/filter/show.html.slime b/lib/philomena_web/templates/filter/show.html.slime new file mode 100644 index 00000000..40daf982 --- /dev/null +++ b/lib/philomena_web/templates/filter/show.html.slime @@ -0,0 +1,69 @@ +h1 + ' Viewing full filter details for + = @filter.name + +.filter + .filter-options + ul + li + ' Spoilers + => number_with_delimiter(length(@filter.spoilered_tag_ids)) + => pluralize("tag", "tags", length(@filter.spoilered_tag_ids)) + ' and hides + => number_with_delimiter(length(@filter.hidden_tag_ids)) + => pluralize("tag", "tags", length(@filter.hidden_tag_ids)) + + = if @filter.id == @conn.assigns.current_filter.id do + li + strong Your current filter + - else + li + = button_to "Use this filter", Routes.filter_current_path(@conn, :update, @filter), method: "put", class: "button" + + = if can?(@conn, :edit, @filter) do + li + = link("Edit this filter", to: Routes.filter_path(@conn, :edit, @filter)) + + = if can?(@conn, :delete, @filter) do + = button_to "Destroy this filter", Routes.filter_path(@conn, :delete, @filter), method: "delete", class: "button", data: [confirm: "Are you sure?"] + + = if @filter.user do + p.filter-maintainer + ' This filter is maintained by + = render PhilomenaWeb.UserAttributionView, "_user.html", object: @filter + ' . + + p.filter-description + = @filter.description + + = if length(@spoilered_tags) > 0 or !!@filter.spoilered_complex_str do + h5 This filter spoilers... + + = for tag <- @spoilered_tags do + = render PhilomenaWeb.TagView, "_tag.html", tag: tag + + p Complex filter: + pre.spoiler-filter-code + = @filter.spoilered_complex_str + + - else + p This filter doesn't spoiler any tags. + + + = if length(@hidden_tags) > 0 or !!@filter.hidden_complex_str do + h5 This filter hides... + + = for tag <- @hidden_tags do + = render PhilomenaWeb.TagView, "_tag.html", tag: tag + + p Complex filter: + pre.spoiler-filter-code + = @filter.hidden_complex_str + + - else + p This filter doesn't hide any tags. + + + +/p = link("Report filter to moderators", new_report_path(reportable_class: 'filter', reportable_id: @filter.id) +p = link("Back to filters", to: Routes.filter_path(@conn, :index)) diff --git a/lib/philomena_web/views/app_view.ex b/lib/philomena_web/views/app_view.ex index a5ec52fe..31954760 100644 --- a/lib/philomena_web/views/app_view.ex +++ b/lib/philomena_web/views/app_view.ex @@ -47,4 +47,32 @@ defmodule PhilomenaWeb.AppView do def can?(conn, action, model) do Canada.Can.can?(conn.assigns.current_user, action, model) end + + def number_with_delimiter(number) do + number + |> to_charlist() + |> Enum.reverse() + |> Enum.chunk_every(3) + |> Enum.map(&Enum.reverse(&1)) + |> Enum.reverse() + |> Enum.join(",") + end + + def pluralize(singular, plural, count) do + if count == 1 do + singular + else + plural + end + end + + def button_to(text, route, args) do + method = Keyword.get(args, :method, "get") + class = Keyword.get(args, :class, nil) + data = Keyword.get(args, :data, []) + + form_for(nil, route, [method: method, class: "button_to"], fn _f -> + submit text, class: class, data: data + end) + end end