From 78188cf7a351f235b7d244aa4f3f4576d17adbf8 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Thu, 29 Oct 2026 07:14:34 +0900 Subject: [PATCH] =?UTF-8?q?fix(B05=C2=B7B06):=20=EC=A1=B0=EC=9E=91=20?= =?UTF-8?q?=EB=86=93=EC=9D=80=20=EC=A7=81=ED=9B=84=20=E2=86=B6=20=EB=B0=94?= =?UTF-8?q?=EB=A1=9C=20=EC=BC=9C=EC=A7=90=20=C2=B7=20=EA=B8=B0=EB=8B=A4?= =?UTF-8?q?=EB=A6=BC=20=EC=A4=91=20=E2=86=B6=20=3D=20=EB=A8=BC=EC=A0=80=20?= =?UTF-8?q?=EC=B0=8D=EA=B3=A0=20=EB=90=98=EB=8F=8C=EB=A6=BC=20(PLAN=20477-?= =?UTF-8?q?3=20=C2=B7=20=EC=9A=94=EA=B5=AC=20433)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 찍기 기다림(400 ms) 들어가면 한 틱 뒤 단추 맞춤 — 세션이 지금 걸음과 다를 때만 켜짐(바뀐 것 없는 누름은 그대로 꺼짐) - ↶ ↷ 누르면 기다리던 찍기 먼저(누름 중이어도) — 방금 조작이 한 걸음으로 되돌아감 - 기다림 시간 · 서버 다시 셈 묶음은 그대로 Co-Authored-By: Claude Opus 5.5 --- B05_Profile/B05_Profile_UI_Profile_History.ts | 35 ++++++++++++++----- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/B05_Profile/B05_Profile_UI_Profile_History.ts b/B05_Profile/B05_Profile_UI_Profile_History.ts index 37fe67636..c7b91d28a 100644 --- a/B05_Profile/B05_Profile_UI_Profile_History.ts +++ b/B05_Profile/B05_Profile_UI_Profile_History.ts @@ -114,10 +114,18 @@ const changed = (): void => hooks.forEach((entry) => entry.change?.()); function settle(): void { clearTimeout(settleTimer); settling = true; - settleTimer = setTimeout(() => { - settling = false; - active?.record(); - }, SETTLE_MS); + settleTimer = setTimeout(flushSettle, SETTLE_MS); + // ↶ 는 기다리지 않고 켬(477-3) — 같은 손길의 칸 쓰기가 끝난 한 틱 뒤 단추만 맞춤 + setTimeout(changed, 0); +} + +/** 기다리던 찍기를 지금 — 기다림이 끝났거나 그 사이 ↶ ↷ 를 누름(477-3 · 한 걸음 그대로). */ +function flushSettle(): void { + if (!settling) return; + clearTimeout(settleTimer); + settling = false; + active?.recordNow(); + changed(); } function watchPointer(): void { @@ -167,6 +175,8 @@ function restoreSnapshot(projectId: string, snapshot: HistorySnapshot): void { export interface ProfileHistory { /** 조작이 끝난 뒤 현재 상태를 이력에 쌓는다(직전과 같으면 무시). */ record(): void; + /** 누름이 남아 있어도 지금 찍음 — ↶ 단추 누름 중 기다리던 찍기(477-3). */ + recordNow(): void; /** 연속 조작(길게 누르기) 동안 기록을 미룬다 — 20칸 이동이 되돌리기 20번이 되는 것을 막는다. */ pause(): void; /** 연속 조작이 끝났음을 알린다 — 그 동안의 변화를 **한 덩어리로** 한 번만 쌓는다. */ @@ -224,6 +234,10 @@ export function createProfileHistory( return true; } + /** 찍기를 기다리는 동안 세션이 지금 걸음과 다름 — ↶ 를 바로 켜는 몫(477-3). */ + const pending = (): boolean => + settling && !restoring && !sameSnapshot(takeSnapshot(projectId, stack[cursor]), stack[cursor]); + const history: ProfileHistory = { record() { if (restoring || paused) return; @@ -231,6 +245,10 @@ export function createProfileHistory( releaseWaiters.add(history.record); return; } + history.recordNow(); + }, + recordNow() { + if (restoring || paused) return; sync(); restAt = gestures; const snapshot = takeSnapshot(projectId, stack[cursor]); @@ -253,10 +271,11 @@ export function createProfileHistory( paused = false; history.record(); }, - undo: () => apply(cursor - 1), - redo: () => apply(cursor + 1), - canUndo: () => cursor > 0, - canRedo: () => cursor < stack.length - 1, + // 기다리던 찍기 먼저 — 바로 누른 ↶ = 방금 조작 되돌림 · 묶음 한 걸음(477-3) + undo: () => (flushSettle(), apply(cursor - 1)), + redo: () => (flushSettle(), apply(cursor + 1)), + canUndo: () => cursor > 0 || pending(), + canRedo: () => cursor < stack.length - 1 && !pending(), }; rebaseActive = () => { if (restoring || paused || pointerHeld || settling || gestures !== restAt) return;