- Refactor message saving strategy from automatic to manual saving - Save messages only on key operations: send, complete, edit, delete, role toggle, clear - Prevent frequent localStorage writes during streaming responses - Remove excessive console logging - Remove all console.log statements from save/load operations - Clean up debug logs to reduce console noise - Optimize initial state loading with lazy initialization - Replace useRef with useState lazy initialization for config and messages - Ensure loadConfig and loadMessages are called only once on mount - Prevent redundant localStorage reads during re-renders - Update hooks to support new save strategy - Pass saveMessages callback through component hierarchy - Add saveMessagesImmediately to relevant hooks (useApiRequest, useMessageActions, useMessageEdit) - Trigger saves at appropriate lifecycle points This significantly improves performance by reducing localStorage I/O operations from continuous writes during streaming to discrete saves at meaningful points.
197 lines
5.6 KiB
JavaScript
197 lines
5.6 KiB
JavaScript
import { useState, useCallback, useRef, useEffect } from 'react';
|
|
import { DEFAULT_MESSAGES, DEFAULT_CONFIG, DEBUG_TABS } from '../utils/constants';
|
|
import { loadConfig, saveConfig, loadMessages, saveMessages } from '../components/playground/configStorage';
|
|
|
|
export const usePlaygroundState = () => {
|
|
// 使用惰性初始化,确保只在组件首次挂载时加载配置和消息
|
|
const [savedConfig] = useState(() => loadConfig());
|
|
const [initialMessages] = useState(() => loadMessages() || DEFAULT_MESSAGES);
|
|
|
|
// 基础配置状态
|
|
const [inputs, setInputs] = useState(savedConfig.inputs || DEFAULT_CONFIG.inputs);
|
|
const [parameterEnabled, setParameterEnabled] = useState(
|
|
savedConfig.parameterEnabled || DEFAULT_CONFIG.parameterEnabled
|
|
);
|
|
const [showDebugPanel, setShowDebugPanel] = useState(
|
|
savedConfig.showDebugPanel || DEFAULT_CONFIG.showDebugPanel
|
|
);
|
|
const [customRequestMode, setCustomRequestMode] = useState(
|
|
savedConfig.customRequestMode || DEFAULT_CONFIG.customRequestMode
|
|
);
|
|
const [customRequestBody, setCustomRequestBody] = useState(
|
|
savedConfig.customRequestBody || DEFAULT_CONFIG.customRequestBody
|
|
);
|
|
|
|
// UI状态
|
|
const [showSettings, setShowSettings] = useState(false);
|
|
const [models, setModels] = useState([]);
|
|
const [groups, setGroups] = useState([]);
|
|
const [status, setStatus] = useState({});
|
|
|
|
// 消息相关状态 - 使用加载的消息初始化
|
|
const [message, setMessage] = useState(initialMessages);
|
|
|
|
// 调试状态
|
|
const [debugData, setDebugData] = useState({
|
|
request: null,
|
|
response: null,
|
|
timestamp: null,
|
|
previewRequest: null,
|
|
previewTimestamp: null
|
|
});
|
|
const [activeDebugTab, setActiveDebugTab] = useState(DEBUG_TABS.PREVIEW);
|
|
const [previewPayload, setPreviewPayload] = useState(null);
|
|
|
|
// 编辑状态
|
|
const [editingMessageId, setEditingMessageId] = useState(null);
|
|
const [editValue, setEditValue] = useState('');
|
|
|
|
// Refs
|
|
const sseSourceRef = useRef(null);
|
|
const chatRef = useRef(null);
|
|
const saveConfigTimeoutRef = useRef(null);
|
|
const saveMessagesTimeoutRef = useRef(null);
|
|
|
|
// 配置更新函数
|
|
const handleInputChange = useCallback((name, value) => {
|
|
setInputs(prev => ({ ...prev, [name]: value }));
|
|
}, []);
|
|
|
|
const handleParameterToggle = useCallback((paramName) => {
|
|
setParameterEnabled(prev => ({
|
|
...prev,
|
|
[paramName]: !prev[paramName]
|
|
}));
|
|
}, []);
|
|
|
|
// 消息保存函数 - 改为立即保存
|
|
const saveMessagesImmediately = useCallback(() => {
|
|
saveMessages(message);
|
|
}, [message]);
|
|
|
|
// 配置保存
|
|
const debouncedSaveConfig = useCallback(() => {
|
|
if (saveConfigTimeoutRef.current) {
|
|
clearTimeout(saveConfigTimeoutRef.current);
|
|
}
|
|
|
|
saveConfigTimeoutRef.current = setTimeout(() => {
|
|
const configToSave = {
|
|
inputs,
|
|
parameterEnabled,
|
|
showDebugPanel,
|
|
customRequestMode,
|
|
customRequestBody,
|
|
};
|
|
saveConfig(configToSave);
|
|
}, 1000);
|
|
}, [inputs, parameterEnabled, showDebugPanel, customRequestMode, customRequestBody]);
|
|
|
|
// 配置导入/重置
|
|
const handleConfigImport = useCallback((importedConfig) => {
|
|
if (importedConfig.inputs) {
|
|
setInputs(prev => ({ ...prev, ...importedConfig.inputs }));
|
|
}
|
|
if (importedConfig.parameterEnabled) {
|
|
setParameterEnabled(prev => ({ ...prev, ...importedConfig.parameterEnabled }));
|
|
}
|
|
if (typeof importedConfig.showDebugPanel === 'boolean') {
|
|
setShowDebugPanel(importedConfig.showDebugPanel);
|
|
}
|
|
if (importedConfig.customRequestMode) {
|
|
setCustomRequestMode(importedConfig.customRequestMode);
|
|
}
|
|
if (importedConfig.customRequestBody) {
|
|
setCustomRequestBody(importedConfig.customRequestBody);
|
|
}
|
|
// 如果导入的配置包含消息,也恢复消息
|
|
if (importedConfig.messages && Array.isArray(importedConfig.messages)) {
|
|
setMessage(importedConfig.messages);
|
|
}
|
|
}, []);
|
|
|
|
const handleConfigReset = useCallback((options = {}) => {
|
|
const { resetMessages = false } = options;
|
|
|
|
setInputs(DEFAULT_CONFIG.inputs);
|
|
setParameterEnabled(DEFAULT_CONFIG.parameterEnabled);
|
|
setShowDebugPanel(DEFAULT_CONFIG.showDebugPanel);
|
|
setCustomRequestMode(DEFAULT_CONFIG.customRequestMode);
|
|
setCustomRequestBody(DEFAULT_CONFIG.customRequestBody);
|
|
|
|
// 只有在明确指定时才重置消息
|
|
if (resetMessages) {
|
|
setMessage(DEFAULT_MESSAGES);
|
|
}
|
|
}, []);
|
|
|
|
// 清理定时器
|
|
useEffect(() => {
|
|
return () => {
|
|
if (saveConfigTimeoutRef.current) {
|
|
clearTimeout(saveConfigTimeoutRef.current);
|
|
}
|
|
// 移除消息保存定时器的清理
|
|
// if (saveMessagesTimeoutRef.current) {
|
|
// clearTimeout(saveMessagesTimeoutRef.current);
|
|
// }
|
|
};
|
|
}, []);
|
|
|
|
return {
|
|
// 配置状态
|
|
inputs,
|
|
parameterEnabled,
|
|
showDebugPanel,
|
|
customRequestMode,
|
|
customRequestBody,
|
|
|
|
// UI状态
|
|
showSettings,
|
|
models,
|
|
groups,
|
|
status,
|
|
|
|
// 消息状态
|
|
message,
|
|
|
|
// 调试状态
|
|
debugData,
|
|
activeDebugTab,
|
|
previewPayload,
|
|
|
|
// 编辑状态
|
|
editingMessageId,
|
|
editValue,
|
|
|
|
// Refs
|
|
sseSourceRef,
|
|
chatRef,
|
|
saveConfigTimeoutRef,
|
|
|
|
// 更新函数
|
|
setInputs,
|
|
setParameterEnabled,
|
|
setShowDebugPanel,
|
|
setCustomRequestMode,
|
|
setCustomRequestBody,
|
|
setShowSettings,
|
|
setModels,
|
|
setGroups,
|
|
setStatus,
|
|
setMessage,
|
|
setDebugData,
|
|
setActiveDebugTab,
|
|
setPreviewPayload,
|
|
setEditingMessageId,
|
|
setEditValue,
|
|
|
|
// 处理函数
|
|
handleInputChange,
|
|
handleParameterToggle,
|
|
debouncedSaveConfig,
|
|
saveMessagesImmediately, // 改为导出立即保存函数
|
|
handleConfigImport,
|
|
handleConfigReset,
|
|
};
|
|
};
|