From 183351044a5d62db13ddb0230004a983368f6c5f Mon Sep 17 00:00:00 2001 From: "v.lagerev" Date: Mon, 18 May 2026 02:12:55 +0300 Subject: [PATCH] tweak(stream-header): require curtain drag past 90% of full peek travel to commit so short drags snap back as accidental --- src/app/components/stream-header/geometry.ts | 13 +++++++++++-- .../components/stream-header/useCurtainGesture.ts | 13 +++++++------ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/app/components/stream-header/geometry.ts b/src/app/components/stream-header/geometry.ts index 516fcd17..9afdc3d3 100644 --- a/src/app/components/stream-header/geometry.ts +++ b/src/app/components/stream-header/geometry.ts @@ -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; diff --git a/src/app/components/stream-header/useCurtainGesture.ts b/src/app/components/stream-header/useCurtainGesture.ts index facf87fb..53efb23d 100644 --- a/src/app/components/stream-header/useCurtainGesture.ts +++ b/src/app/components/stream-header/useCurtainGesture.ts @@ -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';