fix: comments drawer fix
This commit is contained in:
@@ -80,6 +80,51 @@ export function PostCommentsDrawer({
|
|||||||
const [toReport, setToReport] = useState<Comment | null>(null);
|
const [toReport, setToReport] = useState<Comment | null>(null);
|
||||||
const inputRef = useRef<HTMLTextAreaElement>(null);
|
const inputRef = useRef<HTMLTextAreaElement>(null);
|
||||||
|
|
||||||
|
// iOS/Android on-screen keyboard handling for the mobile bottom sheet.
|
||||||
|
//
|
||||||
|
// On iOS Safari the keyboard shrinks only the *visual* viewport, not the
|
||||||
|
// layout viewport, so a `bottom-0` fixed sheet stays anchored behind the
|
||||||
|
// keyboard; Safari then scrolls the whole webview up to reveal the focused
|
||||||
|
// composer, dragging the sheet's top off-screen (the "weird upward shift").
|
||||||
|
// vaul's own `repositionInputs` is disabled here, so we drive it from the
|
||||||
|
// VisualViewport API: pin the sheet's bottom to the top of the keyboard and
|
||||||
|
// cap its height to the visible area. The top never overflows and the
|
||||||
|
// comment list simply shrinks — Instagram-style — instead of the sheet
|
||||||
|
// sliding out of the viewport.
|
||||||
|
const [kbStyle, setKbStyle] = useState<
|
||||||
|
{ bottom: number; height: number } | undefined
|
||||||
|
>(undefined);
|
||||||
|
useEffect(() => {
|
||||||
|
if (!open || !isMobile) {
|
||||||
|
setKbStyle(undefined);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const vv = window.visualViewport;
|
||||||
|
if (!vv) return;
|
||||||
|
const update = () => {
|
||||||
|
// Keyboard height = full layout height minus what's still visible.
|
||||||
|
const inset = Math.max(0, window.innerHeight - vv.height - vv.offsetTop);
|
||||||
|
if (inset < 1) {
|
||||||
|
setKbStyle(undefined);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Keep the sheet at its resting 80vh unless the space above the keyboard
|
||||||
|
// is smaller, in which case fill exactly that so nothing overflows.
|
||||||
|
const height = Math.min(
|
||||||
|
window.innerHeight * 0.8,
|
||||||
|
window.innerHeight - inset,
|
||||||
|
);
|
||||||
|
setKbStyle({ bottom: inset, height });
|
||||||
|
};
|
||||||
|
update();
|
||||||
|
vv.addEventListener("resize", update);
|
||||||
|
vv.addEventListener("scroll", update);
|
||||||
|
return () => {
|
||||||
|
vv.removeEventListener("resize", update);
|
||||||
|
vv.removeEventListener("scroll", update);
|
||||||
|
};
|
||||||
|
}, [open, isMobile]);
|
||||||
|
|
||||||
// Load the first page whenever the drawer opens for a post.
|
// Load the first page whenever the drawer opens for a post.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!open) return;
|
if (!open) return;
|
||||||
@@ -238,6 +283,10 @@ export function PostCommentsDrawer({
|
|||||||
direction={direction}
|
direction={direction}
|
||||||
// Transparent scrim: keep the post visible behind the sheet.
|
// Transparent scrim: keep the post visible behind the sheet.
|
||||||
overlayClassName="bg-transparent"
|
overlayClassName="bg-transparent"
|
||||||
|
// When the mobile keyboard is up, `kbStyle` pins the sheet above it
|
||||||
|
// and caps its height (see the VisualViewport effect); otherwise the
|
||||||
|
// sheet keeps its resting 80vh from the class below.
|
||||||
|
style={kbStyle}
|
||||||
className={cn(
|
className={cn(
|
||||||
"bg-card flex flex-col shadow-2xl",
|
"bg-card flex flex-col shadow-2xl",
|
||||||
isMobile ? "h-[80vh]" : "h-full w-[420px] max-w-[92vw]",
|
isMobile ? "h-[80vh]" : "h-full w-[420px] max-w-[92vw]",
|
||||||
|
|||||||
Reference in New Issue
Block a user