mirror of
https://github.com/philomena-dev/philomena.git
synced 2024-11-23 20:18:00 +01:00
Merge pull request #310 from philomena-dev/subscriptions-cleanup
Deduplicate common subscription logic
This commit is contained in:
commit
3c0c12602f
8 changed files with 254 additions and 321 deletions
|
@ -8,7 +8,10 @@ defmodule Philomena.Channels do
|
|||
|
||||
alias Philomena.Channels.AutomaticUpdater
|
||||
alias Philomena.Channels.Channel
|
||||
alias Philomena.Notifications
|
||||
|
||||
use Philomena.Subscriptions,
|
||||
actor_types: ~w(Channel LivestreamChannel),
|
||||
id_name: :channel_id
|
||||
|
||||
@doc """
|
||||
Updates all the tracked channels for which an update scheme is known.
|
||||
|
@ -115,69 +118,4 @@ defmodule Philomena.Channels do
|
|||
def change_channel(%Channel{} = channel) do
|
||||
Channel.changeset(channel, %{})
|
||||
end
|
||||
|
||||
alias Philomena.Channels.Subscription
|
||||
|
||||
@doc """
|
||||
Creates a subscription.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> create_subscription(%{field: value})
|
||||
{:ok, %Subscription{}}
|
||||
|
||||
iex> create_subscription(%{field: bad_value})
|
||||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def create_subscription(_channel, nil), do: {:ok, nil}
|
||||
|
||||
def create_subscription(channel, user) do
|
||||
%Subscription{channel_id: channel.id, user_id: user.id}
|
||||
|> Subscription.changeset(%{})
|
||||
|> Repo.insert(on_conflict: :nothing)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Deletes a Subscription.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> delete_subscription(subscription)
|
||||
{:ok, %Subscription{}}
|
||||
|
||||
iex> delete_subscription(subscription)
|
||||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def delete_subscription(channel, user) do
|
||||
clear_notification(channel, user)
|
||||
|
||||
%Subscription{channel_id: channel.id, user_id: user.id}
|
||||
|> Repo.delete()
|
||||
end
|
||||
|
||||
def subscribed?(_channel, nil), do: false
|
||||
|
||||
def subscribed?(channel, user) do
|
||||
Subscription
|
||||
|> where(channel_id: ^channel.id, user_id: ^user.id)
|
||||
|> Repo.exists?()
|
||||
end
|
||||
|
||||
def subscriptions(_channels, nil), do: %{}
|
||||
|
||||
def subscriptions(channels, user) do
|
||||
channel_ids = Enum.map(channels, & &1.id)
|
||||
|
||||
Subscription
|
||||
|> where([s], s.channel_id in ^channel_ids and s.user_id == ^user.id)
|
||||
|> Repo.all()
|
||||
|> Map.new(&{&1.channel_id, true})
|
||||
end
|
||||
|
||||
def clear_notification(channel, user) do
|
||||
Notifications.delete_unread_notification("Channel", channel.id, user)
|
||||
Notifications.delete_unread_notification("LivestreamChannel", channel.id, user)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -19,7 +19,6 @@ defmodule Philomena.Comments do
|
|||
alias Philomena.NotificationWorker
|
||||
alias Philomena.Versions
|
||||
alias Philomena.Reports
|
||||
alias Philomena.Users.User
|
||||
|
||||
@doc """
|
||||
Gets a single comment.
|
||||
|
@ -58,24 +57,17 @@ defmodule Philomena.Comments do
|
|||
Image
|
||||
|> where(id: ^image.id)
|
||||
|
||||
image_lock_query =
|
||||
lock(image_query, "FOR UPDATE")
|
||||
|
||||
Multi.new()
|
||||
|> Multi.one(:image, image_lock_query)
|
||||
|> Multi.insert(:comment, comment)
|
||||
|> Multi.update_all(:image, image_query, inc: [comments_count: 1])
|
||||
|> maybe_create_subscription_on_reply(image, attribution[:user])
|
||||
|> Multi.update_all(:update_image, image_query, inc: [comments_count: 1])
|
||||
|> Images.maybe_subscribe_on(:image, attribution[:user], :watch_on_reply)
|
||||
|> Repo.transaction()
|
||||
end
|
||||
|
||||
defp maybe_create_subscription_on_reply(multi, image, %User{watch_on_reply: true} = user) do
|
||||
multi
|
||||
|> Multi.run(:subscribe, fn _repo, _changes ->
|
||||
Images.create_subscription(image, user)
|
||||
end)
|
||||
end
|
||||
|
||||
defp maybe_create_subscription_on_reply(multi, _image, _user) do
|
||||
multi
|
||||
end
|
||||
|
||||
def notify_comment(comment) do
|
||||
Exq.enqueue(Exq, "notifications", NotificationWorker, ["Comments", comment.id])
|
||||
end
|
||||
|
|
|
@ -7,8 +7,10 @@ defmodule Philomena.Forums do
|
|||
alias Philomena.Repo
|
||||
|
||||
alias Philomena.Forums.Forum
|
||||
alias Philomena.Forums.Subscription
|
||||
alias Philomena.Notifications
|
||||
|
||||
use Philomena.Subscriptions,
|
||||
actor_types: ~w(Forum),
|
||||
id_name: :forum_id
|
||||
|
||||
@doc """
|
||||
Returns the list of forums.
|
||||
|
@ -103,45 +105,4 @@ defmodule Philomena.Forums do
|
|||
def change_forum(%Forum{} = forum) do
|
||||
Forum.changeset(forum, %{})
|
||||
end
|
||||
|
||||
def subscribed?(_forum, nil), do: false
|
||||
|
||||
def subscribed?(forum, user) do
|
||||
Subscription
|
||||
|> where(forum_id: ^forum.id, user_id: ^user.id)
|
||||
|> Repo.exists?()
|
||||
end
|
||||
|
||||
def create_subscription(_forum, nil), do: {:ok, nil}
|
||||
|
||||
def create_subscription(forum, user) do
|
||||
%Subscription{forum_id: forum.id, user_id: user.id}
|
||||
|> Subscription.changeset(%{})
|
||||
|> Repo.insert(on_conflict: :nothing)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Deletes a Subscription.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> delete_subscription(subscription)
|
||||
{:ok, %Subscription{}}
|
||||
|
||||
iex> delete_subscription(subscription)
|
||||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def delete_subscription(forum, user) do
|
||||
clear_notification(forum, user)
|
||||
|
||||
%Subscription{forum_id: forum.id, user_id: user.id}
|
||||
|> Repo.delete()
|
||||
end
|
||||
|
||||
def clear_notification(_forum, nil), do: nil
|
||||
|
||||
def clear_notification(forum, user) do
|
||||
Notifications.delete_unread_notification("Forum", forum.id, user)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -18,6 +18,10 @@ defmodule Philomena.Galleries do
|
|||
alias Philomena.Notifications.{Notification, UnreadNotification}
|
||||
alias Philomena.Images
|
||||
|
||||
use Philomena.Subscriptions,
|
||||
actor_types: ~w(Gallery),
|
||||
id_name: :gallery_id
|
||||
|
||||
@doc """
|
||||
Gets a single gallery.
|
||||
|
||||
|
@ -356,55 +360,4 @@ defmodule Philomena.Galleries do
|
|||
|
||||
defp position_order(%{order_position_asc: true}), do: [asc: :position]
|
||||
defp position_order(_gallery), do: [desc: :position]
|
||||
|
||||
alias Philomena.Galleries.Subscription
|
||||
|
||||
def subscribed?(_gallery, nil), do: false
|
||||
|
||||
def subscribed?(gallery, user) do
|
||||
Subscription
|
||||
|> where(gallery_id: ^gallery.id, user_id: ^user.id)
|
||||
|> Repo.exists?()
|
||||
end
|
||||
|
||||
@doc """
|
||||
Creates a subscription.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> create_subscription(%{field: value})
|
||||
{:ok, %Subscription{}}
|
||||
|
||||
iex> create_subscription(%{field: bad_value})
|
||||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def create_subscription(gallery, user) do
|
||||
%Subscription{gallery_id: gallery.id, user_id: user.id}
|
||||
|> Subscription.changeset(%{})
|
||||
|> Repo.insert(on_conflict: :nothing)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Deletes a Subscription.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> delete_subscription(subscription)
|
||||
{:ok, %Subscription{}}
|
||||
|
||||
iex> delete_subscription(subscription)
|
||||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def delete_subscription(gallery, user) do
|
||||
%Subscription{gallery_id: gallery.id, user_id: user.id}
|
||||
|> Repo.delete()
|
||||
end
|
||||
|
||||
def clear_notification(_gallery, nil), do: nil
|
||||
|
||||
def clear_notification(gallery, user) do
|
||||
Notifications.delete_unread_notification("Gallery", gallery.id, user)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -37,6 +37,10 @@ defmodule Philomena.Images do
|
|||
alias Philomena.Galleries.Interaction
|
||||
alias Philomena.Users.User
|
||||
|
||||
use Philomena.Subscriptions,
|
||||
actor_types: ~w(Image),
|
||||
id_name: :image_id
|
||||
|
||||
@doc """
|
||||
Gets a single image.
|
||||
|
||||
|
@ -103,7 +107,7 @@ defmodule Philomena.Images do
|
|||
|
||||
{:ok, count}
|
||||
end)
|
||||
|> maybe_create_subscription_on_upload(attribution[:user])
|
||||
|> maybe_subscribe_on(:image, attribution[:user], :watch_on_upload)
|
||||
|> Repo.transaction()
|
||||
|> case do
|
||||
{:ok, %{image: image}} = result ->
|
||||
|
@ -157,17 +161,6 @@ defmodule Philomena.Images do
|
|||
Logger.error("Aborting upload of #{image.id} after #{retry_count} retries")
|
||||
end
|
||||
|
||||
defp maybe_create_subscription_on_upload(multi, %User{watch_on_upload: true} = user) do
|
||||
multi
|
||||
|> Multi.run(:subscribe, fn _repo, %{image: image} ->
|
||||
create_subscription(image, user)
|
||||
end)
|
||||
end
|
||||
|
||||
defp maybe_create_subscription_on_upload(multi, _user) do
|
||||
multi
|
||||
end
|
||||
|
||||
def approve_image(image) do
|
||||
image
|
||||
|> Repo.preload(:user)
|
||||
|
@ -868,53 +861,6 @@ defmodule Philomena.Images do
|
|||
|
||||
alias Philomena.Images.Subscription
|
||||
|
||||
def subscribed?(_image, nil), do: false
|
||||
|
||||
def subscribed?(image, user) do
|
||||
Subscription
|
||||
|> where(image_id: ^image.id, user_id: ^user.id)
|
||||
|> Repo.exists?()
|
||||
end
|
||||
|
||||
@doc """
|
||||
Creates a subscription.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> create_subscription(%{field: value})
|
||||
{:ok, %Subscription{}}
|
||||
|
||||
iex> create_subscription(%{field: bad_value})
|
||||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def create_subscription(_image, nil), do: {:ok, nil}
|
||||
|
||||
def create_subscription(image, user) do
|
||||
%Subscription{image_id: image.id, user_id: user.id}
|
||||
|> Subscription.changeset(%{})
|
||||
|> Repo.insert(on_conflict: :nothing)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Deletes a subscription.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> delete_subscription(subscription)
|
||||
{:ok, %Subscription{}}
|
||||
|
||||
iex> delete_subscription(subscription)
|
||||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def delete_subscription(image, user) do
|
||||
clear_notification(image, user)
|
||||
|
||||
%Subscription{image_id: image.id, user_id: user.id}
|
||||
|> Repo.delete()
|
||||
end
|
||||
|
||||
def migrate_subscriptions(source, target) do
|
||||
subscriptions =
|
||||
Subscription
|
||||
|
@ -968,10 +914,4 @@ defmodule Philomena.Images do
|
|||
}
|
||||
)
|
||||
end
|
||||
|
||||
def clear_notification(_image, nil), do: nil
|
||||
|
||||
def clear_notification(image, user) do
|
||||
Notifications.delete_unread_notification("Image", image.id, user)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -20,7 +20,6 @@ defmodule Philomena.Posts do
|
|||
alias Philomena.Versions
|
||||
alias Philomena.Reports
|
||||
alias Philomena.Reports.Report
|
||||
alias Philomena.Users.User
|
||||
|
||||
@doc """
|
||||
Gets a single post.
|
||||
|
@ -66,7 +65,7 @@ defmodule Philomena.Posts do
|
|||
|> where(id: ^topic.forum_id)
|
||||
|
||||
Multi.new()
|
||||
|> Multi.all(:topic_lock, topic_lock_query)
|
||||
|> Multi.one(:topic, topic_lock_query)
|
||||
|> Multi.run(:post, fn repo, _ ->
|
||||
last_position =
|
||||
Post
|
||||
|
@ -95,7 +94,7 @@ defmodule Philomena.Posts do
|
|||
|
||||
{:ok, count}
|
||||
end)
|
||||
|> maybe_create_subscription_on_reply(topic, attributes[:user])
|
||||
|> Topics.maybe_subscribe_on(:topic, attributes[:user], :watch_on_reply)
|
||||
|> Repo.transaction()
|
||||
|> case do
|
||||
{:ok, %{post: post}} = result ->
|
||||
|
@ -108,17 +107,6 @@ defmodule Philomena.Posts do
|
|||
end
|
||||
end
|
||||
|
||||
defp maybe_create_subscription_on_reply(multi, topic, %User{watch_on_reply: true} = user) do
|
||||
multi
|
||||
|> Multi.run(:subscribe, fn _repo, _changes ->
|
||||
Topics.create_subscription(topic, user)
|
||||
end)
|
||||
end
|
||||
|
||||
defp maybe_create_subscription_on_reply(multi, _topic, _user) do
|
||||
multi
|
||||
end
|
||||
|
||||
def notify_post(post) do
|
||||
Exq.enqueue(Exq, "notifications", NotificationWorker, ["Posts", post.id])
|
||||
end
|
||||
|
|
224
lib/philomena/subscriptions.ex
Normal file
224
lib/philomena/subscriptions.ex
Normal file
|
@ -0,0 +1,224 @@
|
|||
defmodule Philomena.Subscriptions do
|
||||
@moduledoc """
|
||||
Common subscription logic.
|
||||
|
||||
`use Philomena.Subscriptions` requires the following properties:
|
||||
|
||||
- `:actor_types`
|
||||
This is the "actor_type" in the notifications table.
|
||||
For `Philomena.Images`, this would be `["Image"]`.
|
||||
|
||||
- `:id_name`
|
||||
This is the name of the object field in the subscription table.
|
||||
For `Philomena.Images`, this would be `:image_id`.
|
||||
|
||||
The following functions and documentation are produced in the calling module:
|
||||
- `subscribed?/2`
|
||||
- `subscriptions/2`
|
||||
- `create_subscription/2`
|
||||
- `delete_subscription/2`
|
||||
- `clear_notification/2`
|
||||
- `maybe_subscribe_on/4`
|
||||
"""
|
||||
|
||||
import Ecto.Query, warn: false
|
||||
alias Ecto.Multi
|
||||
|
||||
alias Philomena.Notifications
|
||||
alias Philomena.Repo
|
||||
|
||||
defmacro __using__(opts) do
|
||||
# For Philomena.Images, this yields ["Image"]
|
||||
actor_types = Keyword.fetch!(opts, :actor_types)
|
||||
|
||||
# For Philomena.Images, this yields :image_id
|
||||
field_name = Keyword.fetch!(opts, :id_name)
|
||||
|
||||
# For Philomena.Images, this yields Philomena.Images.Subscription
|
||||
subscription_module = Module.concat(__CALLER__.module, Subscription)
|
||||
|
||||
quote do
|
||||
@doc """
|
||||
Returns whether the user is currently subscribed to this object.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> subscribed?(object, user)
|
||||
false
|
||||
|
||||
"""
|
||||
def subscribed?(object, user) do
|
||||
Philomena.Subscriptions.subscribed?(
|
||||
unquote(subscription_module),
|
||||
unquote(field_name),
|
||||
object,
|
||||
user
|
||||
)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Returns a map containing whether the user is currently subscribed to any of
|
||||
the provided objects.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> subscriptions([%{id: 1}, %{id: 2}], user)
|
||||
%{2 => true}
|
||||
|
||||
"""
|
||||
def subscriptions(objects, user) do
|
||||
Philomena.Subscriptions.subscriptions(
|
||||
unquote(subscription_module),
|
||||
unquote(field_name),
|
||||
objects,
|
||||
user
|
||||
)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Creates a subscription.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> create_subscription(object, user)
|
||||
{:ok, %Subscription{}}
|
||||
|
||||
iex> create_subscription(object, user)
|
||||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def create_subscription(object, user) do
|
||||
Philomena.Subscriptions.create_subscription(
|
||||
unquote(subscription_module),
|
||||
unquote(field_name),
|
||||
object,
|
||||
user
|
||||
)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Deletes a subscription and removes notifications for it.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> delete_subscription(object, user)
|
||||
{:ok, %Subscription{}}
|
||||
|
||||
iex> delete_subscription(object, user)
|
||||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def delete_subscription(object, user) do
|
||||
clear_notification(object, user)
|
||||
|
||||
Philomena.Subscriptions.delete_subscription(
|
||||
unquote(subscription_module),
|
||||
unquote(field_name),
|
||||
object,
|
||||
user
|
||||
)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Deletes any active notifications for a subscription.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> clear_notification(object, user)
|
||||
:ok
|
||||
|
||||
"""
|
||||
def clear_notification(object, user) do
|
||||
for type <- unquote(actor_types) do
|
||||
Philomena.Subscriptions.clear_notification(type, object, user)
|
||||
end
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
@doc """
|
||||
Creates a subscription inside the `m:Ecto.Multi` flow if `user` is not nil
|
||||
and `field` in `user` is `true`.
|
||||
|
||||
Valid values for field are `:watch_on_reply`, `:watch_on_upload`, `:watch_on_new_topic`.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> maybe_subscribe_on(multi, :image, user, :watch_on_reply)
|
||||
%Ecto.Multi{}
|
||||
|
||||
iex> maybe_subscribe_on(multi, :topic, nil, :watch_on_reply)
|
||||
%Ecto.Multi{}
|
||||
|
||||
"""
|
||||
def maybe_subscribe_on(multi, change_name, user, field) do
|
||||
Philomena.Subscriptions.maybe_subscribe_on(multi, __MODULE__, change_name, user, field)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@doc false
|
||||
def subscribed?(subscription_module, field_name, object, user) do
|
||||
case user do
|
||||
nil ->
|
||||
false
|
||||
|
||||
_ ->
|
||||
subscription_module
|
||||
|> where([s], field(s, ^field_name) == ^object.id and s.user_id == ^user.id)
|
||||
|> Repo.exists?()
|
||||
end
|
||||
end
|
||||
|
||||
@doc false
|
||||
def subscriptions(subscription_module, field_name, objects, user) do
|
||||
case user do
|
||||
nil ->
|
||||
%{}
|
||||
|
||||
_ ->
|
||||
object_ids = Enum.map(objects, & &1.id)
|
||||
|
||||
subscription_module
|
||||
|> where([s], field(s, ^field_name) in ^object_ids and s.user_id == ^user.id)
|
||||
|> Repo.all()
|
||||
|> Map.new(&{Map.fetch!(&1, field_name), true})
|
||||
end
|
||||
end
|
||||
|
||||
@doc false
|
||||
def create_subscription(subscription_module, field_name, object, user) do
|
||||
struct!(subscription_module, [{field_name, object.id}, {:user_id, user.id}])
|
||||
|> subscription_module.changeset(%{})
|
||||
|> Repo.insert(on_conflict: :nothing)
|
||||
end
|
||||
|
||||
@doc false
|
||||
def delete_subscription(subscription_module, field_name, object, user) do
|
||||
struct!(subscription_module, [{field_name, object.id}, {:user_id, user.id}])
|
||||
|> Repo.delete()
|
||||
end
|
||||
|
||||
@doc false
|
||||
def clear_notification(type, object, user) do
|
||||
case user do
|
||||
nil -> nil
|
||||
_ -> Notifications.delete_unread_notification(type, object.id, user)
|
||||
end
|
||||
end
|
||||
|
||||
@doc false
|
||||
def maybe_subscribe_on(multi, module, change_name, user, field)
|
||||
when field in [:watch_on_reply, :watch_on_upload, :watch_on_new_topic] do
|
||||
case user do
|
||||
%{^field => true} ->
|
||||
Multi.run(multi, :subscribe, fn _repo, changes ->
|
||||
object = Map.fetch!(changes, change_name)
|
||||
module.create_subscription(object, user)
|
||||
end)
|
||||
|
||||
_ ->
|
||||
multi
|
||||
end
|
||||
end
|
||||
end
|
|
@ -12,7 +12,10 @@ defmodule Philomena.Topics do
|
|||
alias Philomena.Posts
|
||||
alias Philomena.Notifications
|
||||
alias Philomena.NotificationWorker
|
||||
alias Philomena.Users.User
|
||||
|
||||
use Philomena.Subscriptions,
|
||||
actor_types: ~w(Topic),
|
||||
id_name: :topic_id
|
||||
|
||||
@doc """
|
||||
Gets a single topic.
|
||||
|
@ -70,7 +73,7 @@ defmodule Philomena.Topics do
|
|||
|
||||
{:ok, count}
|
||||
end)
|
||||
|> maybe_create_subscription_on_new_topic(attribution[:user])
|
||||
|> maybe_subscribe_on(:topic, attribution[:user], :watch_on_new_topic)
|
||||
|> Repo.transaction()
|
||||
|> case do
|
||||
{:ok, %{topic: topic}} = result ->
|
||||
|
@ -84,17 +87,6 @@ defmodule Philomena.Topics do
|
|||
end
|
||||
end
|
||||
|
||||
defp maybe_create_subscription_on_new_topic(multi, %User{watch_on_new_topic: true} = user) do
|
||||
multi
|
||||
|> Multi.run(:subscribe, fn _repo, %{topic: topic} ->
|
||||
create_subscription(topic, user)
|
||||
end)
|
||||
end
|
||||
|
||||
defp maybe_create_subscription_on_new_topic(multi, _user) do
|
||||
multi
|
||||
end
|
||||
|
||||
def notify_topic(topic, post) do
|
||||
Exq.enqueue(Exq, "notifications", NotificationWorker, ["Topics", [topic.id, post.id]])
|
||||
end
|
||||
|
@ -173,55 +165,6 @@ defmodule Philomena.Topics do
|
|||
Topic.changeset(topic, %{})
|
||||
end
|
||||
|
||||
alias Philomena.Topics.Subscription
|
||||
|
||||
def subscribed?(_topic, nil), do: false
|
||||
|
||||
def subscribed?(topic, user) do
|
||||
Subscription
|
||||
|> where(topic_id: ^topic.id, user_id: ^user.id)
|
||||
|> Repo.exists?()
|
||||
end
|
||||
|
||||
@doc """
|
||||
Creates a subscription.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> create_subscription(%{field: value})
|
||||
{:ok, %Subscription{}}
|
||||
|
||||
iex> create_subscription(%{field: bad_value})
|
||||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def create_subscription(_topic, nil), do: {:ok, nil}
|
||||
|
||||
def create_subscription(topic, user) do
|
||||
%Subscription{topic_id: topic.id, user_id: user.id}
|
||||
|> Subscription.changeset(%{})
|
||||
|> Repo.insert(on_conflict: :nothing)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Deletes a Subscription.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> delete_subscription(subscription)
|
||||
{:ok, %Subscription{}}
|
||||
|
||||
iex> delete_subscription(subscription)
|
||||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def delete_subscription(topic, user) do
|
||||
clear_notification(topic, user)
|
||||
|
||||
%Subscription{topic_id: topic.id, user_id: user.id}
|
||||
|> Repo.delete()
|
||||
end
|
||||
|
||||
def stick_topic(topic) do
|
||||
Topic.stick_changeset(topic)
|
||||
|> Repo.update()
|
||||
|
@ -299,10 +242,4 @@ defmodule Philomena.Topics do
|
|||
|> Topic.title_changeset(attrs)
|
||||
|> Repo.update()
|
||||
end
|
||||
|
||||
def clear_notification(_topic, nil), do: nil
|
||||
|
||||
def clear_notification(topic, user) do
|
||||
Notifications.delete_unread_notification("Topic", topic.id, user)
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue