mirror of
https://github.com/philomena-dev/philomena.git
synced 2024-12-18 06:57:59 +01:00
219 lines
4.9 KiB
Elixir
219 lines
4.9 KiB
Elixir
defmodule Philomena.Notifications do
|
|
@moduledoc """
|
|
The Notifications context.
|
|
"""
|
|
|
|
import Ecto.Query, warn: false
|
|
alias Philomena.Repo
|
|
|
|
alias Philomena.Notifications.Notification
|
|
|
|
@doc """
|
|
Returns the list of notifications.
|
|
|
|
## Examples
|
|
|
|
iex> list_notifications()
|
|
[%Notification{}, ...]
|
|
|
|
"""
|
|
def list_notifications do
|
|
Repo.all(Notification)
|
|
end
|
|
|
|
@doc """
|
|
Gets a single notification.
|
|
|
|
Raises `Ecto.NoResultsError` if the Notification does not exist.
|
|
|
|
## Examples
|
|
|
|
iex> get_notification!(123)
|
|
%Notification{}
|
|
|
|
iex> get_notification!(456)
|
|
** (Ecto.NoResultsError)
|
|
|
|
"""
|
|
def get_notification!(id), do: Repo.get!(Notification, id)
|
|
|
|
@doc """
|
|
Creates a notification.
|
|
|
|
## Examples
|
|
|
|
iex> create_notification(%{field: value})
|
|
{:ok, %Notification{}}
|
|
|
|
iex> create_notification(%{field: bad_value})
|
|
{:error, %Ecto.Changeset{}}
|
|
|
|
"""
|
|
def create_notification(attrs \\ %{}) do
|
|
%Notification{}
|
|
|> Notification.changeset(attrs)
|
|
|> Repo.insert()
|
|
end
|
|
|
|
@doc """
|
|
Updates a notification.
|
|
|
|
## Examples
|
|
|
|
iex> update_notification(notification, %{field: new_value})
|
|
{:ok, %Notification{}}
|
|
|
|
iex> update_notification(notification, %{field: bad_value})
|
|
{:error, %Ecto.Changeset{}}
|
|
|
|
"""
|
|
def update_notification(%Notification{} = notification, attrs) do
|
|
notification
|
|
|> Notification.changeset(attrs)
|
|
|> Repo.insert_or_update()
|
|
end
|
|
|
|
@doc """
|
|
Deletes a Notification.
|
|
|
|
## Examples
|
|
|
|
iex> delete_notification(notification)
|
|
{:ok, %Notification{}}
|
|
|
|
iex> delete_notification(notification)
|
|
{:error, %Ecto.Changeset{}}
|
|
|
|
"""
|
|
def delete_notification(%Notification{} = notification) do
|
|
Repo.delete(notification)
|
|
end
|
|
|
|
@doc """
|
|
Returns an `%Ecto.Changeset{}` for tracking notification changes.
|
|
|
|
## Examples
|
|
|
|
iex> change_notification(notification)
|
|
%Ecto.Changeset{source: %Notification{}}
|
|
|
|
"""
|
|
def change_notification(%Notification{} = notification) do
|
|
Notification.changeset(notification, %{})
|
|
end
|
|
|
|
alias Philomena.Notifications.UnreadNotification
|
|
|
|
def count_unread_notifications(user) do
|
|
UnreadNotification
|
|
|> where(user_id: ^user.id)
|
|
|> Repo.aggregate(:count, :notification_id)
|
|
end
|
|
|
|
@doc """
|
|
Creates a unread_notification.
|
|
|
|
## Examples
|
|
|
|
iex> create_unread_notification(%{field: value})
|
|
{:ok, %UnreadNotification{}}
|
|
|
|
iex> create_unread_notification(%{field: bad_value})
|
|
{:error, %Ecto.Changeset{}}
|
|
|
|
"""
|
|
def create_unread_notification(attrs \\ %{}) do
|
|
%UnreadNotification{}
|
|
|> UnreadNotification.changeset(attrs)
|
|
|> Repo.insert()
|
|
end
|
|
|
|
@doc """
|
|
Updates a unread_notification.
|
|
|
|
## Examples
|
|
|
|
iex> update_unread_notification(unread_notification, %{field: new_value})
|
|
{:ok, %UnreadNotification{}}
|
|
|
|
iex> update_unread_notification(unread_notification, %{field: bad_value})
|
|
{:error, %Ecto.Changeset{}}
|
|
|
|
"""
|
|
def update_unread_notification(%UnreadNotification{} = unread_notification, attrs) do
|
|
unread_notification
|
|
|> UnreadNotification.changeset(attrs)
|
|
|> Repo.update()
|
|
end
|
|
|
|
@doc """
|
|
Deletes a UnreadNotification.
|
|
|
|
## Examples
|
|
|
|
iex> delete_unread_notification(unread_notification)
|
|
{:ok, %UnreadNotification{}}
|
|
|
|
iex> delete_unread_notification(unread_notification)
|
|
{:error, %Ecto.Changeset{}}
|
|
|
|
"""
|
|
def delete_unread_notification(actor_type, actor_id, user) do
|
|
notification =
|
|
Notification
|
|
|> where(actor_type: ^actor_type, actor_id: ^actor_id)
|
|
|> Repo.one()
|
|
|
|
if notification do
|
|
UnreadNotification
|
|
|> where(notification_id: ^notification.id, user_id: ^user.id)
|
|
|> Repo.delete_all()
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Returns an `%Ecto.Changeset{}` for tracking unread_notification changes.
|
|
|
|
## Examples
|
|
|
|
iex> change_unread_notification(unread_notification)
|
|
%Ecto.Changeset{source: %UnreadNotification{}}
|
|
|
|
"""
|
|
def change_unread_notification(%UnreadNotification{} = unread_notification) do
|
|
UnreadNotification.changeset(unread_notification, %{})
|
|
end
|
|
|
|
def notify(_actor_child, [], _params), do: nil
|
|
|
|
def notify(actor_child, subscriptions, params) do
|
|
# Don't push to the user that created the notification
|
|
subscriptions =
|
|
case actor_child do
|
|
%{user_id: id} ->
|
|
subscriptions
|
|
|> Enum.reject(&(&1.user_id == id))
|
|
|
|
_ ->
|
|
subscriptions
|
|
end
|
|
|
|
Repo.transaction(fn ->
|
|
notification =
|
|
Notification
|
|
|> Repo.get_by(actor_id: params.actor_id, actor_type: params.actor_type)
|
|
|
|
{:ok, notification} =
|
|
(notification || %Notification{})
|
|
|> update_notification(params)
|
|
|
|
# Insert the notification to any watchers who do not have it
|
|
unreads =
|
|
subscriptions
|
|
|> Enum.map(&%{user_id: &1.user_id, notification_id: notification.id})
|
|
|
|
UnreadNotification
|
|
|> Repo.insert_all(unreads, on_conflict: :nothing)
|
|
end)
|
|
end
|
|
end
|