-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #60 from CaptainFact/feature/notifications
Notifications
- Loading branch information
Showing
68 changed files
with
1,759 additions
and
180 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,3 +21,6 @@ apps/*/priv/secrets/* | |
|
||
# Elixir LS | ||
.elixir_ls | ||
|
||
# IDE | ||
.history |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
defmodule CF.Notifications.NotificationBuilder do | ||
@moduledoc """ | ||
A module to build Notification from various inputs. | ||
""" | ||
|
||
require Logger | ||
|
||
alias DB.Schema.Subscription | ||
alias DB.Schema.UserAction | ||
alias DB.Schema.Notification | ||
alias DB.Type.NotificationType | ||
alias DB.Type.SubscriptionReason | ||
|
||
@doc """ | ||
Return `Notification` params to put in a changeset for given action and | ||
subscription. | ||
## Examples | ||
iex> action = %UserAction{id: 42, type: :create, entity: :statement} | ||
iex> subscription = %Subscription{user_id: 100} | ||
iex> NotificationBuilder.for_subscribed_action(action, subscription) | ||
%{action_id: 42, type: :new_statement, user_id: 100} | ||
""" | ||
@spec for_subscribed_action(UserAction.t(), Subscription.t()) :: Notification.t() | ||
def for_subscribed_action(action, subscription) when not is_nil(subscription) do | ||
%{ | ||
user_id: subscription.user_id, | ||
action_id: action.id, | ||
type: notification_type(action, subscription) | ||
} | ||
end | ||
|
||
@spec notification_type(SubscriptionReason.t(), Subscription.t()) :: NotificationType.t() | ||
defp notification_type( | ||
%{type: :create, entity: :comment, changes: %{"reply_to_id" => comment_id}}, | ||
%{reason: :is_author, comment_id: comment_id} | ||
), | ||
do: :reply_to_comment | ||
|
||
defp notification_type(%{type: :create, entity: :comment}, _), | ||
do: :new_comment | ||
|
||
defp notification_type(%{type: :create, entity: :statement}, _), | ||
do: :new_statement | ||
|
||
defp notification_type(%{type: type, entity: :speaker}, _) when type in [:create, :add], | ||
do: :new_speaker | ||
|
||
defp notification_type(%{type: :update, entity: :statement}, _), | ||
do: :updated_statement | ||
|
||
defp notification_type(%{type: :update, entity: :video}, _), | ||
do: :updated_video | ||
|
||
defp notification_type(%{type: :update, entity: :speaker}, _), | ||
do: :updated_speaker | ||
|
||
defp notification_type(%{type: :remove, entity: :speaker}, _), | ||
do: :removed_speaker | ||
|
||
defp notification_type(%{type: :remove, entity: :statement}, _), | ||
do: :removed_statement | ||
|
||
defp notification_type(%{type: type, entity: entity}, _) do | ||
Logger.warn("Don't know how to generate a notification for #{type} #{entity}") | ||
:default | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
defmodule CF.Notifications do | ||
@moduledoc """ | ||
Functions to create, fetch, and manipulate notifications. | ||
""" | ||
|
||
import Ecto.Query | ||
|
||
alias DB.Repo | ||
alias DB.Schema.User | ||
alias DB.Schema.UserAction | ||
alias DB.Schema.Notification | ||
|
||
@doc """ | ||
Get all notifications for user, last inserted first. | ||
Paginated with `page` + `limit`. | ||
""" | ||
@spec all(User.t(), integer(), integer(), :all | :seen | :unseen) :: Scrivener.Page.t() | ||
def all(%User{id: user_id}, page \\ 1, page_size \\ 10, filter \\ :all) do | ||
Notification | ||
|> where([n], n.user_id == ^user_id) | ||
|> add_filter(filter) | ||
|> order_by(desc: :inserted_at) | ||
|> Repo.paginate(page: page, page_size: page_size) | ||
end | ||
|
||
@doc """ | ||
Insert a new notification in DB. | ||
""" | ||
@spec create!(User.t(), UserAction.t(), atom()) :: | ||
{:ok, Notification.t()} | {:error, Ecto.Changeset.t()} | ||
def create!(%User{id: user_id}, %UserAction{id: action_id}, type) do | ||
%Notification{} | ||
|> Notification.changeset(%{user_id: user_id, action_id: action_id, type: type}) | ||
|> Repo.insert() | ||
end | ||
|
||
@doc """ | ||
Mark the given notification as seen or unseed. | ||
seen. | ||
""" | ||
@spec mark_as_seen(Notification.t(), boolean()) :: Notification.t() | ||
def mark_as_seen(notification = %Notification{seen_at: nil}, true) do | ||
notification | ||
|> Notification.changeset(%{seen_at: DateTime.utc_now()}) | ||
|> Repo.update() | ||
end | ||
|
||
def mark_as_seen(notification = %Notification{seen_at: seen_at}, false) | ||
when not is_nil(seen_at) do | ||
notification | ||
|> Notification.changeset(%{seen_at: nil}) | ||
|> Repo.update() | ||
end | ||
|
||
def mark_as_seen(notification, _), | ||
do: {:ok, notification} | ||
|
||
defp add_filter(query, :seen), do: where(query, [n], not is_nil(n.seen_at)) | ||
defp add_filter(query, :unseen), do: where(query, [n], is_nil(n.seen_at)) | ||
defp add_filter(query, :all), do: query | ||
end |
Oops, something went wrong.