From 38b0e52e89b9cb99ae63d1982fe03d374db4d360 Mon Sep 17 00:00:00 2001 From: npub19x6jnl6rhepymwyl2xlltz3ce7rfg2ktllle3g2vu59n3s490k8s9n40l3 <29b529ff43be424db89f51bff58a38cf86942acbffff98a14ce50b38c2a57d8f@sprout-oss.stage.blox.sqprod.co> Date: Sat, 18 Jul 2026 18:23:39 -0700 Subject: [PATCH 1/2] fix(desktop): align team intro onboarding Co-authored-by: npub19x6jnl6rhepymwyl2xlltz3ce7rfg2ktllle3g2vu59n3s490k8s9n40l3 <29b529ff43be424db89f51bff58a38cf86942acbffff98a14ce50b38c2a57d8f@sprout-oss.stage.blox.sqprod.co> Signed-off-by: npub19x6jnl6rhepymwyl2xlltz3ce7rfg2ktllle3g2vu59n3s490k8s9n40l3 <29b529ff43be424db89f51bff58a38cf86942acbffff98a14ce50b38c2a57d8f@sprout-oss.stage.blox.sqprod.co> --- .../onboarding/ui/CommunityOnboardingFlow.tsx | 132 +++++++++++------- desktop/tests/e2e/deep-link-invite.spec.ts | 26 ++-- desktop/tests/e2e/onboarding.spec.ts | 19 ++- 3 files changed, 98 insertions(+), 79 deletions(-) diff --git a/desktop/src/features/onboarding/ui/CommunityOnboardingFlow.tsx b/desktop/src/features/onboarding/ui/CommunityOnboardingFlow.tsx index e09fd8404..02518fb26 100644 --- a/desktop/src/features/onboarding/ui/CommunityOnboardingFlow.tsx +++ b/desktop/src/features/onboarding/ui/CommunityOnboardingFlow.tsx @@ -109,6 +109,26 @@ function AvatarCircle({ ); } +function LoadingDots({ label }: { label: string }) { + return ( + + {[0, 1, 2].map((index) => ( + + ); +} + export function CommunityOnboardingFlow({ onCancel, onConnect, @@ -235,6 +255,11 @@ export function CommunityOnboardingFlow({ } }, [finish, isPending, queryClient, relayUrl, update]); + const backToProfile = React.useCallback(() => { + if (isPending) return; + update({ stage: "profile", error: undefined }); + }, [isPending, update]); + const isProfileStage = transaction?.stage === "profile"; const isTeamStage = transaction?.stage === "team-intro" || @@ -340,9 +365,9 @@ export function CommunityOnboardingFlow({ className={cn( "relative w-full text-center", isProfileStage - ? "buzz-onboarding-step-frame flex max-w-[500px] flex-col justify-center" + ? "buzz-onboarding-step-frame flex max-w-[500px] flex-col items-center" : isTeamStage - ? "buzz-onboarding-step-frame flex max-w-[760px] flex-col justify-center" + ? "buzz-onboarding-step-frame flex max-w-[760px] flex-col items-center" : "flex min-h-dvh max-w-[560px] flex-col justify-center py-8", )} data-testid="community-onboarding-body" @@ -405,7 +430,7 @@ export function CommunityOnboardingFlow({ ) : ( <> -
+

Build your profile

Add a name and avatar. They’ll show up on your messages, @@ -468,66 +493,67 @@ export function CommunityOnboardingFlow({

Meet your starter team

Buzz lets you bring multiple agents into the same workspace. - This team will help you get started using Buzz. + Your team will help you get started using Buzz.

- {starterPersonas.length > 0 ? ( -
- {starterPersonas.map((persona) => { - const animationUrl = - STARTER_PERSONA_ANIMATIONS[persona.displayName]; - return ( -
- {animationUrl ? ( - {`${persona.displayName} - ) : ( - - )} - - {persona.displayName} - -
- ); - })} -
- ) : null} +
+ {starterPersonas.length > 0 ? ( +
+ {starterPersonas.map((persona) => { + const animationUrl = + STARTER_PERSONA_ANIMATIONS[persona.displayName]; + return ( +
+ {animationUrl ? ( + {`${persona.displayName} + ) : ( + + )} + + {persona.displayName} + +
+ ); + })} +
+ ) : null} +
{transaction.error ? ( -

- {transaction.error} -

+

{transaction.error}

) : null} + - {transaction.error ? ( - - ) : null} )} diff --git a/desktop/tests/e2e/deep-link-invite.spec.ts b/desktop/tests/e2e/deep-link-invite.spec.ts index efd3d9337..e8d45ba3c 100644 --- a/desktop/tests/e2e/deep-link-invite.spec.ts +++ b/desktop/tests/e2e/deep-link-invite.spec.ts @@ -243,7 +243,7 @@ test("queued add-community links open and acknowledge one at a time", async ({ ]); }); -test("Welcome failure can be skipped without abandoning community onboarding", async ({ +test("Welcome failure can go back without abandoning community onboarding", async ({ page, }) => { const welcomeError = "Channel creation is not permitted."; @@ -291,30 +291,26 @@ test("Welcome failure can be skipped without abandoning community onboarding", a ); } - await page.getByRole("button", { name: "Enter hive" }).click(); + await page.getByRole("button", { name: "Take me to Buzz" }).click(); await expect(page.getByText(welcomeError)).toBeVisible(); await expect( - page.getByRole("button", { name: "Preparing Welcome…" }), + page.getByRole("button", { name: "Take me to Buzz" }), ).toBeEnabled(); - const skip = page.getByRole("button", { name: "Skip for now" }); - await expect(skip).toBeVisible(); - await skip.click(); + await expect(page.getByRole("button", { name: "Back" })).toBeVisible(); + await page.getByRole("button", { name: "Back" }).click(); - const completionKey = `buzz-community-onboarding-complete.v1:${encodeURIComponent(COMMUNITY_RELAY_URL)}:${WELCOME_FAILURE_PUBKEY}`; + await expect( + page.getByRole("heading", { name: "Build your profile" }), + ).toBeVisible(); await expect .poll(() => page.evaluate( - ({ completion, transaction }) => ({ - completion: window.localStorage.getItem(completion), - transaction: window.localStorage.getItem(transaction), - }), - { completion: completionKey, transaction: TRANSACTION_STORAGE_KEY }, + (transaction) => window.localStorage.getItem(transaction), + TRANSACTION_STORAGE_KEY, ), ) - .toEqual({ completion: "true", transaction: null }); - await expect(page.getByTestId("community-onboarding-flow")).toHaveCount(0); - await expect(page.getByTestId("app-sidebar")).toBeVisible(); + .toContain('"stage":"profile"'); }); test("persisted deep-link invite hands off to Joining after machine onboarding", async ({ diff --git a/desktop/tests/e2e/onboarding.spec.ts b/desktop/tests/e2e/onboarding.spec.ts index f620df928..b6749bf66 100644 --- a/desktop/tests/e2e/onboarding.spec.ts +++ b/desktop/tests/e2e/onboarding.spec.ts @@ -985,18 +985,15 @@ test("connected first-community profile step cannot discard resumable onboarding await expect( page.getByRole("heading", { name: "Build your profile" }), ).toBeVisible(); - const profileMain = page.getByTestId("community-profile-main"); - const profileMainBox = await profileMain.boundingBox(); - const viewport = page.viewportSize(); - if (!profileMainBox || !viewport) { - throw new Error("Could not measure community profile body position"); + const profileHeading = page.getByRole("heading", { + name: "Build your profile", + }); + await expect(profileHeading).toBeVisible(); + const profileHeadingBox = await profileHeading.boundingBox(); + if (!profileHeadingBox) { + throw new Error("Could not measure community profile heading position"); } - const chromeOffset = 106; - const footerOffset = 144; - const profileMainCenterY = profileMainBox.y + profileMainBox.height / 2; - const centeredInUsableLaneY = - chromeOffset + (viewport.height - chromeOffset - footerOffset) / 2; - expect(Math.abs(profileMainCenterY - centeredInUsableLaneY)).toBeLessThan(32); + expect(Math.abs(profileHeadingBox.y - 106)).toBeLessThan(8); const nameKey = page.getByTestId("community-profile-name-key"); const avatarButton = page.getByTestId("community-avatar-open"); await expect(nameKey).toBeVisible(); From 19d8ac2341e372b4451df3542208c66672992ab2 Mon Sep 17 00:00:00 2001 From: npub19x6jnl6rhepymwyl2xlltz3ce7rfg2ktllle3g2vu59n3s490k8s9n40l3 <29b529ff43be424db89f51bff58a38cf86942acbffff98a14ce50b38c2a57d8f@sprout-oss.stage.blox.sqprod.co> Date: Sat, 18 Jul 2026 21:47:13 -0700 Subject: [PATCH 2/2] fix(desktop): allow skipping failed starter setup Co-authored-by: npub19x6jnl6rhepymwyl2xlltz3ce7rfg2ktllle3g2vu59n3s490k8s9n40l3 <29b529ff43be424db89f51bff58a38cf86942acbffff98a14ce50b38c2a57d8f@sprout-oss.stage.blox.sqprod.co> Signed-off-by: npub19x6jnl6rhepymwyl2xlltz3ce7rfg2ktllle3g2vu59n3s490k8s9n40l3 <29b529ff43be424db89f51bff58a38cf86942acbffff98a14ce50b38c2a57d8f@sprout-oss.stage.blox.sqprod.co> --- .../onboarding/ui/CommunityOnboardingFlow.tsx | 17 +++++- desktop/tests/e2e/deep-link-invite.spec.ts | 53 +++++++++++++++---- 2 files changed, 58 insertions(+), 12 deletions(-) diff --git a/desktop/src/features/onboarding/ui/CommunityOnboardingFlow.tsx b/desktop/src/features/onboarding/ui/CommunityOnboardingFlow.tsx index 02518fb26..25443ecd3 100644 --- a/desktop/src/features/onboarding/ui/CommunityOnboardingFlow.tsx +++ b/desktop/src/features/onboarding/ui/CommunityOnboardingFlow.tsx @@ -146,6 +146,8 @@ export function CommunityOnboardingFlow({ [], ); const [isPending, setIsPending] = React.useState(false); + const [starterChannelFailureCount, setStarterChannelFailureCount] = + React.useState(0); const [deniedPubkey, setDeniedPubkey] = React.useState(""); const [isMembershipDenied, setIsMembershipDenied] = React.useState(false); const [isCommunityChangeOpen, setIsCommunityChangeOpen] = @@ -248,6 +250,7 @@ export function CommunityOnboardingFlow({ } await finish(); } catch (error) { + setStarterChannelFailureCount((count) => count + 1); update({ error: error instanceof Error ? error.message : String(error), }); @@ -257,6 +260,7 @@ export function CommunityOnboardingFlow({ const backToProfile = React.useCallback(() => { if (isPending) return; + setStarterChannelFailureCount(0); update({ stage: "profile", error: undefined }); }, [isPending, update]); @@ -530,17 +534,26 @@ export function CommunityOnboardingFlow({ ) : null}
{transaction.error ? ( -

{transaction.error}

+

+ {transaction.error} + {starterChannelFailureCount === 1 ? " Try again." : null} +

) : null}