11import { DocumentCommands , LibroView } from '@difizen/libro-jupyter/noeditor' ;
22import { CommandRegistry , Container , Disposable , ViewRender } from '@difizen/mana-app' ;
3+ import debounce from 'lodash/debounce' ;
34import * as React from 'react' ;
45
56import { message } from '@opensumi/ide-components' ;
67import { localize , useInjectable } from '@opensumi/ide-core-browser' ;
78import { ReactEditorComponent } from '@opensumi/ide-editor/lib/browser/types' ;
89
10+ import { LibroStateManager } from './libro-state-manager' ;
911import styles from './libro.module.less' ;
1012import { ILibroOpensumiService } from './libro.service' ;
1113import { ManaContainer } from './mana' ;
@@ -16,16 +18,47 @@ export const OpensumiLibroView: ReactEditorComponent = (...params) => {
1618 const libroOpensumiService = useInjectable < ILibroOpensumiService > ( ILibroOpensumiService ) ;
1719 const manaContainer = useInjectable < Container > ( ManaContainer ) ;
1820 const commandRegistry = manaContainer . get ( CommandRegistry ) ;
21+ const stateManager = useInjectable < LibroStateManager > ( LibroStateManager ) ;
1922
2023 const [ libroView , setLibroView ] = React . useState < LibroView | undefined > ( undefined ) ;
24+ const [ isStateRestored , setIsStateRestored ] = React . useState ( false ) ;
25+ const uri = params [ 0 ] . resource . uri ;
26+
27+ // 保存状态的函数
28+ const saveNotebookState = React . useCallback ( ( ) => {
29+ if ( libroView && uri ) {
30+ stateManager . saveState ( uri , libroView ) ;
31+ }
32+ } , [ libroView , uri , stateManager ] ) ;
33+
34+ // 恢复状态的函数
35+ const restoreNotebookState = React . useCallback ( async ( ) => {
36+ if ( libroView && uri && ! isStateRestored ) {
37+ const restored = await stateManager . restoreState ( uri , libroView ) ;
38+ if ( restored ) {
39+ setIsStateRestored ( true ) ;
40+ }
41+ }
42+ } , [ libroView , uri , stateManager , isStateRestored ] ) ;
2143
2244 React . useEffect ( ( ) => {
2345 let autoSaveHandle : undefined | number ;
2446 let modelChangeDisposer : undefined | Disposable ;
25- libroOpensumiService . getOrCreateLibroView ( params [ 0 ] . resource . uri ) . then ( ( libro ) => {
47+
48+ // 监听滚动变化(防抖)
49+ const handleScroll = debounce ( ( ) => {
50+ saveNotebookState ( ) ;
51+ } , 500 ) ;
52+
53+ libroOpensumiService . getOrCreateLibroView ( uri ) . then ( ( libro ) => {
2654 setLibroView ( libro ) ;
55+
56+ // 恢复状态
57+ restoreNotebookState ( ) ;
58+
59+ // 监听模型变化
2760 modelChangeDisposer = libro . model . onChanged ( ( ) => {
28- libroOpensumiService . updateDirtyStatus ( params [ 0 ] . resource . uri , true ) ;
61+ libroOpensumiService . updateDirtyStatus ( uri , true ) ;
2962 if ( autoSaveHandle ) {
3063 window . clearTimeout ( autoSaveHandle ) ;
3164 }
@@ -42,15 +75,37 @@ export const OpensumiLibroView: ReactEditorComponent = (...params) => {
4275 } ) ;
4376 } , AUTO_SAVE_DELAY ) ;
4477 } ) ;
78+
4579 libro . onSave ( ( ) => {
46- libroOpensumiService . updateDirtyStatus ( params [ 0 ] . resource . uri , false ) ;
80+ libroOpensumiService . updateDirtyStatus ( uri , false ) ;
4781 } ) ;
82+
83+ const libroViewContainer = libro . container ?. current ;
84+
85+ if ( libroViewContainer ) {
86+ const libroViewContent = libroViewContainer . querySelector ( LibroStateManager . LIBRO_SCROLL_ELEMENT ) ;
87+ libroViewContent ?. addEventListener ( 'scroll' , handleScroll ) ;
88+ }
4889 } ) ;
90+
4991 return ( ) => {
5092 modelChangeDisposer ?. dispose ( ) ;
5193 window . clearTimeout ( autoSaveHandle ) ;
94+ libroView ?. container ?. current
95+ ?. querySelector ( LibroStateManager . LIBRO_SCROLL_ELEMENT )
96+ ?. removeEventListener ( 'scroll' , handleScroll ) ;
5297 } ;
53- } , [ ] ) ;
98+ } , [ libroOpensumiService , uri , commandRegistry , stateManager , saveNotebookState , restoreNotebookState ] ) ;
99+
100+ // 当 notebook 完全加载后恢复状态
101+ React . useEffect ( ( ) => {
102+ if ( libroView && ! isStateRestored ) {
103+ const timer = setTimeout ( ( ) => {
104+ restoreNotebookState ( ) ;
105+ } , 100 ) ;
106+ return ( ) => clearTimeout ( timer ) ;
107+ }
108+ } , [ libroView , isStateRestored , restoreNotebookState ] ) ;
54109
55110 return < div className = { styles . libroView } > { libroView && < ViewRender view = { libroView } > </ ViewRender > } </ div > ;
56111} ;
0 commit comments