@@ -17,7 +17,8 @@ defmodule Safira.Minigames do
1717 SlotsPayline ,
1818 SlotsPaytable ,
1919 SlotsReelIcon ,
20- WheelDrop
20+ WheelDrop ,
21+ WheelSpin
2122 }
2223
2324 @ pubsub Safira.PubSub
@@ -161,7 +162,10 @@ defmodule Safira.Minigames do
161162
162163 """
163164 def list_wheel_drops do
164- Repo . all ( WheelDrop )
165+ WheelDrop
166+ |> order_by ( [ wd ] , asc: wd . probability )
167+ |> Repo . all ( )
168+ |> Repo . preload ( [ :badge , :prize ] )
165169 end
166170
167171 @ doc """
@@ -193,9 +197,13 @@ defmodule Safira.Minigames do
193197
194198 """
195199 def create_wheel_drop ( attrs \\ % { } ) do
196- % WheelDrop { }
197- |> WheelDrop . changeset ( attrs )
198- |> Repo . insert ( )
200+ result =
201+ % WheelDrop { }
202+ |> WheelDrop . changeset ( attrs )
203+ |> Repo . insert ( )
204+
205+ broadcast_wheel_config_update ( "drops" , list_wheel_drops ( ) )
206+ result
199207 end
200208
201209 @ doc """
@@ -211,9 +219,13 @@ defmodule Safira.Minigames do
211219
212220 """
213221 def update_wheel_drop ( % WheelDrop { } = wheel_drop , attrs ) do
214- wheel_drop
215- |> WheelDrop . changeset ( attrs )
216- |> Repo . update ( )
222+ result =
223+ wheel_drop
224+ |> WheelDrop . changeset ( attrs )
225+ |> Repo . update ( )
226+
227+ broadcast_wheel_config_update ( "drops" , list_wheel_drops ( ) )
228+ result
217229 end
218230
219231 @ doc """
@@ -229,7 +241,9 @@ defmodule Safira.Minigames do
229241
230242 """
231243 def delete_wheel_drop ( % WheelDrop { } = wheel_drop ) do
232- Repo . delete ( wheel_drop )
244+ result = Repo . delete ( wheel_drop )
245+ broadcast_wheel_config_update ( "drops" , list_wheel_drops ( ) )
246+ result
233247 end
234248
235249 @ doc """
@@ -309,6 +323,14 @@ defmodule Safira.Minigames do
309323 end
310324 end
311325
326+ def wheel_latest_wins ( count ) do
327+ WheelSpin
328+ |> order_by ( [ ws ] , desc: ws . inserted_at )
329+ |> limit ( ^ count )
330+ |> Repo . all ( )
331+ |> Repo . preload ( attendee: [ :user ] , drop: [ :prize , :badge ] )
332+ end
333+
312334 defp spin_wheel_transaction ( attendee ) do
313335 Multi . new ( )
314336 # Fetch the wheel spin price
@@ -325,10 +347,40 @@ defmodule Safira.Minigames do
325347 |> Multi . merge ( fn % { drop: drop , attendee: attendee } ->
326348 drop_reward_action ( drop , attendee )
327349 end )
350+ # Add record of the spin transaction to the database
351+ |> Multi . merge ( fn % { drop: drop , attendee: attendee } ->
352+ add_spin_action ( drop , attendee )
353+ end )
354+ |> Multi . run ( :notify , fn _repo , params -> broadcast_spin_changes ( params ) end )
328355 # Execute the transaction
329356 |> Repo . transaction ( )
330357 end
331358
359+ defp broadcast_spin_changes ( params ) do
360+ case broadcast_wheel_win ( Map . get ( params , :spin ) ) do
361+ :ok ->
362+ case broadcast_wheel_config_update ( "drops" , list_wheel_drops ( ) ) do
363+ :ok -> { :ok , :ok }
364+ e -> e
365+ end
366+
367+ e ->
368+ e
369+ end
370+ end
371+
372+ defp add_spin_action ( drop , attendee ) do
373+ if is_nil ( drop ) or ( is_nil ( drop . badge_id ) and is_nil ( drop . prize_id ) ) do
374+ # If there was no prize, or the prize was just tokens, don't insert it
375+ Multi . new ( )
376+ else
377+ Multi . new ( )
378+ |> Multi . insert ( :spin , fn _ ->
379+ WheelSpin . changeset ( % WheelSpin { } , % { drop_id: drop . id , attendee_id: attendee . id } )
380+ end )
381+ end
382+ end
383+
332384 defp generate_valid_wheel_drop ( attendee ) do
333385 drop = generate_wheel_drop ( )
334386
@@ -525,6 +577,29 @@ defmodule Safira.Minigames do
525577 Phoenix.PubSub . broadcast ( @ pubsub , wheel_config_topic ( config ) , { config , value } )
526578 end
527579
580+ @ doc """
581+ Subscribes the caller to the wheel's wins.
582+
583+ ## Examples
584+
585+ iex> subscribe_to_wheel_wins()
586+ :ok
587+ """
588+ def subscribe_to_wheel_wins do
589+ Phoenix.PubSub . subscribe ( @ pubsub , "wheel_win" )
590+ end
591+
592+ defp broadcast_wheel_win ( value ) do
593+ value = value |> Repo . preload ( attendee: [ :user ] , drop: [ :prize , :badge ] )
594+
595+ if not is_nil ( value ) and not is_nil ( value . drop ) and
596+ ( not is_nil ( value . drop . badge ) or not is_nil ( value . drop . prize ) ) do
597+ Phoenix.PubSub . broadcast ( @ pubsub , "wheel_win" , { "win" , value } )
598+ else
599+ :ok
600+ end
601+ end
602+
528603 # Generates a random number using the Erlang crypto module
529604 defp strong_randomizer do
530605 << i1 :: unsigned - integer - 32 , i2 :: unsigned - integer - 32 , i3 :: unsigned - integer - 32 >> =
0 commit comments