Skip to content

feat: interest agent page mockup - #6392

Draft
capJavert wants to merge 7 commits into
mainfrom
feat/interest-agent-mockup
Draft

feat: interest agent page mockup#6392
capJavert wants to merge 7 commits into
mainfrom
feat/interest-agent-mockup

Conversation

@capJavert

@capJavert capJavert commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Rebuild /agent/[id] as a product surface instead of the debug panel.

  • Always-available agent toolbar (fixed bottom): status, pause/resume, settings, freeform "tell the agent what to change" input, quick actions.
  • Feed / Posts / Activity / Debug tabs. Findings render through the real ArticleGrid cards with an agent footer (match score + rationale + "More like this" / "Not relevant" chips).
  • First card is a full-width featured-wide hero showing the agent's latest summary post.
  • Agent posts get inline rewrite chips and a freeform "tell it what to fix" field, with a faked background-rewrite state.
  • Settings modal replaces the debug controls: cadence, delivery hour, FOMO slider, output toggles, sources, pause/stop.
  • Self-contained fake data (mock.ts / mockFeed.ts) so ?demo=1 renders the whole flow with no API dependency.

Findings query now pulls the full FeedPost fragment so real findings render as proper feed cards. Per-card feedback is local state only and does not trigger an agent run.

Changes

Events

Did you introduce any new tracking events?

Experiment

Did you introduce any new experiments?

Manual Testing

Caution

Please make sure existing components are not breaking/affected by this PR

Preview domain

https://feat-interest-agent-mockup.preview.app.daily.dev

Rebuild /agent/[id] as a product surface instead of the debug panel.

- Always-available agent toolbar (fixed bottom): status, pause/resume,
  settings, freeform "tell the agent what to change" input, quick actions.
- Feed / Posts / Activity / Debug tabs. Findings render through the real
  ArticleGrid cards with an agent footer (match score + rationale +
  "More like this" / "Not relevant" chips).
- First card is a full-width featured-wide hero showing the agent's
  latest summary post.
- Agent posts get inline rewrite chips and a freeform "tell it what to
  fix" field, with a faked background-rewrite state.
- Settings modal replaces the debug controls: cadence, delivery hour,
  FOMO slider, output toggles, sources, pause/stop.
- Self-contained fake data (mock.ts / mockFeed.ts) so ?demo=1 renders
  the whole flow with no API dependency.

Findings query now pulls the full FeedPost fragment so real findings
render as proper feed cards. Per-card feedback is local state only and
does not trigger an agent run.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@capJavert capJavert self-assigned this Jul 29, 2026
@vercel

vercel Bot commented Jul 29, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
daily-webapp Ready Ready Preview Jul 31, 2026 4:04pm
storybook Building Building Preview Jul 31, 2026 4:04pm

Request Review

Replace the Feed and Posts tabs with a single Chat tab: an LLM-style
message stream where the agent structures its output with real
daily.dev content instead of plain prose. Activity and Debug stay.

Message blocks (chat.ts):
- text     rendered through the shared Markdown component
- posts    ArticleList card, used for the single standout finding
- picks    /daily-style expandable rows for the tail
- collection  CollectionList with the multi-source avatar stack
- feedLink    chip (no target route yet)

Post cards, picks rows and the collection card all open the real post
modal — both modals take a post object directly, so this works off the
mock posts with no API calls.

The bottom toolbar is now the composer: sending appends a user bubble,
shows a typing bubble, then resolves into a canned agent reply.

AgentPickList replicates the /daily PickRow visual rather than importing
it: PickRow is unexported and wired to useLogImpression with
Origin.DailyPage plus daily's vote/bookmark mutations, so reusing it
would log agent-page impressions into the daily feed's analytics.

Removes AgentFeedSection, AgentFindingCard, AgentHeroCard and
AgentPostSection, superseded by the chat stream.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Clicking any embed in the chat now opens its content beside the
conversation instead of a full-screen modal.

Presentation:
- Laptop+: in-flow sticky column (24rem, 28rem at laptopL) that pushes
  the chat aside rather than covering it. The chat keeps its 48rem width
  and re-centres in the space that's left.
- Mobile: fixed bottom sheet at 2/3 viewport height with no backdrop, so
  the top third stays visible and scrollable.
- Closes on the X or Escape (no outside-click, which would fight with
  scrolling the live area behind it).

The pane body renders the real PostContent — the same component the post
modal uses. It works on mock posts because withPostById falls back to
the passed post when the fetch is empty. PostContent is built for a
full-width modal, so its desktop-only rules are overridden in-pane to
force the mobile single-column layout: laptop:flex-row -> !flex-col, the
laptop:w-[21.25rem] widgets sidebar to full width, and the laptop
borders/padding on <main>/<aside> off. Targeting those by tag is
brittle; fine for a mockup.

Also:
- activePost generalised to an AgentContentTarget union (post | feed),
  so post embeds, picks rows and feed links share one piece of state and
  pane/modal stay mutually exclusive by construction.
- feedLink blocks carry their posts, so "Open all 9 findings as a feed"
  opens a real list; rows drill down into the post view.
- Side pane / Modal toggle in the page header, styled after
  DailySwitcher, shallow-routing a `view` query param. AgentFeedModal
  covers the feed target in modal mode.
- Page header is sticky under the app header, back button moved to the
  left of the title.
- Picks rows open on click instead of expanding (daily's own PickRow is
  untouched).
- Collections dropped: the mock is article posts only.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The sticky bar starts bare — just the back button and the view toggle —
and assembles itself only when the hero leaves the viewport, so the
title isn't duplicated while the hero is on screen.

Once out of view the bar picks up the hero's data: the title fades and
slides in, the agent avatar grows from size-0, and the status chip plus
lastRunSummary fade up. All on one 200ms ease-out so it reads as a
single bar changing shape rather than two bars swapping.

- useInView (react-intersection-observer) watches the hero with
  rootMargin -56px, so the trigger fires when it clears the sticky bar
  rather than the raw viewport edge. initialInView keeps the bare state
  through hydration so it can't flash condensed on load.
- Hidden elements keep their layout box and get pointer-events-none, so
  nothing shifts horizontally and the invisible title can't take clicks.
- Status chip extracted from AgentHero into AgentStatusChip (with a
  compact variant) and used by both, so statusCopy lives in one place
  and the two can't drift.
- PageHeader moved from Page into AgentPageBody, where the observer
  state lives. Same DOM position and sticky behaviour.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Resize:
- Drag handle on the pane's inner left edge (laptop+ only). Pointer
  events go on window so the drag keeps tracking if the cursor outruns
  the handle. It sits inside the pane because the aside's overflow-hidden
  clips anything positioned outside it.
- Both columns floor at 384px (also the pane default) and the pane takes
  whatever is left. The max is measured off the columns row's content
  box: clientWidth includes the row's own px-4/px-6, so using it
  directly let the pane grow past the page gutter.
- Width persists via usePersistentContext. It's idb-backed, so a drag
  updates local state and only commits on pointer release instead of
  writing on every pointermove.

Viewing state:
- The post open in the pane gets a full-card overlay
  (bg-background-default/85 + backdrop-blur-sm) with a Viewing chip, so
  the cover image and title aren't duplicated between chat and pane. The
  card keeps its footprint, so nothing reflows on open/close.
- Picks rows keep a chip plus a held surface-float row; they have no
  image to duplicate and blurring a compact row would just hurt.
- Chip label uses text-surface-invert, which flips with the chip's
  surface-secondary background, so it reads dark on the light chip in
  dark mode and light on the dark chip in light mode.

Layout:
- List rows switch to grid cards below 550px of *container* width, via a
  ResizeObserver hook. The chat column can be 384px on a wide screen, so
  viewport media queries can't express this.
- Chat column sized with flex-1 rather than w-full; with basis auto it
  stalled around its max-width instead of shrinking to the 384 floor.
- Dropped PageBodyContainer's laptop:border-x inside the pane, which
  doubled up against the pane's own border.
- Pane sticks 1rem below the header bar instead of flush against it.
- Sticky bar offset is top-0 on mobile: the v2 sidebar layout has no top
  header there, so top-14 left 56px of dead space.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The sticky header strip hardcoded an offset for the legacy top header.
In layout_v2 the sidebar rail owns the header, so there is nothing to
clear and the strip parked 4rem down leaving dead space above it.

Offsets now come from useLayoutVariant (the same hook FeedContainer
uses):
- laptop v2: strip at top-3.5, the floating card's inner top
  (laptop:my-3 + p-0.5), so it sticks inside the card instead of poking
  out of its rounded corners or being cut by its overflow-clip.
- laptop legacy: strip at top-16, clearing the 4rem header.
- mobile: top-0 for both. useLayoutVariant is false below laptop by
  design, and the legacy mobile header auto-hides on scroll, so by the
  time stickiness matters there is no header to clear; at scroll-top the
  strip is in normal flow below it anyway.

The pane's sticky offset is derived from wherever the strip lands plus
the existing 1rem gap, so the two stay in step across variants.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant