Allow portrait signature confirmation

This commit is contained in:
Frudrax Cheng
2026-05-28 10:45:14 +08:00
parent 2a614851db
commit 7747995b3f
3 changed files with 2 additions and 101 deletions
+1 -62
View File
@@ -1,6 +1,5 @@
import { useEffect, useRef, useState } from 'react';
import { Button } from 'antd';
import { RotateRightOutlined } from '@ant-design/icons';
import SignaturePad, { type SignaturePadHandle } from './SignaturePad';
import './SignatureOverlay.css';
@@ -10,63 +9,18 @@ interface SignatureOverlayProps {
onConfirm: (dataUrl: string) => void;
}
const isLandscapeNow = () =>
typeof window !== 'undefined' &&
(window.matchMedia('(orientation: landscape)').matches ||
window.innerWidth > window.innerHeight ||
((window.visualViewport?.width ?? 0) > (window.visualViewport?.height ?? 0)) ||
Math.abs(window.screen.orientation?.angle ?? 0) % 180 === 90);
function SignatureOverlay({ open, onCancel, onConfirm }: SignatureOverlayProps) {
const padRef = useRef<SignaturePadHandle>(null);
const [, setData] = useState('');
const [landscape, setLandscape] = useState<boolean>(isLandscapeNow);
useEffect(() => {
if (!open) return;
const mq = window.matchMedia('(orientation: landscape)');
const update = () => setLandscape(mq.matches || window.innerWidth > window.innerHeight);
update();
if (typeof mq.addEventListener === 'function') {
mq.addEventListener('change', update);
} else {
mq.addListener(update);
}
window.addEventListener('resize', update);
window.addEventListener('orientationchange', update);
window.visualViewport?.addEventListener('resize', update);
const orientation = (screen as Screen & {
orientation?: {
lock?: (o: string) => Promise<void>;
unlock?: () => void;
addEventListener?: (type: 'change', listener: () => void) => void;
removeEventListener?: (type: 'change', listener: () => void) => void;
};
}).orientation;
orientation?.addEventListener?.('change', update);
if (orientation?.lock) {
orientation.lock('landscape').catch(() => {
// ignore; iOS Safari and most browsers refuse outside fullscreen
});
}
const prevOverflow = document.body.style.overflow;
document.body.style.overflow = 'hidden';
return () => {
if (typeof mq.removeEventListener === 'function') {
mq.removeEventListener('change', update);
} else {
mq.removeListener(update);
}
window.removeEventListener('resize', update);
window.removeEventListener('orientationchange', update);
window.visualViewport?.removeEventListener('resize', update);
orientation?.removeEventListener?.('change', update);
document.body.style.overflow = prevOverflow;
orientation?.unlock?.();
};
}, [open]);
@@ -85,22 +39,7 @@ function SignatureOverlay({ open, onCancel, onConfirm }: SignatureOverlayProps)
return (
<div className="signature-overlay" role="dialog" aria-modal="true">
{!landscape && (
<div className="signature-overlay-rotate">
<RotateRightOutlined className="signature-overlay-rotate-icon" />
<p className="signature-overlay-rotate-text"></p>
<p className="signature-overlay-rotate-hint">
</p>
<Button onClick={onCancel}></Button>
</div>
)}
{/* SignaturePad stays mounted so its strokes survive accidental rotation flips */}
<div
className="signature-overlay-stage"
style={{ visibility: landscape ? 'visible' : 'hidden' }}
aria-hidden={!landscape}
>
<div className="signature-overlay-stage">
<div className="signature-overlay-bar">
<Button type="text" onClick={onCancel}>