fix(ui): add standalone PWA browser controls
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { isChromelessDisplayMode } from "./pwa-display-mode";
|
||||
|
||||
function matchMode(activeMode: string | null) {
|
||||
return (query: string) => ({ matches: query === `(display-mode: ${activeMode})` });
|
||||
}
|
||||
|
||||
describe("isChromelessDisplayMode", () => {
|
||||
it("detects standalone display mode from media queries", () => {
|
||||
expect(isChromelessDisplayMode(matchMode("standalone"), false)).toBe(true);
|
||||
});
|
||||
|
||||
it("detects iOS home-screen standalone launches", () => {
|
||||
expect(isChromelessDisplayMode(matchMode(null), true)).toBe(true);
|
||||
});
|
||||
|
||||
it("ignores normal browser launches", () => {
|
||||
expect(isChromelessDisplayMode(matchMode("browser"), false)).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,26 @@
|
||||
export const CHROMELESS_DISPLAY_MODES = ["standalone", "fullscreen", "window-controls-overlay"] as const;
|
||||
|
||||
type DisplayMode = (typeof CHROMELESS_DISPLAY_MODES)[number];
|
||||
type MatchDisplayMode = (query: string) => Pick<MediaQueryList, "matches">;
|
||||
|
||||
function displayModeQuery(mode: DisplayMode) {
|
||||
return `(display-mode: ${mode})`;
|
||||
}
|
||||
|
||||
function defaultMatchMedia(): MatchDisplayMode | undefined {
|
||||
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return undefined;
|
||||
return window.matchMedia.bind(window);
|
||||
}
|
||||
|
||||
export function isChromelessDisplayMode(
|
||||
matchMedia: MatchDisplayMode | undefined = defaultMatchMedia(),
|
||||
iosStandalone: boolean | undefined =
|
||||
typeof navigator === "undefined"
|
||||
? undefined
|
||||
: (navigator as Navigator & { standalone?: boolean }).standalone,
|
||||
) {
|
||||
if (iosStandalone === true) return true;
|
||||
if (!matchMedia) return false;
|
||||
|
||||
return CHROMELESS_DISPLAY_MODES.some((mode) => matchMedia(displayModeQuery(mode)).matches);
|
||||
}
|
||||
Reference in New Issue
Block a user