Skip to content

Commit

Permalink
feat: add support for animated billboards (algora-io#109)
Browse files Browse the repository at this point in the history
  • Loading branch information
zcesur authored Sep 27, 2024
1 parent 55890b6 commit 677d6c7
Show file tree
Hide file tree
Showing 11 changed files with 148 additions and 34 deletions.
30 changes: 30 additions & 0 deletions assets/js/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,36 @@ const Hooks = {
});
},
},
LiveBillboard: {
setup() {
const urls = JSON.parse(this.el.dataset.urls);
const [img1, img2] = this.el.querySelectorAll("img");
let currentIndex = 0;
let nextIndex = Math.min(1, urls.length - 1);
img2.src = urls[nextIndex];

clearInterval(this.interval);
if (urls.length > 1) {
this.interval = setInterval(() => {
const nextImg = currentIndex % 2 === 0 ? img2 : img1;
const currentImg = currentIndex % 2 === 0 ? img1 : img2;

nextImg.src = urls[nextIndex];
nextImg.classList.remove("opacity-0");
currentImg.classList.add("opacity-0");

currentIndex = nextIndex;
nextIndex = (nextIndex + 1) % urls.length;
}, 5000);
}
},
mounted() {
this.setup();
},
updated() {
this.setup();
},
},
} satisfies Record<string, Partial<ViewHook> & Record<string, unknown>>;

// Accessible focus handling
Expand Down
45 changes: 44 additions & 1 deletion lib/algora/admin.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,49 @@ defmodule Algora.Admin do
video: "g3cFdmlkZW8.m3u8"
}

def kill_ad_overlay_processes do
find_ad_overlay_processes() |> Enum.each(&Process.exit(&1, :kill))
end

def find_ad_overlay_processes do
nodes()
|> Enum.flat_map(fn node ->
:rpc.call(node, __MODULE__, :find_local_ad_overlay_processes, [])
end)
end

def kill_local_ad_overlay_processes do
find_local_ad_overlay_processes() |> Enum.each(&Process.exit(&1, :kill))
end

def find_liveview_processes(module, function \\ :mount, arity \\ 3) do
nodes()
|> Enum.flat_map(fn node ->
:rpc.call(node, __MODULE__, :find_local_liveview_processes, [module, function, arity])
end)
end

def find_local_liveview_processes(module, function \\ :mount, arity \\ 3) do
:erlang.processes()
|> Enum.filter(&local_process_matches?(&1, [{module, function, arity}]))
end

def find_local_ad_overlay_processes do
find_local_liveview_processes(AlgoraWeb.AdOverlayLive)
end

defp local_process_matches?(pid, match_patterns) do
case Process.info(pid, [:dictionary]) do
[dictionary: dict] ->
dict
|> Keyword.get(:"$initial_call")
|> then(&Enum.any?(match_patterns, fn pattern -> pattern == &1 end))

_ ->
false
end
end

def whoami(), do: {System.get_env("FLY_REGION"), Node.self()}

defp get(url) do
Expand Down Expand Up @@ -197,7 +240,7 @@ defmodule Algora.Admin do
{:ok, _} = Accounts.update_settings(user, %{channel_tagline: title})
end

def nodes(), do: [Node.self() | Node.list()]
def nodes(), do: Node.list([:this, :visible])

def pipelines() do
nodes() |> Enum.flat_map(&Membrane.Pipeline.list_pipelines/1)
Expand Down
5 changes: 2 additions & 3 deletions lib/algora/ads/ad.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ defmodule Algora.Ads.Ad do
field :status, Ecto.Enum, values: [:inactive, :active]
field :verified, :boolean, default: false
field :website_url, :string
field :composite_asset_url, :string
field :composite_asset_urls, {:array, :string}
field :asset_url, :string
field :logo_url, :string
field :qrcode_url, :string
Expand All @@ -33,7 +33,7 @@ defmodule Algora.Ads.Ad do
:name,
:verified,
:website_url,
:composite_asset_url,
:composite_asset_urls,
:asset_url,
:logo_url,
:qrcode_url,
Expand All @@ -49,7 +49,6 @@ defmodule Algora.Ads.Ad do
|> validate_required([
:slug,
:website_url,
:composite_asset_url,
:border_color
])
|> validate_format(:border_color, ~r/^#([0-9A-F]{3}){1,2}$/i,
Expand Down
28 changes: 28 additions & 0 deletions lib/algora_web/components/core_components.ex
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,34 @@ defmodule AlgoraWeb.CoreComponents do
"""
end

attr :ad, :any, required: true
attr :id, :string, required: true
attr :class, :string, default: nil

def live_billboard(assigns) do
~H"""
<div
class={["relative w-[1092px] h-[135px] transition-opacity duration-1000", @class]}
phx-hook="LiveBillboard"
data-urls={Jason.encode!(@ad.composite_asset_urls)}
id={@id}
>
<img
src={Enum.at(@ad.composite_asset_urls, 0)}
alt={@ad.website_url}
class="absolute inset-0 h-full w-full object-cover border-[4px] rounded-xl transition-opacity duration-1000"
style={"border-color: #{@ad.border_color || "#fff"}"}
/>
<img
src={Enum.at(@ad.composite_asset_urls, 0)}
alt={@ad.website_url}
class="absolute inset-0 h-full w-full object-cover border-[4px] rounded-xl transition-opacity duration-1000 opacity-0"
style={"border-color: #{@ad.border_color || "#fff"}"}
/>
</div>
"""
end

attr :class, :string, default: nil

def logo(assigns) do
Expand Down
7 changes: 1 addition & 6 deletions lib/algora_web/live/ad_live/analytics.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,7 @@
</span>
</a>
</div>
<img
src={@ad.composite_asset_url}
alt={@ad.website_url}
class="box-content max-h-16 max-w-screen aspect-[1092/135] object-cover border-[3px] rounded-md lg:rounded-xl"
style={"border-color: #{@ad.border_color || "#fff"}"}
/>
<.live_billboard ad={@ad} id={"ad-banner-#{@ad.id}"} />
<div class="shrink-0 hidden sm:flex items-center gap-4">
<div class="flex items-center gap-2">
<button
Expand Down
1 change: 0 additions & 1 deletion lib/algora_web/live/ad_live/form_component.ex
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ defmodule AlgoraWeb.AdLive.FormComponent do
<.input field={@form[:slug]} type="text" label="QR Code URL" class="ps-[6.75rem]" />
</div>
<.input field={@form[:website_url]} type="text" label="Website URL" />
<.input field={@form[:composite_asset_url]} type="text" label="Asset URL" />
<.input
field={@form[:border_color]}
type="text"
Expand Down
7 changes: 1 addition & 6 deletions lib/algora_web/live/ad_live/index.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,7 @@
</div>
</div>
</a>
<img
src={ad.composite_asset_url}
alt={ad.website_url}
class="box-content w-[1092px] h-[135px] object-cover border-[4px] rounded-xl transition-opacity duration-1000"
style={"border-color: #{ad.border_color || "#fff"}"}
/>
<.live_billboard ad={ad} id={"ad-banner-#{ad.id}"} />
</:col>
<:action :let={{_id, ad}}>
<div class="sr-only">
Expand Down
7 changes: 1 addition & 6 deletions lib/algora_web/live/ad_live/schedule.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,6 @@
</div>
</div>
</a>
<img
src={ad.composite_asset_url}
alt={ad.website_url}
class="box-content w-[1092px] h-[135px] object-cover border-[4px] rounded-xl transition-opacity duration-1000"
style={"border-color: #{ad.border_color || "#fff"}"}
/>
<.live_billboard ad={ad} id={"ad-banner-#{ad.id}"} />
</:col>
</.table>
2 changes: 1 addition & 1 deletion lib/algora_web/live/ad_live/show.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<.list>
<:item title="Verified"><%= @ad.verified %></:item>
<:item title="Website url"><%= @ad.website_url %></:item>
<:item title="Composite asset url"><%= @ad.composite_asset_url %></:item>
<:item title="Composite asset url"><%= @ad.composite_asset_urls |> Enum.join(", ") %></:item>
<:item title="Asset url"><%= @ad.asset_url %></:item>
<:item title="Logo url"><%= @ad.logo_url %></:item>
<:item title="Qrcode url"><%= @ad.qrcode_url %></:item>
Expand Down
15 changes: 5 additions & 10 deletions lib/algora_web/live/ad_overlay_live.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,12 @@ defmodule AlgoraWeb.AdOverlayLive do
~H"""
<%= if @ads && length(@ads) > 0 do %>
<div class="relative">
<img
src={@current_ad.composite_asset_url}
alt={@current_ad.website_url}
class={"box-content w-[1092px] h-[135px] object-cover border-[4px] rounded-xl transition-opacity duration-1000 #{if @show_ad, do: "opacity-100", else: "opacity-0"}"}
style={"border-color: #{@current_ad.border_color || "#fff"}"}
/>
<img
src={@next_ad.composite_asset_url}
alt={@next_ad.website_url}
class="absolute top-0 left-0 opacity-0 pointer-events-none"
<.live_billboard
ad={@current_ad}
id="ad-banner-0"
class={if @show_ad, do: "opacity-100", else: "opacity-0"}
/>
<.live_billboard ad={@next_ad} id="ad-banner-1" class="opacity-0 pointer-events-none" />
</div>
<% end %>
"""
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
defmodule Algora.Repo.Local.Migrations.RenameCompositeAssetUrlToCompositeAssetUrls do
use Ecto.Migration

def up do
alter table(:ads) do
add :composite_asset_urls, {:array, :string}, default: []
end

execute """
UPDATE ads
SET composite_asset_urls = ARRAY[composite_asset_url]
WHERE composite_asset_url IS NOT NULL
"""

alter table(:ads) do
remove :composite_asset_url
end
end

def down do
alter table(:ads) do
add :composite_asset_url, :string
end

execute """
UPDATE ads
SET composite_asset_url = composite_asset_urls[1]
WHERE composite_asset_urls IS NOT NULL
"""

alter table(:ads) do
remove :composite_asset_urls
end
end
end

0 comments on commit 677d6c7

Please sign in to comment.