store comment attribution correctly; count unread conversations

This commit is contained in:
byte[] 2019-11-17 13:52:59 -05:00
parent 41bf4790af
commit 790ee13a36
9 changed files with 83 additions and 39 deletions

View file

@ -39,11 +39,10 @@ defmodule Philomena.Comments do
{:error, %Ecto.Changeset{}} {:error, %Ecto.Changeset{}}
""" """
def create_comment(image, user, attrs \\ %{}) do def create_comment(image, attributes, params \\ %{}) do
user_id = if user, do: user.id, else: nil
comment = comment =
%Comment{image_id: image.id, user_id: user_id} struct(Comment, [image_id: image.id] ++ attributes)
|> Comment.creation_changeset(attrs) |> Comment.creation_changeset(params)
image_query = image_query =
Image Image

View file

@ -102,6 +102,21 @@ defmodule Philomena.Conversations do
Conversation.changeset(conversation, %{}) Conversation.changeset(conversation, %{})
end 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 alias Philomena.Conversations.Message
@doc """ @doc """

View file

@ -104,35 +104,12 @@ defmodule Philomena.Notifications do
alias Philomena.Notifications.UnreadNotification alias Philomena.Notifications.UnreadNotification
@doc """ def count_unread_notifications(user) do
Returns the list of unread_notifications. UnreadNotification
|> where(user_id: ^user.id)
## Examples |> Repo.aggregate(:count, :notification_id)
iex> list_unread_notifications()
[%UnreadNotification{}, ...]
"""
def list_unread_notifications do
Repo.all(UnreadNotification)
end 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 """ @doc """
Creates a unread_notification. Creates a unread_notification.

View file

@ -20,7 +20,7 @@ defmodule Philomena.Polymorphic do
@preloads %{ @preloads %{
"Comment" => [:user], "Comment" => [:user],
"Gallery" => [:creator], "Gallery" => [:creator],
"Image" => [:user], "Image" => [:user, :tags],
"Post" => [:user], "Post" => [:user],
"Topic" => [:forum, :user] "Topic" => [:forum, :user]
} }

View file

@ -15,6 +15,7 @@ defmodule PhilomenaWeb.Image.CommentController do
plug :load_and_authorize_resource, model: Comment, only: [:show], preload: [:image, user: [awards: :badge]] 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.FilterBannedUsersPlug when action in [:create, :edit, :update]
plug PhilomenaWeb.UserAttributionPlug when action in [:create]
def index(conn, %{"comment_id" => comment_id}) do def index(conn, %{"comment_id" => comment_id}) do
comment = comment =
@ -60,10 +61,10 @@ defmodule PhilomenaWeb.Image.CommentController do
end end
def create(conn, %{"comment" => comment_params}) do def create(conn, %{"comment" => comment_params}) do
user = conn.assigns.current_user attributes = conn.assigns.attributes
image = conn.assigns.image 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}} -> {:ok, %{comment: comment}} ->
Comments.notify_comment(comment) Comments.notify_comment(comment)
Comments.reindex_comment(comment) Comments.reindex_comment(comment)

View file

@ -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

View file

@ -17,15 +17,16 @@ defmodule PhilomenaWeb.UserAttributionPlug do
@doc false @doc false
@spec call(Plug.Conn.t(), any()) :: Plug.Conn.t() @spec call(Plug.Conn.t(), any()) :: Plug.Conn.t()
def call(conn, _opts) do def call(conn, _opts) do
{:ok, remote_ip} = EctoNetwork.INET.cast(conn.remote_ip)
conn = Conn.fetch_cookies(conn) conn = Conn.fetch_cookies(conn)
attributes = attributes =
%{ [
ip: conn.remote_ip, ip: remote_ip,
fingerprint: conn.cookies["_ses"], fingerprint: conn.cookies["_ses"],
referrer: conn.assigns.referrer, referrer: conn.assigns.referrer,
user_agent: user_agent(conn), user_agent: user_agent(conn),
user_id: user_id(conn) user_id: user_id(conn)
} ]
conn conn
|> Conn.assign(:attributes, attributes) |> Conn.assign(:attributes, attributes)

View file

@ -14,6 +14,7 @@ defmodule PhilomenaWeb.Router do
plug PhilomenaWeb.PaginationPlug plug PhilomenaWeb.PaginationPlug
plug PhilomenaWeb.EnsureUserEnabledPlug plug PhilomenaWeb.EnsureUserEnabledPlug
plug PhilomenaWeb.CurrentBanPlug plug PhilomenaWeb.CurrentBanPlug
plug PhilomenaWeb.NotificationCountPlug
end end
pipeline :api do pipeline :api do

View file

@ -23,14 +23,21 @@ header.header
.flex.flex--centered.flex--no-wrap.header__force-right .flex.flex--centered.flex--no-wrap.header__force-right
= if @current_user do = 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" a.header__link href="/notifications" title="Notifications"
i.fa-embedded--notification> i.fa-embedded--notification>
span.js-notification-ticker.fa__text.header__counter data-notification-count=notification_count = notification_count span.js-notification-ticker.fa__text.header__counter data-notification-count=notification_count = notification_count
a.header__link href="/conversations" title="Conversations" a.header__link href="/conversations" title="Conversations"
i.fa-embedded--message> 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" a.header__link.hide-mobile href="/filters" title="Filters"
i.fa.fa-filter i.fa.fa-filter