Add embed focus mode and adjust layouts

This commit is contained in:
Alex Lion
2026-07-16 22:03:27 +02:00
parent faccbfa5e7
commit 5bbff7701c
5 changed files with 33 additions and 14 deletions

View File

@@ -126,7 +126,7 @@
}
@media (max-height: 500px) {
#focus-slot {
#focus-slot:not([data-interaction-mode="true"]) {
height: 7rem;
min-height: 7rem;
}

View File

@@ -3,9 +3,12 @@ defmodule ClaperWeb.EventLive.EmbedComponent do
@impl true
def render(assigns) do
assigns = assign_new(assigns, :focus_mode, fn -> false end)
~H"""
<div class="font-display">
<div
:if={!@focus_mode}
id="collapsed-embed"
class="mx-auto hidden w-max rounded-full bg-gray-900 px-5 py-3 shadow-xl ring-1 ring-white/10"
>
@@ -36,10 +39,15 @@ defmodule ClaperWeb.EventLive.EmbedComponent do
</div>
<div
id="extended-embed"
class="w-full rounded-2xl bg-gray-900 p-4 text-gray-100 shadow-2xl ring-1 ring-white/10"
class={[
"w-full rounded-2xl bg-gray-900 p-4 text-gray-100",
@focus_mode && "shadow-none ring-0",
!@focus_mode && "shadow-2xl ring-1 ring-white/10"
]}
>
<div class="relative pr-8">
<button
:if={!@focus_mode}
id="embed-pane"
type="button"
aria-label={gettext("Close")}

View File

@@ -76,7 +76,7 @@ defmodule ClaperWeb.EventLive.PollComponent do
<% end %>
</div>
<div>
<div class="flex max-h-[500px] flex-col gap-2 overflow-y-auto">
<div id="poll-options" class="flex flex-col gap-2">
<%= if (length @poll.poll_opts) > 0 do %>
<%= for {opt, idx} <- Enum.with_index(@poll.poll_opts) do %>
<%= if (length @current_poll_vote) > 0 do %>

View File

@@ -8,7 +8,8 @@
<% interaction_mode? =
match?(%Claper.Polls.Poll{}, @current_interaction) ||
match?(%Claper.Forms.Form{}, @current_interaction) ||
match?(%Claper.Quizzes.Quiz{}, @current_interaction) %>
match?(%Claper.Quizzes.Quiz{}, @current_interaction) ||
match?(%Claper.Embeds.Embed{attendee_visibility: true}, @current_interaction) %>
<div class="h-[100dvh] overflow-hidden bg-black lg:bg-primary-700">
<main
id="attendee-room"
@@ -131,7 +132,8 @@
data-interaction-mode={to_string(interaction_mode?)}
class={[
"relative z-10 min-h-0 overflow-hidden border-y border-white/10 bg-gray-950 transition-[height] duration-300",
focus_content? && "h-[40dvh] min-h-40 max-h-[26rem]",
focus_content? && interaction_mode? && "h-auto max-h-[40dvh]",
focus_content? && !interaction_mode? && "h-[40dvh] min-h-40 max-h-[26rem]",
!focus_content? && "h-12"
]}
>
@@ -144,7 +146,7 @@
<%= case @current_interaction do %>
<% %Claper.Polls.Poll{} -> %>
<div class="h-full overflow-y-auto overscroll-contain p-3">
<div class="max-h-[40dvh] overflow-y-auto overscroll-contain p-3">
<.live_component
module={ClaperWeb.EventLive.PollComponent}
id={"#{@current_interaction.id}-poll"}
@@ -159,7 +161,7 @@
/>
</div>
<% %Claper.Forms.Form{} -> %>
<div class="h-full overflow-y-auto overscroll-contain p-3">
<div class="max-h-[40dvh] overflow-y-auto overscroll-contain p-3">
<.live_component
module={ClaperWeb.EventLive.FormComponent}
id={"#{@current_interaction.id}-form"}
@@ -172,7 +174,7 @@
/>
</div>
<% %Claper.Quizzes.Quiz{} -> %>
<div class="h-full overflow-y-auto overscroll-contain p-3">
<div class="max-h-[40dvh] overflow-y-auto overscroll-contain p-3">
<.live_component
module={ClaperWeb.EventLive.QuizComponent}
id={"#{@current_interaction.id}-quiz"}
@@ -188,13 +190,12 @@
/>
</div>
<% %Claper.Embeds.Embed{attendee_visibility: true} -> %>
<div id="focus-media" class="relative h-full w-full bg-black">
<div class="max-h-[40dvh] overflow-y-auto overscroll-contain p-3">
<.live_component
id={"focus-embed-#{@current_interaction.id}"}
module={ClaperWeb.EventLive.EmbedIframeComponent}
provider={@current_interaction.provider}
content={@current_interaction.content}
title={@current_interaction.title}
id={"#{@current_interaction.id}-embed"}
module={ClaperWeb.EventLive.EmbedComponent}
embed={@current_interaction}
focus_mode
/>
</div>
<% _ -> %>

View File

@@ -40,6 +40,7 @@ defmodule ClaperWeb.EventLive.InteractionComponentsTest do
assert "bg-primary-900/40" in option_classes
assert "py-2" in option_classes
assert "shrink-0" in option_classes
refute "overflow-y-auto" in classes(document, "#poll-options")
refute "min-h-11" in option_classes
assert Floki.attribute(document, "#poll-opt-0", "aria-pressed") == ["true"]
assert "btn-gradient" in vote_classes
@@ -284,6 +285,15 @@ defmodule ClaperWeb.EventLive.InteractionComponentsTest do
assert "h-full" in classes(document, "iframe")
assert "w-full" in classes(document, "iframe")
assert Floki.attribute(document, "iframe", "title") == ["Watch the demo"]
focus_document =
EmbedComponent
|> render_component(id: "focus-embed-component", embed: embed, focus_mode: true)
|> Floki.parse_document!()
assert Floki.find(focus_document, "#collapsed-embed") == []
assert Floki.find(focus_document, "#embed-pane") == []
assert "shadow-none" in classes(focus_document, "#extended-embed")
end
test "custom web content is not cropped into a video aspect ratio" do