add filter selection

This commit is contained in:
byte[] 2019-11-17 14:47:01 -05:00
parent 27a443bd2a
commit a8fef6d03c
8 changed files with 125 additions and 2 deletions

View file

@ -116,4 +116,30 @@ defmodule Philomena.Filters do
def change_filter(%Filter{} = filter) do
Filter.changeset(filter, %{})
end
def recent_and_user_filters(user) do
user_filters =
Filter
|> select([f], %{id: f.id, name: f.name, recent: ^"f"})
|> where(user_id: ^user.id)
|> limit(10)
recent_filters =
Filter
|> select([f], %{id: f.id, name: f.name, recent: ^"t"})
|> where([f], f.id in ^user.recent_filter_ids)
|> limit(10)
union(recent_filters, ^user_filters)
|> Repo.all()
|> Enum.group_by(
fn
%{recent: "t"} -> "Recent Filters"
_user -> "Your Filters"
end,
fn %{id: id, name: name} ->
[key: name, value: id]
end
)
end
end

View file

@ -77,6 +77,12 @@ defmodule Philomena.Users do
|> Repo.update()
end
def update_spoiler_type(%User{} = user, attrs) do
user
|> User.spoiler_type_changeset(attrs)
|> Repo.update()
end
@doc """
Returns an `%Ecto.Changeset{}` for tracking user changes.

View file

@ -143,8 +143,19 @@ defmodule Philomena.Users.User do
end
def filter_changeset(user, filter) do
change(user)
changeset = change(user)
user = changeset.data
changeset
|> put_change(:current_filter_id, filter.id)
|> put_change(:recent_filter_ids, Enum.take([filter.id | user.recent_filter_ids], 10))
end
def spoiler_type_changeset(user, attrs) do
user
|> cast(attrs, [:spoiler_type])
|> validate_required([:spoiler_type])
|> validate_inclusion(:spoiler_type, ~W(static click hover off))
end
def create_totp_secret_changeset(user) do

View file

@ -20,7 +20,7 @@ defmodule PhilomenaWeb.Filter.CurrentController do
conn
|> update_filter(user, filter)
|> put_flash(:info, "Switched to filter #{filter.name}")
|> redirect(to: Routes.filter_path(conn, :index))
|> redirect(external: conn.assigns.referrer)
end
defp update_filter(conn, nil, filter) do

View file

@ -0,0 +1,21 @@
defmodule PhilomenaWeb.Filter.SpoilerTypeController do
use PhilomenaWeb, :controller
alias Philomena.Users
plug PhilomenaWeb.RequireUserPlug
def update(conn, %{"user" => user_params}) do
case Users.update_spoiler_type(conn.assigns.current_user, user_params) do
{:ok, user} ->
conn
|> put_flash(:info, "Changed spoiler type to #{user.spoiler_type}")
|> redirect(external: conn.assigns.referrer)
{:error, _changeset} ->
conn
|> put_flash(:error, "Failed to set spoiler type")
|> redirect(external: conn.assigns.referrer)
end
end
end

View file

@ -0,0 +1,47 @@
defmodule PhilomenaWeb.FilterSelectPlug do
@moduledoc """
This plug sets up the filter menu for the layout if there is a
user currently signed in.
## Example
plug PhilomenaWeb.FilterSelectPlug
"""
alias Philomena.Filters
alias Philomena.Users
alias Plug.Conn
@spoiler_types %{
"Spoilers" => [
static: "static",
click: "click",
hover: "hover",
off: "off"
]
}
@doc false
@spec init(any()) :: any()
def init(opts), do: opts
@doc false
@spec call(Conn.t(), any()) :: Conn.t()
def call(conn, _opts) do
user = Pow.Plug.current_user(conn)
conn
|> maybe_assign_filters(user)
end
defp maybe_assign_filters(conn, nil), do: conn
defp maybe_assign_filters(conn, user) do
filters = Filters.recent_and_user_filters(user)
user = Users.change_user(user)
conn
|> Conn.assign(:user_changeset, user)
|> Conn.assign(:available_filters, filters)
|> Conn.assign(:spoiler_types, @spoiler_types)
end
end

View file

@ -15,6 +15,7 @@ defmodule PhilomenaWeb.Router do
plug PhilomenaWeb.EnsureUserEnabledPlug
plug PhilomenaWeb.CurrentBanPlug
plug PhilomenaWeb.NotificationCountPlug
plug PhilomenaWeb.FilterSelectPlug
end
pipeline :api do
@ -67,6 +68,10 @@ defmodule PhilomenaWeb.Router do
resources "/subscription", Topic.SubscriptionController, only: [:create, :delete], singleton: true
end
end
scope "/filters", Filter, as: :filter do
resources "/spoiler_type", SpoilerTypeController, only: [:update], singleton: true
end
end
scope "/", PhilomenaWeb do

View file

@ -43,6 +43,13 @@ header.header
a.header__link.hide-mobile href="/filters" title="Filters"
i.fa.fa-filter
span.hide-limited-desktop< Filters
= form_for @conn.assigns.user_changeset, Routes.filter_current_path(@conn, :update), [class: "header__filter-form", id: "filter-quick-form"], fn f ->
= select f, :current_filter_id, @conn.assigns.available_filters, name: "id", id: "filter-quick-menu", class: "input header__input", data: [change_submit: "#filter-quick-form"], autocomplete: "off"
= form_for @conn.assigns.user_changeset, Routes.filter_spoiler_type_path(@conn, :update), [class: "header__filter-form hide-mobile hide-limited-desktop", id: "spoiler-quick-form"], fn f ->
= select f, :spoiler_type, @conn.assigns.spoiler_types, id: "spoiler-quick-menu", class: "input header__input", data: [change_submit: "#spoiler-quick-form"], autocomplete: "off"
.dropdown.header__dropdown
a.header__link.header__link-user href="/"
= render PhilomenaWeb.UserAttributionView, "_user_avatar.html", object: %{user: @current_user}, class: "avatar--28px"