|
5 | 5 | const pickerInput = document.getElementById("picker-keyboard-input"); |
6 | 6 | if (!loader) return; |
7 | 7 |
|
| 8 | + const viewportState = { |
| 9 | + width: window.innerWidth, |
| 10 | + height: window.innerHeight, |
| 11 | + }; |
| 12 | + let pickerOpen = false; |
| 13 | + |
| 14 | + const applyViewportSizing = () => { |
| 15 | + const width = window.innerWidth; |
| 16 | + const height = window.innerHeight; |
| 17 | + const shouldUpdate = |
| 18 | + !pickerOpen || height >= viewportState.height || width !== viewportState.width; |
| 19 | + |
| 20 | + if (shouldUpdate) { |
| 21 | + viewportState.width = width; |
| 22 | + viewportState.height = height; |
| 23 | + |
| 24 | + const root = document.documentElement; |
| 25 | + const desktopCanvasHeight = Math.min(height * 0.8, 900); |
| 26 | + const mobileCanvasHeight = Math.min(height * 0.82, 900); |
| 27 | + |
| 28 | + root.style.setProperty("--app-viewport-height", `${height}px`); |
| 29 | + root.style.setProperty( |
| 30 | + "--app-canvas-height-desktop", |
| 31 | + `${desktopCanvasHeight}px`, |
| 32 | + ); |
| 33 | + root.style.setProperty( |
| 34 | + "--app-canvas-height-mobile", |
| 35 | + `${mobileCanvasHeight}px`, |
| 36 | + ); |
| 37 | + } |
| 38 | + }; |
| 39 | + |
| 40 | + window.addEventListener("resize", () => { |
| 41 | + window.requestAnimationFrame(applyViewportSizing); |
| 42 | + }); |
| 43 | + applyViewportSizing(); |
| 44 | + |
8 | 45 | const emitPickerQuery = (action) => { |
9 | 46 | if (!pickerInput) return; |
10 | 47 | const query = pickerInput.value || ""; |
|
20 | 57 |
|
21 | 58 | if (pickerInput) { |
22 | 59 | window.addEventListener("vizmat-structure-picker-open", () => { |
| 60 | + pickerOpen = true; |
23 | 61 | pickerInput.value = ""; |
24 | 62 | try { |
25 | 63 | pickerInput.focus({ preventScroll: true }); |
26 | 64 | } catch (error) { |
27 | 65 | pickerInput.focus(); |
| 66 | + window.scrollTo(0, 0); |
28 | 67 | } |
29 | 68 | emitPickerQuery("change"); |
30 | 69 | }); |
31 | 70 |
|
32 | 71 | window.addEventListener("vizmat-structure-picker-close", () => { |
| 72 | + pickerOpen = false; |
33 | 73 | pickerInput.blur(); |
34 | 74 | pickerInput.value = ""; |
| 75 | + applyViewportSizing(); |
35 | 76 | }); |
36 | 77 |
|
37 | 78 | pickerInput.addEventListener("input", () => emitPickerQuery("change")); |
|
322 | 363 | window.setTimeout(() => loader.remove(), 260); |
323 | 364 | }; |
324 | 365 |
|
| 366 | + const setStatus = (message) => { |
| 367 | + if (status) { |
| 368 | + status.textContent = message; |
| 369 | + } |
| 370 | + }; |
| 371 | + |
| 372 | + const startApp = () => { |
| 373 | + const bindings = window.wasmBindings; |
| 374 | + if (!bindings || typeof bindings.start !== "function") { |
| 375 | + setStatus("Waiting for WebAssembly bindings..."); |
| 376 | + return false; |
| 377 | + } |
| 378 | + |
| 379 | + try { |
| 380 | + bindings.start(); |
| 381 | + hideLoader(); |
| 382 | + return true; |
| 383 | + } catch (error) { |
| 384 | + console.error("Failed to start WASM app:", error); |
| 385 | + setStatus("Failed to start WebAssembly app."); |
| 386 | + return false; |
| 387 | + } |
| 388 | + }; |
| 389 | + |
| 390 | + // Trunk injects the WASM module and then fires this event. |
| 391 | + window.addEventListener( |
| 392 | + "TrunkApplicationStarted", |
| 393 | + () => { |
| 394 | + startApp(); |
| 395 | + }, |
| 396 | + { once: true }, |
| 397 | + ); |
| 398 | + |
| 399 | + // If Trunk fired before this script loaded, start immediately. |
| 400 | + if (window.wasmBindings?.start) { |
| 401 | + startApp(); |
| 402 | + } |
| 403 | + |
325 | 404 | // Trunk injects a startup script and emits this event after WASM init. |
326 | 405 | // If the event fired before this listener was added, hide immediately. |
327 | 406 | if (window.wasmBindings) { |
|
0 commit comments