|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import { Logger } from './core/logger.js'; |
|
|
import { appState } from './core/state.js'; |
|
|
import { socketManager } from './network/socket.js'; |
|
|
import { storageManager } from './core/storage.js'; |
|
|
|
|
|
|
|
|
import { domManager } from './ui/dom-manager.js'; |
|
|
import { messageManager } from './ui/message-manager.js'; |
|
|
import { settingsManager } from './ui/settings-manager.js'; |
|
|
import { sessionManager } from './ui/session-manager.js'; |
|
|
import { imageHandler } from './ui/image-handler.js'; |
|
|
|
|
|
|
|
|
import { socketEventHandlers } from './handlers/socket-handlers.js'; |
|
|
|
|
|
|
|
|
window.addEventListener('error', (event) => { |
|
|
Logger.error('Global JavaScript error:', event.error); |
|
|
Logger.error('Error message:', event.message); |
|
|
Logger.error('Error filename:', event.filename); |
|
|
Logger.error('Error line:', event.lineno); |
|
|
Logger.error('Error column:', event.colno); |
|
|
}); |
|
|
|
|
|
window.addEventListener('unhandledrejection', (event) => { |
|
|
Logger.error('Unhandled promise rejection:', event.reason); |
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class PIPSApplication { |
|
|
constructor() { |
|
|
this.isInitialized = false; |
|
|
} |
|
|
|
|
|
async initialize() { |
|
|
if (this.isInitialized) { |
|
|
Logger.warn('App', 'Application already initialized'); |
|
|
return; |
|
|
} |
|
|
|
|
|
try { |
|
|
Logger.log('App', 'Initializing PIPS application...'); |
|
|
|
|
|
|
|
|
domManager.setupDOMReferences(); |
|
|
await domManager.initializeIcons(); |
|
|
|
|
|
|
|
|
socketManager.initialize(); |
|
|
sessionManager.initialize(); |
|
|
settingsManager.initialize(); |
|
|
imageHandler.initialize(); |
|
|
|
|
|
|
|
|
settingsManager.loadUserSettingsFromStorage(); |
|
|
|
|
|
|
|
|
await this.performFirstRunSeeding(); |
|
|
|
|
|
|
|
|
imageHandler.setupPasteHandler(); |
|
|
|
|
|
|
|
|
this.setupCoreEventListeners(); |
|
|
|
|
|
|
|
|
this.setupSocketHandlers(); |
|
|
|
|
|
|
|
|
await socketManager.initialize(); |
|
|
|
|
|
|
|
|
domManager.updateStatus('Connecting to PIPS server...', 'info'); |
|
|
|
|
|
this.isInitialized = true; |
|
|
Logger.log('App', 'PIPS application initialized successfully'); |
|
|
|
|
|
} catch (error) { |
|
|
Logger.error('App', 'Error during initialization:', error); |
|
|
domManager.updateStatus('Failed to initialize application', 'error'); |
|
|
} |
|
|
} |
|
|
|
|
|
async performFirstRunSeeding() { |
|
|
try { |
|
|
|
|
|
if (!localStorage.getItem('pips_first_run_completed')) { |
|
|
Logger.debug('App', 'First run detected, seeding default sessions...'); |
|
|
|
|
|
try { |
|
|
const result = await storageManager.importSessionsFromUrl('/static/default_sessions/builtin_sessions.json'); |
|
|
Logger.log('App', `Seeded ${result.imported} default sessions successfully`); |
|
|
|
|
|
|
|
|
if (result.imported > 0) { |
|
|
const sessions = storageManager.loadSessions(); |
|
|
const defaultSessionIds = Object.keys(sessions); |
|
|
storageManager.saveDefaultSessionIds(defaultSessionIds); |
|
|
Logger.debug('App', `Tracked ${defaultSessionIds.length} default session IDs`); |
|
|
} |
|
|
|
|
|
|
|
|
localStorage.setItem('pips_first_run_completed', 'yes'); |
|
|
localStorage.setItem('pips_default_sessions_loaded', new Date().toISOString()); |
|
|
|
|
|
} catch (error) { |
|
|
Logger.warn('App', 'Could not load default sessions (this is normal in development):', error.message); |
|
|
|
|
|
localStorage.setItem('pips_first_run_completed', 'yes'); |
|
|
} |
|
|
} else { |
|
|
Logger.debug('App', 'Not first run, skipping default session seeding'); |
|
|
} |
|
|
} catch (error) { |
|
|
Logger.error('App', 'Error during first-run seeding:', error); |
|
|
} |
|
|
} |
|
|
|
|
|
setupCoreEventListeners() { |
|
|
|
|
|
domManager.getElement('solveBtn')?.addEventListener('click', () => this.solveProblem()); |
|
|
domManager.getElement('interruptBtn')?.addEventListener('click', () => this.interruptSolving()); |
|
|
domManager.getElement('downloadBtn')?.addEventListener('click', () => messageManager.downloadChat()); |
|
|
|
|
|
Logger.debug('App', 'Core event listeners set up'); |
|
|
|
|
|
|
|
|
window.addEventListener('beforeunload', () => { |
|
|
Logger.debug('App', 'Page unloading - performing emergency cleanup'); |
|
|
sessionManager.emergencyCleanupAndSave(); |
|
|
}); |
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
setupSocketHandlers() { |
|
|
console.log('[DEBUG] Setting up socket handlers...'); |
|
|
|
|
|
|
|
|
const eventHandlers = socketEventHandlers.getEventHandlers(); |
|
|
console.log('[DEBUG] Event handlers to register:', Object.keys(eventHandlers)); |
|
|
socketManager.registerEventHandlers(eventHandlers); |
|
|
|
|
|
|
|
|
const connectionHandlers = socketEventHandlers.getConnectionHandlers(); |
|
|
console.log('[DEBUG] Connection handlers to register:', Object.keys(connectionHandlers)); |
|
|
Object.entries(connectionHandlers).forEach(([event, handler]) => { |
|
|
socketManager.on(event, handler); |
|
|
}); |
|
|
|
|
|
Logger.debug('App', 'Socket event handlers set up successfully'); |
|
|
} |
|
|
|
|
|
|
|
|
solveProblem() { |
|
|
const questionInput = domManager.getElement('questionInput'); |
|
|
const text = questionInput?.value.trim(); |
|
|
|
|
|
if (!text) { |
|
|
domManager.updateStatus('Please enter a problem description', 'warning'); |
|
|
return; |
|
|
} |
|
|
|
|
|
|
|
|
if (appState.currentSessionData && sessionManager.isSessionUsed(appState.currentSessionData)) { |
|
|
domManager.updateStatus('This session has been used. Please start a new session to solve another problem.', 'warning'); |
|
|
|
|
|
sessionManager.startNewSession(); |
|
|
return; |
|
|
} |
|
|
|
|
|
|
|
|
const imageData = imageHandler.getImageForSubmission(); |
|
|
|
|
|
|
|
|
const sessionId = sessionManager.handleSolveProblem(text, imageData); |
|
|
|
|
|
|
|
|
settingsManager.sendCurrentSettingsToServer(); |
|
|
|
|
|
|
|
|
socketManager.send('solve_problem', { |
|
|
text: text, |
|
|
image: imageData, |
|
|
session_id: sessionId |
|
|
}); |
|
|
|
|
|
Logger.debug('App', 'Problem submitted for solving'); |
|
|
} |
|
|
|
|
|
interruptSolving() { |
|
|
Logger.debug('App', 'Interrupt button clicked'); |
|
|
socketManager.send('interrupt_solving'); |
|
|
domManager.updateStatus('Interrupting current task...', 'warning'); |
|
|
} |
|
|
|
|
|
|
|
|
toggleExpandMessage(button) { |
|
|
messageManager.toggleExpandMessage(button); |
|
|
} |
|
|
|
|
|
|
|
|
get sessionManager() { |
|
|
return sessionManager; |
|
|
} |
|
|
|
|
|
|
|
|
getModules() { |
|
|
return { |
|
|
domManager, |
|
|
messageManager, |
|
|
settingsManager, |
|
|
sessionManager, |
|
|
imageHandler, |
|
|
socketEventHandlers, |
|
|
appState, |
|
|
socketManager, |
|
|
storageManager |
|
|
}; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
document.addEventListener('DOMContentLoaded', async () => { |
|
|
Logger.log('DOM content loaded'); |
|
|
|
|
|
try { |
|
|
const app = new PIPSApplication(); |
|
|
await app.initialize(); |
|
|
|
|
|
|
|
|
window.pipsApp = app; |
|
|
|
|
|
|
|
|
window.toggleExpandMessage = (button) => app.toggleExpandMessage(button); |
|
|
|
|
|
|
|
|
|
|
|
} catch (error) { |
|
|
Logger.error('Failed to initialize PIPS application:', error); |
|
|
} |
|
|
}); |
|
|
|