From 2a2ebd6a46c1b5fa582e9e22daef6c77c0000edb Mon Sep 17 00:00:00 2001 From: filemon Date: Wed, 22 Apr 2026 18:58:36 -0300 Subject: [PATCH 1/2] Enable Blobbi eye tracking on feed cards (feed-only, with touch support) BlobbiStateCard gains an optional lookMode prop (default: 'forward'), threaded through to BlobbiStageVisual. Only the NoteCard feed call site passes 'follow-pointer'; post detail, embedded notes, and embedded naddr keep the default forward gaze. The global pointer listener in useBlobbiEyes now also tracks touchstart and touchmove so the effect works on mobile. --- src/blobbi/ui/lib/useBlobbiEyes.ts | 10 ++++++++++ src/components/BlobbiStateCard.tsx | 12 +++++++++--- src/components/NoteCard.tsx | 2 +- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/blobbi/ui/lib/useBlobbiEyes.ts b/src/blobbi/ui/lib/useBlobbiEyes.ts index 8daafcee..b1f08bd2 100644 --- a/src/blobbi/ui/lib/useBlobbiEyes.ts +++ b/src/blobbi/ui/lib/useBlobbiEyes.ts @@ -75,8 +75,18 @@ function attachGlobalMouseListener() { globalMouseY = e.clientY; }; + const handleTouch = (e: TouchEvent) => { + const touch = e.touches[0]; + if (touch) { + globalMouseX = touch.clientX; + globalMouseY = touch.clientY; + } + }; + // Use capture phase for earliest possible update window.addEventListener('mousemove', handleMouseMove, { capture: true, passive: true }); + window.addEventListener('touchstart', handleTouch, { capture: true, passive: true }); + window.addEventListener('touchmove', handleTouch, { capture: true, passive: true }); mouseListenerAttached = true; } diff --git a/src/components/BlobbiStateCard.tsx b/src/components/BlobbiStateCard.tsx index 5d0fcb27..dae31314 100644 --- a/src/components/BlobbiStateCard.tsx +++ b/src/components/BlobbiStateCard.tsx @@ -1,13 +1,19 @@ import { useMemo } from 'react'; import type { NostrEvent } from '@nostrify/nostrify'; -import { BlobbiStageVisual } from '@/blobbi/ui/BlobbiStageVisual'; +import { BlobbiStageVisual, type BlobbiLookMode } from '@/blobbi/ui/BlobbiStageVisual'; import { parseBlobbiEvent } from '@/blobbi/core/lib/blobbi'; import { calculateProjectedDecay } from '@/blobbi/core/hooks/useProjectedBlobbiState'; import { resolveStatusRecipe, attenuateRecipeForFeed, EMPTY_RECIPE } from '@/blobbi/ui/lib/status-reactions'; import { buildSleepingRecipe } from '@/blobbi/ui/lib/recipe'; -export function BlobbiStateCard({ event }: { event: NostrEvent }) { +interface BlobbiStateCardProps { + event: NostrEvent; + /** Controls eye tracking behavior. Default: 'forward' (eyes look straight ahead). */ + lookMode?: BlobbiLookMode; +} + +export function BlobbiStateCard({ event, lookMode = 'forward' }: BlobbiStateCardProps) { const companion = useMemo(() => parseBlobbiEvent(event), [event]); const isSleeping = companion?.state === 'sleeping'; @@ -44,7 +50,7 @@ export function BlobbiStateCard({ event }: { event: NostrEvent }) { companion={companion} size="lg" animated={!isSleeping} - lookMode="forward" + lookMode={lookMode} recipe={feedRecipe} recipeLabel={feedRecipeLabel} className="size-48 sm:size-56" diff --git a/src/components/NoteCard.tsx b/src/components/NoteCard.tsx index b5ffdfd0..b49b732e 100644 --- a/src/components/NoteCard.tsx +++ b/src/components/NoteCard.tsx @@ -668,7 +668,7 @@ export const NoteCard = memo(function NoteCard({ ) : isBlobbiState ? ( }> - + ) : ( Date: Thu, 23 Apr 2026 20:53:35 -0500 Subject: [PATCH 2/2] Enable Blobbi eye tracking on detail page Pass lookMode="follow-pointer" to BlobbiStateCard in PostDetailPage, matching the feed card behavior so Blobbi eyes follow the cursor on the detail view as well. --- src/pages/PostDetailPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/PostDetailPage.tsx b/src/pages/PostDetailPage.tsx index 40b38268..f6c74739 100644 --- a/src/pages/PostDetailPage.tsx +++ b/src/pages/PostDetailPage.tsx @@ -2165,7 +2165,7 @@ function PostDetailContent({ event }: { event: NostrEvent }) { ) : isBlobbiState ? ( }> - + ) : isBadgeAward ? (