Skip to content

Fix float teaser delay from API embed settings being ignored#70

Merged
LEVI-RIVKIN merged 2 commits into
mainfrom
claude/teaser-delay-not-working-y4ktk4
Jul 9, 2026
Merged

Fix float teaser delay from API embed settings being ignored#70
LEVI-RIVKIN merged 2 commits into
mainfrom
claude/teaser-delay-not-working-y4ktk4

Conversation

@LEVI-RIVKIN

@LEVI-RIVKIN LEVI-RIVKIN commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Problem

Dashboard embed settings for the float teaser delay (embedSettings.teaser.delay) had no effect on customer sites. Reported for research mype6y13 (embedded on greencountryhomebuyers.com): the delay was set to 30000ms and the config API returned it correctly, but the teaser always appeared after ~3 seconds.

Root cause

For script-tag embeds (data-perspective-float), the float bubble mounts immediately while the embed config is fetched asynchronously. createFloatBubble armed the welcome sequence (teaser + chime timers) at mount using the delay known at that moment — the hardcoded 3000ms default — and set welcomeSequenceStarted. When the API config arrived moments later via update()syncTeaserState(), maybeStartWelcomeSequence() returned early because the sequence was already marked as started, so the configured delay was silently ignored.

Fix

  • Defer arming while the config fetch is in flight. Script-tag float mounts set an internal _apiConfigPending flag; the welcome sequence does not arm until update({ _apiConfig }) clears it, so the teaser can never fire on the default delay while waiting for the API. fetchEmbedConfig never rejects (it resolves with the default theme on error/timeout), so the deferral always ends.
  • Measure the delay from a persistent anchor. The anchor is set when the sequence first could have started (mount, or a re-enable after a disable) and survives deferred arms and reschedules — the teaser fires at the resolved delay measured from mount, crediting time already waited. Repeated delay changes on a still-pending teaser reschedule against the same anchor (not the latest reschedule), and a disable resets the anchor so a re-enable measures from the re-enable.
  • A delivered or cancelled teaser (e.g. the visitor opened the chat) is never re-armed by a late config refresh.

Testing

  • New regression tests: deferred arm with elapsed-time credit, immediate show when the config resolves past the default delay, delay reschedule on async config arrival, second delay change crediting from the first arm, re-enable measuring from the re-enable, no-op refresh with an unchanged delay, no re-arm after the teaser has shown, and no arming while the fetch is unresolved (browser auto-init).
  • Full suite green: 449 SDK tests, 90 sdk-react tests, typecheck, lint, and format.
  • Patch changeset added for @perspective-ai/sdk.

🤖 Generated with Claude Code

https://claude.ai/code/session_01U6W4LcRde56iDNCwCMj76Q

The welcome sequence was armed at mount with whatever teaser delay was
known at that moment — for script-tag embeds that's the 3s default,
since the async /embed/config fetch hasn't resolved yet. When the API
config later arrived via update(), maybeStartWelcomeSequence() bailed
out because the sequence was already marked as started, so a dashboard
teaser delay (e.g. 30000ms) never took effect and the teaser always
appeared after ~3s.

syncTeaserState() now reschedules the pending timers when the resolved
delay changes, crediting the time already waited so the teaser fires at
the configured delay relative to mount. Once the teaser has been
delivered or the sequence cancelled (e.g. the float was opened), a
late config refresh no longer re-arms it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U6W4LcRde56iDNCwCMj76Q
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

📦 Snapshot Release

Published snapshot packages for this PR:

pnpm add @perspective-ai/sdk@1.14.1-pr-70-20260709215800
pnpm add @perspective-ai/sdk-react@1.14.1-pr-70-20260709215800

Or use the npm tag (always points to the latest snapshot from this PR):

pnpm add @perspective-ai/sdk@pr-70
pnpm add @perspective-ai/sdk-react@pr-70

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes float teaser delay being ignored when dashboard/API embed settings arrive asynchronously after the float bubble mounts, by rescheduling the welcome sequence timers to respect the resolved embedSettings.teaser.delay (crediting time already elapsed since mount).

Changes:

  • Track which teaser delay the welcome sequence was armed with and when, so pending timers can be rescheduled when API config changes the delay.
  • Reschedule teaser + chime timers on delay changes while the teaser is still pending, without re-arming after the teaser has already fired.
  • Add regression tests covering async delay reschedule, unchanged-delay refresh behavior, and no re-arm after the teaser has shown; add a patch changeset for @perspective-ai/sdk.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
packages/sdk/src/float.ts Adds arm-tracking and rescheduling logic so async API teaser delay updates take effect.
packages/sdk/src/float.test.ts Adds regression tests for delay rescheduling and non-rearming scenarios.
.changeset/teaser-delay-reschedule.md Patch changeset documenting the behavioral fix for @perspective-ai/sdk.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/sdk/src/float.ts Outdated
Comment thread packages/sdk/src/float.ts
Instead of arming the welcome sequence at mount with the default delay
and rescheduling when the API config arrives, script-tag embeds now
defer arming entirely while the config fetch is in flight (internal
_apiConfigPending flag, cleared by update({_apiConfig})). This removes
any chance of the teaser firing early on a slow fetch; fetchEmbedConfig
never rejects (it resolves with the default theme on error/timeout), so
the deferral always ends.

The delay is measured from a persistent anchor set when the sequence
first could have started (mount, or re-enable after a disable), so the
eventual arm credits the time already waited, and repeated delay
changes on a still-pending teaser reschedule against the same anchor
rather than the latest reschedule. Addresses both Copilot review
comments on the previous approach.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U6W4LcRde56iDNCwCMj76Q

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.

@LEVI-RIVKIN LEVI-RIVKIN merged commit 274f6ef into main Jul 9, 2026
6 checks passed
@LEVI-RIVKIN LEVI-RIVKIN deleted the claude/teaser-delay-not-working-y4ktk4 branch July 9, 2026 22:10
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.

2 participants