diff --git a/src/modules/assets/assistant/AssetAssistant.tsx b/src/modules/assets/assistant/AssetAssistant.tsx index c13450a..f6546b9 100644 --- a/src/modules/assets/assistant/AssetAssistant.tsx +++ b/src/modules/assets/assistant/AssetAssistant.tsx @@ -92,18 +92,47 @@ export default function AssetAssistant({ const page = useRef(null); useLayoutEffect(() => { const viewport = window.visualViewport; + const mobile = window.matchMedia('(max-width: 767px)'); + let frame = 0; + let unlock: (() => void) | undefined; const updateViewport = () => { + frame = 0; + if (!mobile.matches || (viewport && viewport.scale !== 1)) return; page.current?.style.setProperty('--aq-viewport-height', `${viewport?.height ?? window.innerHeight}px`); page.current?.style.setProperty('--aq-viewport-top', `${viewport?.offsetTop ?? 0}px`); }; - updateViewport(); - viewport?.addEventListener('resize', updateViewport); - viewport?.addEventListener('scroll', updateViewport); - window.addEventListener('resize', updateViewport); + const scheduleViewport = () => { + if (!frame) frame = requestAnimationFrame(updateViewport); + }; + const syncMobile = () => { + unlock?.(); + unlock = undefined; + if (mobile.matches) { + const scrollY = window.scrollY; + const body = document.body; + const previous = body.style.top; + body.style.top = `${-scrollY}px`; + body.classList.add('aq-mobile-open'); + unlock = () => { + body.classList.remove('aq-mobile-open'); + body.style.top = previous; + window.scrollTo({ top: scrollY, behavior: 'instant' }); + }; + } + updateViewport(); + }; + syncMobile(); + mobile.addEventListener('change', syncMobile); + viewport?.addEventListener('resize', scheduleViewport); + viewport?.addEventListener('scroll', scheduleViewport); + window.addEventListener('resize', scheduleViewport); return () => { - viewport?.removeEventListener('resize', updateViewport); - viewport?.removeEventListener('scroll', updateViewport); - window.removeEventListener('resize', updateViewport); + cancelAnimationFrame(frame); + mobile.removeEventListener('change', syncMobile); + viewport?.removeEventListener('resize', scheduleViewport); + viewport?.removeEventListener('scroll', scheduleViewport); + window.removeEventListener('resize', scheduleViewport); + unlock?.(); }; }, []); const [theme, setTheme] = useState(appearance); @@ -214,7 +243,7 @@ export default function AssetAssistant({ setActiveResult(undefined); sessionRef.current = undefined; setIndependent(true); - composer.current?.focus(); + composer.current?.focus({ preventScroll: true }); }; useEffect( () => () => { @@ -360,7 +389,7 @@ export default function AssetAssistant({ setTurns([]); setExpandedTurns(new Set()); setDraft(""); - composer.current?.focus(); + composer.current?.focus({ preventScroll: true }); }; useEffect(() => { reset(); @@ -390,7 +419,7 @@ export default function AssetAssistant({ className="aq-nav-active" onClick={() => { scroller.current?.scrollTo({ top: 0 }); - composer.current?.focus(); + composer.current?.focus({ preventScroll: true }); }} > diff --git a/src/modules/assets/assistant/ResultView.tsx b/src/modules/assets/assistant/ResultView.tsx index 3bc78bb..dc266f0 100644 --- a/src/modules/assets/assistant/ResultView.tsx +++ b/src/modules/assets/assistant/ResultView.tsx @@ -799,9 +799,7 @@ function ResultViewContent({ "分组", "车辆数", "占比", - "运营率", - "异动", - "待交车", + ...(result.plan.category === "operating" ? [] : ["运营率", "异动", "待交车"]), "下钻", ].map((h) => ( {h} @@ -814,9 +812,11 @@ function ResultViewContent({ {g.name} {g.count} {g.share}% - {g.rate}% - {g.abnormal} - {g.pending} + {result.plan.category !== "operating" && <> + {g.rate}% + {g.abnormal} + {g.pending} + }