fix(B05·B06): 조작 놓은 직후 ↶ 바로 켜짐 · 기다림 중 ↶ = 먼저 찍고 되돌림 (PLAN 477-3 · 요구 433)
- 찍기 기다림(400 ms) 들어가면 한 틱 뒤 단추 맞춤 — 세션이 지금 걸음과 다를 때만 켜짐(바뀐 것 없는 누름은 그대로 꺼짐) - ↶ ↷ 누르면 기다리던 찍기 먼저(누름 중이어도) — 방금 조작이 한 걸음으로 되돌아감 - 기다림 시간 · 서버 다시 셈 묶음은 그대로 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -114,10 +114,18 @@ const changed = (): void => hooks.forEach((entry) => entry.change?.());
|
|||||||
function settle(): void {
|
function settle(): void {
|
||||||
clearTimeout(settleTimer);
|
clearTimeout(settleTimer);
|
||||||
settling = true;
|
settling = true;
|
||||||
settleTimer = setTimeout(() => {
|
settleTimer = setTimeout(flushSettle, SETTLE_MS);
|
||||||
settling = false;
|
// ↶ 는 기다리지 않고 켬(477-3) — 같은 손길의 칸 쓰기가 끝난 한 틱 뒤 단추만 맞춤
|
||||||
active?.record();
|
setTimeout(changed, 0);
|
||||||
}, SETTLE_MS);
|
}
|
||||||
|
|
||||||
|
/** 기다리던 찍기를 지금 — 기다림이 끝났거나 그 사이 ↶ ↷ 를 누름(477-3 · 한 걸음 그대로). */
|
||||||
|
function flushSettle(): void {
|
||||||
|
if (!settling) return;
|
||||||
|
clearTimeout(settleTimer);
|
||||||
|
settling = false;
|
||||||
|
active?.recordNow();
|
||||||
|
changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
function watchPointer(): void {
|
function watchPointer(): void {
|
||||||
@@ -167,6 +175,8 @@ function restoreSnapshot(projectId: string, snapshot: HistorySnapshot): void {
|
|||||||
export interface ProfileHistory {
|
export interface ProfileHistory {
|
||||||
/** 조작이 끝난 뒤 현재 상태를 이력에 쌓는다(직전과 같으면 무시). */
|
/** 조작이 끝난 뒤 현재 상태를 이력에 쌓는다(직전과 같으면 무시). */
|
||||||
record(): void;
|
record(): void;
|
||||||
|
/** 누름이 남아 있어도 지금 찍음 — ↶ 단추 누름 중 기다리던 찍기(477-3). */
|
||||||
|
recordNow(): void;
|
||||||
/** 연속 조작(길게 누르기) 동안 기록을 미룬다 — 20칸 이동이 되돌리기 20번이 되는 것을 막는다. */
|
/** 연속 조작(길게 누르기) 동안 기록을 미룬다 — 20칸 이동이 되돌리기 20번이 되는 것을 막는다. */
|
||||||
pause(): void;
|
pause(): void;
|
||||||
/** 연속 조작이 끝났음을 알린다 — 그 동안의 변화를 **한 덩어리로** 한 번만 쌓는다. */
|
/** 연속 조작이 끝났음을 알린다 — 그 동안의 변화를 **한 덩어리로** 한 번만 쌓는다. */
|
||||||
@@ -224,6 +234,10 @@ export function createProfileHistory(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 찍기를 기다리는 동안 세션이 지금 걸음과 다름 — ↶ 를 바로 켜는 몫(477-3). */
|
||||||
|
const pending = (): boolean =>
|
||||||
|
settling && !restoring && !sameSnapshot(takeSnapshot(projectId, stack[cursor]), stack[cursor]);
|
||||||
|
|
||||||
const history: ProfileHistory = {
|
const history: ProfileHistory = {
|
||||||
record() {
|
record() {
|
||||||
if (restoring || paused) return;
|
if (restoring || paused) return;
|
||||||
@@ -231,6 +245,10 @@ export function createProfileHistory(
|
|||||||
releaseWaiters.add(history.record);
|
releaseWaiters.add(history.record);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
history.recordNow();
|
||||||
|
},
|
||||||
|
recordNow() {
|
||||||
|
if (restoring || paused) return;
|
||||||
sync();
|
sync();
|
||||||
restAt = gestures;
|
restAt = gestures;
|
||||||
const snapshot = takeSnapshot(projectId, stack[cursor]);
|
const snapshot = takeSnapshot(projectId, stack[cursor]);
|
||||||
@@ -253,10 +271,11 @@ export function createProfileHistory(
|
|||||||
paused = false;
|
paused = false;
|
||||||
history.record();
|
history.record();
|
||||||
},
|
},
|
||||||
undo: () => apply(cursor - 1),
|
// 기다리던 찍기 먼저 — 바로 누른 ↶ = 방금 조작 되돌림 · 묶음 한 걸음(477-3)
|
||||||
redo: () => apply(cursor + 1),
|
undo: () => (flushSettle(), apply(cursor - 1)),
|
||||||
canUndo: () => cursor > 0,
|
redo: () => (flushSettle(), apply(cursor + 1)),
|
||||||
canRedo: () => cursor < stack.length - 1,
|
canUndo: () => cursor > 0 || pending(),
|
||||||
|
canRedo: () => cursor < stack.length - 1 && !pending(),
|
||||||
};
|
};
|
||||||
rebaseActive = () => {
|
rebaseActive = () => {
|
||||||
if (restoring || paused || pointerHeld || settling || gestures !== restAt) return;
|
if (restoring || paused || pointerHeld || settling || gestures !== restAt) return;
|
||||||
|
|||||||
Reference in New Issue
Block a user