Spaces:
Sleeping
Sleeping
François Pachet commited on
Commit ·
7a29cd5
1
Parent(s): 4b17f2c
Make phone layout load reliably
Browse files- README.md +6 -4
- backend/app/main.py +4 -1
- frontend/app.js +4 -0
- frontend/index.html +18 -2
README.md
CHANGED
|
@@ -86,10 +86,12 @@ The UX principle is to keep the performance flow visible at all times and hide l
|
|
| 86 |
Phones use the same application and backend as desktop browsers. A compact,
|
| 87 |
touch-oriented layout is selected from viewport and pointer capabilities rather
|
| 88 |
than device names. Detection combines the current viewport, mobile browser
|
| 89 |
-
client hints, touch-pointer capability, and
|
| 90 |
-
Android phones still select the phone surface
|
| 91 |
-
desktop-sized viewport. The
|
| 92 |
-
|
|
|
|
|
|
|
| 93 |
Configuration, accounts, memory inspection, hardware MIDI, and device routing
|
| 94 |
remain available in the unchanged desktop/tablet layout.
|
| 95 |
|
|
|
|
| 86 |
Phones use the same application and backend as desktop browsers. A compact,
|
| 87 |
touch-oriented layout is selected from viewport and pointer capabilities rather
|
| 88 |
than device names. Detection combines the current viewport, mobile browser
|
| 89 |
+
client hints, phone browser identification, touch-pointer capability, and
|
| 90 |
+
physical CSS screen dimensions so Android phones still select the phone surface
|
| 91 |
+
when the browser reports a desktop-sized viewport. The layout class is applied
|
| 92 |
+
before styles load to avoid briefly showing the full desktop controls. The phone
|
| 93 |
+
surface contains only the virtual keyboard, a small live-status message, and the
|
| 94 |
+
captured/generated piano rolls.
|
| 95 |
Configuration, accounts, memory inspection, hardware MIDI, and device routing
|
| 96 |
remain available in the unchanged desktop/tablet layout.
|
| 97 |
|
backend/app/main.py
CHANGED
|
@@ -105,7 +105,10 @@ def require_current_user(
|
|
| 105 |
|
| 106 |
@app.get("/", include_in_schema=False)
|
| 107 |
def read_index() -> FileResponse:
|
| 108 |
-
return FileResponse(
|
|
|
|
|
|
|
|
|
|
| 109 |
|
| 110 |
|
| 111 |
@app.get("/health", tags=["system"])
|
|
|
|
| 105 |
|
| 106 |
@app.get("/", include_in_schema=False)
|
| 107 |
def read_index() -> FileResponse:
|
| 108 |
+
return FileResponse(
|
| 109 |
+
settings.frontend_dir / "index.html",
|
| 110 |
+
headers={"Cache-Control": "no-cache, must-revalidate"},
|
| 111 |
+
)
|
| 112 |
|
| 113 |
|
| 114 |
@app.get("/health", tags=["system"])
|
frontend/app.js
CHANGED
|
@@ -1626,6 +1626,9 @@ function isPhoneLayout() {
|
|
| 1626 |
window.matchMedia?.(PHONE_LAYOUT_MEDIA_QUERY).matches,
|
| 1627 |
);
|
| 1628 |
const mobileClientHint = navigator.userAgentData?.mobile === true;
|
|
|
|
|
|
|
|
|
|
| 1629 |
const coarseTouch =
|
| 1630 |
Boolean(window.matchMedia?.("(pointer: coarse)").matches) ||
|
| 1631 |
navigator.maxTouchPoints > 0;
|
|
@@ -1639,6 +1642,7 @@ function isPhoneLayout() {
|
|
| 1639 |
return (
|
| 1640 |
responsiveMatch ||
|
| 1641 |
mobileClientHint ||
|
|
|
|
| 1642 |
(coarseTouch && compactPhysicalScreen)
|
| 1643 |
);
|
| 1644 |
}
|
|
|
|
| 1626 |
window.matchMedia?.(PHONE_LAYOUT_MEDIA_QUERY).matches,
|
| 1627 |
);
|
| 1628 |
const mobileClientHint = navigator.userAgentData?.mobile === true;
|
| 1629 |
+
const phoneUserAgent = /Android.+Mobile|iPhone|iPod/i.test(
|
| 1630 |
+
navigator.userAgent || "",
|
| 1631 |
+
);
|
| 1632 |
const coarseTouch =
|
| 1633 |
Boolean(window.matchMedia?.("(pointer: coarse)").matches) ||
|
| 1634 |
navigator.maxTouchPoints > 0;
|
|
|
|
| 1642 |
return (
|
| 1643 |
responsiveMatch ||
|
| 1644 |
mobileClientHint ||
|
| 1645 |
+
phoneUserAgent ||
|
| 1646 |
(coarseTouch && compactPhysicalScreen)
|
| 1647 |
);
|
| 1648 |
}
|
frontend/index.html
CHANGED
|
@@ -6,7 +6,23 @@
|
|
| 6 |
<meta name="color-scheme" content="only light" />
|
| 7 |
<meta name="theme-color" content="#071217" />
|
| 8 |
<title>Web Continuator</title>
|
| 9 |
-
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
</head>
|
| 11 |
<body>
|
| 12 |
<div class="page-aura"></div>
|
|
@@ -1198,6 +1214,6 @@
|
|
| 1198 |
</section>
|
| 1199 |
</main>
|
| 1200 |
|
| 1201 |
-
<script type="module" src="/assets/app.js?v=20260729-
|
| 1202 |
</body>
|
| 1203 |
</html>
|
|
|
|
| 6 |
<meta name="color-scheme" content="only light" />
|
| 7 |
<meta name="theme-color" content="#071217" />
|
| 8 |
<title>Web Continuator</title>
|
| 9 |
+
<script>
|
| 10 |
+
(() => {
|
| 11 |
+
const requestedLayout = new URLSearchParams(window.location.search).get("layout");
|
| 12 |
+
const phoneUserAgent = /Android.+Mobile|iPhone|iPod/i.test(
|
| 13 |
+
navigator.userAgent || "",
|
| 14 |
+
);
|
| 15 |
+
const narrowViewport = window.matchMedia?.("(max-width: 700px)").matches;
|
| 16 |
+
const phoneLayout =
|
| 17 |
+
requestedLayout === "phone" ||
|
| 18 |
+
(requestedLayout !== "desktop" &&
|
| 19 |
+
(phoneUserAgent ||
|
| 20 |
+
navigator.userAgentData?.mobile === true ||
|
| 21 |
+
narrowViewport));
|
| 22 |
+
document.documentElement.classList.toggle("phone-layout", phoneLayout);
|
| 23 |
+
})();
|
| 24 |
+
</script>
|
| 25 |
+
<link rel="stylesheet" href="/assets/styles.css?v=20260729-phone6" />
|
| 26 |
</head>
|
| 27 |
<body>
|
| 28 |
<div class="page-aura"></div>
|
|
|
|
| 1214 |
</section>
|
| 1215 |
</main>
|
| 1216 |
|
| 1217 |
+
<script type="module" src="/assets/app.js?v=20260729-phone6"></script>
|
| 1218 |
</body>
|
| 1219 |
</html>
|