import React, { useCallback, useEffect, useMemo, useRef, useState, } from "react"; import { useTranslation } from "react-i18next"; import JsonEditor from "@/components/JsonEditor"; import { extractCodexTopLevelInt, setCodexTopLevelInt, removeCodexTopLevelField, } from "@/utils/providerConfigUtils"; interface CodexAuthSectionProps { value: string; onChange: (value: string) => void; onBlur?: () => void; error?: string; } /** * CodexAuthSection - Auth JSON editor section */ export const CodexAuthSection: React.FC = ({ value, onChange, onBlur, error, }) => { const { t } = useTranslation(); const [isDarkMode, setIsDarkMode] = useState(false); useEffect(() => { setIsDarkMode(document.documentElement.classList.contains("dark")); const observer = new MutationObserver(() => { setIsDarkMode(document.documentElement.classList.contains("dark")); }); observer.observe(document.documentElement, { attributes: true, attributeFilter: ["class"], }); return () => observer.disconnect(); }, []); const handleChange = (newValue: string) => { onChange(newValue); if (onBlur) { onBlur(); } }; return (
{error && (

{error}

)} {!error && (

{t("codexConfig.authJsonHint")}

)}
); }; interface CodexConfigSectionProps { value: string; onChange: (value: string) => void; useCommonConfig: boolean; onCommonConfigToggle: (checked: boolean) => void; onEditCommonConfig: () => void; commonConfigError?: string; configError?: string; } /** * CodexConfigSection - Config TOML editor section */ export const CodexConfigSection: React.FC = ({ value, onChange, useCommonConfig, onCommonConfigToggle, onEditCommonConfig, commonConfigError, configError, }) => { const { t } = useTranslation(); const [isDarkMode, setIsDarkMode] = useState(false); useEffect(() => { setIsDarkMode(document.documentElement.classList.contains("dark")); const observer = new MutationObserver(() => { setIsDarkMode(document.documentElement.classList.contains("dark")); }); observer.observe(document.documentElement, { attributes: true, attributeFilter: ["class"], }); return () => observer.disconnect(); }, []); // Mirror value prop to local state (same pattern as CommonConfigEditor) const [localValue, setLocalValue] = useState(value); const localValueRef = useRef(value); useEffect(() => { setLocalValue(value); localValueRef.current = value; }, [value]); const handleLocalChange = useCallback( (newValue: string) => { if (newValue === localValueRef.current) return; localValueRef.current = newValue; setLocalValue(newValue); onChange(newValue); }, [onChange], ); // Parse toggle states from TOML text const toggleStates = useMemo(() => { const contextWindow = extractCodexTopLevelInt( localValue, "model_context_window", ); const compactLimit = extractCodexTopLevelInt( localValue, "model_auto_compact_token_limit", ); return { contextWindow1M: contextWindow === 1000000, compactLimit: compactLimit ?? 900000, }; }, [localValue]); // Debounce timer for compact limit input const compactTimerRef = useRef>(); const handleContextWindowToggle = useCallback( (checked: boolean) => { let toml = localValueRef.current || ""; if (checked) { toml = setCodexTopLevelInt(toml, "model_context_window", 1000000); // Auto-set compact limit if not already present if ( extractCodexTopLevelInt(toml, "model_auto_compact_token_limit") === undefined ) { toml = setCodexTopLevelInt( toml, "model_auto_compact_token_limit", 900000, ); } } else { toml = removeCodexTopLevelField(toml, "model_context_window"); toml = removeCodexTopLevelField(toml, "model_auto_compact_token_limit"); } handleLocalChange(toml); }, [handleLocalChange], ); const handleCompactLimitChange = useCallback( (inputValue: string) => { clearTimeout(compactTimerRef.current); compactTimerRef.current = setTimeout(() => { const num = parseInt(inputValue, 10); if (!Number.isNaN(num) && num > 0) { handleLocalChange( setCodexTopLevelInt( localValueRef.current || "", "model_auto_compact_token_limit", num, ), ); } }, 500); }, [handleLocalChange], ); // Cleanup debounce timer useEffect(() => { return () => clearTimeout(compactTimerRef.current); }, []); return (
{commonConfigError && (

{commonConfigError}

)}
{configError && (

{configError}

)} {!configError && (

{t("codexConfig.configTomlHint")}

)}
); };