Files
svelte-mud/src/lib/utils/ModalHelper.ts
2025-04-22 13:54:57 +02:00

207 lines
6.2 KiB
TypeScript

// No need to import ProfileManager here
import { get } from 'svelte/store';
import { activeProfile } from '$lib/stores/mudStore';
import type { MudProfile } from '$lib/profiles/ProfileManager';
import type { Trigger } from '$lib/triggers/TriggerSystem';
import Modal from '$lib/components/Modal.svelte';
import ProfileEditor from '$lib/components/ProfileEditor.svelte';
import TriggerEditor from '$lib/components/TriggerEditor.svelte';
/**
* Helper class for creating and showing modals programmatically
*/
export class ModalHelper {
private static modal: Modal | null = null;
/**
* Show the full-featured profile editor modal
* @param onSave Callback when profile is saved
* @param onCancel Callback when operation is cancelled
* @param existingProfile Optional existing profile to edit
*/
static showProfileEditor(
onSave: (profile: MudProfile) => void,
onCancel: () => void,
existingProfile?: MudProfile
): void {
console.log('ModalHelper.showProfileEditor called');
try {
// Make sure document.body is available
if (!document.body) {
throw new Error('document.body is not available');
}
// Destroy existing modal if it exists to prevent memory leaks
if (this.modal) {
try {
this.modal.$destroy();
} catch (error) {
console.error('Error destroying previous modal:', error);
}
this.modal = null;
}
// Create a new modal instance
console.log('Creating new Modal instance');
this.modal = new Modal({
target: document.body,
props: {
closable: true,
title: '',
}
});
if (!this.modal) {
throw new Error('Failed to create modal instance');
}
// 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);
// Set up the modal with a short delay to ensure the DOM is ready
setTimeout(() => {
if (this.modal) {
// Set up the modal
this.modal.setProps({
title: isNewProfile ? 'Create New Profile' : 'Edit Profile',
component: ProfileEditor,
componentProps: {
profile,
isNewProfile
},
onSubmit: (result) => {
console.log('Modal submit callback with result:', result);
onSave(result.profile);
},
onCancel: () => {
console.log('Modal cancel callback');
onCancel();
}
});
// Open the modal
this.modal.open();
console.log('Modal opened');
} else {
console.error('Modal instance was destroyed before it could be opened');
}
}, 50);
} catch (error) {
console.error('Error in showProfileEditor:', error);
// Call onCancel to ensure the flow continues even if there's an error
onCancel();
throw error; // Re-throw to allow +page.svelte to handle it
}
}
/**
* Show the trigger editor modal
* @param onSave Callback when trigger is saved
* @param onCancel Callback when operation is cancelled
* @param existingTrigger Optional existing trigger to edit
*/
static showTriggerEditor(
onSave: (trigger: Trigger) => void,
onCancel: () => void,
existingTrigger?: Trigger
): void {
console.log('ModalHelper.showTriggerEditor called');
try {
// Make sure document.body is available
if (!document.body) {
throw new Error('document.body is not available');
}
// Destroy existing modal if it exists to prevent memory leaks
if (this.modal) {
try {
this.modal.$destroy();
} catch (error) {
console.error('Error destroying previous modal:', error);
}
this.modal = null;
}
// Create a new modal instance
console.log('Creating new Modal instance');
this.modal = new Modal({
target: document.body,
props: {
closable: true,
title: '',
}
});
if (!this.modal) {
throw new Error('Failed to create modal instance');
}
const isNewTrigger = !existingTrigger;
console.log('Setting up trigger modal:', existingTrigger || 'new trigger');
// Set up the modal with a short delay to ensure the DOM is ready
setTimeout(() => {
if (this.modal) {
// Set up the modal
this.modal.setProps({
title: isNewTrigger ? 'Create New Trigger' : 'Edit Trigger',
component: TriggerEditor,
componentProps: {
trigger: existingTrigger || null,
isNew: isNewTrigger
},
onSubmit: (result) => {
console.log('Modal submit callback with result:', result);
onSave(result.trigger);
},
onCancel: () => {
console.log('Modal cancel callback');
onCancel();
}
});
// Open the modal
this.modal.open();
console.log('Modal opened');
} else {
console.error('Modal instance was destroyed before it could be opened');
}
}, 50);
} catch (error) {
console.error('Error in showTriggerEditor:', error);
// Call onCancel to ensure the flow continues even if there's an error
onCancel();
throw error; // Re-throw to allow +page.svelte to handle it
}
}
}