fix: resolve layout and relay selection timing issues

Layout fixes:
- Remove conditional flex-1 from ProfileViewer profile content
- Remove conditional flex-1 from EventDetailViewer rendered content
- Main content sections now use natural size, only spell tabs have flex-1
- Prevents stacked headers issue and competing flex layouts

Relay selection fixes:
- Wait for appliedFilter to be resolved before selecting relays
- Ensures relay selection happens AFTER variable substitutions (, , etc.)
- Add appliedFilter check in finalRelays for all viewers (Profile, Event, Relay)
- Prevents relay selection with empty/incomplete filters
This commit is contained in:
Claude
2026-01-23 11:39:06 +00:00
parent 6479d78890
commit b439780b3f
3 changed files with 29 additions and 8 deletions

View File

@@ -151,6 +151,14 @@ function SpellTabContent({
// Resolve relays - use explicit relays from spell, or use relay hints from target event
const finalRelays = useMemo(() => {
// Don't select relays until filter is resolved (variables substituted)
if (!appliedFilter) {
console.log(
`[EventSpell:${spell.name || spellId}] Waiting for filter resolution before selecting relays`,
);
return [];
}
// Use explicit relays from spell if provided
if (parsed?.relays && parsed.relays.length > 0) {
console.log(
@@ -178,7 +186,7 @@ function SpellTabContent({
`[EventSpell:${spell.name || spellId}] Using fallback AGGREGATOR_RELAYS`,
);
return AGGREGATOR_RELAYS;
}, [parsed?.relays, targetEvent, spell.name, spellId]);
}, [appliedFilter, parsed?.relays, targetEvent, spell.name, spellId]);
// Fetch events using the applied filter
// Always call the hook unconditionally (React Rules of Hooks)
@@ -410,9 +418,7 @@ export function EventDetailViewer({ pointer }: EventDetailViewerProps) {
</div>
{/* Rendered Content */}
<div
className={`overflow-y-auto ${eventSpells.length > 0 ? "flex-1 min-h-0" : ""}`}
>
<div className="overflow-y-auto">
<EventErrorBoundary event={event}>
<DetailKindRenderer event={event} />
</EventErrorBoundary>

View File

@@ -233,6 +233,14 @@ function SpellTabContent({
useOutboxRelays(appliedFilter || {}, outboxOptions);
const finalRelays = useMemo(() => {
// Don't select relays until filter is resolved (variables substituted)
if (!appliedFilter) {
console.log(
`[SpellTabContent:${spell.name || spellId}] Waiting for filter resolution before selecting relays`,
);
return [];
}
// Use explicit relays from spell if provided
if (parsed?.relays && parsed.relays.length > 0) {
console.log(
@@ -256,6 +264,7 @@ function SpellTabContent({
);
return selectedRelays;
}, [
appliedFilter,
parsed?.relays,
relaySelectionPhase,
selectedRelays,
@@ -692,9 +701,7 @@ export function ProfileViewer({ pubkey }: ProfileViewerProps) {
</div>
{/* Profile Content */}
<div
className={`overflow-y-auto p-4 ${pubkeySpells.length > 0 ? "flex-1 min-h-0" : ""}`}
>
<div className="overflow-y-auto p-4">
{!profile && !profileEvent && <ProfileCardSkeleton variant="full" />}
{!profile && profileEvent && (

View File

@@ -135,6 +135,14 @@ function SpellTabContent({
// Resolve relays - for $relay spells, we query FROM the target relay itself
const finalRelays = useMemo(() => {
// Don't select relays until filter is resolved (variables substituted)
if (!appliedFilter) {
console.log(
`[RelaySpell:${spell.name || spellId}] Waiting for filter resolution before selecting relays`,
);
return [];
}
// Use explicit relays from spell if provided
if (parsed?.relays && parsed.relays.length > 0) {
console.log(
@@ -149,7 +157,7 @@ function SpellTabContent({
targetRelay,
]);
return [targetRelay];
}, [parsed?.relays, targetRelay, spell.name, spellId]);
}, [appliedFilter, parsed?.relays, targetRelay, spell.name, spellId]);
// Fetch events using the applied filter
// Always call the hook unconditionally (React Rules of Hooks)