fix(space): 정리된 intent hud와 리뷰 반영

This commit is contained in:
2026-03-14 16:28:26 +09:00
parent 6154bd54a8
commit bc08a049b6
17 changed files with 746 additions and 214 deletions

View File

@@ -36,6 +36,10 @@ interface UseSpaceWorkspaceSessionControlsParams {
pauseSession: () => Promise<FocusSession | null>;
resumeSession: () => Promise<FocusSession | null>;
restartCurrentPhase: () => Promise<FocusSession | null>;
updateCurrentIntent: (payload: {
goal?: string;
microStep?: string | null;
}) => Promise<FocusSession | null>;
advanceGoal: (input: {
completedGoal: string;
nextGoal: string;
@@ -73,6 +77,7 @@ export const useSpaceWorkspaceSessionControls = ({
pauseSession,
resumeSession,
restartCurrentPhase,
updateCurrentIntent,
advanceGoal,
abandonSession,
setGoalInput,
@@ -289,6 +294,50 @@ export const useSpaceWorkspaceSessionControls = ({
unlockPlayback,
]);
const handleIntentUpdate = useCallback(async (input: {
goal?: string;
microStep?: string | null;
}) => {
if (!currentSession) {
return false;
}
const nextGoal = input.goal?.trim();
const nextMicroStep = input.microStep === undefined
? undefined
: input.microStep?.trim() || null;
if (input.goal !== undefined && !nextGoal) {
return false;
}
const updatedSession = await updateCurrentIntent({
goal: nextGoal,
microStep: nextMicroStep,
});
if (!updatedSession) {
pushStatusLine({
message: copy.space.workspace.intentSyncFailed,
});
return false;
}
setGoalInput(updatedSession.goal);
setLinkedFocusPlanItemId(updatedSession.focusPlanItemId ?? null);
setSelectedGoalId(null);
setShowResumePrompt(false);
return true;
}, [
currentSession,
pushStatusLine,
setGoalInput,
setLinkedFocusPlanItemId,
setSelectedGoalId,
setShowResumePrompt,
updateCurrentIntent,
]);
useEffect(() => {
const previousBodyOverflow = document.body.style.overflow;
const previousHtmlOverflow = document.documentElement.style.overflow;
@@ -357,6 +406,7 @@ export const useSpaceWorkspaceSessionControls = ({
handleExitRequested,
handlePauseRequested,
handleRestartRequested,
handleIntentUpdate,
handleGoalAdvance,
};
};

View File

@@ -110,12 +110,12 @@ export const SpaceWorkspaceWidget = () => {
isBootstrapping,
isMutating: isSessionMutating,
timeDisplay,
playbackState,
phase,
startSession,
pauseSession,
resumeSession,
restartCurrentPhase,
updateCurrentIntent,
updateCurrentSelection,
advanceGoal,
abandonSession,
@@ -190,6 +190,7 @@ export const SpaceWorkspaceWidget = () => {
pauseSession,
resumeSession,
restartCurrentPhase,
updateCurrentIntent,
advanceGoal,
abandonSession,
setGoalInput: selection.setGoalInput,
@@ -283,34 +284,32 @@ export const SpaceWorkspaceWidget = () => {
}
/>
<SpaceFocusHudWidget
goal={selection.goalInput.trim()}
microStep={currentSession?.microStep ?? null}
timerLabel={selection.selectedTimerLabel}
timeDisplay={resolvedTimeDisplay}
visible={isFocusMode}
hasActiveSession={Boolean(currentSession)}
playbackState={resolvedPlaybackState}
sessionPhase={phase ?? 'focus'}
isSessionActionPending={isSessionMutating}
canStartSession={controls.canStartSession}
canPauseSession={controls.canPauseSession}
canRestartSession={controls.canRestartSession}
onStartRequested={() => {
void controls.handleStartRequested();
}}
onPauseRequested={() => {
void controls.handlePauseRequested();
}}
onRestartRequested={() => {
void controls.handleRestartRequested();
}}
onExitRequested={() => {
void controls.handleExitRequested();
}}
onStatusMessage={pushStatusLine}
onGoalUpdate={controls.handleGoalAdvance}
/>
{isFocusMode ? (
<SpaceFocusHudWidget
goal={selection.goalInput.trim()}
microStep={currentSession?.microStep ?? null}
timeDisplay={resolvedTimeDisplay}
hasActiveSession={Boolean(currentSession)}
playbackState={resolvedPlaybackState}
sessionPhase={phase ?? 'focus'}
isSessionActionPending={isSessionMutating}
canStartSession={controls.canStartSession}
canPauseSession={controls.canPauseSession}
canRestartSession={controls.canRestartSession}
onStartRequested={() => {
void controls.handleStartRequested();
}}
onPauseRequested={() => {
void controls.handlePauseRequested();
}}
onRestartRequested={() => {
void controls.handleRestartRequested();
}}
onStatusMessage={pushStatusLine}
onIntentUpdate={controls.handleIntentUpdate}
onGoalUpdate={controls.handleGoalAdvance}
/>
) : null}
<FocusTopToast
visible={isFocusMode && Boolean(activeStatus)}