Skip to content

Commit

Permalink
notify subscribers and studio members when an offering has closed
Browse files Browse the repository at this point in the history
Fixes: #574
  • Loading branch information
zkat committed Aug 13, 2023
1 parent 053221b commit 6f40336
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 10 deletions.
56 changes: 55 additions & 1 deletion lib/banchan/offerings/notifications.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ defmodule Banchan.Offerings.Notifications do
alias Banchan.Notifications
alias Banchan.Repo
alias Banchan.Offerings.{Offering, OfferingSubscription}
alias Banchan.Studios.StudioFollower
alias Banchan.Studios.{StudioFollower, StudioSubscription}
alias Banchan.Uploads.Upload

# Unfortunate, but needed for crafting URLs for notifications
Expand Down Expand Up @@ -92,6 +92,60 @@ defmodule Banchan.Offerings.Notifications do
end)
end

def offering_closed(%Offering{} = offering, actor \\ nil) do
Notifications.with_task(fn ->
{:ok, _} =
Repo.transaction(fn ->
subs = closure_notifiants(offering)

studio = Repo.preload(offering, :studio).studio

url = url(~p"/offerings/#{studio.handle}/#{offering.type}")

{:safe, safe_url} = Phoenix.HTML.html_escape(url)

Notifications.notify_subscribers!(
actor,
subs,
%Notifications.UserNotification{
type: "offering_closed",
title: "Offering has closed!",
short_body: "'#{offering.name}' from #{studio.name} is now closed.",
text_body: "'#{offering.name}' from #{studio.name} is now closed.\n\n#{url}",
html_body:
"<p>'#{offering.name}' from #{studio.name} is now closed.</p><p><a href=\"#{safe_url}\">View it</a></p>",
url: url,
read: false
}
)
end)
end)
end

defp closure_notifiants(%Offering{} = offering) do
from(
u in User,
join: us in "users_studios",
on: us.studio_id == ^offering.studio_id,
left_join: settings in assoc(u, :notification_settings),
left_join: studio_sub in StudioSubscription,
on: studio_sub.studio_id == ^offering.studio_id and u.id == studio_sub.user_id,
left_join: offering_sub in OfferingSubscription,
on: offering_sub.offering_id == ^offering.id and u.id == offering_sub.user_id,
where:
(not is_nil(offering_sub.id) and offering_sub.silenced != true) or
(not is_nil(studio_sub.id) and studio_sub.silenced != true) or
(us.user_id == u.id and is_nil(studio_sub.id)),
distinct: u.id,
select: %User{
id: u.id,
email: u.email,
notification_settings: settings
}
)
|> Repo.stream()
end

def subscribe_to_offering_updates(%Offering{} = offering) do
topic = "offering:#{offering.studio.handle}:#{offering.type}"
Phoenix.PubSub.subscribe(@pubsub, topic)
Expand Down
9 changes: 7 additions & 2 deletions lib/banchan/offerings/offerings.ex
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,9 @@ defmodule Banchan.Offerings do
max_proposals = Ecto.Changeset.get_field(changeset, :max_proposals)

changeset =
if (!is_nil(slots) && slots < used_slots) ||
(!is_nil(max_proposals) && max_proposals < proposal_count) do
if (!is_nil(slots) && !is_nil(used_slots) && slots < used_slots) ||
(!is_nil(max_proposals) && !is_nil(proposal_count) &&
max_proposals < proposal_count) do
changeset
|> Ecto.Changeset.put_change(:open, false)
else
Expand Down Expand Up @@ -149,6 +150,10 @@ defmodule Banchan.Offerings do
Notifications.offering_opened(changed)
end

if open_before? && !changed.open do
Notifications.offering_closed(changed)
end

{:ok, changed}
else
{:error, error} ->
Expand Down
17 changes: 10 additions & 7 deletions test/banchan/offerings_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,19 @@ defmodule Banchan.OfferingsTest do

Notifications.wait_for_notifications()

# Artist does not follow the studio, so no notifs.
assert [] = Notifications.unread_notifications(artist).entries
assert [%{title: "Offering has closed!"}] =
Notifications.unread_notifications(artist).entries

# User is specifically-subscribed
assert [%{short_body: "Commission slots are now available for " <> _}] =
Notifications.unread_notifications(client).entries
assert [
%{title: "Offering has closed!"},
%{short_body: "Commission slots are now available for " <> _}
] = Notifications.unread_notifications(client).entries

# User follows studio
assert [%{short_body: "Commission slots are now available for " <> _}] =
Notifications.unread_notifications(client2).entries
assert [
%{short_body: "Commission slots are now available for " <> _}
] = Notifications.unread_notifications(client2).entries

# And this rando isn't at all
assert [] = Notifications.unread_notifications(client3).entries
Expand Down Expand Up @@ -427,7 +430,7 @@ defmodule Banchan.OfferingsTest do
Offerings.update_offering(
artist,
offering |> Repo.reload(),
%{open: true},
%{open: true, max_proposals: 4},
nil
)

Expand Down

0 comments on commit 6f40336

Please sign in to comment.