87 lines
4.0 KiB
HTML
87 lines
4.0 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="vi">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<title>SonicForge DAW</title>
|
||
<style>
|
||
body { font-family: system-ui, sans-serif; background: #12141a; color: #e8eaf0;
|
||
display: flex; align-items: center; justify-content: center; height: 100vh; margin: 0; }
|
||
#msg { text-align: center; max-width: 480px; line-height: 1.6; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div id="msg">Đang khởi động SonicForge Engine…</div>
|
||
<script>
|
||
// Frontend host (Tauri asset page). KHÔNG location.href redirect: chuyển
|
||
// sang http://127.0.0.1:8000 sẽ rời Tauri context -> mất window.__TAURI__
|
||
// -> NativeBridgeService vô hiệu (bridge-audio/load_instrument không dùng
|
||
// được; MIDI rơi về fallback WASM/native). Thay vào đó: quét port engine
|
||
// (8000-8010), nạp toàn bộ UI engine qua document.write trên CÙNG document
|
||
// (origin tauri:// giữ nguyên -> __TAURI__ sống), base href + API_BASE_URL
|
||
// trỏ engine HTTP (CORS * đã bật).
|
||
(async function () {
|
||
// Đợi engine của CHÍNH app này (port do desktop_engine.py ghi vào
|
||
// engine_port.txt, đọc qua lệnh Tauri get_engine_port) tối đa 60s.
|
||
// Fallback: quét 8000-8010 (engine cũ/cài chồng) nhưng CÓ timeout mỗi
|
||
// port — trước đây fetch không timeout + không retry: port giữ kết nối
|
||
// không phản hồi → UI treo "Đang khởi động" vĩnh viễn; engine khởi
|
||
// động chậm (cold start) → "Không tìm thấy" dù sau đó engine sống.
|
||
var base = null;
|
||
var deadline = Date.now() + 60000;
|
||
function withTimeout(ms) {
|
||
var ctl = new AbortController();
|
||
var t = setTimeout(function () { ctl.abort(); }, ms);
|
||
return { ctl: ctl, t: t };
|
||
}
|
||
while (!base && Date.now() < deadline) {
|
||
try {
|
||
if (window.__TAURI__ && window.__TAURI__.core && window.__TAURI__.core.invoke) {
|
||
var port = await window.__TAURI__.core.invoke('get_engine_port');
|
||
if (port && port > 0) {
|
||
var h = withTimeout(2000);
|
||
try {
|
||
var r = await fetch('http://127.0.0.1:' + port + '/health', { signal: h.ctl.signal, cache: 'no-store' });
|
||
if (r.ok) base = 'http://127.0.0.1:' + port + '/';
|
||
} finally { clearTimeout(h.t); }
|
||
}
|
||
}
|
||
} catch (e) { /* engine chưa ghi port — retry */ }
|
||
if (base) break;
|
||
for (var p = 8000; p <= 8010 && !base; p++) {
|
||
var h2 = withTimeout(1000);
|
||
try {
|
||
var r2 = await fetch('http://127.0.0.1:' + p + '/health', { signal: h2.ctl.signal, cache: 'no-store' });
|
||
if (r2.ok) base = 'http://127.0.0.1:' + p + '/';
|
||
} catch (e) { /* port chưa mở */ } finally { clearTimeout(h2.t); }
|
||
}
|
||
if (!base) await new Promise(function (res) { setTimeout(res, 1500); });
|
||
}
|
||
if (!base) {
|
||
document.getElementById('msg').textContent =
|
||
'Không tìm thấy SonicForge Engine (port 8000–8010) sau 60s. Hãy đóng và chạy lại ứng dụng. ' +
|
||
'Nếu lặp lại, xem log: %APPDATA%\\SonicForgeDAW\\logs\\engine.log';
|
||
return;
|
||
}
|
||
var html;
|
||
try {
|
||
var res = await fetch(base, { cache: 'no-store' });
|
||
html = await res.text();
|
||
} catch (e) {
|
||
document.getElementById('msg').textContent = 'Engine không phản hồi: ' + e;
|
||
return;
|
||
}
|
||
// base href để /static, /api resolve về engine; API_BASE_URL override
|
||
// location.origin (origin thật là tauri://). KHÔNG trailing slash trong
|
||
// API_BASE_URL: api.js nối `${API_BASE_URL}/api/...` -> double slash
|
||
// `//api/...` -> FastAPI 404 "Not Found" (login báo not found).
|
||
html = html.replace('<head>',
|
||
'<head>\n<base href="' + base + '">\n' +
|
||
'<script>window.API_BASE_URL = "' + base.replace(/\/$/, '') + '";<\/script>');
|
||
document.open();
|
||
document.write(html);
|
||
document.close();
|
||
})();
|
||
</script>
|
||
</body>
|
||
</html>
|