Update: Basic Functions of chat.html 75% maybe
This commit is contained in:
178
frontend/js/pages/chat/SessionManager.js
Normal file
178
frontend/js/pages/chat/SessionManager.js
Normal file
@@ -0,0 +1,178 @@
|
||||
// Filename: frontend/js/pages/chat/SessionManager.js
|
||||
|
||||
import { nanoid } from 'https://cdn.jsdelivr.net/npm/nanoid/nanoid.js';
|
||||
|
||||
const LOCAL_STORAGE_KEY = 'gemini_chat_state';
|
||||
|
||||
/**
|
||||
* Manages the state and persistence of chat sessions.
|
||||
* This class handles loading from/saving to localStorage,
|
||||
* and all operations like creating, switching, and deleting sessions.
|
||||
*/
|
||||
export class SessionManager {
|
||||
constructor() {
|
||||
this.state = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the manager by loading state from localStorage or creating a default state.
|
||||
*/
|
||||
init() {
|
||||
this._loadState();
|
||||
}
|
||||
|
||||
// --- Public API for state access ---
|
||||
|
||||
getSessions() {
|
||||
return this.state.sessions;
|
||||
}
|
||||
|
||||
getCurrentSessionId() {
|
||||
return this.state.currentSessionId;
|
||||
}
|
||||
|
||||
getCurrentSession() {
|
||||
return this.state.sessions.find(s => s.id === this.state.currentSessionId);
|
||||
}
|
||||
|
||||
// --- Public API for state mutation ---
|
||||
|
||||
/**
|
||||
* Creates a new, empty session and sets it as the current one.
|
||||
*/
|
||||
createSession() {
|
||||
const newSessionId = nanoid();
|
||||
const newSession = {
|
||||
id: newSessionId,
|
||||
name: '新会话',
|
||||
systemPrompt: '',
|
||||
messages: [],
|
||||
modelConfig: { model: 'gemini-2.0-flash-lite' },
|
||||
params: { temperature: 0.7 }
|
||||
};
|
||||
this.state.sessions.unshift(newSession);
|
||||
this.state.currentSessionId = newSessionId;
|
||||
this._saveState();
|
||||
}
|
||||
|
||||
/**
|
||||
* Switches the current session to the one with the given ID.
|
||||
* @param {string} sessionId The ID of the session to switch to.
|
||||
*/
|
||||
switchSession(sessionId) {
|
||||
if (this.state.currentSessionId === sessionId) return;
|
||||
this.state.currentSessionId = sessionId;
|
||||
this._saveState();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a session by its ID.
|
||||
* @param {string} sessionId The ID of the session to delete.
|
||||
*/
|
||||
deleteSession(sessionId) {
|
||||
this.state.sessions = this.state.sessions.filter(s => s.id !== sessionId);
|
||||
|
||||
if (this.state.currentSessionId === sessionId) {
|
||||
this.state.currentSessionId = this.state.sessions[0]?.id || null;
|
||||
if (!this.state.currentSessionId) {
|
||||
this._createInitialState(); // Create a new one if all are deleted
|
||||
}
|
||||
}
|
||||
|
||||
this._saveState();
|
||||
}
|
||||
|
||||
/**
|
||||
* [NEW] Clears all messages from the currently active session.
|
||||
*/
|
||||
clearCurrentSession() {
|
||||
const currentSession = this.getCurrentSession();
|
||||
if (currentSession) {
|
||||
currentSession.messages = [];
|
||||
this._saveState();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a message to the current session and updates the session name if it's the first message.
|
||||
* @param {object} message The message object to add.
|
||||
* @returns {object} The session that was updated.
|
||||
*/
|
||||
addMessage(message) {
|
||||
const currentSession = this.getCurrentSession();
|
||||
if (currentSession) {
|
||||
if (currentSession.messages.length === 0 && message.role === 'user') {
|
||||
currentSession.name = message.content.substring(0, 30);
|
||||
}
|
||||
currentSession.messages.push(message);
|
||||
this._saveState();
|
||||
return currentSession;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
deleteMessage(messageId) {
|
||||
const currentSession = this.getCurrentSession();
|
||||
if (currentSession) {
|
||||
const messageIndex = currentSession.messages.findIndex(m => m.id === messageId);
|
||||
if (messageIndex > -1) {
|
||||
currentSession.messages.splice(messageIndex, 1);
|
||||
this._saveState();
|
||||
console.log(`Message ${messageId} deleted.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
truncateMessagesAfter(messageId) {
|
||||
const currentSession = this.getCurrentSession();
|
||||
if (currentSession) {
|
||||
const messageIndex = currentSession.messages.findIndex(m => m.id === messageId);
|
||||
// Ensure the message exists and it's not already the last one
|
||||
if (messageIndex > -1 && messageIndex < currentSession.messages.length - 1) {
|
||||
currentSession.messages.splice(messageIndex + 1);
|
||||
this._saveState();
|
||||
console.log(`Truncated messages after ${messageId}.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
// --- Private persistence methods ---
|
||||
|
||||
_saveState() {
|
||||
try {
|
||||
localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(this.state));
|
||||
} catch (error) {
|
||||
console.error("Failed to save session state:", error);
|
||||
}
|
||||
}
|
||||
|
||||
_loadState() {
|
||||
try {
|
||||
const stateString = localStorage.getItem(LOCAL_STORAGE_KEY);
|
||||
if (stateString) {
|
||||
this.state = JSON.parse(stateString);
|
||||
} else {
|
||||
this._createInitialState();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to load session state, creating initial state:", error);
|
||||
this._createInitialState();
|
||||
}
|
||||
}
|
||||
|
||||
_createInitialState() {
|
||||
const initialSessionId = nanoid();
|
||||
this.state = {
|
||||
sessions: [{
|
||||
id: initialSessionId,
|
||||
name: '新会话',
|
||||
systemPrompt: '',
|
||||
messages: [],
|
||||
modelConfig: { model: 'gemini-2.0-flash-lite' },
|
||||
params: { temperature: 0.7 }
|
||||
}],
|
||||
currentSessionId: initialSessionId,
|
||||
settings: {}
|
||||
};
|
||||
this._saveState();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user