11import { DocumentCommands , LibroView } from '@difizen/libro-jupyter/noeditor' ;
2- import { CommandRegistry , Container , Disposable , ViewRender } from '@difizen/mana-app' ;
2+ import { CommandRegistry , Container , 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' ;
8+ import { Disposable } from '@opensumi/ide-core-common' ;
79import { ReactEditorComponent } from '@opensumi/ide-editor/lib/browser/types' ;
810
11+ import { LibroStateManager } from './libro-state-manager' ;
912import styles from './libro.module.less' ;
1013import { ILibroOpensumiService } from './libro.service' ;
1114import { ManaContainer } from './mana' ;
@@ -16,16 +19,47 @@ export const OpensumiLibroView: ReactEditorComponent = (...params) => {
1619 const libroOpensumiService = useInjectable < ILibroOpensumiService > ( ILibroOpensumiService ) ;
1720 const manaContainer = useInjectable < Container > ( ManaContainer ) ;
1821 const commandRegistry = manaContainer . get ( CommandRegistry ) ;
22+ const stateManager = useInjectable < LibroStateManager > ( LibroStateManager ) ;
1923
2024 const [ libroView , setLibroView ] = React . useState < LibroView | undefined > ( undefined ) ;
25+ const [ isStateRestored , setIsStateRestored ] = React . useState ( false ) ;
26+ const uri = params [ 0 ] . resource . uri ;
27+
28+ // 保存状态的函数
29+ const saveNotebookState = React . useCallback ( ( ) => {
30+ if ( libroView && uri ) {
31+ stateManager . saveState ( uri , libroView ) ;
32+ }
33+ } , [ libroView , uri , stateManager ] ) ;
34+
35+ // 恢复状态的函数
36+ const restoreNotebookState = React . useCallback ( async ( ) => {
37+ if ( libroView && uri && ! isStateRestored ) {
38+ const restored = await stateManager . restoreState ( uri , libroView ) ;
39+ if ( restored ) {
40+ setIsStateRestored ( true ) ;
41+ }
42+ }
43+ } , [ libroView , uri , stateManager , isStateRestored ] ) ;
2144
2245 React . useEffect ( ( ) => {
2346 let autoSaveHandle : undefined | number ;
2447 let modelChangeDisposer : undefined | Disposable ;
25- libroOpensumiService . getOrCreateLibroView ( params [ 0 ] . resource . uri ) . then ( ( libro ) => {
48+
49+ // 监听滚动变化(防抖)
50+ const handleScroll = debounce ( ( ) => {
51+ saveNotebookState ( ) ;
52+ } , 500 ) ;
53+
54+ libroOpensumiService . getOrCreateLibroView ( uri ) . then ( ( libro ) => {
2655 setLibroView ( libro ) ;
56+
57+ // 恢复状态
58+ restoreNotebookState ( ) ;
59+
60+ // 监听模型变化
2761 modelChangeDisposer = libro . model . onChanged ( ( ) => {
28- libroOpensumiService . updateDirtyStatus ( params [ 0 ] . resource . uri , true ) ;
62+ libroOpensumiService . updateDirtyStatus ( uri , true ) ;
2963 if ( autoSaveHandle ) {
3064 window . clearTimeout ( autoSaveHandle ) ;
3165 }
@@ -42,15 +76,37 @@ export const OpensumiLibroView: ReactEditorComponent = (...params) => {
4276 } ) ;
4377 } , AUTO_SAVE_DELAY ) ;
4478 } ) ;
79+
4580 libro . onSave ( ( ) => {
46- libroOpensumiService . updateDirtyStatus ( params [ 0 ] . resource . uri , false ) ;
81+ libroOpensumiService . updateDirtyStatus ( uri , false ) ;
4782 } ) ;
83+
84+ const libroViewContainer = libro . container ?. current ;
85+
86+ if ( libroViewContainer ) {
87+ const libroViewContent = libroViewContainer . querySelector ( LibroStateManager . LIBRO_SCROLL_ELEMENT ) ;
88+ libroViewContent ?. addEventListener ( 'scroll' , handleScroll ) ;
89+ }
4890 } ) ;
91+
4992 return ( ) => {
5093 modelChangeDisposer ?. dispose ( ) ;
5194 window . clearTimeout ( autoSaveHandle ) ;
95+ libroView ?. container ?. current
96+ ?. querySelector ( LibroStateManager . LIBRO_SCROLL_ELEMENT )
97+ ?. removeEventListener ( 'scroll' , handleScroll ) ;
5298 } ;
53- } , [ ] ) ;
99+ } , [ libroOpensumiService , uri , commandRegistry , stateManager , saveNotebookState , restoreNotebookState ] ) ;
100+
101+ // 当 notebook 完全加载后恢复状态
102+ React . useEffect ( ( ) => {
103+ if ( libroView && ! isStateRestored ) {
104+ const timer = setTimeout ( ( ) => {
105+ restoreNotebookState ( ) ;
106+ } , 100 ) ;
107+ return ( ) => clearTimeout ( timer ) ;
108+ }
109+ } , [ libroView , isStateRestored , restoreNotebookState ] ) ;
54110
55111 return < div className = { styles . libroView } > { libroView && < ViewRender view = { libroView } > </ ViewRender > } </ div > ;
56112} ;
0 commit comments