Skip to content

Main page redesign#4015

Open
elstua wants to merge 2 commits intofastrepl:mainfrom
elstua:new-main-page
Open

Main page redesign#4015
elstua wants to merge 2 commits intofastrepl:mainfrom
elstua:new-main-page

Conversation

@elstua
Copy link
Contributor

@elstua elstua commented Feb 16, 2026

  1. Add the large manifesto as first screen
  2. rework the current feature blocks

mostly want to figure out how to work with staging


Open with Devin

@netlify
Copy link

netlify bot commented Feb 16, 2026

Deploy Preview for hyprnote failed.

Name Link
🔨 Latest commit eb2b903
🔍 Latest deploy log https://app.netlify.com/projects/hyprnote/deploys/6993b3258e918e00082afd8e

@netlify
Copy link

netlify bot commented Feb 16, 2026

Deploy Preview for hyprnote-storybook ready!

Name Link
🔨 Latest commit eb2b903
🔍 Latest deploy log https://app.netlify.com/projects/hyprnote-storybook/deploys/6993b3254092580008d449e6
😎 Deploy Preview https://deploy-preview-4015--hyprnote-storybook.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 2 potential issues.

View 5 additional findings in Devin Review.

Open in Devin Review

Comment on lines 169 to 173
Copy link
Contributor

Choose a reason for hiding this comment

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

🔴 CTA button for waitlist users is broken because HeroSection (with email input) is commented out

The CTASection at the bottom of the page uses heroInputRef to scroll to and focus the hero email input when platformCTA.action === "waitlist". However, HeroSection (which contained the <input ref={heroInputRef}>) is now commented out at apps/web/src/routes/_view/index.tsx:169-172.

Root Cause and Impact

In handleCTAClick (apps/web/src/routes/_view/index.tsx:2413-2431), when the platform action is "waitlist", the code calls window.scrollTo({ top: 0 }) and then tries to focus heroInputRef.current. Since HeroSection is commented out, heroInputRef.current is always null, so the if (heroInputRef.current) guard prevents a crash but the button becomes effectively non-functional — it scrolls to the top of the page but provides no further interaction (no focus, no shake animation, no email input visible).

Impact: On non-macOS platforms where platformCTA.action === "waitlist", clicking the bottom CTA button scrolls to the top of the page with no actionable UI, creating a confusing dead-end for users.

Prompt for agents
In apps/web/src/routes/_view/index.tsx, the HeroSection is commented out (lines 169-172) but CTASection (line 192) still receives heroInputRef and tries to use it to focus an email input that no longer exists. Either: (1) Uncomment HeroSection, (2) Replace the CTASection's waitlist behavior with a new action (e.g. navigate to /auth/ or show a signup modal), or (3) Add an email input to the new HeroParagraphSection and attach heroInputRef to it. The heroInputRef, selectedFeature, featuresScrollRef, and scrollToFeature are also unused now and can be cleaned up.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it's fine rn

<MockWindow
showAudioIndicator={activeTab === "notes"}
audioIndicatorColor="#ef4444"
audioIndicatorWidth={120}
Copy link
Contributor

Choose a reason for hiding this comment

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

🟡 audioIndicatorWidth prop passed to MockWindow is silently ignored

At line 1188, audioIndicatorWidth={120} is passed to MockWindow, but this component does not accept an audioIndicatorWidth prop.

Root Cause and Impact

The MockWindow component (apps/web/src/components/mock-window.tsx:4-21) only accepts: showAudioIndicator, variant, className, title, prefixIcons, headerClassName, audioIndicatorColor, and children. There is no audioIndicatorWidth prop, so the value 120 is silently ignored.

The inner DancingSticks component uses its default width of 17px instead of the intended 120px. The developer's intent is visible at apps/web/src/routes/_view/index.tsx:1347 where DancingSticks is used directly with width={120} — the same width was intended for the MockWindow's audio indicator but isn't being forwarded.

Impact: The audio indicator in the "How it works" MockWindow renders at 17px wide instead of the intended 120px, making it visually inconsistent with the standalone DancingSticks used below it.

Prompt for agents
In apps/web/src/components/mock-window.tsx, add an optional `audioIndicatorWidth` prop (type: number) to the MockWindow component's props interface, and pass it through to the DancingSticks component as the `width` prop at line 61 (i.e. `<DancingSticks amplitude={1} height={isMobile ? 10 : 12} color={audioIndicatorColor ?? "#a3a3a3"} width={audioIndicatorWidth} />`). This will allow the caller at apps/web/src/routes/_view/index.tsx:1188 to control the width of the audio indicator.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@elstua
Copy link
Contributor Author

elstua commented Feb 16, 2026

/staging

Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 2 new potential issues.

View 6 additional findings in Devin Review.

Open in Devin Review

Comment on lines 1075 to 1105
clearInterval(interval2);

setTimeout(() => {
setEnhancedLines(1);
setActiveTab("summary");

setTimeout(() => {
setEnhancedLines(2);
setEnhancedLines(1);
setTimeout(() => {
setEnhancedLines(3);
setEnhancedLines(2);
setTimeout(() => {
setEnhancedLines(4);
setEnhancedLines(3);
setTimeout(() => {
setEnhancedLines(5);
setEnhancedLines(4);
setTimeout(() => {
setEnhancedLines(6);
setEnhancedLines(5);
setTimeout(() => {
setEnhancedLines(7);
setTimeout(() => runAnimation(), 1000);
setEnhancedLines(6);
setTimeout(() => {
setEnhancedLines(7);
setTimeout(() => runAnimation(), 2000);
}, 800);
}, 800);
}, 800);
}, 800);
}, 800);
}, 800);
}, 800);
}, 500);
}, 300);
}, 800);
}
}, 50);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🔴 HowItWorksSection animation timers are never cleaned up on unmount

The useEffect in HowItWorksSection (line 1053) starts a recursive animation loop using deeply nested setTimeout and setInterval calls, but returns no cleanup function. When the component unmounts, all pending timers continue to fire.

Detailed Explanation

The animation at apps/web/src/routes/_view/index.tsx:1053-1111 works as follows:

  1. runAnimation() is called, which starts a setTimeout (line 1061)
  2. Inside, a setInterval types text1 character by character (line 1062)
  3. When done, another setInterval types text2 (line 1070)
  4. Then a chain of ~9 nested setTimeout calls reveal summary lines (lines 1077-1101)
  5. Finally, setTimeout(() => runAnimation(), 2000) restarts the whole cycle (line 1094)

None of these timer IDs are tracked or cleaned up. The useEffect has no return/cleanup function. If the user navigates away mid-animation, all pending setTimeout/setInterval callbacks will fire and call setTypedText1, setTypedText2, setEnhancedLines, and setActiveTab on an unmounted component. While React suppresses the state-update-on-unmounted warning in newer versions, this still causes unnecessary work and the timers accumulate if the component is remounted (e.g. navigating away and back).

Impact: Timer/resource leak on navigation. Multiple animation cycles can stack up if the component is repeatedly mounted and unmounted.

(Refers to lines 1053-1111)

Prompt for agents
In apps/web/src/routes/_view/index.tsx, the HowItWorksSection useEffect (lines 1053-1111) starts a complex chain of setTimeout and setInterval calls in runAnimation() but has no cleanup. Add a cleanup mechanism: create a mutable ref or closure variable (e.g. let cancelled = false) and an array to collect all timer IDs. In the cleanup function returned by useEffect, set cancelled = true and clear all collected timers. Guard each setTimeout/setInterval callback with an if (!cancelled) check before calling setState or scheduling further timers. This prevents timer leaks when the component unmounts mid-animation.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

<MockWindow
showAudioIndicator={activeTab === "notes"}
audioIndicatorColor="#ef4444"
audioIndicatorWidth={120}
Copy link
Contributor

Choose a reason for hiding this comment

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

🚩 audioIndicatorWidth prop passed to MockWindow but not accepted

At apps/web/src/routes/_view/index.tsx:1130, the HowItWorksSection passes audioIndicatorWidth={120} to MockWindow. However, MockWindow (apps/web/src/components/mock-window.tsx) does not declare audioIndicatorWidth in its props type. In standard React with TypeScript strict mode, this would be a type error caught by the compiler. If it somehow passes type checking (e.g. due to config), the prop is silently ignored — the DancingSticks component inside MockWindow uses its own default width (17px from packages/ui/src/components/ui/dancing-sticks.tsx:86). The intended wider audio indicator (120px) is never applied in the window header. This should be caught by pnpm -r typecheck per the repo's conventions.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@elstua
Copy link
Contributor Author

elstua commented Feb 17, 2026

/staging

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

Comments