Files
hsa/code-server-like/templates/index.html
2025-09-21 15:33:00 +08:00

197 lines
9.1 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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://cdnjs.cloudflare.com/ajax/libs/xterm/5.5.0/xterm.css" />
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/xterm/5.5.0/xterm.js"></script> -->
<script src="https://unpkg.com/xterm@3.6.0/dist/xterm.js"></script>
<script src="https://unpkg.com/xterm@3.6.0/dist/addons/fit/fit.js"></script>
<script src="https://unpkg.com/xterm@3.6.0/dist/addons/webLinks/webLinks.js"></script>
<script src="https://unpkg.com/xterm@3.6.0/dist/addons/fullscreen/fullscreen.js"></script>
<script src="https://unpkg.com/xterm@3.6.0/dist/addons/search/search.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="/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">
</div>
<!-- 终端部分 -->
<span style="font-size: small;">status: <span style="font-size: small;" id="status">connecting...</span></span>
<div id="terminal">
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.0/min/vs/loader.js"></script>
<script src="/vsc-like/static/js/code-like-extension.js"></script>
<script src="/vsc-like/static/js/file.js"></script>
<script src="/vsc-like/static/js/terminal.js"></script>
<script>
window.lesson_data = {
course_id:'{{course_id}}',
chapter_name:'{{chapter_name}}',
lesson_name:'{{lesson_name}}'
}
let code_like_config = JSON.parse('{{code_like_config}}'.replace(/&#39;/g,'"'))
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');
// 监听文本编辑事件
editor.onDidChangeModelContent(event => {
const filePath = selectedItem.path + '/' +selectedItem.name;
const changes = event.changes;
console.log("changes",changes)
// 检查是否有大段文本插入,判断为粘贴操作
changes.forEach(change => {
if (change.text.length > 20 && !change.rangeLength) { // 设置长度阈值为20字符且非删除操作
console.log(`Detected paste action in file ${filePath}. Sending content...`);
sendToServer({
type: 'paste',
filePath: filePath,
content: change.text,
config: code_like_config,
});
}
});
// 防抖处理非粘贴的编辑操作
const content = changes.text;
debounceSendToServer({
type: 'fileEdit',
filePath: filePath,
content: content,
config: code_like_config,
}, 5000
);
});
// 监听粘贴事件
editor.onDidPaste(function(event) {
console.log('Paste event: ', event); // 这里你可以调用自定义的粘贴逻辑
});
// 切换全局搜索侧栏
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) {
// document.getElementById('terminal').style.display = 'block';
if (document.getElementById('terminal').style.display === 'none' || document.getElementById('terminal').style.display === '') {
document.getElementById('terminal').style.display = 'block';
}else{
document.getElementById('terminal').style.display = 'none';
}
// 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>