Allow portrait signature confirmation
This commit is contained in:
@@ -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}>
|
||||
取消
|
||||
|
||||
Reference in New Issue
Block a user