refactor(toast): HUD 상태 라인 피드백 통합 및 우선순위 큐 적용

This commit is contained in:
2026-03-04 20:46:19 +09:00
parent c451175b9c
commit 06dbee8d63
6 changed files with 186 additions and 32 deletions

View File

@@ -2,30 +2,30 @@ interface ApplyQuickPackParams {
packId: 'balanced' | 'deep-work' | 'gentle';
onTimerSelect: (timerLabel: string) => void;
onSelectPreset: (presetId: string) => void;
pushToast: (payload: { title: string; description?: string }) => void;
onApplied?: (message: string) => void;
}
export const applyQuickPack = ({
packId,
onTimerSelect,
onSelectPreset,
pushToast,
onApplied,
}: ApplyQuickPackParams) => {
if (packId === 'balanced') {
onTimerSelect('25/5');
onSelectPreset('rain-focus');
pushToast({ title: 'Balanced 팩을 적용했어요.' });
onApplied?.('Balanced 팩을 적용했어요.');
return;
}
if (packId === 'deep-work') {
onTimerSelect('50/10');
onSelectPreset('deep-white');
pushToast({ title: 'Deep Work 팩을 적용했어요.' });
onApplied?.('Deep Work 팩을 적용했어요.');
return;
}
onTimerSelect('25/5');
onSelectPreset('silent');
pushToast({ title: 'Gentle 팩을 적용했어요.' });
onApplied?.('Gentle 팩을 적용했어요.');
};

View File

@@ -6,6 +6,7 @@ import { SOUND_PRESETS, type RecentThought, type TimerPreset } from '@/entities/
import { ExitHoldButton } from '@/features/exit-hold';
import { ManagePlanSheetContent, PaywallSheetContent } from '@/features/paywall-sheet';
import { PlanPill } from '@/features/plan-pill';
import type { HudStatusLinePayload } from '@/shared/lib/useHudStatusLine';
import { useToast } from '@/shared/ui';
import { cn } from '@/shared/lib/cn';
import { ControlCenterSheetWidget } from '@/widgets/control-center-sheet';
@@ -40,6 +41,7 @@ interface SpaceToolsDockWidgetProps {
onRestoreThought: (thought: RecentThought) => void;
onRestoreThoughts: (thoughts: RecentThought[]) => void;
onClearInbox: () => RecentThought[];
onStatusMessage: (payload: HudStatusLinePayload) => void;
onExitRequested: () => void;
}
@@ -65,6 +67,7 @@ export const SpaceToolsDockWidget = ({
onRestoreThought,
onRestoreThoughts,
onClearInbox,
onStatusMessage,
onExitRequested,
}: SpaceToolsDockWidgetProps) => {
const { pushToast } = useToast();
@@ -171,9 +174,10 @@ export const SpaceToolsDockWidget = ({
}
setNoteDraft('');
pushToast({
title: '인박스에 저장됨',
onStatusMessage({
message: '인박스에 저장됨',
durationMs: 4200,
priority: 'undo',
action: {
label: '실행취소',
onClick: () => {
@@ -183,7 +187,7 @@ export const SpaceToolsDockWidget = ({
return;
}
pushToast({ title: '저장 취소됨' });
onStatusMessage({ message: '저장 취소됨' });
},
},
});
@@ -198,14 +202,15 @@ export const SpaceToolsDockWidget = ({
const willBeCompleted = !thought.isCompleted;
pushToast({
title: willBeCompleted ? '완료 처리됨' : '완료 해제됨',
onStatusMessage({
message: willBeCompleted ? '완료 처리됨' : '완료 해제됨',
durationMs: 4200,
priority: 'undo',
action: {
label: '실행취소',
onClick: () => {
onRestoreThought(previousThought);
pushToast({ title: willBeCompleted ? '완료 처리를 취소했어요.' : '완료 해제를 취소했어요.' });
onStatusMessage({ message: willBeCompleted ? '완료 처리를 취소했어요.' : '완료 해제를 취소했어요.' });
},
},
});
@@ -218,14 +223,15 @@ export const SpaceToolsDockWidget = ({
return;
}
pushToast({
title: '삭제됨',
onStatusMessage({
message: '삭제됨',
durationMs: 4200,
priority: 'undo',
action: {
label: '실행취소',
onClick: () => {
onRestoreThought(removedThought);
pushToast({ title: '삭제를 취소했어요.' });
onStatusMessage({ message: '삭제를 취소했어요.' });
},
},
});
@@ -235,18 +241,19 @@ export const SpaceToolsDockWidget = ({
const snapshot = onClearInbox();
if (snapshot.length === 0) {
pushToast({ title: '인박스가 비어 있어요.' });
onStatusMessage({ message: '인박스가 비어 있어요.' });
return;
}
pushToast({
title: '모두 비워짐',
onStatusMessage({
message: '모두 비워짐',
durationMs: 4200,
priority: 'undo',
action: {
label: '실행취소',
onClick: () => {
onRestoreThoughts(snapshot);
pushToast({ title: '인박스를 복구했어요.' });
onStatusMessage({ message: '인박스를 복구했어요.' });
},
},
});
@@ -273,7 +280,14 @@ export const SpaceToolsDockWidget = ({
};
const handleApplyPack = (packId: 'balanced' | 'deep-work' | 'gentle') =>
applyQuickPack({ packId, onTimerSelect, onSelectPreset, pushToast });
applyQuickPack({
packId,
onTimerSelect,
onSelectPreset,
onApplied: (message) => {
onStatusMessage({ message, durationMs: 1200 });
},
});
const showVolumeFeedback = (nextVolume: number) => {
setVolumeFeedback(`${nextVolume}%`);
@@ -413,7 +427,6 @@ export const SpaceToolsDockWidget = ({
onVolumeKeyDown={handleVolumeKeyDown}
onSelectPreset={(presetId) => {
onSelectPreset(presetId);
pushToast({ title: '사운드 변경(더미)' });
setOpenPopover(null);
}}
/>
@@ -447,15 +460,12 @@ export const SpaceToolsDockWidget = ({
soundPresets={SOUND_PRESETS}
onSelectRoom={(roomId) => {
onRoomSelect(roomId);
pushToast({ title: '공간을 바꿨어요.' });
}}
onSelectTimer={(label) => {
onTimerSelect(label);
pushToast({ title: `타이머를 ${label}로 바꿨어요.` });
}}
onSelectSound={(presetId) => {
onSelectPreset(presetId);
pushToast({ title: '사운드를 바꿨어요.' });
}}
onApplyPack={handleApplyPack}
onLockedClick={handleLockedClick}