({
onDone,
}: AntModelSwitchCalloutProps)
| 17 | } |
| 18 | |
| 19 | export function AntModelSwitchCallout({ |
| 20 | onDone, |
| 21 | }: AntModelSwitchCalloutProps): React.ReactNode { |
| 22 | const switchCallout = getSwitchCalloutConfig() |
| 23 | |
| 24 | // Record this appearance so repeat surfacing is throttled and version-aware. |
| 25 | useEffect(() => { |
| 26 | if (!switchCallout) { |
| 27 | return |
| 28 | } |
| 29 | |
| 30 | const shownAt = Date.now() |
| 31 | saveGlobalConfig(current => ({ |
| 32 | ...current, |
| 33 | modelSwitchCalloutLastShown: shownAt, |
| 34 | modelSwitchCalloutVersion: switchCallout.version, |
| 35 | })) |
| 36 | }, [switchCallout]) |
| 37 | |
| 38 | useEffect(() => { |
| 39 | if (!switchCallout) { |
| 40 | onDone('dismiss') |
| 41 | } |
| 42 | }, [switchCallout, onDone]) |
| 43 | |
| 44 | const handleSelect = useCallback( |
| 45 | (value: string): void => { |
| 46 | if (value === 'never') { |
| 47 | saveGlobalConfig(current => { |
| 48 | if (current.modelSwitchCalloutDismissed) { |
| 49 | return current |
| 50 | } |
| 51 | return { |
| 52 | ...current, |
| 53 | modelSwitchCalloutDismissed: true, |
| 54 | } |
| 55 | }) |
| 56 | onDone('dismiss') |
| 57 | return |
| 58 | } |
| 59 | |
| 60 | if (value === 'switch' && switchCallout?.modelAlias) { |
| 61 | onDone('switch', switchCallout.modelAlias) |
| 62 | return |
| 63 | } |
| 64 | |
| 65 | onDone('dismiss') |
| 66 | }, |
| 67 | [onDone, switchCallout], |
| 68 | ) |
| 69 | |
| 70 | const options = useMemo<OptionWithDescription<string>[]>(() => { |
| 71 | const base: OptionWithDescription<string>[] = [ |
| 72 | { |
| 73 | label: 'Not now', |
| 74 | description: 'Keep your current model for now.', |
| 75 | value: 'dismiss', |
| 76 | }, |
nothing calls this directly
no test coverage detected