fix: 修复前端多个问题
- 修复 favicon 未加载:构建脚本未内联 public/favicon.svg - 修复终端重连残留:断开连接后清空终端内容和状态 - 修复 sz 下载文件损坏:将 Uint8Array 转为普通数组传给 save_to_disk - 修复 rz 上传失败:input 元素过早移除导致 onchange 无法触发
This commit is contained in:
1 parent
0871b64426
commit
bdc8d0da17
3 files changed
+41
-6
No files matched your search
@@ -113,6 +113,11 @@ export class SSHTerminal {
|
||||
|
||||
async connect(config: SSHConnectionConfig): Promise<void> {
|
||||
this.lastConfig = config;
|
||||
this.terminal.clear();
|
||||
|
||||
const termStatus = document.getElementById('term-status');
|
||||
if (termStatus) termStatus.innerHTML = '<div class="w-2 h-2 bg-primary-container animate-pulse"></div> Connected';
|
||||
|
||||
const wsUrl = new URL(window.location.href);
|
||||
wsUrl.protocol = wsUrl.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||
wsUrl.pathname = '/api/ssh';
|
||||
@@ -156,6 +161,10 @@ export class SSHTerminal {
|
||||
connectWithWebSocket(ws: WebSocket): void {
|
||||
this.lastConfig = null;
|
||||
this.ws = ws;
|
||||
this.terminal.clear();
|
||||
|
||||
const termStatus = document.getElementById('term-status');
|
||||
if (termStatus) termStatus.innerHTML = '<div class="w-2 h-2 bg-primary-container animate-pulse"></div> Connected';
|
||||
|
||||
ws.onopen = () => {
|
||||
this.terminal.writeln('\x1b[32m[+] WebSocket connected, authenticating...\x1b[0m');
|
||||
@@ -301,6 +310,8 @@ export class SSHTerminal {
|
||||
this.ws = null;
|
||||
this.disposables.forEach(d => d.dispose());
|
||||
this.disposables = [];
|
||||
this.lastConfig = null;
|
||||
this.terminal.clear();
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
|
||||
@@ -55,9 +55,9 @@ export class ZmodemHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
const packets: Array<Uint8Array> = [];
|
||||
const packets: Array<number>[] = [];
|
||||
xfer.on('input', (payload: Uint8Array) => {
|
||||
packets.push(payload);
|
||||
packets.push(Array.from(payload));
|
||||
});
|
||||
|
||||
xfer.accept().then(() => {
|
||||
@@ -89,14 +89,27 @@ export class ZmodemHandler {
|
||||
}
|
||||
}).then(() => {
|
||||
zsession.close();
|
||||
input.remove();
|
||||
});
|
||||
} else {
|
||||
zsession.close();
|
||||
input.remove();
|
||||
}
|
||||
};
|
||||
|
||||
// Handle cancel (focus returns without file selection)
|
||||
const onFocusBack = () => {
|
||||
setTimeout(() => {
|
||||
if (input.files?.length === 0) {
|
||||
zsession.close();
|
||||
input.remove();
|
||||
}
|
||||
}, 1000);
|
||||
window.removeEventListener('focus', onFocusBack);
|
||||
};
|
||||
window.addEventListener('focus', onFocusBack);
|
||||
|
||||
document.body.appendChild(input);
|
||||
input.click();
|
||||
document.body.removeChild(input);
|
||||
}
|
||||
}
|
||||
+14
-3
@@ -34,15 +34,26 @@ try {
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Inline CSS (replace <link rel="stylesheet" ...>)
|
||||
// 4. Inline favicon.svg as base64 data URL
|
||||
const faviconPath = path.join(frontendDir, 'public', 'favicon.svg');
|
||||
if (fs.existsSync(faviconPath)) {
|
||||
const faviconContent = fs.readFileSync(faviconPath, 'utf8');
|
||||
const faviconBase64 = Buffer.from(faviconContent).toString('base64');
|
||||
html = html.replace(
|
||||
/href=["']\/favicon\.svg["']/i,
|
||||
`href="data:image/svg+xml;base64,${faviconBase64}"`
|
||||
);
|
||||
}
|
||||
|
||||
// 5. Inline CSS (replace <link rel="stylesheet" ...>)
|
||||
html = html.replace(/<link[^>]*rel=["']stylesheet["'][^>]*href=["']\/assets\/[^"']+["'][^>]*>/i, () => `<style>${cssContent}</style>`);
|
||||
html = html.replace(/<link[^>]*rel=["']stylesheet["'][^>]*href=["']\/src\/[^"']+["'][^>]*>/i, () => `<style>${cssContent}</style>`);
|
||||
|
||||
// 5. Inline JS (replace <script type="module" src="/src/main.ts"></script> or similar)
|
||||
// 6. Inline JS (replace <script type="module" src="/src/main.ts"></script> or similar)
|
||||
html = html.replace(/<script[^>]*type=["']module["'][^>]*src=["']\/assets\/[^"']+["'][^>]*><\/script>/i, () => `<script type="module">${jsContent}</script>`);
|
||||
html = html.replace(/<script[^>]*type=["']module["'][^>]*src=["']\/src\/[^"']+["'][^>]*><\/script>/i, () => `<script type="module">${jsContent}</script>`);
|
||||
|
||||
// 6. Write to src/worker/html.ts
|
||||
// 7. Write to src/worker/html.ts
|
||||
const escapedHtml = html
|
||||
.replace(/\\/g, '\\\\')
|
||||
.replace(/`/g, '\\`')
|
||||
|
||||
Reference in new issue
Block a user