diff --git a/src/lib/components/MudTerminal.svelte b/src/lib/components/MudTerminal.svelte index 70b35fd..4d7f3cd 100644 --- a/src/lib/components/MudTerminal.svelte +++ b/src/lib/components/MudTerminal.svelte @@ -1,6 +1,6 @@ @@ -73,7 +79,12 @@
Dark Mode
@@ -153,7 +164,12 @@
Text-to-Speech
diff --git a/src/lib/profiles/ProfileManager.ts b/src/lib/profiles/ProfileManager.ts index eec284f..fc1c827 100644 --- a/src/lib/profiles/ProfileManager.ts +++ b/src/lib/profiles/ProfileManager.ts @@ -53,26 +53,52 @@ export class ProfileManager extends EventEmitter { try { const storedProfiles = localStorage.getItem(this.storageKey); + console.log('Retrieved from localStorage:', storedProfiles); + if (storedProfiles) { - this.profiles = JSON.parse(storedProfiles); - console.log('Loaded profiles from localStorage:', this.profiles); - this.emit('profilesLoaded', this.profiles); + const parsed = JSON.parse(storedProfiles); + console.log('Parsed profiles:', parsed); + + // Validate profiles before assigning + if (Array.isArray(parsed)) { + // Filter out invalid profiles + this.profiles = parsed.filter(profile => this.isValidProfile(profile)); + console.log('Loaded profiles from localStorage:', this.profiles); + + if (this.profiles.length > 0) { + this.emit('profilesLoaded', this.profiles); + return; // Success, exit early + } else { + console.warn('No valid profiles found in stored data, creating default'); + } + } else { + console.warn('Stored profiles data is not an array, creating default'); + } } else { console.log('No profiles found in localStorage, creating default profile'); - // Add a default profile if none exist - const defaultProfile = this.createDefaultProfile(); - defaultProfile.name = 'Aardwolf MUD'; - defaultProfile.host = 'aardmud.org'; - defaultProfile.port = 23; - this.addProfile(defaultProfile); } + + // If we got here, we need to create a default profile + const defaultProfile = this.createDefaultProfile(); + defaultProfile.name = 'Aardwolf MUD'; + defaultProfile.host = 'aardmud.org'; + defaultProfile.port = 23; + + // Clear profiles array and add the default + this.profiles = []; + this.addProfile(defaultProfile); } catch (error) { console.error('Failed to load profiles from local storage:', error); + console.error('Error details:', error.message, error.stack); + // Add a default profile if there was an error const defaultProfile = this.createDefaultProfile(); defaultProfile.name = 'Aardwolf MUD'; defaultProfile.host = 'aardmud.org'; defaultProfile.port = 23; + + // Clear profiles array and add the default + this.profiles = []; this.addProfile(defaultProfile); } } @@ -86,9 +112,21 @@ export class ProfileManager extends EventEmitter { } try { - localStorage.setItem(this.storageKey, JSON.stringify(this.profiles)); + // Add logging to help debug + console.log('Saving profiles to localStorage:', this.profiles); + + const profilesJson = JSON.stringify(this.profiles); + console.log('Profiles JSON:', profilesJson); + + localStorage.setItem(this.storageKey, profilesJson); + console.log('Profiles saved successfully'); + + // Validate by reading back + const readBack = localStorage.getItem(this.storageKey); + console.log('Read back from localStorage:', readBack); } catch (error) { console.error('Failed to save profiles to local storage:', error); + console.error('Error details:', error.message, error.stack); } } diff --git a/src/lib/settings/SettingsManager.ts b/src/lib/settings/SettingsManager.ts index 1651552..9acfc71 100644 --- a/src/lib/settings/SettingsManager.ts +++ b/src/lib/settings/SettingsManager.ts @@ -1,6 +1,5 @@ import { EventEmitter } from '$lib/utils/EventEmitter'; -import { get } from 'svelte/store'; -import { accessibilitySettings, uiSettings } from '$lib/stores/mudStore'; +import { get, writable, type Writable } from 'svelte/store'; export interface Settings { accessibility: { @@ -30,6 +29,11 @@ export interface Settings { export class SettingsManager extends EventEmitter { private settings: Settings; private readonly STORAGE_KEY = 'svelte-mud-settings'; + private initialized = false; + + // Create our own stores rather than depending on the ones from mudStore + public accessibilitySettings: Writable; + public uiSettings: Writable; constructor() { super(); @@ -60,6 +64,31 @@ export class SettingsManager extends EventEmitter { } }; + // Create the stores with default values + this.accessibilitySettings = writable(this.settings.accessibility); + this.uiSettings = writable(this.settings.ui); + + // Set up subscriptions to save settings when they change + this.accessibilitySettings.subscribe(value => { + // Skip during initialization + if (!this.initialized) return; + + if (typeof window !== 'undefined') { + // Use a small timeout to batch multiple rapid changes + setTimeout(() => this.saveSettings(), 100); + } + }); + + this.uiSettings.subscribe(value => { + // Skip during initialization + if (!this.initialized) return; + + if (typeof window !== 'undefined') { + // Use a small timeout to batch multiple rapid changes + setTimeout(() => this.saveSettings(), 100); + } + }); + // Load settings from storage this.loadSettings(); } @@ -68,102 +97,87 @@ export class SettingsManager extends EventEmitter { * Load settings from localStorage */ private loadSettings(): void { - if (typeof window === 'undefined') { - return; // Skip during SSR + // Skip during SSR + if (typeof window === 'undefined' || typeof localStorage === 'undefined') { + console.log('SSR environment detected, skipping settings load'); + return; } - + try { const storedSettings = localStorage.getItem(this.STORAGE_KEY); if (storedSettings) { + console.log('Retrieved settings from localStorage'); const parsedSettings = JSON.parse(storedSettings); // Merge with defaults to ensure all properties exist - this.settings = { - accessibility: { - ...this.settings.accessibility, - ...parsedSettings.accessibility - }, - ui: { - ...this.settings.ui, - ...parsedSettings.ui - } - }; - - console.log('Loaded settings from localStorage:', this.settings); - - // Update Svelte stores with loaded settings - accessibilitySettings.set(this.settings.accessibility); - uiSettings.set(this.settings.ui); - - this.emit('settingsLoaded', this.settings); + if (parsedSettings && typeof parsedSettings === 'object') { + // Update internal settings + this.settings = { + accessibility: { + ...this.settings.accessibility, + ...(parsedSettings.accessibility || {}) + }, + ui: { + ...this.settings.ui, + ...(parsedSettings.ui || {}) + } + }; + + console.log('Loaded settings from localStorage:', this.settings); + + // Set the stores without triggering the save callback + this.accessibilitySettings.set(this.settings.accessibility); + this.uiSettings.set(this.settings.ui); + } else { + console.warn('Invalid settings format found in localStorage'); + } } else { console.log('No settings found in localStorage, using defaults'); - // Update Svelte stores with default settings - accessibilitySettings.set(this.settings.accessibility); - uiSettings.set(this.settings.ui); } + + // Now that settings are loaded, mark as initialized + this.initialized = true; + + // Notify listeners + this.emit('settingsLoaded', this.settings); } catch (error) { console.error('Failed to load settings from localStorage:', error); + // Mark as initialized even on error + this.initialized = true; } } - /** - * Save settings to localStorage - */ + // Save settings to localStorage public saveSettings(): void { - if (typeof window === 'undefined') { - return; // Skip during SSR - } + if (typeof window === 'undefined' || !this.initialized) return; try { // Get current values from stores - this.settings.accessibility = get(accessibilitySettings); - this.settings.ui = get(uiSettings); + this.settings.accessibility = get(this.accessibilitySettings); + this.settings.ui = get(this.uiSettings); localStorage.setItem(this.STORAGE_KEY, JSON.stringify(this.settings)); - console.log('Saved settings to localStorage:', this.settings); + console.log('Saved settings to localStorage'); this.emit('settingsSaved', this.settings); } catch (error) { - console.error('Failed to save settings to localStorage:', error); + console.error('Failed to save settings:', error); } } - /** - * Update accessibility settings - */ + // Update methods public updateAccessibilitySettings(newSettings: Partial): void { - accessibilitySettings.update(current => { - const updated = { ...current, ...newSettings }; - this.settings.accessibility = updated; - this.saveSettings(); - return updated; - }); - - this.emit('accessibilitySettingsUpdated', get(accessibilitySettings)); + this.accessibilitySettings.update(current => ({...current, ...newSettings})); } - /** - * Update UI settings - */ public updateUiSettings(newSettings: Partial): void { - uiSettings.update(current => { - const updated = { ...current, ...newSettings }; - this.settings.ui = updated; - this.saveSettings(); - return updated; - }); - - this.emit('uiSettingsUpdated', get(uiSettings)); + this.uiSettings.update(current => ({...current, ...newSettings})); } - /** - * Reset settings to defaults - */ + // Reset settings to defaults public resetSettings(): void { - // Create default settings - const defaultSettings: Settings = { + const defaults = { accessibility: { textToSpeech: false, highContrast: false, @@ -188,27 +202,19 @@ export class SettingsManager extends EventEmitter { } }; - // Update stores - accessibilitySettings.set(defaultSettings.accessibility); - uiSettings.set(defaultSettings.ui); - - // Update internal settings and save - this.settings = defaultSettings; - this.saveSettings(); - - this.emit('settingsReset', defaultSettings); + this.accessibilitySettings.set(defaults.accessibility); + this.uiSettings.set(defaults.ui); + this.emit('settingsReset', defaults); } - /** - * Import settings from a JSON string - */ + // Import/export public importSettings(json: string): void { try { const imported = JSON.parse(json); if (typeof imported === 'object' && imported !== null) { // Create a valid settings object with defaults for missing properties - const newSettings: Settings = { + const newSettings = { accessibility: { ...this.settings.accessibility, ...(imported.accessibility || {}) @@ -220,12 +226,11 @@ export class SettingsManager extends EventEmitter { }; // Update stores - accessibilitySettings.set(newSettings.accessibility); - uiSettings.set(newSettings.ui); + this.accessibilitySettings.set(newSettings.accessibility); + this.uiSettings.set(newSettings.ui); - // Update internal settings and save + // Update internal settings this.settings = newSettings; - this.saveSettings(); this.emit('settingsImported', newSettings); } @@ -235,13 +240,10 @@ export class SettingsManager extends EventEmitter { } } - /** - * Export settings to a JSON string - */ public exportSettings(): string { // Get current values from stores - this.settings.accessibility = get(accessibilitySettings); - this.settings.ui = get(uiSettings); + this.settings.accessibility = get(this.accessibilitySettings); + this.settings.ui = get(this.uiSettings); return JSON.stringify(this.settings, null, 2); } diff --git a/src/lib/stores/mudStore.ts b/src/lib/stores/mudStore.ts index 1e13a4a..ecd6b90 100644 --- a/src/lib/stores/mudStore.ts +++ b/src/lib/stores/mudStore.ts @@ -16,64 +16,27 @@ export const activeProfileId = writable(null); // Store for triggers export const triggers = writable([]); -// Store for MUD output history +// Store for MUD output history - keyed by profile ID export const outputHistory = writable<{ - id: string; - text: string; - timestamp: number; - isInput?: boolean; - highlights?: { pattern: string; color: string; isRegex: boolean }[] -}[]>([]); + [profileId: string]: { + id: string; + text: string; + timestamp: number; + isInput?: boolean; + highlights?: { pattern: string; color: string; isRegex: boolean }[] + }[]; +}>({}); // Store for connection status export const connectionStatus = writable<{ [key: string]: 'connected' | 'disconnected' | 'connecting' | 'error' }>({}); -// Store for accessibility settings -export const accessibilitySettings = writable({ - textToSpeech: false, - highContrast: false, - fontSize: 16, - lineSpacing: 1.2, - speechRate: 1, - speechPitch: 1, - speechVolume: 1, - interruptSpeechOnEnter: true // New setting for interrupting speech on Enter key -}); +// Use the stores from SettingsManager +export const accessibilitySettings = settingsManager.accessibilitySettings; +export const uiSettings = settingsManager.uiSettings; -// Store for UI settings -export const uiSettings = writable({ - isDarkMode: true, - showTimestamps: true, - showSidebar: true, - splitViewDirection: 'horizontal', // or 'vertical' - inputHistorySize: 100, - outputBufferSize: 1000, - ansiColor: true, - font: 'monospace', - debugGmcp: false, // Setting for GMCP debugging - globalVolume: 0.7 // Global volume control for sounds (0-1) -}); - -// Subscribe to settings changes to save to localStorage -accessibilitySettings.subscribe(value => { - // Skip during SSR - if (typeof window !== 'undefined') { - // Use a small timeout to batch multiple rapid changes - setTimeout(() => settingsManager.saveSettings(), 100); - } -}); - -uiSettings.subscribe(value => { - // Skip during SSR - if (typeof window !== 'undefined') { - // Use a small timeout to batch multiple rapid changes - setTimeout(() => settingsManager.saveSettings(), 100); - } -}); - -// Store for input history -export const inputHistory = writable([]); -export const inputHistoryIndex = writable(-1); +// Store for input history - keyed by profile ID +export const inputHistory = writable<{ [profileId: string]: string[] }>({}); +export const inputHistoryIndex = writable<{ [profileId: string]: number }>({}); // Derived store for active profile export const activeProfile = derived( @@ -93,6 +56,44 @@ export const activeConnection = derived( } ); +// Derived store for active output history +export const activeOutputHistory = derived( + [outputHistory, activeProfileId], + ([$outputHistory, $activeProfileId]) => { + // If we have an active profile, use its history + if ($activeProfileId && $outputHistory[$activeProfileId]) { + return $outputHistory[$activeProfileId]; + } + + // Otherwise fall back to the default profile's history or an empty array + return $outputHistory['default'] || []; + } +); + +// Derived store for active input history +export const activeInputHistory = derived( + [inputHistory, activeProfileId], + ([$inputHistory, $activeProfileId]) => { + // If we have an active profile, use its history + if ($activeProfileId && $inputHistory[$activeProfileId]) { + return $inputHistory[$activeProfileId]; + } + + // Otherwise fall back to the default profile's history or an empty array + return $inputHistory['default'] || []; + } +); + +// Derived store for active input history index +export const activeInputHistoryIndex = derived( + [inputHistoryIndex, activeProfileId], + ([$inputHistoryIndex, $activeProfileId]) => { + const targetProfileId = $activeProfileId || 'default'; + return $inputHistoryIndex[targetProfileId] !== undefined ? + $inputHistoryIndex[targetProfileId] : -1; + } +); + // Store for GMCP data export const gmcpData = writable<{ [module: string]: any }>({}); @@ -101,7 +102,17 @@ export const gmcpDebugLog = writable<{ id: string; module: string; data: any; ti // Helper functions export function addToOutputHistory(text: string, isInput = false, highlights: { pattern: string; color: string; isRegex: boolean }[] = []) { - outputHistory.update(history => { + const profileId = get(activeProfileId); + + outputHistory.update(allHistory => { + // Default profile ID for cases where there's no active profile + const targetProfileId = profileId || 'default'; + + // Initialize history for this profile if it doesn't exist + if (!allHistory[targetProfileId]) { + allHistory[targetProfileId] = []; + } + const maxSize = get(uiSettings).outputBufferSize; const newItem = { id: `output-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`, @@ -111,12 +122,15 @@ export function addToOutputHistory(text: string, isInput = false, highlights: { highlights }; - // Limit history size - const updatedHistory = [...history, newItem]; + // Limit history size for this profile + const updatedHistory = [...allHistory[targetProfileId], newItem]; if (updatedHistory.length > maxSize) { - return updatedHistory.slice(updatedHistory.length - maxSize); + allHistory[targetProfileId] = updatedHistory.slice(updatedHistory.length - maxSize); + } else { + allHistory[targetProfileId] = updatedHistory; } - return updatedHistory; + + return allHistory; }); } @@ -163,30 +177,56 @@ export function logGmcpMessage(module: string, data: any) { } export function addToInputHistory(text: string) { - inputHistory.update(history => { + const profileId = get(activeProfileId); + + inputHistory.update(allHistory => { + // Default profile ID for cases where there's no active profile + const targetProfileId = profileId || 'default'; + + // Initialize history for this profile if it doesn't exist + if (!allHistory[targetProfileId]) { + allHistory[targetProfileId] = []; + } + // Don't add empty strings or duplicates of the last command - if (!text || (history.length > 0 && history[history.length - 1] === text)) { - return history; + if (!text || (allHistory[targetProfileId].length > 0 && allHistory[targetProfileId][allHistory[targetProfileId].length - 1] === text)) { + return allHistory; } const maxSize = get(uiSettings).inputHistorySize; - const updatedHistory = [...history, text]; + const updatedHistory = [...allHistory[targetProfileId], text]; // Limit history size if (updatedHistory.length > maxSize) { - return updatedHistory.slice(updatedHistory.length - maxSize); + allHistory[targetProfileId] = updatedHistory.slice(updatedHistory.length - maxSize); + } else { + allHistory[targetProfileId] = updatedHistory; } - return updatedHistory; + return allHistory; }); // Reset history index to point to the end - inputHistoryIndex.set(-1); + setInputHistoryIndex(profileId || 'default', -1); +} + +// Helper to set input history index for a specific profile +function setInputHistoryIndex(profileId: string, index: number) { + inputHistoryIndex.update(indices => ({ + ...indices, + [profileId]: index + })); } export function navigateInputHistory(direction: 'up' | 'down', currentInput: string) { - const history = get(inputHistory); - let index = get(inputHistoryIndex); + const profileId = get(activeProfileId); + const targetProfileId = profileId || 'default'; + + const allHistory = get(inputHistory); + const history = allHistory[targetProfileId] || []; + + const allIndices = get(inputHistoryIndex); + let index = allIndices[targetProfileId] !== undefined ? allIndices[targetProfileId] : -1; if (history.length === 0) return currentInput; @@ -194,8 +234,13 @@ export function navigateInputHistory(direction: 'up' | 'down', currentInput: str // If we're at the beginning of navigation, save the current input if (index === -1) { inputHistory.update(h => { - if (currentInput && h[h.length - 1] !== currentInput) { - return [...h, currentInput]; + // Initialize if needed + if (!h[targetProfileId]) { + h[targetProfileId] = []; + } + + if (currentInput && h[targetProfileId].length > 0 && h[targetProfileId][h[targetProfileId].length - 1] !== currentInput) { + h[targetProfileId] = [...h[targetProfileId], currentInput]; } return h; }); @@ -208,7 +253,8 @@ export function navigateInputHistory(direction: 'up' | 'down', currentInput: str index = Math.max(-1, index - 1); } - inputHistoryIndex.set(index); + // Update the index for this profile + setInputHistoryIndex(targetProfileId, index); // Return appropriate value from history or empty string if (index === -1) { @@ -219,7 +265,14 @@ export function navigateInputHistory(direction: 'up' | 'down', currentInput: str } export function clearOutputHistory() { - outputHistory.set([]); + const profileId = get(activeProfileId); + const targetProfileId = profileId || 'default'; + + outputHistory.update(allHistory => { + // Clear only the current profile's history + allHistory[targetProfileId] = []; + return allHistory; + }); } export function updateGmcpData(module: string, data: any) { diff --git a/src/lib/utils/ModalHelper.ts b/src/lib/utils/ModalHelper.ts index 591890e..c02e0d1 100644 --- a/src/lib/utils/ModalHelper.ts +++ b/src/lib/utils/ModalHelper.ts @@ -1,4 +1,4 @@ -import { ProfileManager } from '$lib/profiles/ProfileManager'; +// No need to import ProfileManager here import { get } from 'svelte/store'; import { activeProfile } from '$lib/stores/mudStore'; import type { MudProfile } from '$lib/profiles/ProfileManager'; @@ -12,7 +12,6 @@ import TriggerEditor from '$lib/components/TriggerEditor.svelte'; */ export class ModalHelper { private static modal: Modal | null = null; - private static profileManager = new ProfileManager(); /** * Show the full-featured profile editor modal @@ -57,8 +56,31 @@ export class ModalHelper { throw new Error('Failed to create modal instance'); } - // Get profile to edit or create new one - const profile = existingProfile || this.profileManager.createDefaultProfile(); + // Get profile to edit or use the default empty profile + const profile = existingProfile || { + id: `profile-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`, + name: 'New Profile', + host: 'mud.example.com', + port: 23, + useSSL: false, + ansiColor: true, + autoLogin: { + enabled: false, + username: '', + password: '', + commands: [] + }, + aliases: {}, + macros: {}, + gmcpPackages: [], + accessibilityOptions: { + textToSpeech: false, + highContrast: false, + speechRate: 1, + speechPitch: 1, + speechVolume: 1 + } + }; const isNewProfile = !existingProfile; console.log('Setting up modal with profile:', profile); diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 24cb11b..f43cff7 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -68,38 +68,58 @@ onMount(() => { console.log('Page mounted'); - // Initialize profile manager - profileManager = new ProfileManager(); - console.log('Profile manager initialized'); - - // Initialize trigger system - triggerSystem = new TriggerSystem(); - console.log('Trigger system initialized'); - - // Load profiles - loadProfiles(); - - // Load triggers - loadTriggers(); - - // Check URL parameters for debug mode - checkUrlParams(); - - // Subscribe to profile manager events for real-time updates - profileManager.on('profileAdded', () => { - console.log('Profile added event detected'); + try { + console.log('Starting initialization'); + // Initialize profile manager + profileManager = new ProfileManager(); + console.log('Profile manager initialized'); + + // Initialize trigger system + triggerSystem = new TriggerSystem(); + console.log('Trigger system initialized'); + + // Load profiles first to ensure we have them + console.log('Loading profiles...'); loadProfiles(); - }); - - profileManager.on('profileUpdated', () => { - console.log('Profile updated event detected'); - loadProfiles(); - }); - - profileManager.on('profileRemoved', () => { - console.log('Profile removed event detected'); - loadProfiles(); - }); + console.log('Profiles loaded, count:', $profiles.length); + + // Then load triggers + loadTriggers(); + + // Check URL parameters for debug mode + checkUrlParams(); + + // Subscribe to profile manager events for real-time updates + profileManager.on('profileAdded', () => { + console.log('Profile added event detected'); + loadProfiles(); + }); + + profileManager.on('profileUpdated', () => { + console.log('Profile updated event detected'); + loadProfiles(); + }); + + profileManager.on('profileRemoved', () => { + console.log('Profile removed event detected'); + loadProfiles(); + }); + + // Ensure settings are properly loaded and initialized + console.log('Initial profiles state:', $profiles); + console.log('Active profile ID:', $activeProfileId); + + // Make sure we have an active profile selected if any profiles exist + if ($profiles.length > 0 && !$activeProfileId) { + console.log('No active profile selected, setting first profile as active'); + activeProfileId.set($profiles[0].id); + } + } catch (error) { + console.error('Error during page initialization:', error); + console.error('Error details:', error.message, error.stack); + // Provide user feedback about the error + addToOutputHistory(`Error initializing client: ${error.message}. Please reload the page.`); + } }); // Check URL for debug parameters @@ -128,13 +148,63 @@ // Load profiles from manager function loadProfiles() { - const allProfiles = profileManager.getProfiles(); - console.log('Loaded profiles:', allProfiles); // Debug - profiles.set(allProfiles); - - // Set active profile if available and not already set - if (!$activeProfileId && allProfiles.length > 0) { - activeProfileId.set(allProfiles[0].id); + try { + if (!profileManager) { + console.error('Profile manager not initialized'); + return; + } + + // Get all profiles from the manager + const allProfiles = profileManager.getProfiles(); + console.log('Loaded profiles from manager:', allProfiles); + + // Create a default profile if none exist + if (allProfiles.length === 0) { + console.log('No profiles found, creating default profile'); + const defaultProfile = profileManager.createDefaultProfile(); + defaultProfile.name = 'Aardwolf MUD'; + defaultProfile.host = 'aardmud.org'; + defaultProfile.port = 23; + profileManager.addProfile(defaultProfile); + + // Get profiles again after adding the default one + const updatedProfiles = profileManager.getProfiles(); + console.log('Profiles after adding default:', updatedProfiles); + profiles.set(updatedProfiles); + + // Set this as the active profile + if (updatedProfiles.length > 0) { + activeProfileId.set(updatedProfiles[0].id); + } + } else { + // Update the profiles store + profiles.set(allProfiles); + + // Set active profile if available and not already set + if (!$activeProfileId && allProfiles.length > 0) { + console.log('Setting active profile to:', allProfiles[0].id); + activeProfileId.set(allProfiles[0].id); + } + } + + // If active profile ID is set but no longer exists in profiles, reset it + if ($activeProfileId && !allProfiles.some(p => p.id === $activeProfileId)) { + console.log('Active profile no longer exists, resetting'); + if (allProfiles.length > 0) { + activeProfileId.set(allProfiles[0].id); + } else { + activeProfileId.set(null); + } + } + + // Add a default message to the output history so users see something + if (allProfiles.length > 0) { + addToOutputHistory('\nWelcome to SvelteMUD Client!\n\nSelect a profile from the Profiles tab and click Connect to begin.\n\n'); + } + } catch (error) { + console.error('Error loading profiles:', error); + console.error('Error details:', error.message, error.stack); + addToOutputHistory(`Error loading profiles: ${error.message}`); } }