diff --git a/lib/banchan/studios/notifications.ex b/lib/banchan/studios/notifications.ex index f864b447..f5940b05 100644 --- a/lib/banchan/studios/notifications.ex +++ b/lib/banchan/studios/notifications.ex @@ -71,6 +71,25 @@ defmodule Banchan.Studios.Notifications do ) end + @doc """ + Stream of studio followers. Intended for notification use. + """ + def stream_followers(%Studio{} = studio) do + from(u in User, + as: :user, + join: f in StudioFollower, + on: f.user_id == u.id and f.studio_id == ^studio.id, + left_join: settings in assoc(u, :notification_settings), + where: is_nil(u.deactivated_at), + select: %User{ + id: u.id, + email: u.email, + notification_settings: settings + } + ) + |> Repo.stream() + end + @doc """ Adds a user to the given studio's followers. """ diff --git a/lib/banchan/works/notifications.ex b/lib/banchan/works/notifications.ex new file mode 100644 index 00000000..5992ca0f --- /dev/null +++ b/lib/banchan/works/notifications.ex @@ -0,0 +1,46 @@ +defmodule Banchan.Works.Notifications do + @moduledoc """ + Notifications related to Works (new works, etc). + """ + import Ecto.Query, warn: false + + alias Banchan.Notifications + alias Banchan.Repo + alias Banchan.Studios + alias Banchan.Works.Work + + # Unfortunate, but needed for crafting URLs for notifications + use BanchanWeb, :verified_routes + + def work_created(%Work{} = work, actor \\ nil) do + Notifications.with_task(fn -> + {:ok, _} = + Repo.transaction(fn -> + work = Repo.preload(work, :studio) + + studio = work.studio + + subs = Studios.Notifications.stream_followers(studio) + + url = url(~p"/studios/#{studio.handle}/works/#{work.public_id}") + + {:safe, safe_url} = Phoenix.HTML.html_escape(url) + + Notifications.notify_subscribers!( + actor, + subs, + %Notifications.UserNotification{ + type: "work_created", + title: "New work published", + short_body: "#{studio.name} published a new work.", + text_body: "#{studio.name} published a new work, #{work.title}:\n\n#{url}", + html_body: + "

#{studio.name} published a new work: #{work.title}

", + url: url, + read: false + } + ) + end) + end) + end +end diff --git a/lib/banchan/works/works.ex b/lib/banchan/works/works.ex index 877aed2a..a4fa9878 100644 --- a/lib/banchan/works/works.ex +++ b/lib/banchan/works/works.ex @@ -15,7 +15,7 @@ defmodule Banchan.Works do alias Banchan.Uploads alias Banchan.Uploads.Upload alias Banchan.Workers.Thumbnailer - alias Banchan.Works.{Work, WorkUpload} + alias Banchan.Works.{Notifications, Work, WorkUpload} @public_id_size Work.rand_id() |> byte_size() @@ -86,6 +86,14 @@ defmodule Banchan.Works do end) ret + |> case do + {:ok, work} -> + Notifications.work_created(work, actor) + {:ok, work} + + {:error, changeset} -> + {:error, changeset} + end end ## Getting/Listing