fix(web): keep sidebar stable after settings - #7744

Closed
obinnanwachukwu1 wants to merge 3 commits into
pingdotgg:mainfrom
obinnanwachukwu1:fix/sidebar-settings-fade
Closed

fix(web): keep sidebar stable after settings#7744
obinnanwachukwu1 wants to merge 3 commits into
pingdotgg:mainfrom
obinnanwachukwu1:fix/sidebar-settings-fade

Conversation

@obinnanwachukwu1

@obinnanwachukwu1obinnanwachukwu1 commented Aug 21, 2026

Copy link
Copy Markdown

What Changed

  • Keep both project and thread-shell projections subscribed while Settings replaces the thread sidebar.
  • Ignore the animated list's first-frame setup mutations so remounting the sidebar does not animate rows that already exist.
  • Keep normal animations enabled for later additions, removals, and layout changes.

Why

Settings swaps the thread sidebar out of the React tree. The existing retention component only kept projects subscribed, so thread shells could briefly rebuild when the user returned.

There was a second contributor: DndContext installs accessibility nodes just after the list mounts. FormKit interpreted those setup mutations as new content and applied its 225 ms scale/fade animation to every existing thread row. Attaching auto-animate one frame later treats that work as initial rendering without disabling real list animations.

Fixes#7743.

Related: #5930, #6480.

UI Changes

This defect is visible only during the Settings -> Back transition, so short recordings are used instead of still screenshots.

Before

The existing sidebar rows briefly disappear, then scale and fade back in.

sidebar-settings-before.mp4

After

The existing rows remain stable when returning from Settings.

sidebar-settings-after.mp4

Verification

  • vp run --filter @t3tools/web typecheck
  • vp fmt --check apps/web/src/components/AppSidebarLayout.tsx apps/web/src/components/Sidebar.tsx
  • Integrated web repro on current main: Settings -> Back briefly emptied and scaled/faded the existing row.
  • Integrated web verification after the change: the transition emitted no sidebar Web Animations API entries.
  • A post-mount list mutation still emitted the expected FormKit animation, confirming normal list transitions remain enabled.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included clear before/after evidence for this motion change

Built with GPT-5.6 Codex in T3 Code.

Note

Keep sidebar stable after settings by retaining thread projections and deferring auto-animate

  • Renames ProjectProjectionRetention to SidebarProjectionRetention and adds useThreadShells() so thread-related projections stay subscribed when the thread sidebar is swapped out (AppSidebarLayout.tsx)
  • Defers autoAnimate attachment by one requestAnimationFrame in the Sidebar list, skipping immediate setup mutations and destroying the controller on detach or ref changes (Sidebar.tsx)
  • Risk: attachListAutoAnimateRef now relies on requestAnimationFrame and node connectivity checks; if the list node disconnects before the frame fires, auto-animate will not attach

Macroscope summarized dafb19e.


Note

Low Risk
UI-only subscription and animation-timing tweaks; no auth, data, or API changes. Worst case is a missed first-frame auto-animate attach if the list unmounts before rAF.

Overview
Stops the thread sidebar from emptying and animating existing rows when returning from Settings.

Keeps thread-shell projections subscribed (alongside projects) while Settings unmounts the sidebar, so lists do not flash empty while the environment snapshot reconnects.

Defers FormKit autoAnimate on the thread list by one frame so DndContext accessibility setup is not treated as new content. Later add/remove/layout animations stay enabled.

Reviewed by Cursor Bugbot for commit dafb19e. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitaiBot commented Aug 21, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b63355a1-baa1-4e9a-a56d-35a4a5bf74c3

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Aug 21, 2026

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One finding: the new disable() + one-frame enable() sequence cancels auto-animate's initial coordinate bootstrap, so the first real thread-list change after each sidebar mount replays enter keyframes instead of a FLIP move. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/Sidebar.tsx Outdated
@obinnanwachukwu1
obinnanwachukwu1 marked this pull request as ready for review August 21, 2026 03:04
@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 1079dab

Macroscope's review found this PR approvable — Straightforward UI stability fix that prevents sidebar flicker when returning from Settings. Changes add a read-only subscription hook (matching existing pattern) and defer animation setup to skip irrelevant mutations. Limited scope, clear intent, no business logic impact.

You can add or adjust custom eligibility rules. Learn more.

@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

We're closing this PR as we clean up the T3 Code backlog. Thank you for taking the time to put this together.

This branch keeps thread projections subscribed across Settings and delays AutoAnimate setup by one frame. It overlaps the related sidebar proposal in #6480, but this PR adds its own animation timing and projection retention choices. We are not taking this version of the Settings-to-sidebar polish forward as a current product priority.

If you believe we closed this in error, please reopen the PR and leave a comment explaining what we missed.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Thread sidebar briefly empties after returning from Settings

2 participants

@obinnanwachukwu1@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

fix(web): keep sidebar stable after settings - #7744

Closed
obinnanwachukwu1 wants to merge 3 commits into
pingdotgg:mainfrom
obinnanwachukwu1:fix/sidebar-settings-fade
Closed

fix(web): keep sidebar stable after settings#7744
obinnanwachukwu1 wants to merge 3 commits into
pingdotgg:mainfrom
obinnanwachukwu1:fix/sidebar-settings-fade

Conversation

@obinnanwachukwu1

@obinnanwachukwu1obinnanwachukwu1 commented Aug 21, 2026

Copy link
Copy Markdown

What Changed

  • Keep both project and thread-shell projections subscribed while Settings replaces the thread sidebar.
  • Ignore the animated list's first-frame setup mutations so remounting the sidebar does not animate rows that already exist.
  • Keep normal animations enabled for later additions, removals, and layout changes.

Why

Settings swaps the thread sidebar out of the React tree. The existing retention component only kept projects subscribed, so thread shells could briefly rebuild when the user returned.

There was a second contributor: DndContext installs accessibility nodes just after the list mounts. FormKit interpreted those setup mutations as new content and applied its 225 ms scale/fade animation to every existing thread row. Attaching auto-animate one frame later treats that work as initial rendering without disabling real list animations.

Fixes#7743.

Related: #5930, #6480.

UI Changes

This defect is visible only during the Settings -> Back transition, so short recordings are used instead of still screenshots.

Before

The existing sidebar rows briefly disappear, then scale and fade back in.

sidebar-settings-before.mp4

After

The existing rows remain stable when returning from Settings.

sidebar-settings-after.mp4

Verification

  • vp run --filter @t3tools/web typecheck
  • vp fmt --check apps/web/src/components/AppSidebarLayout.tsx apps/web/src/components/Sidebar.tsx
  • Integrated web repro on current main: Settings -> Back briefly emptied and scaled/faded the existing row.
  • Integrated web verification after the change: the transition emitted no sidebar Web Animations API entries.
  • A post-mount list mutation still emitted the expected FormKit animation, confirming normal list transitions remain enabled.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included clear before/after evidence for this motion change

Built with GPT-5.6 Codex in T3 Code.

Note

Keep sidebar stable after settings by retaining thread projections and deferring auto-animate

  • Renames ProjectProjectionRetention to SidebarProjectionRetention and adds useThreadShells() so thread-related projections stay subscribed when the thread sidebar is swapped out (AppSidebarLayout.tsx)
  • Defers autoAnimate attachment by one requestAnimationFrame in the Sidebar list, skipping immediate setup mutations and destroying the controller on detach or ref changes (Sidebar.tsx)
  • Risk: attachListAutoAnimateRef now relies on requestAnimationFrame and node connectivity checks; if the list node disconnects before the frame fires, auto-animate will not attach

Macroscope summarized dafb19e.


Note

Low Risk
UI-only subscription and animation-timing tweaks; no auth, data, or API changes. Worst case is a missed first-frame auto-animate attach if the list unmounts before rAF.

Overview
Stops the thread sidebar from emptying and animating existing rows when returning from Settings.

Keeps thread-shell projections subscribed (alongside projects) while Settings unmounts the sidebar, so lists do not flash empty while the environment snapshot reconnects.

Defers FormKit autoAnimate on the thread list by one frame so DndContext accessibility setup is not treated as new content. Later add/remove/layout animations stay enabled.

Reviewed by Cursor Bugbot for commit dafb19e. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitaiBot commented Aug 21, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b63355a1-baa1-4e9a-a56d-35a4a5bf74c3

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Aug 21, 2026

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One finding: the new disable() + one-frame enable() sequence cancels auto-animate's initial coordinate bootstrap, so the first real thread-list change after each sidebar mount replays enter keyframes instead of a FLIP move. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/Sidebar.tsx Outdated
@obinnanwachukwu1
obinnanwachukwu1 marked this pull request as ready for review August 21, 2026 03:04
@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 1079dab

Macroscope's review found this PR approvable — Straightforward UI stability fix that prevents sidebar flicker when returning from Settings. Changes add a read-only subscription hook (matching existing pattern) and defer animation setup to skip irrelevant mutations. Limited scope, clear intent, no business logic impact.

You can add or adjust custom eligibility rules. Learn more.

@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

We're closing this PR as we clean up the T3 Code backlog. Thank you for taking the time to put this together.

This branch keeps thread projections subscribed across Settings and delays AutoAnimate setup by one frame. It overlaps the related sidebar proposal in #6480, but this PR adds its own animation timing and projection retention choices. We are not taking this version of the Settings-to-sidebar polish forward as a current product priority.

If you believe we closed this in error, please reopen the PR and leave a comment explaining what we missed.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Thread sidebar briefly empties after returning from Settings

2 participants

@obinnanwachukwu1@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(web): keep sidebar stable after settings - #7744

Closed
obinnanwachukwu1 wants to merge 3 commits into
pingdotgg:mainfrom
obinnanwachukwu1:fix/sidebar-settings-fade
Closed

fix(web): keep sidebar stable after settings#7744
obinnanwachukwu1 wants to merge 3 commits into
pingdotgg:mainfrom
obinnanwachukwu1:fix/sidebar-settings-fade

Conversation

@obinnanwachukwu1

@obinnanwachukwu1obinnanwachukwu1 commented Aug 21, 2026

Copy link
Copy Markdown

What Changed

  • Keep both project and thread-shell projections subscribed while Settings replaces the thread sidebar.
  • Ignore the animated list's first-frame setup mutations so remounting the sidebar does not animate rows that already exist.
  • Keep normal animations enabled for later additions, removals, and layout changes.

Why

Settings swaps the thread sidebar out of the React tree. The existing retention component only kept projects subscribed, so thread shells could briefly rebuild when the user returned.

There was a second contributor: DndContext installs accessibility nodes just after the list mounts. FormKit interpreted those setup mutations as new content and applied its 225 ms scale/fade animation to every existing thread row. Attaching auto-animate one frame later treats that work as initial rendering without disabling real list animations.

Fixes#7743.

Related: #5930, #6480.

UI Changes

This defect is visible only during the Settings -> Back transition, so short recordings are used instead of still screenshots.

Before

The existing sidebar rows briefly disappear, then scale and fade back in.

sidebar-settings-before.mp4

After

The existing rows remain stable when returning from Settings.

sidebar-settings-after.mp4

Verification

  • vp run --filter @t3tools/web typecheck
  • vp fmt --check apps/web/src/components/AppSidebarLayout.tsx apps/web/src/components/Sidebar.tsx
  • Integrated web repro on current main: Settings -> Back briefly emptied and scaled/faded the existing row.
  • Integrated web verification after the change: the transition emitted no sidebar Web Animations API entries.
  • A post-mount list mutation still emitted the expected FormKit animation, confirming normal list transitions remain enabled.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included clear before/after evidence for this motion change

Built with GPT-5.6 Codex in T3 Code.

Note

Keep sidebar stable after settings by retaining thread projections and deferring auto-animate

  • Renames ProjectProjectionRetention to SidebarProjectionRetention and adds useThreadShells() so thread-related projections stay subscribed when the thread sidebar is swapped out (AppSidebarLayout.tsx)
  • Defers autoAnimate attachment by one requestAnimationFrame in the Sidebar list, skipping immediate setup mutations and destroying the controller on detach or ref changes (Sidebar.tsx)
  • Risk: attachListAutoAnimateRef now relies on requestAnimationFrame and node connectivity checks; if the list node disconnects before the frame fires, auto-animate will not attach

Macroscope summarized dafb19e.


Note

Low Risk
UI-only subscription and animation-timing tweaks; no auth, data, or API changes. Worst case is a missed first-frame auto-animate attach if the list unmounts before rAF.

Overview
Stops the thread sidebar from emptying and animating existing rows when returning from Settings.

Keeps thread-shell projections subscribed (alongside projects) while Settings unmounts the sidebar, so lists do not flash empty while the environment snapshot reconnects.

Defers FormKit autoAnimate on the thread list by one frame so DndContext accessibility setup is not treated as new content. Later add/remove/layout animations stay enabled.

Reviewed by Cursor Bugbot for commit dafb19e. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitaiBot commented Aug 21, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b63355a1-baa1-4e9a-a56d-35a4a5bf74c3

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Aug 21, 2026

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One finding: the new disable() + one-frame enable() sequence cancels auto-animate's initial coordinate bootstrap, so the first real thread-list change after each sidebar mount replays enter keyframes instead of a FLIP move. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/Sidebar.tsx Outdated
@obinnanwachukwu1
obinnanwachukwu1 marked this pull request as ready for review August 21, 2026 03:04
@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 1079dab

Macroscope's review found this PR approvable — Straightforward UI stability fix that prevents sidebar flicker when returning from Settings. Changes add a read-only subscription hook (matching existing pattern) and defer animation setup to skip irrelevant mutations. Limited scope, clear intent, no business logic impact.

You can add or adjust custom eligibility rules. Learn more.

@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

We're closing this PR as we clean up the T3 Code backlog. Thank you for taking the time to put this together.

This branch keeps thread projections subscribed across Settings and delays AutoAnimate setup by one frame. It overlaps the related sidebar proposal in #6480, but this PR adds its own animation timing and projection retention choices. We are not taking this version of the Settings-to-sidebar polish forward as a current product priority.

If you believe we closed this in error, please reopen the PR and leave a comment explaining what we missed.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Thread sidebar briefly empties after returning from Settings

2 participants

@obinnanwachukwu1@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(web): keep sidebar stable after settings - #7744

Closed
obinnanwachukwu1 wants to merge 3 commits into
pingdotgg:mainfrom
obinnanwachukwu1:fix/sidebar-settings-fade
Closed

fix(web): keep sidebar stable after settings#7744
obinnanwachukwu1 wants to merge 3 commits into
pingdotgg:mainfrom
obinnanwachukwu1:fix/sidebar-settings-fade

Conversation

@obinnanwachukwu1

@obinnanwachukwu1obinnanwachukwu1 commented Aug 21, 2026

Copy link
Copy Markdown

What Changed

  • Keep both project and thread-shell projections subscribed while Settings replaces the thread sidebar.
  • Ignore the animated list's first-frame setup mutations so remounting the sidebar does not animate rows that already exist.
  • Keep normal animations enabled for later additions, removals, and layout changes.

Why

Settings swaps the thread sidebar out of the React tree. The existing retention component only kept projects subscribed, so thread shells could briefly rebuild when the user returned.

There was a second contributor: DndContext installs accessibility nodes just after the list mounts. FormKit interpreted those setup mutations as new content and applied its 225 ms scale/fade animation to every existing thread row. Attaching auto-animate one frame later treats that work as initial rendering without disabling real list animations.

Fixes#7743.

Related: #5930, #6480.

UI Changes

This defect is visible only during the Settings -> Back transition, so short recordings are used instead of still screenshots.

Before

The existing sidebar rows briefly disappear, then scale and fade back in.

sidebar-settings-before.mp4

After

The existing rows remain stable when returning from Settings.

sidebar-settings-after.mp4

Verification

  • vp run --filter @t3tools/web typecheck
  • vp fmt --check apps/web/src/components/AppSidebarLayout.tsx apps/web/src/components/Sidebar.tsx
  • Integrated web repro on current main: Settings -> Back briefly emptied and scaled/faded the existing row.
  • Integrated web verification after the change: the transition emitted no sidebar Web Animations API entries.
  • A post-mount list mutation still emitted the expected FormKit animation, confirming normal list transitions remain enabled.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included clear before/after evidence for this motion change

Built with GPT-5.6 Codex in T3 Code.

Note

Keep sidebar stable after settings by retaining thread projections and deferring auto-animate

  • Renames ProjectProjectionRetention to SidebarProjectionRetention and adds useThreadShells() so thread-related projections stay subscribed when the thread sidebar is swapped out (AppSidebarLayout.tsx)
  • Defers autoAnimate attachment by one requestAnimationFrame in the Sidebar list, skipping immediate setup mutations and destroying the controller on detach or ref changes (Sidebar.tsx)
  • Risk: attachListAutoAnimateRef now relies on requestAnimationFrame and node connectivity checks; if the list node disconnects before the frame fires, auto-animate will not attach

Macroscope summarized dafb19e.


Note

Low Risk
UI-only subscription and animation-timing tweaks; no auth, data, or API changes. Worst case is a missed first-frame auto-animate attach if the list unmounts before rAF.

Overview
Stops the thread sidebar from emptying and animating existing rows when returning from Settings.

Keeps thread-shell projections subscribed (alongside projects) while Settings unmounts the sidebar, so lists do not flash empty while the environment snapshot reconnects.

Defers FormKit autoAnimate on the thread list by one frame so DndContext accessibility setup is not treated as new content. Later add/remove/layout animations stay enabled.

Reviewed by Cursor Bugbot for commit dafb19e. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitaiBot commented Aug 21, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b63355a1-baa1-4e9a-a56d-35a4a5bf74c3

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Aug 21, 2026

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One finding: the new disable() + one-frame enable() sequence cancels auto-animate's initial coordinate bootstrap, so the first real thread-list change after each sidebar mount replays enter keyframes instead of a FLIP move. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/Sidebar.tsx Outdated
@obinnanwachukwu1
obinnanwachukwu1 marked this pull request as ready for review August 21, 2026 03:04
@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 1079dab

Macroscope's review found this PR approvable — Straightforward UI stability fix that prevents sidebar flicker when returning from Settings. Changes add a read-only subscription hook (matching existing pattern) and defer animation setup to skip irrelevant mutations. Limited scope, clear intent, no business logic impact.

You can add or adjust custom eligibility rules. Learn more.

@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

We're closing this PR as we clean up the T3 Code backlog. Thank you for taking the time to put this together.

This branch keeps thread projections subscribed across Settings and delays AutoAnimate setup by one frame. It overlaps the related sidebar proposal in #6480, but this PR adds its own animation timing and projection retention choices. We are not taking this version of the Settings-to-sidebar polish forward as a current product priority.

If you believe we closed this in error, please reopen the PR and leave a comment explaining what we missed.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Thread sidebar briefly empties after returning from Settings

2 participants

@obinnanwachukwu1@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

fix(web): keep sidebar stable after settings - #7744

Closed
obinnanwachukwu1 wants to merge 3 commits into
pingdotgg:mainfrom
obinnanwachukwu1:fix/sidebar-settings-fade
Closed

fix(web): keep sidebar stable after settings#7744
obinnanwachukwu1 wants to merge 3 commits into
pingdotgg:mainfrom
obinnanwachukwu1:fix/sidebar-settings-fade

Conversation

@obinnanwachukwu1

@obinnanwachukwu1obinnanwachukwu1 commented Aug 21, 2026

Copy link
Copy Markdown

What Changed

  • Keep both project and thread-shell projections subscribed while Settings replaces the thread sidebar.
  • Ignore the animated list's first-frame setup mutations so remounting the sidebar does not animate rows that already exist.
  • Keep normal animations enabled for later additions, removals, and layout changes.

Why

Settings swaps the thread sidebar out of the React tree. The existing retention component only kept projects subscribed, so thread shells could briefly rebuild when the user returned.

There was a second contributor: DndContext installs accessibility nodes just after the list mounts. FormKit interpreted those setup mutations as new content and applied its 225 ms scale/fade animation to every existing thread row. Attaching auto-animate one frame later treats that work as initial rendering without disabling real list animations.

Fixes#7743.

Related: #5930, #6480.

UI Changes

This defect is visible only during the Settings -> Back transition, so short recordings are used instead of still screenshots.

Before

The existing sidebar rows briefly disappear, then scale and fade back in.

sidebar-settings-before.mp4

After

The existing rows remain stable when returning from Settings.

sidebar-settings-after.mp4

Verification

  • vp run --filter @t3tools/web typecheck
  • vp fmt --check apps/web/src/components/AppSidebarLayout.tsx apps/web/src/components/Sidebar.tsx
  • Integrated web repro on current main: Settings -> Back briefly emptied and scaled/faded the existing row.
  • Integrated web verification after the change: the transition emitted no sidebar Web Animations API entries.
  • A post-mount list mutation still emitted the expected FormKit animation, confirming normal list transitions remain enabled.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included clear before/after evidence for this motion change

Built with GPT-5.6 Codex in T3 Code.

Note

Keep sidebar stable after settings by retaining thread projections and deferring auto-animate

  • Renames ProjectProjectionRetention to SidebarProjectionRetention and adds useThreadShells() so thread-related projections stay subscribed when the thread sidebar is swapped out (AppSidebarLayout.tsx)
  • Defers autoAnimate attachment by one requestAnimationFrame in the Sidebar list, skipping immediate setup mutations and destroying the controller on detach or ref changes (Sidebar.tsx)
  • Risk: attachListAutoAnimateRef now relies on requestAnimationFrame and node connectivity checks; if the list node disconnects before the frame fires, auto-animate will not attach

Macroscope summarized dafb19e.


Note

Low Risk
UI-only subscription and animation-timing tweaks; no auth, data, or API changes. Worst case is a missed first-frame auto-animate attach if the list unmounts before rAF.

Overview
Stops the thread sidebar from emptying and animating existing rows when returning from Settings.

Keeps thread-shell projections subscribed (alongside projects) while Settings unmounts the sidebar, so lists do not flash empty while the environment snapshot reconnects.

Defers FormKit autoAnimate on the thread list by one frame so DndContext accessibility setup is not treated as new content. Later add/remove/layout animations stay enabled.

Reviewed by Cursor Bugbot for commit dafb19e. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitaiBot commented Aug 21, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b63355a1-baa1-4e9a-a56d-35a4a5bf74c3

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Aug 21, 2026

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One finding: the new disable() + one-frame enable() sequence cancels auto-animate's initial coordinate bootstrap, so the first real thread-list change after each sidebar mount replays enter keyframes instead of a FLIP move. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/Sidebar.tsx Outdated
@obinnanwachukwu1
obinnanwachukwu1 marked this pull request as ready for review August 21, 2026 03:04
@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 1079dab

Macroscope's review found this PR approvable — Straightforward UI stability fix that prevents sidebar flicker when returning from Settings. Changes add a read-only subscription hook (matching existing pattern) and defer animation setup to skip irrelevant mutations. Limited scope, clear intent, no business logic impact.

You can add or adjust custom eligibility rules. Learn more.

@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

We're closing this PR as we clean up the T3 Code backlog. Thank you for taking the time to put this together.

This branch keeps thread projections subscribed across Settings and delays AutoAnimate setup by one frame. It overlaps the related sidebar proposal in #6480, but this PR adds its own animation timing and projection retention choices. We are not taking this version of the Settings-to-sidebar polish forward as a current product priority.

If you believe we closed this in error, please reopen the PR and leave a comment explaining what we missed.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Thread sidebar briefly empties after returning from Settings

2 participants

@obinnanwachukwu1@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(web): keep sidebar stable after settings - #7744

Closed
obinnanwachukwu1 wants to merge 3 commits into
pingdotgg:mainfrom
obinnanwachukwu1:fix/sidebar-settings-fade
Closed

fix(web): keep sidebar stable after settings#7744
obinnanwachukwu1 wants to merge 3 commits into
pingdotgg:mainfrom
obinnanwachukwu1:fix/sidebar-settings-fade

Conversation

@obinnanwachukwu1

@obinnanwachukwu1obinnanwachukwu1 commented Aug 21, 2026

Copy link
Copy Markdown

What Changed

  • Keep both project and thread-shell projections subscribed while Settings replaces the thread sidebar.
  • Ignore the animated list's first-frame setup mutations so remounting the sidebar does not animate rows that already exist.
  • Keep normal animations enabled for later additions, removals, and layout changes.

Why

Settings swaps the thread sidebar out of the React tree. The existing retention component only kept projects subscribed, so thread shells could briefly rebuild when the user returned.

There was a second contributor: DndContext installs accessibility nodes just after the list mounts. FormKit interpreted those setup mutations as new content and applied its 225 ms scale/fade animation to every existing thread row. Attaching auto-animate one frame later treats that work as initial rendering without disabling real list animations.

Fixes#7743.

Related: #5930, #6480.

UI Changes

This defect is visible only during the Settings -> Back transition, so short recordings are used instead of still screenshots.

Before

The existing sidebar rows briefly disappear, then scale and fade back in.

sidebar-settings-before.mp4

After

The existing rows remain stable when returning from Settings.

sidebar-settings-after.mp4

Verification

  • vp run --filter @t3tools/web typecheck
  • vp fmt --check apps/web/src/components/AppSidebarLayout.tsx apps/web/src/components/Sidebar.tsx
  • Integrated web repro on current main: Settings -> Back briefly emptied and scaled/faded the existing row.
  • Integrated web verification after the change: the transition emitted no sidebar Web Animations API entries.
  • A post-mount list mutation still emitted the expected FormKit animation, confirming normal list transitions remain enabled.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included clear before/after evidence for this motion change

Built with GPT-5.6 Codex in T3 Code.

Note

Keep sidebar stable after settings by retaining thread projections and deferring auto-animate

  • Renames ProjectProjectionRetention to SidebarProjectionRetention and adds useThreadShells() so thread-related projections stay subscribed when the thread sidebar is swapped out (AppSidebarLayout.tsx)
  • Defers autoAnimate attachment by one requestAnimationFrame in the Sidebar list, skipping immediate setup mutations and destroying the controller on detach or ref changes (Sidebar.tsx)
  • Risk: attachListAutoAnimateRef now relies on requestAnimationFrame and node connectivity checks; if the list node disconnects before the frame fires, auto-animate will not attach

Macroscope summarized dafb19e.


Note

Low Risk
UI-only subscription and animation-timing tweaks; no auth, data, or API changes. Worst case is a missed first-frame auto-animate attach if the list unmounts before rAF.

Overview
Stops the thread sidebar from emptying and animating existing rows when returning from Settings.

Keeps thread-shell projections subscribed (alongside projects) while Settings unmounts the sidebar, so lists do not flash empty while the environment snapshot reconnects.

Defers FormKit autoAnimate on the thread list by one frame so DndContext accessibility setup is not treated as new content. Later add/remove/layout animations stay enabled.

Reviewed by Cursor Bugbot for commit dafb19e. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitaiBot commented Aug 21, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b63355a1-baa1-4e9a-a56d-35a4a5bf74c3

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Aug 21, 2026

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One finding: the new disable() + one-frame enable() sequence cancels auto-animate's initial coordinate bootstrap, so the first real thread-list change after each sidebar mount replays enter keyframes instead of a FLIP move. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/Sidebar.tsx Outdated
@obinnanwachukwu1
obinnanwachukwu1 marked this pull request as ready for review August 21, 2026 03:04
@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 1079dab

Macroscope's review found this PR approvable — Straightforward UI stability fix that prevents sidebar flicker when returning from Settings. Changes add a read-only subscription hook (matching existing pattern) and defer animation setup to skip irrelevant mutations. Limited scope, clear intent, no business logic impact.

You can add or adjust custom eligibility rules. Learn more.

@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

We're closing this PR as we clean up the T3 Code backlog. Thank you for taking the time to put this together.

This branch keeps thread projections subscribed across Settings and delays AutoAnimate setup by one frame. It overlaps the related sidebar proposal in #6480, but this PR adds its own animation timing and projection retention choices. We are not taking this version of the Settings-to-sidebar polish forward as a current product priority.

If you believe we closed this in error, please reopen the PR and leave a comment explaining what we missed.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Thread sidebar briefly empties after returning from Settings

2 participants

@obinnanwachukwu1@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(web): keep sidebar stable after settings - #7744

Closed
obinnanwachukwu1 wants to merge 3 commits into
pingdotgg:mainfrom
obinnanwachukwu1:fix/sidebar-settings-fade
Closed

fix(web): keep sidebar stable after settings#7744
obinnanwachukwu1 wants to merge 3 commits into
pingdotgg:mainfrom
obinnanwachukwu1:fix/sidebar-settings-fade

Conversation

@obinnanwachukwu1

@obinnanwachukwu1obinnanwachukwu1 commented Aug 21, 2026

Copy link
Copy Markdown

What Changed

  • Keep both project and thread-shell projections subscribed while Settings replaces the thread sidebar.
  • Ignore the animated list's first-frame setup mutations so remounting the sidebar does not animate rows that already exist.
  • Keep normal animations enabled for later additions, removals, and layout changes.

Why

Settings swaps the thread sidebar out of the React tree. The existing retention component only kept projects subscribed, so thread shells could briefly rebuild when the user returned.

There was a second contributor: DndContext installs accessibility nodes just after the list mounts. FormKit interpreted those setup mutations as new content and applied its 225 ms scale/fade animation to every existing thread row. Attaching auto-animate one frame later treats that work as initial rendering without disabling real list animations.

Fixes#7743.

Related: #5930, #6480.

UI Changes

This defect is visible only during the Settings -> Back transition, so short recordings are used instead of still screenshots.

Before

The existing sidebar rows briefly disappear, then scale and fade back in.

sidebar-settings-before.mp4

After

The existing rows remain stable when returning from Settings.

sidebar-settings-after.mp4

Verification

  • vp run --filter @t3tools/web typecheck
  • vp fmt --check apps/web/src/components/AppSidebarLayout.tsx apps/web/src/components/Sidebar.tsx
  • Integrated web repro on current main: Settings -> Back briefly emptied and scaled/faded the existing row.
  • Integrated web verification after the change: the transition emitted no sidebar Web Animations API entries.
  • A post-mount list mutation still emitted the expected FormKit animation, confirming normal list transitions remain enabled.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included clear before/after evidence for this motion change

Built with GPT-5.6 Codex in T3 Code.

Note

Keep sidebar stable after settings by retaining thread projections and deferring auto-animate

  • Renames ProjectProjectionRetention to SidebarProjectionRetention and adds useThreadShells() so thread-related projections stay subscribed when the thread sidebar is swapped out (AppSidebarLayout.tsx)
  • Defers autoAnimate attachment by one requestAnimationFrame in the Sidebar list, skipping immediate setup mutations and destroying the controller on detach or ref changes (Sidebar.tsx)
  • Risk: attachListAutoAnimateRef now relies on requestAnimationFrame and node connectivity checks; if the list node disconnects before the frame fires, auto-animate will not attach

Macroscope summarized dafb19e.


Note

Low Risk
UI-only subscription and animation-timing tweaks; no auth, data, or API changes. Worst case is a missed first-frame auto-animate attach if the list unmounts before rAF.

Overview
Stops the thread sidebar from emptying and animating existing rows when returning from Settings.

Keeps thread-shell projections subscribed (alongside projects) while Settings unmounts the sidebar, so lists do not flash empty while the environment snapshot reconnects.

Defers FormKit autoAnimate on the thread list by one frame so DndContext accessibility setup is not treated as new content. Later add/remove/layout animations stay enabled.

Reviewed by Cursor Bugbot for commit dafb19e. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitaiBot commented Aug 21, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b63355a1-baa1-4e9a-a56d-35a4a5bf74c3

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Aug 21, 2026

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One finding: the new disable() + one-frame enable() sequence cancels auto-animate's initial coordinate bootstrap, so the first real thread-list change after each sidebar mount replays enter keyframes instead of a FLIP move. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/Sidebar.tsx Outdated
@obinnanwachukwu1
obinnanwachukwu1 marked this pull request as ready for review August 21, 2026 03:04
@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 1079dab

Macroscope's review found this PR approvable — Straightforward UI stability fix that prevents sidebar flicker when returning from Settings. Changes add a read-only subscription hook (matching existing pattern) and defer animation setup to skip irrelevant mutations. Limited scope, clear intent, no business logic impact.

You can add or adjust custom eligibility rules. Learn more.

@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

We're closing this PR as we clean up the T3 Code backlog. Thank you for taking the time to put this together.

This branch keeps thread projections subscribed across Settings and delays AutoAnimate setup by one frame. It overlaps the related sidebar proposal in #6480, but this PR adds its own animation timing and projection retention choices. We are not taking this version of the Settings-to-sidebar polish forward as a current product priority.

If you believe we closed this in error, please reopen the PR and leave a comment explaining what we missed.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Thread sidebar briefly empties after returning from Settings

2 participants

@obinnanwachukwu1@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

fix(web): keep sidebar stable after settings - #7744

Closed
obinnanwachukwu1 wants to merge 3 commits into
pingdotgg:mainfrom
obinnanwachukwu1:fix/sidebar-settings-fade
Closed

fix(web): keep sidebar stable after settings#7744
obinnanwachukwu1 wants to merge 3 commits into
pingdotgg:mainfrom
obinnanwachukwu1:fix/sidebar-settings-fade

Conversation

@obinnanwachukwu1

@obinnanwachukwu1obinnanwachukwu1 commented Aug 21, 2026

Copy link
Copy Markdown

What Changed

  • Keep both project and thread-shell projections subscribed while Settings replaces the thread sidebar.
  • Ignore the animated list's first-frame setup mutations so remounting the sidebar does not animate rows that already exist.
  • Keep normal animations enabled for later additions, removals, and layout changes.

Why

Settings swaps the thread sidebar out of the React tree. The existing retention component only kept projects subscribed, so thread shells could briefly rebuild when the user returned.

There was a second contributor: DndContext installs accessibility nodes just after the list mounts. FormKit interpreted those setup mutations as new content and applied its 225 ms scale/fade animation to every existing thread row. Attaching auto-animate one frame later treats that work as initial rendering without disabling real list animations.

Fixes#7743.

Related: #5930, #6480.

UI Changes

This defect is visible only during the Settings -> Back transition, so short recordings are used instead of still screenshots.

Before

The existing sidebar rows briefly disappear, then scale and fade back in.

sidebar-settings-before.mp4

After

The existing rows remain stable when returning from Settings.

sidebar-settings-after.mp4

Verification

  • vp run --filter @t3tools/web typecheck
  • vp fmt --check apps/web/src/components/AppSidebarLayout.tsx apps/web/src/components/Sidebar.tsx
  • Integrated web repro on current main: Settings -> Back briefly emptied and scaled/faded the existing row.
  • Integrated web verification after the change: the transition emitted no sidebar Web Animations API entries.
  • A post-mount list mutation still emitted the expected FormKit animation, confirming normal list transitions remain enabled.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included clear before/after evidence for this motion change

Built with GPT-5.6 Codex in T3 Code.

Note

Keep sidebar stable after settings by retaining thread projections and deferring auto-animate

  • Renames ProjectProjectionRetention to SidebarProjectionRetention and adds useThreadShells() so thread-related projections stay subscribed when the thread sidebar is swapped out (AppSidebarLayout.tsx)
  • Defers autoAnimate attachment by one requestAnimationFrame in the Sidebar list, skipping immediate setup mutations and destroying the controller on detach or ref changes (Sidebar.tsx)
  • Risk: attachListAutoAnimateRef now relies on requestAnimationFrame and node connectivity checks; if the list node disconnects before the frame fires, auto-animate will not attach

Macroscope summarized dafb19e.


Note

Low Risk
UI-only subscription and animation-timing tweaks; no auth, data, or API changes. Worst case is a missed first-frame auto-animate attach if the list unmounts before rAF.

Overview
Stops the thread sidebar from emptying and animating existing rows when returning from Settings.

Keeps thread-shell projections subscribed (alongside projects) while Settings unmounts the sidebar, so lists do not flash empty while the environment snapshot reconnects.

Defers FormKit autoAnimate on the thread list by one frame so DndContext accessibility setup is not treated as new content. Later add/remove/layout animations stay enabled.

Reviewed by Cursor Bugbot for commit dafb19e. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitaiBot commented Aug 21, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b63355a1-baa1-4e9a-a56d-35a4a5bf74c3

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Aug 21, 2026

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One finding: the new disable() + one-frame enable() sequence cancels auto-animate's initial coordinate bootstrap, so the first real thread-list change after each sidebar mount replays enter keyframes instead of a FLIP move. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/Sidebar.tsx Outdated
@obinnanwachukwu1
obinnanwachukwu1 marked this pull request as ready for review August 21, 2026 03:04
@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 1079dab

Macroscope's review found this PR approvable — Straightforward UI stability fix that prevents sidebar flicker when returning from Settings. Changes add a read-only subscription hook (matching existing pattern) and defer animation setup to skip irrelevant mutations. Limited scope, clear intent, no business logic impact.

You can add or adjust custom eligibility rules. Learn more.

@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

We're closing this PR as we clean up the T3 Code backlog. Thank you for taking the time to put this together.

This branch keeps thread projections subscribed across Settings and delays AutoAnimate setup by one frame. It overlaps the related sidebar proposal in #6480, but this PR adds its own animation timing and projection retention choices. We are not taking this version of the Settings-to-sidebar polish forward as a current product priority.

If you believe we closed this in error, please reopen the PR and leave a comment explaining what we missed.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Thread sidebar briefly empties after returning from Settings

2 participants

@obinnanwachukwu1@t3dotgg