fix(core): remember scroll position switch mode (#8771)

This commit is contained in:
EYHN
2024-11-12 06:05:51 +00:00
parent e6a4fc7210
commit 51b00c476c
@@ -30,20 +30,22 @@ export class Editor extends Entity {
readonly doc = this.docService.doc; readonly doc = this.docService.doc;
readonly isSharedMode = readonly isSharedMode =
this.workspaceService.workspace.openOptions.isSharedMode; this.workspaceService.workspace.openOptions.isSharedMode;
readonly editorContainer$ = new LiveData<AffineEditorContainer | null>(null); readonly editorContainer$ = new LiveData<AffineEditorContainer | null>(null);
readonly defaultOpenProperty$ = new LiveData<DefaultOpenProperty | undefined>( readonly defaultOpenProperty$ = new LiveData<DefaultOpenProperty | undefined>(
undefined undefined
); );
workbenchView: WorkbenchView | null = null; workbenchView: WorkbenchView | null = null;
defaultScrollPosition: scrollPosition: {
| number page: number | null;
| { edgeless: {
centerX: number; centerX: number;
centerY: number; centerY: number;
zoom: number; zoom: number;
} } | null;
| null = null; } = {
page: null,
edgeless: null,
};
private readonly focusAt$ = LiveData.computed(get => { private readonly focusAt$ = LiveData.computed(get => {
const selector = get(this.selector$); const selector = get(this.selector$);
@@ -96,13 +98,22 @@ export class Editor extends Entity {
/** /**
* sync editor params with view query string * sync editor params with view query string
*
* this function will be called when editor is initialized with in a workbench view
*
* this won't be called in shared page.
*/ */
bindWorkbenchView(view: WorkbenchView) { bindWorkbenchView(view: WorkbenchView) {
if (this.workbenchView) { if (this.workbenchView) {
throw new Error('already bound'); throw new Error('already bound');
} }
this.workbenchView = view; this.workbenchView = view;
this.defaultScrollPosition = view.getScrollPosition() ?? null; const savedScrollPosition = view.getScrollPosition() ?? null;
if (typeof savedScrollPosition === 'number') {
this.scrollPosition.page = savedScrollPosition;
} else if (typeof savedScrollPosition === 'object') {
this.scrollPosition.edgeless = savedScrollPosition;
}
const stablePrimaryMode = this.doc.getPrimaryMode(); const stablePrimaryMode = this.doc.getPrimaryMode();
@@ -198,26 +209,20 @@ export class Editor extends Entity {
const rootService = editorContainer.host?.std.getService('affine:page'); const rootService = editorContainer.host?.std.getService('affine:page');
// ----- Scroll Position and Selection ----- // ----- Scroll Position and Selection -----
if (this.defaultScrollPosition) { // if we have default scroll position, we should restore it
// if we have default scroll position, we should restore it if (this.mode$.value === 'page' && this.scrollPosition.page !== null) {
if ( scrollViewport?.scrollTo(0, this.scrollPosition.page);
this.mode$.value === 'page' && } else if (
typeof this.defaultScrollPosition === 'number' this.mode$.value === 'edgeless' &&
) { this.scrollPosition.edgeless &&
scrollViewport?.scrollTo(0, this.defaultScrollPosition || 0); rootService instanceof EdgelessRootService
} else if ( ) {
this.mode$.value === 'edgeless' && rootService.viewport.setViewport(this.scrollPosition.edgeless.zoom, [
typeof this.defaultScrollPosition === 'object' && this.scrollPosition.edgeless.centerX,
rootService instanceof EdgelessRootService this.scrollPosition.edgeless.centerY,
) { ]);
rootService.viewport.setViewport(this.defaultScrollPosition.zoom, [
this.defaultScrollPosition.centerX,
this.defaultScrollPosition.centerY,
]);
}
this.defaultScrollPosition = null; // reset default scroll position
} else { } else {
// if we don't have default scroll position, we should focus on the title
const initialFocusAt = this.focusAt$.value; const initialFocusAt = this.focusAt$.value;
if (initialFocusAt === null) { if (initialFocusAt === null) {
@@ -244,16 +249,19 @@ export class Editor extends Entity {
// update scroll position when scrollViewport scroll // update scroll position when scrollViewport scroll
const saveScrollPosition = () => { const saveScrollPosition = () => {
if (this.mode$.value === 'page' && scrollViewport) { if (this.mode$.value === 'page' && scrollViewport) {
this.scrollPosition.page = scrollViewport.scrollTop;
this.workbenchView?.setScrollPosition(scrollViewport.scrollTop); this.workbenchView?.setScrollPosition(scrollViewport.scrollTop);
} else if ( } else if (
this.mode$.value === 'edgeless' && this.mode$.value === 'edgeless' &&
rootService instanceof EdgelessRootService rootService instanceof EdgelessRootService
) { ) {
this.workbenchView?.setScrollPosition({ const pos = {
centerX: rootService.viewport.centerX, centerX: rootService.viewport.centerX,
centerY: rootService.viewport.centerY, centerY: rootService.viewport.centerY,
zoom: rootService.viewport.zoom, zoom: rootService.viewport.zoom,
}); };
this.scrollPosition.edgeless = pos;
this.workbenchView?.setScrollPosition(pos);
} }
}; };
scrollViewport?.addEventListener('scroll', saveScrollPosition); scrollViewport?.addEventListener('scroll', saveScrollPosition);