Settings: add safe area inset emulation
This commit is contained in:
parent
0255956297
commit
f15a52b3db
1 changed files with 131 additions and 0 deletions
|
@ -3,6 +3,7 @@ import {
|
|||
createSignal,
|
||||
For,
|
||||
Show,
|
||||
type JSX,
|
||||
type ParentComponent,
|
||||
} from "solid-js";
|
||||
import Scaffold from "../material/Scaffold.js";
|
||||
|
@ -17,6 +18,7 @@ import {
|
|||
ListItemSecondaryAction,
|
||||
ListItemText,
|
||||
ListSubheader,
|
||||
NativeSelect,
|
||||
Switch,
|
||||
Toolbar,
|
||||
} from "@suid/material";
|
||||
|
@ -46,6 +48,96 @@ import BottomSheet from "../material/BottomSheet.jsx";
|
|||
import { useServiceWorker } from "../platform/host.js";
|
||||
import { useSessions } from "../masto/clients.js";
|
||||
|
||||
type Inset = {
|
||||
top?: number;
|
||||
right?: number;
|
||||
bottom?: number;
|
||||
left?: number;
|
||||
};
|
||||
|
||||
type SafeAreaInsets = {
|
||||
landscape: Inset;
|
||||
protrait: Inset;
|
||||
};
|
||||
|
||||
const safeAreaInsets: Record<string, SafeAreaInsets> = {
|
||||
iphone15: {
|
||||
protrait: {
|
||||
top: 59,
|
||||
bottom: 34,
|
||||
},
|
||||
landscape: {
|
||||
bottom: 21,
|
||||
left: 59,
|
||||
right: 59,
|
||||
},
|
||||
},
|
||||
iphone12: {
|
||||
protrait: {
|
||||
top: 47,
|
||||
bottom: 34,
|
||||
},
|
||||
landscape: {
|
||||
bottom: 21,
|
||||
left: 47,
|
||||
right: 47,
|
||||
},
|
||||
},
|
||||
iphone13mini: {
|
||||
protrait: {
|
||||
top: 50,
|
||||
bottom: 34,
|
||||
},
|
||||
landscape: {
|
||||
bottom: 21,
|
||||
left: 50,
|
||||
right: 50,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
let screenOrientationCallback: (() => void) | undefined;
|
||||
|
||||
function applySafeAreaEmulation(root: HTMLElement, insets: Inset) {
|
||||
for (const key of Object.keys(insets) as (keyof Inset)[]) {
|
||||
const value = insets[key];
|
||||
if (!value || value === 0) continue;
|
||||
root.style.setProperty(`--safe-area-inset-${key}`, `${value}px`);
|
||||
}
|
||||
}
|
||||
|
||||
function setupSafeAreaEmulation(name: string) {
|
||||
const insets = safeAreaInsets[name];
|
||||
const root = document.querySelector(":root")! as HTMLElement;
|
||||
if (!insets) {
|
||||
if (screenOrientationCallback) {
|
||||
window.screen.orientation.removeEventListener(
|
||||
"change",
|
||||
screenOrientationCallback,
|
||||
);
|
||||
screenOrientationCallback = undefined;
|
||||
}
|
||||
for (const name of ["top", "right", "bottom", "left"]) {
|
||||
root.style.removeProperty(`--safe-area-inset-${name}`);
|
||||
}
|
||||
} else {
|
||||
screenOrientationCallback = () => {
|
||||
if (window.screen.orientation.type === "portrait-primary") {
|
||||
console.debug("safe area emulation: protrait");
|
||||
applySafeAreaEmulation(root, insets.protrait);
|
||||
} else if (window.screen.orientation.type === "landscape-primary") {
|
||||
console.debug("safe area emulation: landscape");
|
||||
applySafeAreaEmulation(root, insets.landscape);
|
||||
}
|
||||
};
|
||||
window.screen.orientation.addEventListener(
|
||||
"change",
|
||||
screenOrientationCallback,
|
||||
);
|
||||
screenOrientationCallback();
|
||||
}
|
||||
}
|
||||
|
||||
type Strings = {
|
||||
["lang.auto"]: Template<{ detected: string }>;
|
||||
} & Record<string, string | undefined>;
|
||||
|
@ -235,6 +327,45 @@ const Settings: ParentComponent = (props) => {
|
|||
</ListItem>
|
||||
<Divider />
|
||||
</li>
|
||||
{import.meta.env.DEV ? (
|
||||
<li>
|
||||
<ListSubheader>Developer Tools</ListSubheader>
|
||||
<ListItem
|
||||
secondaryAction={
|
||||
window.screen?.orientation ? (
|
||||
<NativeSelect
|
||||
sx={{ maxWidth: "40vw" }}
|
||||
onChange={(event) => {
|
||||
const k = event.currentTarget.value;
|
||||
setupSafeAreaEmulation(k);
|
||||
}}
|
||||
>
|
||||
<option>Don't change</option>
|
||||
<option value={"ua"}>User agent</option>
|
||||
<option value={"iphone15"}>
|
||||
iPhone 15 and Plus, Pro, Pro Max
|
||||
</option>
|
||||
<option value={"iphone12"}>iPhone 12, 13 and 14</option>
|
||||
<option value={"iphone13mini"}>iPhone 13 mini</option>
|
||||
</NativeSelect>
|
||||
) : undefined
|
||||
}
|
||||
>
|
||||
<ListItemText
|
||||
secondary={
|
||||
window.screen?.orientation
|
||||
? undefined
|
||||
: "Unsupported on This Platform"
|
||||
}
|
||||
>
|
||||
Safe Area Insets
|
||||
</ListItemText>
|
||||
</ListItem>
|
||||
<Divider />
|
||||
</li>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</List>
|
||||
</Scaffold>
|
||||
);
|
||||
|
|
Loading…
Reference in a new issue