1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
{{define "body-files"}}
<div class="editor-container">
<div class="editor-list" id="fileList">
<div class="search-bar"><input placeholder="Filter files..." oninput="filterFiles(this.value)"></div>
<div id="listEntries"></div>
</div>
<div class="editor-main" id="editorMain">
<p style="color:#888;text-align:center;margin-top:60px">Select a file to edit</p>
</div>
</div>
<script>
var currentPath = '';
window._allFiles = [];
function loadFiles(path) {
currentPath = path || '';
API.get('/api/files' + (path ? '?path=' + encodeURIComponent(path) : '')).then(function(r){
var files = r.files || r || [];
window._allFiles = files;
renderFileList('');
}).catch(function(e){notify('Failed: '+e.message,'error')});
}
function renderFileList(filter){
var el = $('#listEntries');
var f = filter.toLowerCase();
var items = window._allFiles.filter(function(x){ return !f || x.name.toLowerCase().indexOf(f) >= 0; });
var html = '<div class="item" onclick="loadFiles(\'\')" style="color:#6cf">[root]</div>';
if (currentPath) {
var parent = currentPath.split('/').slice(0,-1).join('/');
html += '<div class="item" onclick="loadFiles(\''+escJs(parent)+'\')" style="color:#6cf">[..]</div>';
}
items.forEach(function(x){
if (x.dir) {
var sub = currentPath ? currentPath + '/' + x.name : x.name;
html += '<div class="item" onclick="loadFiles(\''+escJs(sub)+'\')" style="color:#fc6">'+escHtml(x.name)+'/</div>';
} else {
var fp = currentPath ? currentPath + '/' + x.name : x.name;
html += '<div class="item" onclick="loadFileContent(\''+escJs(fp)+'\',\''+escJs(x.name)+'\')">'+escHtml(x.name)+'</div>';
}
});
el.innerHTML = html;
}
function filterFiles(val) { renderFileList(val); }
function loadFileContent(path, name) {
currentPath = path;
API.get('/api/files?path=' + encodeURIComponent(path)).then(function(r){
var content = r.content || r.raw || JSON.stringify(r,null,2);
var html = '<h2>'+escHtml(name)+'</h2>';
html += '<div class="form-group"><label>Path</label><span style="font-size:11px;color:#888">'+escHtml(path)+'</span></div>';
html += '<textarea id="fileContent" rows="20" style="width:100%;font-family:monospace;font-size:12px;background:var(--input-bg);color:var(--text);border:1px solid var(--input-border);padding:8px">'+escHtml(content)+'</textarea>';
html += '<div class="btn-row"><button class="btn btn-primary" onclick="saveFile(\''+escJs(path)+'\')">Save</button></div>';
$('#editorMain').innerHTML = html;
}).catch(function(e){notify('Failed: '+e.message,'error')});
}
function saveFile(path) {
var content = $('#fileContent').value;
fetch('/api/files?path=' + encodeURIComponent(path), {
method: 'PUT',
headers: {'Content-Type': 'text/plain'},
body: content,
credentials: 'same-origin'
}).then(function(r) {
if (!r.ok) throw new Error('Save failed');
return r.json();
}).then(function() {
notify('File saved', 'success');
updateUndoBar();
}).catch(function(e) { notify('Save failed: '+e.message, 'error'); });
}
window.refreshPage = function() { loadFiles(currentPath); };
function escHtml(s) { return String(s||'').replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"'); }
function escJs(s) { return String(s||'').replace(/\\/g,'\\\\').replace(/'/g,"\\'").replace(/"/g,'\\"'); }
loadFiles('');
</script>
{{end}}
|