From 790ee13a36b32dba0dc6252f5ce81f192df38e35 Mon Sep 17 00:00:00 2001 From: "byte[]" Date: Sun, 17 Nov 2019 13:52:59 -0500 Subject: [PATCH] store comment attribution correctly; count unread conversations --- lib/philomena/comments.ex | 7 ++- lib/philomena/conversations.ex | 15 +++++++ lib/philomena/notifications.ex | 31 ++----------- lib/philomena/polymorphic.ex | 2 +- .../controllers/image/comment_controller.ex | 5 ++- .../plugs/notification_count_plug.ex | 43 +++++++++++++++++++ .../plugs/user_attribution_plug.ex | 7 +-- lib/philomena_web/router.ex | 1 + .../templates/layout/_header.html.slime | 11 ++++- 9 files changed, 83 insertions(+), 39 deletions(-) create mode 100644 lib/philomena_web/plugs/notification_count_plug.ex diff --git a/lib/philomena/comments.ex b/lib/philomena/comments.ex index 7b6876e8..276020d2 100644 --- a/lib/philomena/comments.ex +++ b/lib/philomena/comments.ex @@ -39,11 +39,10 @@ defmodule Philomena.Comments do {:error, %Ecto.Changeset{}} """ - def create_comment(image, user, attrs \\ %{}) do - user_id = if user, do: user.id, else: nil + def create_comment(image, attributes, params \\ %{}) do comment = - %Comment{image_id: image.id, user_id: user_id} - |> Comment.creation_changeset(attrs) + struct(Comment, [image_id: image.id] ++ attributes) + |> Comment.creation_changeset(params) image_query = Image diff --git a/lib/philomena/conversations.ex b/lib/philomena/conversations.ex index 8bca0edb..9f91a3b3 100644 --- a/lib/philomena/conversations.ex +++ b/lib/philomena/conversations.ex @@ -102,6 +102,21 @@ defmodule Philomena.Conversations do Conversation.changeset(conversation, %{}) end + def count_unread_conversations(user) do + Conversation + |> where([c], + ( + (c.to_id == ^user.id and c.to_read == false) or + (c.from_id == ^user.id and c.from_read == false) + ) + and not ( + (c.to_id == ^user.id and c.to_hidden == true) or + (c.from_id == ^user.id and c.from_hidden == true) + ) + ) + |> Repo.aggregate(:count, :id) + end + alias Philomena.Conversations.Message @doc """ diff --git a/lib/philomena/notifications.ex b/lib/philomena/notifications.ex index 4508c40a..d5e1e932 100644 --- a/lib/philomena/notifications.ex +++ b/lib/philomena/notifications.ex @@ -104,35 +104,12 @@ defmodule Philomena.Notifications do alias Philomena.Notifications.UnreadNotification - @doc """ - Returns the list of unread_notifications. - - ## Examples - - iex> list_unread_notifications() - [%UnreadNotification{}, ...] - - """ - def list_unread_notifications do - Repo.all(UnreadNotification) + def count_unread_notifications(user) do + UnreadNotification + |> where(user_id: ^user.id) + |> Repo.aggregate(:count, :notification_id) end - @doc """ - Gets a single unread_notification. - - Raises `Ecto.NoResultsError` if the Unread notification does not exist. - - ## Examples - - iex> get_unread_notification!(123) - %UnreadNotification{} - - iex> get_unread_notification!(456) - ** (Ecto.NoResultsError) - - """ - def get_unread_notification!(id), do: Repo.get!(UnreadNotification, id) - @doc """ Creates a unread_notification. diff --git a/lib/philomena/polymorphic.ex b/lib/philomena/polymorphic.ex index 29eee2b3..51cae744 100644 --- a/lib/philomena/polymorphic.ex +++ b/lib/philomena/polymorphic.ex @@ -20,7 +20,7 @@ defmodule Philomena.Polymorphic do @preloads %{ "Comment" => [:user], "Gallery" => [:creator], - "Image" => [:user], + "Image" => [:user, :tags], "Post" => [:user], "Topic" => [:forum, :user] } diff --git a/lib/philomena_web/controllers/image/comment_controller.ex b/lib/philomena_web/controllers/image/comment_controller.ex index 9f49afca..750ef842 100644 --- a/lib/philomena_web/controllers/image/comment_controller.ex +++ b/lib/philomena_web/controllers/image/comment_controller.ex @@ -15,6 +15,7 @@ defmodule PhilomenaWeb.Image.CommentController do plug :load_and_authorize_resource, model: Comment, only: [:show], preload: [:image, user: [awards: :badge]] plug PhilomenaWeb.FilterBannedUsersPlug when action in [:create, :edit, :update] + plug PhilomenaWeb.UserAttributionPlug when action in [:create] def index(conn, %{"comment_id" => comment_id}) do comment = @@ -60,10 +61,10 @@ defmodule PhilomenaWeb.Image.CommentController do end def create(conn, %{"comment" => comment_params}) do - user = conn.assigns.current_user + attributes = conn.assigns.attributes image = conn.assigns.image - case Comments.create_comment(image, user, comment_params) do + case Comments.create_comment(image, attributes, comment_params) do {:ok, %{comment: comment}} -> Comments.notify_comment(comment) Comments.reindex_comment(comment) diff --git a/lib/philomena_web/plugs/notification_count_plug.ex b/lib/philomena_web/plugs/notification_count_plug.ex new file mode 100644 index 00000000..00e1d328 --- /dev/null +++ b/lib/philomena_web/plugs/notification_count_plug.ex @@ -0,0 +1,43 @@ +defmodule PhilomenaWeb.NotificationCountPlug do + @moduledoc """ + This plug stores the current notification count. + + ## Example + + plug PhilomenaWeb.NotificationCountPlug + """ + + alias Plug.Conn + alias Philomena.Conversations + alias Philomena.Notifications + + @doc false + @spec init(any()) :: any() + def init(opts), do: opts + + @doc false + @spec call(Plug.Conn.t(), any()) :: Plug.Conn.t() + def call(conn, _opts) do + user = Pow.Plug.current_user(conn) + + conn + |> maybe_assign_notifications(user) + |> maybe_assign_conversations(user) + end + + defp maybe_assign_notifications(conn, nil), do: conn + defp maybe_assign_notifications(conn, user) do + notifications = Notifications.count_unread_notifications(user) + + conn + |> Conn.assign(:notification_count, notifications) + end + + defp maybe_assign_conversations(conn, nil), do: conn + defp maybe_assign_conversations(conn, user) do + conversations = Conversations.count_unread_conversations(user) + + conn + |> Conn.assign(:conversation_count, conversations) + end +end \ No newline at end of file diff --git a/lib/philomena_web/plugs/user_attribution_plug.ex b/lib/philomena_web/plugs/user_attribution_plug.ex index a1ab0364..b97e31b3 100644 --- a/lib/philomena_web/plugs/user_attribution_plug.ex +++ b/lib/philomena_web/plugs/user_attribution_plug.ex @@ -17,15 +17,16 @@ defmodule PhilomenaWeb.UserAttributionPlug do @doc false @spec call(Plug.Conn.t(), any()) :: Plug.Conn.t() def call(conn, _opts) do + {:ok, remote_ip} = EctoNetwork.INET.cast(conn.remote_ip) conn = Conn.fetch_cookies(conn) attributes = - %{ - ip: conn.remote_ip, + [ + ip: remote_ip, fingerprint: conn.cookies["_ses"], referrer: conn.assigns.referrer, user_agent: user_agent(conn), user_id: user_id(conn) - } + ] conn |> Conn.assign(:attributes, attributes) diff --git a/lib/philomena_web/router.ex b/lib/philomena_web/router.ex index 66bb3358..e1c181a9 100644 --- a/lib/philomena_web/router.ex +++ b/lib/philomena_web/router.ex @@ -14,6 +14,7 @@ defmodule PhilomenaWeb.Router do plug PhilomenaWeb.PaginationPlug plug PhilomenaWeb.EnsureUserEnabledPlug plug PhilomenaWeb.CurrentBanPlug + plug PhilomenaWeb.NotificationCountPlug end pipeline :api do diff --git a/lib/philomena_web/templates/layout/_header.html.slime b/lib/philomena_web/templates/layout/_header.html.slime index c06509a1..cfd0e80e 100644 --- a/lib/philomena_web/templates/layout/_header.html.slime +++ b/lib/philomena_web/templates/layout/_header.html.slime @@ -23,14 +23,21 @@ header.header .flex.flex--centered.flex--no-wrap.header__force-right = if @current_user do - - notification_count = 0 + - notification_count = @conn.assigns.notification_count + - conversation_count = @conn.assigns.conversation_count + a.header__link href="/notifications" title="Notifications" i.fa-embedded--notification> span.js-notification-ticker.fa__text.header__counter data-notification-count=notification_count = notification_count a.header__link href="/conversations" title="Conversations" i.fa-embedded--message> - span.fa-embedded__text.header__counter.hidden = "0" + = if @conversation_count > 0 do + span.fa-embedded__text.header__counter + = @conversation_count + - else + span.fa-embedded__text.header__counter.hidden + | 0 a.header__link.hide-mobile href="/filters" title="Filters" i.fa.fa-filter