mirror of
https://github.com/wu736139669/hapi.git
synced 2026-08-05 06:24:37 +00:00
fix(web): stabilize chat scrolling and mobile alignment (#1278)
* fix(web): stabilize chat scrolling and mobile alignment * fix(web): scope chat scroll containment
This commit is contained in:
@@ -461,6 +461,28 @@ export function HappyThread(props: {
|
||||
failureCount: 0,
|
||||
autoPaused: false
|
||||
})
|
||||
|
||||
useLayoutEffect(() => {
|
||||
const viewport = viewportRef.current
|
||||
if (!viewport) return
|
||||
|
||||
const updateScrollbarGutter = () => {
|
||||
const supportsStableBothEdges = typeof CSS !== 'undefined'
|
||||
&& typeof CSS.supports === 'function'
|
||||
&& CSS.supports('scrollbar-gutter: stable both-edges')
|
||||
const gutter = supportsStableBothEdges
|
||||
? Math.max(0, (viewport.offsetWidth - viewport.clientWidth) / 2)
|
||||
: 0
|
||||
viewport.style.setProperty('--chat-scroll-gutter-inline', `${gutter}px`)
|
||||
}
|
||||
|
||||
updateScrollbarGutter()
|
||||
if (typeof ResizeObserver === 'undefined') return
|
||||
|
||||
const observer = new ResizeObserver(updateScrollbarGutter)
|
||||
observer.observe(viewport)
|
||||
return () => observer.disconnect()
|
||||
}, [])
|
||||
const requestOlderRef = useRef<(source: HistoryLoadSource) => Promise<OlderHistoryLoadResult>>(
|
||||
() => Promise.resolve('transient-stop')
|
||||
)
|
||||
@@ -1414,10 +1436,10 @@ export function HappyThread(props: {
|
||||
>
|
||||
<div
|
||||
ref={viewportRef}
|
||||
className="app-scroll-y min-h-0 flex-1 overflow-x-hidden"
|
||||
className="app-scroll-y chat-scroll-y min-h-0 flex-1 overflow-x-hidden"
|
||||
tabIndex={0}
|
||||
>
|
||||
<div ref={contentRef} className="mx-auto w-full max-w-content min-w-0 p-3">
|
||||
<div ref={contentRef} className="chat-scroll-content mx-auto w-full max-w-content min-w-0 p-3">
|
||||
<div ref={topSentinelRef} className="h-px w-full" aria-hidden="true" />
|
||||
{showSkeleton ? (
|
||||
<MessageSkeleton />
|
||||
|
||||
@@ -310,6 +310,14 @@ body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* Chat viewports own vertical scrolling; keep transiently oversized messages
|
||||
* from creating a second document scrollbar without locking non-chat routes. */
|
||||
html:has(.chat-scroll-y),
|
||||
html:has(.chat-scroll-y) body,
|
||||
html:has(.chat-scroll-y) #root {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.app-scroll-y {
|
||||
overflow-y: auto;
|
||||
overscroll-behavior-y: contain;
|
||||
@@ -317,6 +325,20 @@ body {
|
||||
touch-action: pan-y;
|
||||
}
|
||||
|
||||
/* On touch-first devices, keep the chat scrollbar from shifting centered content. */
|
||||
@media (hover: none) and (pointer: coarse) {
|
||||
.chat-scroll-y {
|
||||
scrollbar-gutter: stable both-edges;
|
||||
}
|
||||
|
||||
.chat-scroll-content {
|
||||
padding-inline: max(
|
||||
0.125rem,
|
||||
calc(0.75rem - var(--chat-scroll-gutter-inline, 0px))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@media (hover: hover) and (pointer: fine) {
|
||||
.session-list-item:hover,
|
||||
.session-list-new-button:hover {
|
||||
|
||||
Reference in New Issue
Block a user