Skip to content

AppControl: Add setting to hide the fast scroller on the app list#2396

Draft
d4rken wants to merge 1 commit into
mainfrom
feat/appcontrol-fastscroller-toggle
Draft

AppControl: Add setting to hide the fast scroller on the app list#2396
d4rken wants to merge 1 commit into
mainfrom
feat/appcontrol-fastscroller-toggle

Conversation

@d4rken
Copy link
Copy Markdown
Member

@d4rken d4rken commented Apr 23, 2026

What changed

A new "Fast scroller" toggle has been added to AppControl's settings. When turned off, the index bar on the right edge of the app list (and its bubble that appears while scrubbing) is hidden — so information that was sitting behind it, like the byte-size labels under the "Size" sort, becomes fully visible.

The toggle defaults to on, so nothing changes for existing users until they opt in.

Technical Context

  • The flag is wired into AppControlListViewModel.State via an outer combine(settings.listFastScrollerEnabled.flow) rather than being added to currentDisplayOptions. Putting it inside the flatMapLatest pipeline would trigger a 250 ms blank-list/progress-overlay re-emission on every toggle.
  • Fragment visibility is computed once (when { !enabled -> GONE; progress-or-empty -> INVISIBLE; else -> VISIBLE }) and applied to both fastscroller and fastscrollerThumb. Hiding only the scroller column previously left the thumb reachable via RecyclerView scroll events, so the two views now move in lockstep.
  • BadgedCheckboxPreference.isRestricted defaults to true, so AppControlSettingsFragment explicitly unrestricts the new row — without this it would render badge-overlaid and disabled out of the box.
  • Scope is AppControl only; other list screens use zhanghai.FastScroller via setupDefaults(), which is a different component and out of scope for this change.

Closes #2378

Add a new 'Fast scroller' preference to AppControl settings, defaulting to on, that hides both FastScrollerView and FastScrollerThumbView when disabled. Users sorting by size lose byte-size labels behind the scroller bubble; the toggle lets them reclaim that space.

The flag is wired into AppControlListViewModel.State via an outer combine so toggling does not restart the list flatMapLatest pipeline (avoids a 250ms blank-list blink). Fragment visibility is computed in one when expression and applied to both the scroller and its thumb together, ensuring the thumb never hangs around when the scroller column is hidden.

BadgedCheckboxPreference defaults to isRestricted = true, so the preference fragment explicitly unrestricts the new row.

Closes #2378
@d4rken d4rken added enhancement New feature, request, improvement or optimization c: AppControl labels Apr 23, 2026
@d4rken
Copy link
Copy Markdown
Member Author

d4rken commented Apr 24, 2026

Might delay this and actually replace it with a collapsible scroll menu, after finishing #2381 🤔

@d4rken d4rken marked this pull request as draft April 25, 2026 16:02
d4rken added a commit that referenced this pull request May 14, 2026
Adds a new shared SdmFastScroller composable in app-common-ui and wires it into AppControl. The scroller is off by default and can be turned on via a new "Fast scroller" entry in the AppControl toolbar's overflow menu — a checkmark indicates the current state. When enabled and the list has at least 30 items, an end-aligned 48dp touch lane appears with a draggable thumb; while dragging the user sees a bubble with the current section label (first letter of the app name when sorting by name, first letter of the package name when sorting by package name). Other sort modes show the thumb only.

Technical context:

- SdmFastScroller has two public overloads (LazyListState, LazyGridState) backed by an internal FastScrollAdapter. Drag scrubbing uses snapshotFlow { dragTargetIndex } + distinctUntilChanged + collectLatest so in-flight scrollToItem calls are cancelled when the user moves their finger again. totalItems is re-read inside the snapshotFlow so the clamp stays fresh if items load/unload mid-drag.

- AppControlListViewModel wires settings.listFastScrollerEnabled.flow into State via an outer combine (after the existing pipeline) so toggling does not invalidate the row pipeline and flash the loading overlay. Row gains pre-computed sectionKeyName/sectionKeyPkg derived from the existing normalizedLabel/normalizedPackageName caches, avoiding duplicate label resolution in the screen.

- AppControlListScreen separates normalOverflowOpen and selectionOverflowOpen flags (one was previously shared which could open the wrong menu across mode transitions). LazyVerticalGrid contentPadding only carves out the 48dp end gutter when the scroller will actually render (enabled AND rows >= threshold), so short app lists don't see dead space. Alignment.CenterEnd + logical offsets keep RTL working.

- Replaces draft PR #2396, which targeted the pre-rewrite RecyclerView screen and no longer applies to the Compose rewrite. Other long-list screens (Analyzer, Picker, Stats, Deduplicator) can opt in later by reusing SdmFastScroller.

Closes #2378
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c: AppControl enhancement New feature, request, improvement or optimization

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Request to hide the green bar at the center-right in AppControl

1 participant