refactor: refactor lock scroll

This commit is contained in:
qishaoxuan
2022-07-28 15:52:17 +08:00
parent 439eb90e93
commit f4d3a6eafa
3 changed files with 83 additions and 102 deletions

View File

@@ -1,5 +1,5 @@
/* eslint-disable filename-rules/match */
import { useEffect, useRef, type UIEvent } from 'react';
import { useEffect, useRef, type UIEvent, useState } from 'react';
import { useParams } from 'react-router';
import {
MuiBox as Box,
@@ -37,8 +37,6 @@ export function Page(props: PageProps) {
const { user } = useUserAndSpaces();
const templatesPortalFlag = useFlag('BooleanTemplatesPortal', false);
const dailyNotesFlag = useFlag('BooleanDailyNotes', false);
const editorRef = useRef<BlockEditor>();
const scrollContainerRef = useRef();
useEffect(() => {
if (!user?.id || !page_id) return;
@@ -61,16 +59,6 @@ export function Page(props: PageProps) {
updateRecentPages();
}, [user, props.workspace, page_id]);
const onScroll = (event: UIEvent) => {
editorRef.current.getHooks().onRootNodeScroll(event);
editorRef.current.scrollManager.emitScrollEvent(event);
};
useEffect(() => {
editorRef.current.scrollManager.scrollContainer =
scrollContainerRef.current;
}, []);
return (
<LigoApp>
<LigoLeftContainer style={{ width: fixedDisplay ? '300px' : 0 }}>
@@ -115,11 +103,46 @@ export function Page(props: PageProps) {
</WorkspaceSidebarContent>
</WorkspaceSidebar>
</LigoLeftContainer>
<LigoRightContainer ref={scrollContainerRef} onScroll={onScroll}>
{page_id ? (
<EditorContainer workspace={props.workspace} pageId={page_id} />
</LigoApp>
);
}
const EditorContainer = ({
pageId,
workspace,
}: {
pageId: string;
workspace: string;
}) => {
const [lockScroll, setLockScroll] = useState(false);
const scrollContainerRef = useRef();
const editorRef = useRef<BlockEditor>();
const onScroll = (event: UIEvent) => {
editorRef.current.getHooks().onRootNodeScroll(event);
editorRef.current.scrollManager.emitScrollEvent(event);
};
useEffect(() => {
editorRef.current.scrollManager.scrollContainer =
scrollContainerRef.current;
editorRef.current.scrollManager.scrollController = {
lockScroll: () => setLockScroll(true),
unLockScroll: () => setLockScroll(false),
};
}, []);
return (
<StyledEditorContainer
lockScroll={lockScroll}
ref={scrollContainerRef}
onScroll={onScroll}
>
{pageId ? (
<AffineEditor
workspace={props.workspace}
rootBlockId={page_id}
workspace={workspace}
rootBlockId={pageId}
ref={editorRef}
/>
) : (
@@ -134,10 +157,19 @@ export function Page(props: PageProps) {
<CircularProgress />
</Box>
)}
</LigoRightContainer>
</LigoApp>
</StyledEditorContainer>
);
};
const StyledEditorContainer = styled('div')<{ lockScroll: boolean }>(
({ lockScroll }) => {
return {
width: '100%',
overflowY: lockScroll ? 'hidden' : 'auto',
flex: 'auto',
};
}
);
const LigoApp = styled('div')({
width: '100vw',
@@ -147,12 +179,6 @@ const LigoApp = styled('div')({
margin: '10px 0',
});
const LigoRightContainer = styled('div')({
width: '100%',
overflowY: 'auto',
flex: 'auto',
});
const LigoLeftContainer = styled('div')({
flex: '0 0 auto',
position: 'relative',

View File

@@ -14,6 +14,8 @@ html {
font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, Tahoma,
PingFang SC, Microsoft Yahei, Arial, Hiragino Sans GB, sans-serif,
Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji;
/* prevent page shaking when scroll show or hide*/
padding-left: calc(100vw - 100%);
}
*,

View File

@@ -9,27 +9,9 @@ import { AsyncBlock } from '../block';
type VerticalTypes = 'up' | 'down' | null;
type HorizontalTypes = 'left' | 'right' | null;
const setStyle = (dom: HTMLElement, style: CSSProperties) => {
const styleStr = Object.entries(style).reduce(
(styleStr, [styleName, styleValue]) => {
return `${styleStr} ${styleName}: ${styleValue};`;
},
''
);
dom.setAttribute('style', styleStr);
};
// 这里只获取 style 里设置过的属性
// 在恢复 body 后重新设置,不需要获取计算属性
const getStyle = (dom: HTMLElement, styleName: any) => {
return dom.style[styleName];
};
const getStyles = (dom: HTMLElement, styleNames: any[]) => {
return styleNames.reduce((style, styleName) => {
style[styleName] = getStyle(dom, styleName);
return style;
}, {});
type ScrollController = {
lockScroll: () => void;
unLockScroll: () => void;
};
export class ScrollManager {
@@ -44,12 +26,10 @@ export class ScrollManager {
private _scrollMoveOffset = 8;
private _autoScrollMoveOffset = 8;
private _scrollingEvent = new EventEmitter();
private _isFrozen = false;
private _scrollContainerStyle: CSSProperties = {};
private _scrollController: ScrollController;
constructor(editor: BlockEditor) {
this._editor = editor;
(window as any).scrollManager = this;
}
@@ -82,6 +62,14 @@ export class ScrollManager {
this._scrollContainer = dom;
}
public get scrollController() {
return this._scrollController;
}
public set scrollController(controller: ScrollController) {
this._scrollController = controller;
}
public get verticalScrollTriggerDistance() {
return 15;
}
@@ -308,46 +296,11 @@ export class ScrollManager {
}
}
public frozen() {
if (this._isFrozen) {
return;
public lock() {
this._scrollController.lockScroll();
}
this._scrollContainerStyle = getStyles(this._scrollContainer, [
// 'position',
// 'top',
// 'left',
'overflow',
'height',
]);
// const [recordScrollLeft, recordScrollTop] = this._scrollRecord;
setStyle(this._scrollContainer, {
// Position style maybe should set in mobile
// position: 'fixed',
// top: `-${recordScrollTop}px`,
// left: `-${recordScrollLeft}px`,
overflow: 'hidden',
height: '100%',
});
this._isFrozen = true;
}
public thaw() {
if (!this._isFrozen) {
return;
}
setStyle(this._scrollContainer, this._scrollContainerStyle);
const [recordScrollLeft, recordScrollTop] = this._scrollRecord;
this._scrollContainer.scrollTo(recordScrollLeft, recordScrollTop);
this._scrollContainerStyle = {};
this._isFrozen = false;
public unLock() {
this._scrollController.unLockScroll();
}
}