devportal2 / static /js /editor.js
akborana4's picture
Create static/js/editor.js
002b4a7 verified
// static/js/editor.js
let editor;
function initEditor() {
if (!document.getElementById("ace-editor")) return;
// Initialize Ace
editor = ace.edit("ace-editor");
editor.setTheme("ace/theme/tomorrow_night_eighties"); // Deep dark theme matching mockups
editor.session.setMode("ace/mode/python");
editor.setOptions({
fontSize: "14px",
fontFamily: "var(--font-mono)",
showPrintMargin: false,
enableBasicAutocompletion: true
});
// Load files immediately after init
loadFiles();
}
async function loadFiles() {
if (!currentToken) return;
try {
const res = await fetch('/api/files', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({token: currentToken})
});
const data = await res.json();
const list = document.getElementById('file-list');
if(!list) return;
list.innerHTML = '';
if (data.files && data.files.length > 0) {
data.files.forEach(f => {
const div = document.createElement('div');
div.className = 'file-item';
div.innerHTML = `📄 ${f}`;
div.onclick = () => openFile(f);
list.appendChild(div);
});
} else {
list.innerHTML = `<div style="color: var(--text-muted); font-size: 12px; text-align: center; margin-top: 20px;">No files yet. Click + New</div>`;
}
} catch(e) {
console.error("Failed to load files", e);
}
}
function newFile() {
document.getElementById('current-filename').value = "untitled.txt";
if(editor) {
editor.setValue("", -1);
editor.session.setMode("ace/mode/text");
editor.focus();
}
}
async function openFile(filename) {
document.getElementById('current-filename').value = filename;
try {
const res = await fetch('/api/file/read', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({token: currentToken, filename: filename})
});
const data = await res.json();
if(!data.error && editor) {
editor.setValue(data.content, -1);
// Set Syntax Highlighting
if(filename.endsWith('.py')) editor.session.setMode("ace/mode/python");
else if(filename.endsWith('.js')) editor.session.setMode("ace/mode/javascript");
else if(filename.endsWith('.html')) editor.session.setMode("ace/mode/html");
else if(filename.endsWith('.css')) editor.session.setMode("ace/mode/css");
else if(filename.endsWith('.json')) editor.session.setMode("ace/mode/json");
else editor.session.setMode("ace/mode/text");
}
} catch (e) {
alert("Network error reading file.");
}
}
async function saveFile() {
const filename = document.getElementById('current-filename').value;
const content = editor ? editor.getValue() : "";
if(!filename) {
alert("Please enter a filename");
return;
}
const saveBtn = document.querySelector('.editor-btn.primary');
saveBtn.innerText = "Saving...";
try {
const res = await fetch('/api/file/save', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({token: currentToken, filename: filename, content: content})
});
const data = await res.json();
if(data.success) {
saveBtn.innerText = "✓ Saved";
setTimeout(() => saveBtn.innerText = "💾 Save", 2000);
loadFiles(); // Refresh list just in case it's a new file
} else {
alert("Error saving: " + data.error);
saveBtn.innerText = "💾 Save";
}
} catch(e) {
alert("Network error while saving.");
saveBtn.innerText = "💾 Save";
}
}
async function renameFile() {
const newName = prompt("Enter new filename:");
if(!newName) return;
const oldName = document.getElementById('current-filename').value;
try {
await fetch('/api/file/rename', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({token: currentToken, filename: oldName, new_name: newName})
});
document.getElementById('current-filename').value = newName;
loadFiles();
} catch (e) {
alert("Error renaming file.");
}
}
async function aiEdit() {
const promptStr = prompt("✨ AI Edit: What should the AI do to this code? (e.g., 'Fix the loop bug', 'Add comments')");
if(!promptStr || !editor) return;
const originalCode = editor.getValue();
editor.setValue("✨ AI is analyzing and rewriting your code... please wait.", -1);
try {
const res = await fetch('/api/ai_edit', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({prompt: promptStr, content: originalCode})
});
const data = await res.json();
if(data.code && !data.code.includes("NETWORK_ERROR")) {
editor.setValue(data.code, -1);
} else {
editor.setValue(originalCode, -1);
alert("AI Edit failed: \n" + (data.code || "Unknown error"));
}
} catch(e) {
editor.setValue(originalCode, -1);
alert("Network error during AI edit.");
}
}