mirror of
https://github.com/AppFlowy-IO/AppFlowy-Web.git
synced 2025-11-29 19:08:33 +08:00
fix: scroll to top when swithc embeded database view
This commit is contained in:
@@ -153,7 +153,7 @@ function DatabaseViews({
|
|||||||
}, [isLoading, viewVisible, layout, viewId]);
|
}, [isLoading, viewVisible, layout, viewId]);
|
||||||
|
|
||||||
// Scroll restoration with RAF enforcement
|
// Scroll restoration with RAF enforcement
|
||||||
// Even with keep-mounted, Board's autoScrollForElements can still interfere on first switch
|
// Board's autoScrollForElements interferes with scroll, so we enforce for multiple frames
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isLoading) return;
|
if (isLoading) return;
|
||||||
if (lastScrollRef.current == null) return;
|
if (lastScrollRef.current == null) return;
|
||||||
@@ -168,8 +168,17 @@ function DatabaseViews({
|
|||||||
let rafCount = 0;
|
let rafCount = 0;
|
||||||
let rafId: number;
|
let rafId: number;
|
||||||
|
|
||||||
|
// Temporarily prevent scroll events during restoration
|
||||||
|
const preventScroll = (e: Event) => {
|
||||||
|
if (scrollElement.scrollTop !== targetScroll) {
|
||||||
|
e.preventDefault();
|
||||||
|
scrollElement.scrollTop = targetScroll;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
scrollElement.addEventListener('scroll', preventScroll, { passive: false });
|
||||||
|
|
||||||
// Use RAF loop to enforce scroll position
|
// Use RAF loop to enforce scroll position
|
||||||
// This handles Board's autoScrollForElements which may still interfere on first display
|
|
||||||
const enforceScroll = () => {
|
const enforceScroll = () => {
|
||||||
const currentScroll = scrollElement.scrollTop;
|
const currentScroll = scrollElement.scrollTop;
|
||||||
const delta = Math.abs(currentScroll - targetScroll);
|
const delta = Math.abs(currentScroll - targetScroll);
|
||||||
@@ -185,16 +194,22 @@ function DatabaseViews({
|
|||||||
}
|
}
|
||||||
|
|
||||||
rafCount++;
|
rafCount++;
|
||||||
// Run for 3 frames (~48ms) - shorter than before since views stay mounted
|
// Run for 5 frames (~80ms) to catch delayed scroll changes from Board mount
|
||||||
if (rafCount < 3) {
|
if (rafCount < 5) {
|
||||||
rafId = requestAnimationFrame(enforceScroll);
|
rafId = requestAnimationFrame(enforceScroll);
|
||||||
} else {
|
} else {
|
||||||
logDebug('[DatabaseViews] scroll restoration completed', {
|
logDebug('[DatabaseViews] scroll restoration completed', {
|
||||||
final: scrollElement.scrollTop,
|
final: scrollElement.scrollTop,
|
||||||
target: targetScroll,
|
target: targetScroll,
|
||||||
});
|
});
|
||||||
|
// Remove scroll listener and clean up
|
||||||
|
scrollElement.removeEventListener('scroll', preventScroll);
|
||||||
lastScrollRef.current = null;
|
lastScrollRef.current = null;
|
||||||
setViewVisible(true);
|
setViewVisible(true);
|
||||||
|
// Release height lock to allow view to resize to its natural height
|
||||||
|
if (!fixedHeight) {
|
||||||
|
setLockedHeight(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -204,6 +219,7 @@ function DatabaseViews({
|
|||||||
if (rafId) {
|
if (rafId) {
|
||||||
cancelAnimationFrame(rafId);
|
cancelAnimationFrame(rafId);
|
||||||
}
|
}
|
||||||
|
scrollElement.removeEventListener('scroll', preventScroll);
|
||||||
};
|
};
|
||||||
}, [isLoading, viewId]);
|
}, [isLoading, viewId]);
|
||||||
|
|
||||||
@@ -251,20 +267,17 @@ function DatabaseViews({
|
|||||||
className={'relative flex h-full w-full flex-1 flex-col overflow-hidden'}
|
className={'relative flex h-full w-full flex-1 flex-col overflow-hidden'}
|
||||||
style={
|
style={
|
||||||
effectiveHeight !== null
|
effectiveHeight !== null
|
||||||
? { height: `${effectiveHeight}px` }
|
? { height: `${effectiveHeight}px`, maxHeight: `${effectiveHeight}px` }
|
||||||
: undefined
|
: undefined
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className='h-full w-full transition-opacity duration-100'
|
className='h-full w-full'
|
||||||
style={{
|
style={
|
||||||
...(effectiveHeight !== null
|
effectiveHeight !== null
|
||||||
? { minHeight: `${effectiveHeight}px`, height: `${effectiveHeight}px` }
|
? { height: `${effectiveHeight}px`, maxHeight: `${effectiveHeight}px` }
|
||||||
: {}),
|
: {}
|
||||||
opacity: viewVisible ? 1 : 0,
|
}
|
||||||
pointerEvents: viewVisible ? undefined : 'none',
|
|
||||||
}}
|
|
||||||
aria-hidden={!viewVisible}
|
|
||||||
>
|
>
|
||||||
<Suspense fallback={skeleton}>
|
<Suspense fallback={skeleton}>
|
||||||
<ErrorBoundary fallbackRender={ElementFallbackRender}>{view}</ErrorBoundary>
|
<ErrorBoundary fallbackRender={ElementFallbackRender}>{view}</ErrorBoundary>
|
||||||
|
|||||||
@@ -67,25 +67,6 @@ export const DatabaseBlock = memo(
|
|||||||
};
|
};
|
||||||
}, [doc, viewId]);
|
}, [doc, viewId]);
|
||||||
|
|
||||||
const EMBEDDED_DB_HEIGHT = 560;
|
|
||||||
|
|
||||||
const logContainerSize = () => {
|
|
||||||
if (!containerRef.current) return;
|
|
||||||
const rect = containerRef.current.getBoundingClientRect();
|
|
||||||
console.debug('[DatabaseBlock] container size', {
|
|
||||||
viewId,
|
|
||||||
selectedViewId,
|
|
||||||
width,
|
|
||||||
height: rect.height,
|
|
||||||
paddingStart,
|
|
||||||
paddingEnd,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
logContainerSize();
|
|
||||||
}, [selectedViewId, width, paddingStart, paddingEnd]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div {...attributes} contentEditable={readOnly ? false : undefined} className='relative w-full cursor-pointer'>
|
<div {...attributes} contentEditable={readOnly ? false : undefined} className='relative w-full cursor-pointer'>
|
||||||
<div ref={ref} className='absolute left-0 top-0 h-full w-full caret-transparent'>
|
<div ref={ref} className='absolute left-0 top-0 h-full w-full caret-transparent'>
|
||||||
@@ -95,11 +76,6 @@ export const DatabaseBlock = memo(
|
|||||||
contentEditable={false}
|
contentEditable={false}
|
||||||
ref={containerRef}
|
ref={containerRef}
|
||||||
className='container-bg relative my-1 flex w-full select-none flex-col'
|
className='container-bg relative my-1 flex w-full select-none flex-col'
|
||||||
style={{
|
|
||||||
minHeight: EMBEDDED_DB_HEIGHT,
|
|
||||||
height: EMBEDDED_DB_HEIGHT,
|
|
||||||
width: '100%',
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<DatabaseContent
|
<DatabaseContent
|
||||||
selectedViewId={selectedViewId}
|
selectedViewId={selectedViewId}
|
||||||
@@ -121,7 +97,6 @@ export const DatabaseBlock = memo(
|
|||||||
onChangeView={onChangeView}
|
onChangeView={onChangeView}
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
context={context as DatabaseContextState}
|
context={context as DatabaseContextState}
|
||||||
fixedHeight={EMBEDDED_DB_HEIGHT}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user