mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-18 14:25:51 +00:00
纯格式化:移除分号、React Compiler import、import 多行展开。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
145 lines
4.0 KiB
TypeScript
145 lines
4.0 KiB
TypeScript
import { randomUUID } from 'crypto'
|
|
import { useCallback, useRef, useState } from 'react'
|
|
import type { TranscriptShareResponse } from './TranscriptSharePrompt.js'
|
|
import type { FeedbackSurveyResponse } from './utils.js'
|
|
|
|
type SurveyState =
|
|
| 'closed'
|
|
| 'open'
|
|
| 'thanks'
|
|
| 'transcript_prompt'
|
|
| 'submitting'
|
|
| 'submitted'
|
|
|
|
type UseSurveyStateOptions = {
|
|
hideThanksAfterMs: number
|
|
onOpen: (appearanceId: string) => void | Promise<void>
|
|
onSelect: (
|
|
appearanceId: string,
|
|
selected: FeedbackSurveyResponse,
|
|
) => void | Promise<void>
|
|
shouldShowTranscriptPrompt?: (selected: FeedbackSurveyResponse) => boolean
|
|
onTranscriptPromptShown?: (
|
|
appearanceId: string,
|
|
surveyResponse: FeedbackSurveyResponse,
|
|
) => void
|
|
onTranscriptSelect?: (
|
|
appearanceId: string,
|
|
selected: TranscriptShareResponse,
|
|
surveyResponse: FeedbackSurveyResponse | null,
|
|
) => boolean | Promise<boolean>
|
|
}
|
|
|
|
export function useSurveyState({
|
|
hideThanksAfterMs,
|
|
onOpen,
|
|
onSelect,
|
|
shouldShowTranscriptPrompt,
|
|
onTranscriptPromptShown,
|
|
onTranscriptSelect,
|
|
}: UseSurveyStateOptions): {
|
|
state: SurveyState
|
|
lastResponse: FeedbackSurveyResponse | null
|
|
open: () => void
|
|
handleSelect: (selected: FeedbackSurveyResponse) => boolean
|
|
handleTranscriptSelect: (selected: TranscriptShareResponse) => void
|
|
} {
|
|
const [state, setState] = useState<SurveyState>('closed')
|
|
const [lastResponse, setLastResponse] =
|
|
useState<FeedbackSurveyResponse | null>(null)
|
|
const appearanceId = useRef(randomUUID())
|
|
const lastResponseRef = useRef<FeedbackSurveyResponse | null>(null)
|
|
|
|
const showThanksThenClose = useCallback(() => {
|
|
setState('thanks')
|
|
setTimeout(
|
|
(setState, setLastResponse) => {
|
|
setState('closed')
|
|
setLastResponse(null)
|
|
},
|
|
hideThanksAfterMs,
|
|
setState,
|
|
setLastResponse,
|
|
)
|
|
}, [hideThanksAfterMs])
|
|
|
|
const showSubmittedThenClose = useCallback(() => {
|
|
setState('submitted')
|
|
setTimeout(setState, hideThanksAfterMs, 'closed')
|
|
}, [hideThanksAfterMs])
|
|
|
|
const open = useCallback(() => {
|
|
if (state !== 'closed') {
|
|
return
|
|
}
|
|
setState('open')
|
|
appearanceId.current = randomUUID()
|
|
void onOpen(appearanceId.current)
|
|
}, [state, onOpen])
|
|
|
|
const handleSelect = useCallback(
|
|
(selected: FeedbackSurveyResponse): boolean => {
|
|
setLastResponse(selected)
|
|
lastResponseRef.current = selected
|
|
// Always fire the survey response event first
|
|
void onSelect(appearanceId.current, selected)
|
|
|
|
if (selected === 'dismissed') {
|
|
setState('closed')
|
|
setLastResponse(null)
|
|
} else if (shouldShowTranscriptPrompt?.(selected)) {
|
|
setState('transcript_prompt')
|
|
onTranscriptPromptShown?.(appearanceId.current, selected)
|
|
return true
|
|
} else {
|
|
showThanksThenClose()
|
|
}
|
|
return false
|
|
},
|
|
[
|
|
showThanksThenClose,
|
|
onSelect,
|
|
shouldShowTranscriptPrompt,
|
|
onTranscriptPromptShown,
|
|
],
|
|
)
|
|
|
|
const handleTranscriptSelect = useCallback(
|
|
(selected: TranscriptShareResponse) => {
|
|
switch (selected) {
|
|
case 'yes':
|
|
setState('submitting')
|
|
void (async () => {
|
|
try {
|
|
const success = await onTranscriptSelect?.(
|
|
appearanceId.current,
|
|
selected,
|
|
lastResponseRef.current,
|
|
)
|
|
if (success) {
|
|
showSubmittedThenClose()
|
|
} else {
|
|
showThanksThenClose()
|
|
}
|
|
} catch {
|
|
showThanksThenClose()
|
|
}
|
|
})()
|
|
break
|
|
case 'no':
|
|
case 'dont_ask_again':
|
|
void onTranscriptSelect?.(
|
|
appearanceId.current,
|
|
selected,
|
|
lastResponseRef.current,
|
|
)
|
|
showThanksThenClose()
|
|
break
|
|
}
|
|
},
|
|
[showThanksThenClose, showSubmittedThenClose, onTranscriptSelect],
|
|
)
|
|
|
|
return { state, lastResponse, open, handleSelect, handleTranscriptSelect }
|
|
}
|