From 0002281c07a80fa5996d029ab1e12363eeff747e Mon Sep 17 00:00:00 2001 From: Fisto Date: Tue, 22 Sep 2026 13:49:58 +0200 Subject: [PATCH] Honor Request Desktop Website on mobile browsers --- CURRENT.md | 8 ++++++++ poc/public/app.js | 27 +++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/CURRENT.md b/CURRENT.md index d5a08fe..7f7fe06 100644 --- a/CURRENT.md +++ b/CURRENT.md @@ -40,6 +40,14 @@ mobile draft at 390px. - [x] C11 preview caching: Discord-hosted image/GIF previews (WebP 320px, hash-addressed, 5 MiB cap, one attempt) run after every walk in both modes. Live run `...-20260916090722`: `previewed: 2`; thumbs served over `/api/media///thumb` (200). + - [x] C80 Request Desktop Website is honored. The layout was already width-driven, so browsers + that widen the viewport for desktop mode (Safari, Chrome) got the desktop layout. Browsers + that only swap the user agent (Firefox Android) stayed mobile. `app.js` now detects that case + (touch device, desktop user agent, phone-sized screen, still-narrow viewport) and rewrites the + viewport meta to `width=980`, so the width-driven CSS and JS both go desktop. `isMobileLayout` + also returns false when the flag is set. Verified: phone stays mobile, 980px stays desktop, + and the narrow desktop-UA case drops the mobile tab flow (the viewport re-layout depends on the + browser honoring the meta change; the user accepted rough edges here). - [x] C79 Mobile form controls and the focus zoom. iOS Safari zooms the page when a focused text field renders below 16px and does not always zoom back out. `style.css` now forces 16px on text-entry controls at the mobile breakpoint (25 fields were under 16px, the smallest 11px), diff --git a/poc/public/app.js b/poc/public/app.js index c7259b0..6d05621 100644 --- a/poc/public/app.js +++ b/poc/public/app.js @@ -1,5 +1,29 @@ "use strict"; +/* + * Request Desktop Website. + * + * Most browsers answer that request with a desktop-width layout viewport, and + * the width-driven layout follows. Some browsers only swap the user agent and + * keep the phone-width viewport, which would leave this page in the mobile + * layout the user just asked to escape. In that case, widen the viewport meta + * so the whole page lays out as desktop. It is not designed for a phone; the + * user asked for it. + */ +function desktopSiteRequested() { + if (!navigator.maxTouchPoints) return false; + if (/Mobi|Android|iPhone|iPad|iPod/i.test(navigator.userAgent)) return false; + // Tablets and touch laptops keep the normal responsive layout. + if (Math.min(window.screen.width, window.screen.height) > 500) return false; + return window.innerWidth <= 768; +} + +if (desktopSiteRequested()) { + const meta = document.querySelector('meta[name="viewport"]'); + if (meta) meta.setAttribute("content", "width=980"); + document.documentElement.dataset.layout = "desktop"; +} + const $ = (selector, root = document) => root.querySelector(selector); const $$ = (selector, root = document) => [...root.querySelectorAll(selector)]; @@ -1550,6 +1574,9 @@ const MOBILE_QUERY = window.matchMedia("(max-width: 768px)"); const MOBILE_TABS = new Set(["users", "chat", "call", "activity"]); function isMobileLayout() { + // A narrow viewport in Request Desktop Website mode stays desktop: the user + // chose it, even if the browser did not widen the layout viewport. + if (document.documentElement.dataset.layout === "desktop") return false; return MOBILE_QUERY.matches; }