Files
hsa/code-server-like/templates/index.html
2025-09-15 19:35:01 +08:00

148 lines
6.4 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Cloud IDE</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.0/min/vs/editor/editor.main.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.5.1/socket.io.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xterm@4.15.0/dist/xterm.css">
<link rel="stylesheet" href="/vsc-like/static/css/index.css">
</head>
<body>
<div id="container">
<div id="fileTree" onclick="selectEmpty(this)">
<div id="topbar">
<button id="newFileBtn"><i class="fas fa-file"></i></button>
<button id="newFolderBtn"><i class="fas fa-folder"></i></button>
<button id="toggleSearchBtn"><i class="fas fa-search"></i></button>
<button id="refreshBtn"><i class="fas fa-sync-alt"></i></button>
<button id="saveBtn"><i class="fas fa-save"></i></button>
<button id="openTerminalBtn"><i class="fas fa-terminal"></i></button>
</div>
<div id="fileTreeContent"></div>
<div id="searchSidebar">
<h3>Global Search</h3>
<input type="text" id="searchInput" placeholder="Search..." oninput="searchFiles()">
<ul id="searchResults"></ul>
</div>
</div>
<!-- 右键菜单 -->
<div id="contextMenu" class="context-menu" style="display: none;">
<ul>
<li id="renameOption">Rename</li>
<li id="copyOption">Copy</li>
<li id="pasteOption">Paste</li>
<li id="deleteOption">Delete</li>
</ul>
</div>
<div id="contentArea">
<!-- 编辑器部分 -->
<div id="editorContainer">
<h3>Editor</h3>
<textarea style="width: 100%; height: 100%;"></textarea>
</div>
<!-- 终端部分 -->
<div id="terminal">
<h3>Terminal</h3>
<div id="terminalContent"></div>
</div>
</div>
</div>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.0/min/vs/loader.js"></script>
<script src="/vsc-like/static/js/file.js"></script>
<script src="/vsc-like/static/js/terminal.js"></script>
<script>
require.config({ paths: { vs: 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.0/min/vs' } });
require(['vs/editor/editor.main'], function() {
editor = monaco.editor.create(document.getElementById('editorContainer'), {
value: '',
language: 'javascript'
});
const fileTreeDiv = document.getElementById('fileTreeContent');
const searchSidebar = document.getElementById('searchSidebar');
const searchInput = document.getElementById('searchInput');
const searchResults = document.getElementById('searchResults');
const saveBtn = document.getElementById('saveBtn');
const openTerminalBtn = document.getElementById('openTerminalBtn');
// 切换全局搜索侧栏
function toggleSearchSidebar(event) {
event.stopPropagation();
searchSidebar.style.display = (searchSidebar.style.display === 'none' || searchSidebar.style.display === '') ? 'block' : 'none';
if (searchSidebar.style.display === 'block') {
fileTreeDiv.style.display = 'none';
}
else{
fileTreeDiv.style.display = 'block';
}
}
// 刷新文件树
function refreshFileTree(event) {
event.stopPropagation();
loadFileTree();
}
// 搜索文件
function searchFiles() {
const query = searchInput.value;
fetch(`/vsc-like/search-files?query=${query}`)
.then(response => response.json())
.then(data => {
searchResults.innerHTML = '';
data.forEach(result => {
const li = document.createElement('li');
li.textContent = result.name;
li.onclick = () => loadFileContent(result);
searchResults.appendChild(li);
});
});
}
let socket = null;
function openTerminal(event) {
event.stopPropagation();
const terminalDiv = document.getElementById('terminal');
terminalDiv.style.display = (terminalDiv.style.display === 'none' || terminalDiv.style.display === '') ? 'block' : 'none';
if (socket == null) {
socket = io.connect('http://' + document.domain + ':5200/vsc-like/terminal');
}
socket.on('connected', function(data) {
console.log('Terminal connected');
});
socket.on('terminal_output', function(data) {
const terminalDiv = document.getElementById('terminal');
terminalDiv.textContent += data.data;
});
function sendTerminalInput(input) {
socket.emit('send_input', { input: input });
}
}
// 按钮绑定事件
document.getElementById('newFileBtn').addEventListener('click', (event) => createNewFile(event));
document.getElementById('newFolderBtn').addEventListener('click', (event) => createNewFolder(event));
document.getElementById('toggleSearchBtn').addEventListener('click', (event) => toggleSearchSidebar(event));
document.getElementById('refreshBtn').addEventListener('click', (event) => refreshFileTree(event));
document.getElementById('saveBtn').addEventListener('click', (event) => saveFile(event));
document.getElementById('openTerminalBtn').addEventListener('click', (event) => openTerminal(event));
loadFileTree();
});
</script>
</body>
</html>