tweak(stream-header): require curtain drag past 90% of full peek travel to commit so short drags snap back as accidental

This commit is contained in:
heaven 2026-05-18 02:12:55 +03:00
parent 0c704aac38
commit af97549e48
2 changed files with 18 additions and 8 deletions

View file

@ -52,11 +52,20 @@ export const CURTAIN_SNAP_EASING = 'cubic-bezier(0.22, 1, 0.36, 1)';
// horseshoe surfaces elsewhere in the app.
export const CURTAIN_RADIUS_PX = 24;
// Total vertical travel of the curtain between `closed` and `peek` —
// the resting-top delta between the two snaps. Used as the basis for
// the peek-commit threshold: the user must drag (rubber-banded) at
// least COMMIT_THRESHOLD × PEEK_TRAVEL_PX before release for the snap
// to flip. Anything shorter reads as accidental and springs back.
export const PEEK_TRAVEL_PX = CHIP_ROW_PX + CHIP_GAP_PX + CHIP_ROW_PX + CURTAIN_BREATHER_PX;
// Touch gesture tuning. RUBBER_BAND dampens finger→curtain motion so
// the chip reveal feels resistive; COMMIT_THRESHOLD is the fraction of
// a stage the user must cross on release to advance.
// the full peek travel the user must cross on release for the snap to
// commit. Tuned high (≈90%) so anything below «дотянул почти до конца»
// reads as accidental and snaps back to `closed`.
export const RUBBER_BAND = 0.65;
export const DIRECTION_DEAD_ZONE_PX = 10;
export const COMMIT_THRESHOLD = 0.65;
export const COMMIT_THRESHOLD = 0.9;
// Pull-up distance (raw finger px) required to close an active form.
export const ACTIVE_CLOSE_THRESHOLD_PX = 100;

View file

@ -2,9 +2,9 @@ import { MutableRefObject, useEffect, useRef } from 'react';
import { isNativePlatform } from '../../utils/capacitor';
import {
ACTIVE_CLOSE_THRESHOLD_PX,
CHIP_ROW_PX,
COMMIT_THRESHOLD,
DIRECTION_DEAD_ZONE_PX,
PEEK_TRAVEL_PX,
RUBBER_BAND,
} from './geometry';
import { CurtainSnap, isFormSnap } from './useCurtainState';
@ -144,11 +144,12 @@ export function useCurtainGesture({ scrollRef, snap, setLiveDrag, commit }: Args
next = 'closed';
}
} else {
// Single-stage peek toggle. Threshold is COMMIT_THRESHOLD of a
// chip-row worth of rubber-banded drag — same touch effort as
// the old per-stage commit, but now flips the WHOLE peek in
// one motion (`closed` ⇄ `peek`).
const progress = lastDelta / CHIP_ROW_PX;
// Single-stage peek toggle. Threshold is COMMIT_THRESHOLD of
// the FULL peek travel — the rubber-banded drag must reach
// ≈90% of the closed→peek distance before release for the
// snap to flip. Anything shorter springs back so a brisk-but-
// short drag doesn't accidentally open (or close) the curtain.
const progress = lastDelta / PEEK_TRAVEL_PX;
if (Math.abs(progress) >= COMMIT_THRESHOLD) {
if (currentSnap === 'closed' && progress > 0) next = 'peek';
else if (currentSnap === 'peek' && progress < 0) next = 'closed';