import { api } from '../api.js'; class CodeEditorView extends HTMLElement { constructor() { super(); this.editor = null; this.file = null; this.previousView = null; this.boundHandleClick = this.handleClick.bind(this); this.boundHandleEscape = this.handleEscape.bind(this); } connectedCallback() { this.addEventListener('click', this.boundHandleClick); document.addEventListener('keydown', this.boundHandleEscape); } disconnectedCallback() { this.removeEventListener('click', this.boundHandleClick); document.removeEventListener('keydown', this.boundHandleEscape); if (this.editor) { this.editor.toTextArea(); this.editor = null; } } handleEscape(e) { if (e.key === 'Escape') { this.goBack(); } } async setFile(file, previousView = 'files') { this.file = file; this.previousView = previousView; await this.loadAndRender(); } async loadAndRender() { try { const blob = await api.downloadFile(this.file.id); const content = await blob.text(); this.render(content); this.initializeEditor(content); } catch (error) { console.error('Failed to load file:', error); document.dispatchEvent(new CustomEvent('show-toast', { detail: { message: 'Failed to load file: ' + error.message, type: 'error' } })); this.render(''); window.history.back(); } } getMimeType(filename) { const extension = filename.split('.').pop().toLowerCase(); const mimeMap = { 'js': 'text/javascript', 'json': 'application/json', 'py': 'text/x-python', 'md': 'text/x-markdown', 'html': 'text/html', 'xml': 'application/xml', 'css': 'text/css', 'txt': 'text/plain', 'log': 'text/plain', 'sh': 'text/x-sh', 'yaml': 'text/x-yaml', 'yml': 'text/x-yaml' }; return mimeMap[extension] || 'text/plain'; } render(content) { this.innerHTML = `

${this.file.name}

`; } initializeEditor(content) { const textarea = this.querySelector('#code-editor-textarea'); if (!textarea) return; this.editor = CodeMirror.fromTextArea(textarea, { value: content, mode: this.getMimeType(this.file.name), lineNumbers: true, theme: 'default', lineWrapping: true, indentUnit: 4, indentWithTabs: false, extraKeys: { 'Ctrl-S': () => this.save(), 'Cmd-S': () => this.save() } }); this.editor.setSize('100%', '100%'); } handleClick(e) { if (e.target.id === 'back-btn') { this.goBack(); } else if (e.target.id === 'save-btn') { this.save(); } } async save() { if (!this.editor) return; try { const content = this.editor.getValue(); await api.updateFile(this.file.id, content); document.dispatchEvent(new CustomEvent('show-toast', { detail: { message: 'File saved successfully!', type: 'success' } })); } catch (error) { document.dispatchEvent(new CustomEvent('show-toast', { detail: { message: 'Failed to save file: ' + error.message, type: 'error' } })); } } goBack() { window.history.back(); } hide() { document.removeEventListener('keydown', this.boundHandleEscape); if (this.editor) { this.editor.toTextArea(); this.editor = null; } this.remove(); } } customElements.define('code-editor-view', CodeEditorView); export { CodeEditorView };