📜
filemanager_copy4.js
Back
📝 Javascript ⚡ Executable Ctrl+S: Save • Ctrl+R: Run • Ctrl+F: Find
(function(){ const FileManager = { id: "fileManager", label: "📁 File Manager", html: ` <div class="fm-container"> <div class="fm-toolbar"> <div class="fm-left" data-toolbar></div> <span id="fmStatus" class="fm-status">Loading...</span> </div> <div id="fmList" class="fm-list"></div> </div> `, toolbar: [ { id: "up", label: "⬅️ Up", action: "goUpDirectory" }, { id: "refresh", label: "🔄 Refresh", action: "reload" } ], currentPath: "/", async onRender(el) { this.el = el; this.renderToolbar(); await this.loadFiles("/"); }, renderToolbar() { const bar = this.el.querySelector("[data-toolbar]"); bar.innerHTML = ""; this.toolbar.forEach(btn => { const el = document.createElement("button"); el.className = "fm-btn"; el.textContent = btn.label; el.addEventListener("click", () => this.runAction(btn.action)); bar.appendChild(el); }); }, runAction(action) { if (FileManagerActions[action]) FileManagerActions[action](this); }, async loadFiles(path="/") { const fmList = this.el.querySelector("#fmList"); const fmStatus = this.el.querySelector("#fmStatus"); fmList.innerHTML = `<p style="color:#94a3b8;">Loading ${path}...</p>`; fmStatus.textContent = `Loading ${path}...`; this.currentPath = path; try { const res = await fetch("SFTPconnector.php", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ action: "list", path }) }); const text = await res.text(); let data; try { data = JSON.parse(text); } catch { throw new Error("Server returned non-JSON:\n" + text); } if (!data.success) throw new Error(data.message); this.renderFiles(data.data); fmStatus.textContent = `Path: ${path} (${data.data.length} items)`; } catch (err) { fmList.innerHTML = `<p style="color:#ef4444;">${err.message}</p>`; fmStatus.textContent = "Error loading files"; } }, renderFiles(files) { const fmList = this.el.querySelector("#fmList"); fmList.innerHTML = ""; if (!files || files.length === 0) { fmList.innerHTML = `<p>No files found.</p>`; return; } files.forEach(f => { const div = document.createElement("div"); div.className = "fm-item"; div.innerHTML = ` <div class="fm-name">${f.is_dir ? "📁" : "📄"} ${f.name}</div> <div class="fm-meta">${f.is_dir ? "Folder" : this.formatBytes(f.size)} • ${f.modified}</div> `; // Folder click = open next directory if (f.is_dir) { div.querySelector(".fm-name").addEventListener("click", () => { const newPath = this.currentPath.endsWith("/") ? this.currentPath + f.name : this.currentPath + "/" + f.name; this.loadFiles(newPath); }); } fmList.appendChild(div); }); }, formatBytes(bytes) { if (!bytes) return ""; if (bytes < 1024) return bytes + " B"; const units = ["KB", "MB", "GB", "TB"]; let u = -1; do { bytes /= 1024; ++u; } while (bytes >= 1024 && u < units.length - 1); return bytes.toFixed(1) + " " + units[u]; } }; const FileManagerActions = { reload: ctx => ctx.loadFiles(ctx.currentPath), goUpDirectory: ctx => { const parts = ctx.currentPath.split("/").filter(Boolean); parts.pop(); const newPath = "/" + parts.join("/"); ctx.loadFiles(newPath || "/"); } }; window.AppItems = window.AppItems || []; window.AppItems.push(FileManager); })();