Fix release build: box CallPanel's in-call subtree to avoid recursion limit

Mesh calling's nested Show/For inside ChatShell's own Show inlined as a
type parameter, blowing rustc's query recursion limit during the wasm
release build (CI: "queries overflow the depth limit!"). Splitting the
in-call view into its own component and type-erasing both CallPanel
branches with .into_any() keeps the type shallow instead of raising the
crate-wide limit.
This commit is contained in:
2026-07-28 10:53:32 +02:00
parent 4cc0103448
commit 64bc5222fc
+38 -13
View File
@@ -472,16 +472,49 @@ fn CallPanel(room: Memo<String>, me: String) -> impl IntoView {
view! { view! {
<div class="call-panel"> <div class="call-panel">
<Show {move || {
when=move || in_call.get() if in_call.get() {
fallback=move || { view! {
<CallActive
local_video_ref=local_video_ref
call_state=call_state.get_value()
on_leave=on_leave
/>
}
.into_any()
} else {
view! { view! {
<button class="call-join" on:click=on_join> <button class="call-join" on:click=on_join>
"☎ join call" "☎ join call"
</button> </button>
} }
.into_any()
} }
> }}
</div>
}
.into_any()
}
#[cfg(not(feature = "hydrate"))]
{
let _ = (room, me);
view! { <div class="call-panel"></div> }.into_any()
}
}
/// The in-call subtree (video grid + leave button), split out of
/// `CallPanel` so its `<For>`-over-peers view doesn't get inlined as a type
/// parameter of `CallPanel`'s own `if`/`else` branch - that inlining is what
/// was blowing the compiler's query recursion limit once mesh calling's
/// nested `Show`/`For` landed inside `ChatShell`'s own `Show`.
#[cfg(feature = "hydrate")]
#[component]
fn CallActive(
local_video_ref: NodeRef<leptos::html::Video>,
call_state: crate::webrtc::CallState,
on_leave: impl Fn(leptos::ev::MouseEvent) + 'static,
) -> impl IntoView {
view! {
<div class="call-active"> <div class="call-active">
<div class="video-grid"> <div class="video-grid">
<video <video
@@ -492,7 +525,7 @@ fn CallPanel(room: Memo<String>, me: String) -> impl IntoView {
playsinline=true playsinline=true
></video> ></video>
<For <For
each=move || call_state.get_value().peer_streams() each=move || call_state.peer_streams()
key=|(id, _)| id.clone() key=|(id, _)| id.clone()
children=move |(_id, stream)| { children=move |(_id, stream)| {
view! { <PeerVideoTile stream=stream/> } view! { <PeerVideoTile stream=stream/> }
@@ -503,14 +536,6 @@ fn CallPanel(room: Memo<String>, me: String) -> impl IntoView {
"⏏ leave call" "⏏ leave call"
</button> </button>
</div> </div>
</Show>
</div>
}
}
#[cfg(not(feature = "hydrate"))]
{
let _ = (room, me);
view! { <div class="call-panel"></div> }
} }
} }