@@ -964,6 +964,7 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
964964
965965 const statusBar = this . instantiationService . createInstance ( CellEditorStatusBar , editorPart ) ;
966966 const timer = new TimerRenderer ( statusBar . durationContainer ) ;
967+ const cellRunState = new RunStateRenderer ( statusBar . cellRunStatusContainer , runToolbar , this . instantiationService ) ;
967968
968969 const outputContainer = DOM . append ( container , $ ( '.output' ) ) ;
969970
@@ -986,7 +987,7 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
986987 container,
987988 cellContainer,
988989 statusBarContainer : statusBar . statusBarContainer ,
989- cellRunStatusContainer : statusBar . cellRunStatusContainer ,
990+ cellRunState ,
990991 cellStatusMessageContainer : statusBar . cellStatusMessageContainer ,
991992 languageStatusBarItem : statusBar . languageStatusBarItem ,
992993 progressBar,
@@ -1022,26 +1023,6 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
10221023 return templateData ;
10231024 }
10241025
1025- private updateForRunState ( runState : NotebookCellRunState | undefined , templateData : CodeCellRenderTemplate ) : void {
1026- if ( typeof runState === 'undefined' ) {
1027- runState = NotebookCellRunState . Idle ;
1028- }
1029-
1030- if ( runState === NotebookCellRunState . Running ) {
1031- templateData . progressBar . infinite ( ) . show ( 500 ) ;
1032-
1033- templateData . runToolbar . setActions ( [
1034- this . instantiationService . createInstance ( CancelCellAction )
1035- ] ) ;
1036- } else {
1037- templateData . progressBar . hide ( ) ;
1038-
1039- templateData . runToolbar . setActions ( [
1040- this . instantiationService . createInstance ( ExecuteCellAction )
1041- ] ) ;
1042- }
1043- }
1044-
10451026 private updateForOutputs ( element : CodeCellViewModel , templateData : CodeCellRenderTemplate ) : void {
10461027 if ( element . outputs . length ) {
10471028 DOM . show ( templateData . focusSinkElement ) ;
@@ -1056,15 +1037,7 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
10561037 this . updateExecutionOrder ( metadata , templateData ) ;
10571038 templateData . cellStatusMessageContainer . textContent = metadata ?. statusMessage || '' ;
10581039
1059- if ( metadata . runState === NotebookCellRunState . Success ) {
1060- templateData . cellRunStatusContainer . innerHTML = renderCodicons ( '$(check)' ) ;
1061- } else if ( metadata . runState === NotebookCellRunState . Error ) {
1062- templateData . cellRunStatusContainer . innerHTML = renderCodicons ( '$(error)' ) ;
1063- } else if ( metadata . runState === NotebookCellRunState . Running ) {
1064- templateData . cellRunStatusContainer . innerHTML = renderCodicons ( '$(sync~spin)' ) ;
1065- } else {
1066- templateData . cellRunStatusContainer . innerHTML = '' ;
1067- }
1040+ templateData . cellRunState . renderState ( element . metadata ?. runState ) ;
10681041
10691042 if ( metadata . runState === NotebookCellRunState . Running ) {
10701043 if ( metadata . runStartTime ) {
@@ -1082,7 +1055,11 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
10821055 this . editorOptions . setGlyphMargin ( metadata . breakpointMargin ) ;
10831056 }
10841057
1085- this . updateForRunState ( metadata . runState , templateData ) ;
1058+ if ( metadata . runState === NotebookCellRunState . Running ) {
1059+ templateData . progressBar . infinite ( ) . show ( 500 ) ;
1060+ } else {
1061+ templateData . progressBar . hide ( ) ;
1062+ }
10861063 }
10871064
10881065 private updateExecutionOrder ( metadata : NotebookCellMetadata , templateData : CodeCellRenderTemplate ) : void {
@@ -1141,6 +1118,7 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
11411118 this . updateForLayout ( element , templateData ) ;
11421119 } ) ) ;
11431120
1121+ templateData . cellRunState . clear ( ) ;
11441122 this . updateForMetadata ( element , templateData ) ;
11451123 this . updateForHover ( element , templateData ) ;
11461124 elementDisposables . add ( element . onDidChangeState ( ( e ) => {
@@ -1230,3 +1208,50 @@ export class TimerRenderer {
12301208 return `${ seconds } .${ tenths } s` ;
12311209 }
12321210}
1211+
1212+ export class RunStateRenderer {
1213+ private static readonly MIN_SPINNER_TIME = 200 ;
1214+
1215+ private spinnerTimer : NodeJS . Timeout | undefined ;
1216+ private pendingNewState : NotebookCellRunState | undefined ;
1217+
1218+ constructor ( private readonly element : HTMLElement , private readonly runToolbar : ToolBar , private readonly instantiationService : IInstantiationService ) {
1219+ }
1220+
1221+ clear ( ) {
1222+ if ( this . spinnerTimer ) {
1223+ clearTimeout ( this . spinnerTimer ) ;
1224+ }
1225+ }
1226+
1227+ renderState ( runState : NotebookCellRunState = NotebookCellRunState . Idle ) {
1228+ if ( this . spinnerTimer ) {
1229+ this . pendingNewState = runState ;
1230+ return ;
1231+ }
1232+
1233+ if ( runState === NotebookCellRunState . Running ) {
1234+ this . runToolbar . setActions ( [ this . instantiationService . createInstance ( CancelCellAction ) ] ) ;
1235+ } else {
1236+ this . runToolbar . setActions ( [ this . instantiationService . createInstance ( ExecuteCellAction ) ] ) ;
1237+ }
1238+
1239+ if ( runState === NotebookCellRunState . Success ) {
1240+ this . element . innerHTML = renderCodicons ( '$(check)' ) ;
1241+ } else if ( runState === NotebookCellRunState . Error ) {
1242+ this . element . innerHTML = renderCodicons ( '$(error)' ) ;
1243+ } else if ( runState === NotebookCellRunState . Running ) {
1244+ this . element . innerHTML = renderCodicons ( '$(sync~spin)' ) ;
1245+
1246+ this . spinnerTimer = setTimeout ( ( ) => {
1247+ this . spinnerTimer = undefined ;
1248+ if ( this . pendingNewState ) {
1249+ this . renderState ( this . pendingNewState ) ;
1250+ this . pendingNewState = undefined ;
1251+ }
1252+ } , RunStateRenderer . MIN_SPINNER_TIME ) ;
1253+ } else {
1254+ this . element . innerHTML = '' ;
1255+ }
1256+ }
1257+ }
0 commit comments