Skip to content

fix(web): slow scrolls stop snapping back to the end; icon picker chunk shrinks 200x - #66

Merged
NicholasZolton merged 2 commits into
mainfrom
NicholasZolton/fix-gif-recording-issue
Nov 7, 2026
Merged

NicholasZolton merged 2 commits into
mainfrom
NicholasZolton/fix-gif-recording-issue

Conversation

@NicholasZolton

Copy link
Copy Markdown
Owner

Summary

Scrolling the chat up slowly kept snapping back to the bottom. On a trackpad you could not get more than about 40px into history before the view jumped back to the end.

Scrolling up collapsed the composer, which shrank the space reserved under the timeline. Near the end, the browser clamped the scroll position back to the bottom, the composer expanded again, and auto-follow re-armed and scrolled to the end. Every slow tick repeated that loop.

The collapse was upstream's feature. Upstream removed it, together with its setting, in bd84b17, but this fork's November 1 upstream sync brought it back as if it were fork behavior. This PR removes it to match upstream: the composer wiring, the timeline-follow hooks, and the composerCollapseOnScroll setting. The collapsed composer on mobile web is upstream's own and stays. The wiki no longer lists scroll-collapse as retained fork behavior, so the next sync keeps it out.

A search for other upstream changes the fork had undone found two more:

  • Project icon search bundled lucide's dynamic icon map. It imported iconNames from lucide-react/dynamic, which pulls in a map of 1,917 lazy icon imports. Upstream removed that in b47746b, and a later merge kept the fork's version of the file. Search now ranks upstream's lucideIconNames and keeps the fork's fuzzy matching.
  • buildGitActionProgressStages was dead code. Upstream deleted it, and nothing here called it except its own test.

Before + After

Slow upward scroll from the end, then back down, using real wheel events on a replay thread:

Before: the view is stuck within 40px of the end while the composer flickers. After: it scrolls smoothly to 192px and back

Settings → Chat → Composer:

Before After
Composer settings with the Collapse composer on scroll toggle Composer settings without the toggle

Web build (vp build):

Before After
Icon picker chunk 1.78 MB, 1,917 import() calls 8.6 KB, none
JS files 1,010 960
Total JS 38.1 MB 36.2 MB

Test plan

  • Dev server with real wheel events: before, a slow scroll up stays stuck between 0 and 38px from the end. After, it climbs smoothly and returns to the end, whether or not the composer has focus.
  • Settings → Chat no longer shows "Collapse composer on scroll".
  • Icon search still fuzzy-matches (termnl finds terminal, git branch finds git-branch). It no longer offers 252 deprecated lucide aliases, matching upstream; icons already saved under those names still resolve.
  • Web build measured before and after (table above).
  • vp run check:changed: format, lint, knip, typecheck and React Compiler pass.
  • GuestPage.browser.test.tsx ("follows the end as replies stream…") fails. It fails the same way on main without this change; not investigated here.

bronze-ferret-orchid

Slow upward scrolls snapped the timeline back to the end. Scrolling up
collapsed the composer, which shortened the list under the reader; near the
end the browser clamped them back, the composer re-expanded, and follow
re-armed.

The collapse was upstream's feature. Upstream removed it with its setting in
behavior. This removes it to match upstream: the composer wiring, the follow
hooks, and the composerCollapseOnScroll setting. Mobile web's collapsed
composer is upstream's and stays.
The fork's fuzzy icon search imported iconNames from lucide-react/dynamic,
which pulls in its map of 1,917 lazy icon imports. Upstream removed that in
pingdotgg#20147; a later merge kept the fork's version of the file. Search now ranks
upstream's lucideIconNames instead, keeping the fork's fuzzy matching. The
icon picker chunk drops from 1.78 MB to 8.6 KB, and the web build emits 50
fewer JS files (-1.9 MB).

Also drops buildGitActionProgressStages, which upstream deleted in pingdotgg#22557 and
nothing outside its own test still called.
Copilot AI balanced review requested due to automatic review settings November 7, 2026 19:22
@NicholasZolton
NicholasZolton merged commit fc46af3 into main Nov 7, 2026

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.

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Copilot review overview

3 open issues
What changed in this PR

Aligns the fork’s web behavior with upstream by removing the “composer collapse on scroll” feature (and its setting/wiring) to stop slow upward scrolling from snapping back to the end, while also shrinking the icon picker bundle by avoiding lucide’s dynamic icon map and dropping dead Git action progress helper code.

Changes:

  • Removed scroll-collapse composer behavior, its timeline-follow wiring, and composerCollapseOnScroll setting + settings UI entries.
  • Reworked project icon search to use a local lucideIconNames list instead of lucide-react/dynamic’s iconNames map.
  • Deleted unused buildGitActionProgressStages logic and its now-orphaned tests; updated wiki docs/log.
File Description
wiki/​upstream-integration.md Updates upstream integration notes to document composer scroll-collapse removal and prevent reintroduction on future syncs.
wiki/​log.md Logs the correction that composer scroll-collapse was upstream behavior and is now dropped.
packages/​contracts/​src/​settings.ts Removes composerCollapseOnScroll from settings schema and patch schema.
apps/​web/​src/​projectIconOptions.ts Switches icon search source to local lucide name list to drastically reduce bundle size.
apps/​web/​src/​components/​settings/​settingsSearch.ts Removes settings search entry for the deleted composer-collapse toggle.
apps/​web/​src/​components/​settings/​SettingsPanels.tsx Removes the deleted composer-collapse toggle from Chat settings panel config.
apps/​web/​src/​components/​guest/​GuestPage.tsx Updates useTimelineFollow call site after hook input API change.
apps/​web/​src/​components/​chat/​useTimelineFollow.ts Removes timeline-follow callbacks that drove composer scroll-collapse behavior.
apps/​web/​src/​components/​chat/​ChatComposer.tsx Removes scroll-collapse state/handlers and simplifies collapse logic to mobile-only.
apps/​web/​src/​components/​GitActionsControl.logic.ts Deletes dead buildGitActionProgressStages helper.
apps/​web/​src/​components/​GitActionsControl.logic.test.ts Removes tests that only exercised the deleted helper.
apps/​web/​src/​components/​ChatView.tsx Stops passing composer-collapse callbacks into useTimelineFollow.

Review effort: Lite

Comment on lines 3013 to 3020
composerRef,
() => ({
focusAtEnd: () => {
revealScrollCollapsedEditor();
composerEditorRef.current?.focusAtEnd();
},
focusAt: (cursor: number) => {
revealScrollCollapsedEditor();
composerEditorRef.current?.focusAt(cursor);
},
Comment on lines 1 to +5
import { searchItems } from "@t3tools/shared/searchRanking";
import { lucideIconNames } from "./lib/lucideIconByName";
export { PROJECT_ICON_COLORS, projectIconColorClassName } from "./projectIconColors";

const POPULAR_PROJECT_ICONS: ReadonlyArray<IconName> = [
const POPULAR_PROJECT_ICONS: ReadonlyArray<string> = [
@@ -504,7 +504,6 @@ export const ClientSettingsSchema = Schema.Struct({
planModeEnabled: Schema.Boolean.pipe(Schema.withDecodingDefault(Effect.succeed(false))),
contextWindowMeterEnabled: Schema.Boolean.pipe(Schema.withDecodingDefault(Effect.succeed(false))),
composerRichTextEnabled: Schema.Boolean.pipe(Schema.withDecodingDefault(Effect.succeed(true))),
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