diff --git a/frontend/public/global.css b/frontend/public/global.css index 9965eec..4e988b1 100644 --- a/frontend/public/global.css +++ b/frontend/public/global.css @@ -65,9 +65,6 @@ --radius-lg: calc(2 * var(--radius-unit)); --radius-xl: calc(3.25 * var(--radius-unit)); --radius-xxl: calc(5.25 * var(--sradius-unit)); - - --100vw: calc(100.0 * 1vw); - --100vh: calc(100.0 * 1vh); } html, body { @@ -77,12 +74,8 @@ html, body { color-scheme: dark; accent-color: var(--purple-2); - width: 100%; - height: 100%; - min-width: 100%; - min-height: 100%; - max-width: 100%; - max-height: 100%; + width: var(--viewportWidth); + height: var(--viewportHeight); } body { @@ -99,22 +92,6 @@ body { flex-direction: column; } -@supports(width: 1dvw) { - html, body { - min-width: 100dvw; - max-width: 100dvw; - width: 100dvw; - } -} - -@supports(height: 1dvh) { - html, body { - min-height: 100dvh; - max-height: 100dvh; - height: 100dvh; - } -} - /* fullscreen message */ .fullscreen-message { diff --git a/frontend/src/responsive.js b/frontend/src/responsive.js index d6a2bf2..3fdd2f4 100644 --- a/frontend/src/responsive.js +++ b/frontend/src/responsive.js @@ -1,6 +1,31 @@ +import { getItem } from "./storage"; import { showSidebar, smallViewport } from "./stores"; +function initViewportSizeHandler() { + const root = document.querySelector(':root'); + const method = getItem("ui:useragent:viewportSizeJustificationMethod"); + + if (method === "dynamicViewportUnits") { + root.style.setProperty("--viewportWidth", "100dvw"); + root.style.setProperty("--viewportHeight", "100dvh"); + } else if (method === "javascriptResponsive") { + const updateUnits = () => { + root.style.setProperty("--viewportWidth", `${window.innerWidth}px`); + root.style.setProperty("--viewportHeight", `${window.innerHeight}px`); + }; + window.addEventListener("resize", updateUnits); + updateUnits(); + } else if (method === "normalUnits") { + root.style.setProperty("--viewportWidth", "100vw"); + root.style.setProperty("--viewportHeight", "100vh"); + } else { + throw new Error("initViewportSizeHandler(): got unexpected value from getItem('ui:useragent:viewportSizeJustificationMethod')."); + } +} + export function initResponsiveHandlers() { + initViewportSizeHandler(); + const mediaQuery = window.matchMedia('(min-width: 768px)'); const update = ({ matches }) => { diff --git a/frontend/src/storage.js b/frontend/src/storage.js index ed32924..8359942 100644 --- a/frontend/src/storage.js +++ b/frontend/src/storage.js @@ -13,7 +13,20 @@ const defaults = { "ui:online:processRemoteTypingEvents": true, "ui:online:processRemotePresenceEvents": true, "ui:online:loadMessageHistory": true, - "ui:online:sendTypingUpdates": true + "ui:online:sendTypingUpdates": true, + + "ui:useragent:formFactor": () => { + return (window.navigator && window.navigator.maxTouchPoints > 0) ? "touch" : "desktop"; + }, + "ui:useragent:viewportSizeJustificationMethod": () => { + if (CSS.supports("(width: 1dvw)")) { + return "dynamicViewportUnits"; + } else if (getItem("ui:useragent:formFactor") === "touch") { + return "javascriptResponsive"; + } else { + return "normalUnits"; + } + } }; const store = new Map(Object.entries(defaults)); const persistentProvider = localStorage; @@ -30,7 +43,11 @@ export function getItem(key) { if (!didCacheProvider) { init(); } - return store.get(key); + const value = store.get(key); + if (typeof value === "function") { + return value(); + } + return value; } export function removeItem(key) {