@@ -38,12 +38,26 @@ import { Icon } from '..';
3838const SUMMARY_COLLAPSE_THRESHOLD = 80 ;
3939const SUMMARY_EXPAND_THRESHOLD = 8 ;
4040const SUMMARY_TOGGLE_COOLDOWN_MS = 550 ;
41+ // The header also reveals mid-list once the user has dragged upward this many px in one
42+ // continuous run (#1915). Because the header can now be open while scrolled deep into the
43+ // list, collapse must be direction-aware as well or the next cooldown recheck past the
44+ // threshold would immediately undo a mid-list reveal: both legs read one signed run that
45+ // accumulates same-direction deltas and resets when direction flips. Per-event deltas at
46+ // or above the jump size are layout blips (the post-toggle reflow, tab switches), not
47+ // user scrolling: they zero the run, because a stale blip-inflated run would otherwise
48+ // mistoggle when the cooldown recheck fires.
49+ const SUMMARY_REVEAL_SCROLL_UP_PX = 60 ;
50+ const SUMMARY_COLLAPSE_RUN_PX = 20 ;
51+ const SUMMARY_LAYOUT_JUMP_PX = 250 ;
4152
4253class ProfileView extends PureComponent < any , any > {
4354 _lastSummaryToggleAt = 0 ;
4455
4556 _lastOffsetY = 0 ;
4657
58+ // signed: positive = downward scrolling, negative = upward
59+ _scrollRun = 0 ;
60+
4761 _summaryRecheckTimer : any = null ;
4862
4963 constructor ( props : any ) {
@@ -69,8 +83,13 @@ class ProfileView extends PureComponent<any, any> {
6983 _evaluateSummary = ( ) => {
7084 const { isSummaryOpen } = this . state ;
7185 const offsetY = this . _lastOffsetY ;
72- const wantCollapse = isSummaryOpen && offsetY > SUMMARY_COLLAPSE_THRESHOLD ;
73- const wantExpand = ! isSummaryOpen && offsetY <= SUMMARY_EXPAND_THRESHOLD ;
86+ const wantCollapse =
87+ isSummaryOpen &&
88+ offsetY > SUMMARY_COLLAPSE_THRESHOLD &&
89+ this . _scrollRun >= SUMMARY_COLLAPSE_RUN_PX ;
90+ const wantExpand =
91+ ! isSummaryOpen &&
92+ ( offsetY <= SUMMARY_EXPAND_THRESHOLD || this . _scrollRun <= - SUMMARY_REVEAL_SCROLL_UP_PX ) ;
7493 if ( ! wantCollapse && ! wantExpand ) {
7594 return ;
7695 }
@@ -89,6 +108,7 @@ class ProfileView extends PureComponent<any, any> {
89108 }
90109
91110 this . _lastSummaryToggleAt = now ;
111+ this . _scrollRun = 0 ;
92112 this . setState ( { isSummaryOpen : wantExpand } ) ;
93113 } ;
94114
@@ -97,6 +117,13 @@ class ProfileView extends PureComponent<any, any> {
97117 if ( offsetY === undefined ) {
98118 return ;
99119 }
120+ const delta = offsetY - this . _lastOffsetY ;
121+ if ( Math . abs ( delta ) >= SUMMARY_LAYOUT_JUMP_PX ) {
122+ this . _scrollRun = 0 ;
123+ } else if ( delta !== 0 ) {
124+ const sameDirection = delta > 0 === this . _scrollRun > 0 || this . _scrollRun === 0 ;
125+ this . _scrollRun = sameDirection ? this . _scrollRun + delta : delta ;
126+ }
100127 this . _lastOffsetY = offsetY ;
101128 this . _evaluateSummary ( ) ;
102129 } ;
0 commit comments