@ -197,6 +197,7 @@ export class GristDoc extends DisposableWithEvents {
private _isRickRowing : Observable < boolean > = Observable . create ( this , false ) ;
private _isRickRowing : Observable < boolean > = Observable . create ( this , false ) ;
private _showBackgroundVideoPlayer : Observable < boolean > = Observable . create ( this , false ) ;
private _showBackgroundVideoPlayer : Observable < boolean > = Observable . create ( this , false ) ;
private _backgroundVideoPlayerHolder : Holder < YouTubePlayer > = Holder . create ( this ) ;
private _backgroundVideoPlayerHolder : Holder < YouTubePlayer > = Holder . create ( this ) ;
private _disableAutoStartingTours : boolean = false ;
constructor (
constructor (
@ -278,54 +279,56 @@ export class GristDoc extends DisposableWithEvents {
// Subscribe to URL state, and navigate to anchor or open a popup if necessary.
// Subscribe to URL state, and navigate to anchor or open a popup if necessary.
this . autoDispose ( subscribe ( urlState ( ) . state , async ( use , state ) = > {
this . autoDispose ( subscribe ( urlState ( ) . state , async ( use , state ) = > {
if ( state . hash ) {
if ( ! state . hash ) { return ; }
try {
if ( state . hash . popup ) {
try {
await this . openPopup ( state . hash ) ;
if ( state . hash . popup ) {
} else {
await this . openPopup ( state . hash ) ;
// Navigate to an anchor if one is present in the url hash.
} else {
const cursorPos = this . _getCursorPosFromHash ( state . hash ) ;
// Navigate to an anchor if one is present in the url hash.
await this . recursiveMoveToCursorPos ( cursorPos , true ) ;
const cursorPos = this . _getCursorPosFromHash ( state . hash ) ;
}
await this . recursiveMoveToCursorPos ( cursorPos , true ) ;
if ( state . hash . rickRow && ! this . _isRickRowing . get ( ) ) {
}
YouTubePlayer . create ( this . _backgroundVideoPlayerHolder , RICK_ROLL_YOUTUBE_EMBED_ID , {
height : '100%' ,
const isTourOrTutorialActive = isTourActive ( ) || this . docModel . isTutorial ( ) ;
width : '100%' ,
if ( state . hash . rickRow && ! this . _isRickRowing . get ( ) && ! isTourOrTutorialActive ) {
origin : getMainOrgUrl ( ) ,
YouTubePlayer . create ( this . _backgroundVideoPlayerHolder , RICK_ROLL_YOUTUBE_EMBED_ID , {
playerVars : {
height : '100%' ,
controls : 0 ,
width : '100%' ,
disablekb : 1 ,
origin : getMainOrgUrl ( ) ,
fs : 0 ,
playerVars : {
iv_load_policy : 3 ,
controls : 0 ,
modestbranding : 1 ,
disablekb : 1 ,
} ,
fs : 0 ,
onPlayerStateChange : ( _player , event ) = > {
iv_load_policy : 3 ,
if ( event . data === PlayerState . Playing ) {
modestbranding : 1 ,
this . _isRickRowing . set ( true ) ;
} ,
}
onPlayerStateChange : ( _player , event ) = > {
} ,
if ( event . data === PlayerState . Playing ) {
} , cssYouTubePlayer . cls ( '' ) ) ;
this . _isRickRowing . set ( true ) ;
this . _showBackgroundVideoPlayer . set ( true ) ;
}
this . _waitForView ( )
} ,
. then ( ( ) = > {
} , cssYouTubePlayer . cls ( '' ) ) ;
const cursor = document . querySelector ( '.selected_cursor.active_cursor' ) ;
this . _showBackgroundVideoPlayer . set ( true ) ;
if ( cursor ) {
this . _waitForView ( )
this . behavioralPromptsManager . showTip ( cursor , 'rickRow' , {
. then ( ( ) = > {
forceShow : true ,
const cursor = document . querySelector ( '.selected_cursor.active_cursor' ) ;
hideDontShowTips : true ,
if ( ! cursor ) { return ; }
markAsSeen : false ,
showOnMobile : true ,
this . behavioralPromptsManager . showTip ( cursor , 'rickRow' , {
onDispose : ( ) = > this . playRickRollVideo ( ) ,
forceShow : true ,
} ) ;
hideDontShowTips : true ,
}
markAsSeen : false ,
} )
showOnMobile : true ,
. catch ( reportError ) ;
onDispose : ( ) = > this . playRickRollVideo ( ) ,
}
} ) ;
} catch ( e ) {
} )
reportError ( e ) ;
. catch ( reportError ) ;
} finally {
setTimeout ( finalizeAnchor , 0 ) ;
}
}
} catch ( e ) {
reportError ( e ) ;
} finally {
setTimeout ( finalizeAnchor , 0 ) ;
}
}
} ) ) ;
} ) ) ;
@ -337,12 +340,17 @@ export class GristDoc extends DisposableWithEvents {
return ;
return ;
}
}
const shouldStart Tutorial = this . docModel . isTutorial ( ) ;
const i sTutorial = this . docModel . isTutorial ( ) ;
// Onboarding tours were not designed with mobile support in mind. Disable until fixed.
// Onboarding tours were not designed with mobile support in mind. Disable until fixed.
if ( isNarrowScreen ( ) && ! shouldStart Tutorial) {
if ( isNarrowScreen ( ) && ! i sTutorial) {
return ;
return ;
}
}
// Onboarding tours can conflict with rick rowing.
if ( state . hash ? . rickRow ) {
this . _disableAutoStartingTours = true ;
}
// If we have an active tour or tutorial (or are in the process of starting one), don't start
// If we have an active tour or tutorial (or are in the process of starting one), don't start
// a new one.
// a new one.
const hasActiveTourOrTutorial = isTourActive ( ) || ! this . _docTutorialHolder . isEmpty ( ) ;
const hasActiveTourOrTutorial = isTourActive ( ) || ! this . _docTutorialHolder . isEmpty ( ) ;
@ -350,6 +358,7 @@ export class GristDoc extends DisposableWithEvents {
return ;
return ;
}
}
const shouldStartTutorial = isTutorial ;
const shouldStartDocTour = state . docTour || this . _shouldAutoStartDocTour ( ) ;
const shouldStartDocTour = state . docTour || this . _shouldAutoStartDocTour ( ) ;
const shouldStartWelcomeTour = state . welcomeTour || this . _shouldAutoStartWelcomeTour ( ) ;
const shouldStartWelcomeTour = state . welcomeTour || this . _shouldAutoStartWelcomeTour ( ) ;
if ( shouldStartTutorial || shouldStartDocTour || shouldStartWelcomeTour ) {
if ( shouldStartTutorial || shouldStartDocTour || shouldStartWelcomeTour ) {
@ -1438,7 +1447,7 @@ export class GristDoc extends DisposableWithEvents {
* seen the tour before .
* seen the tour before .
* /
* /
private _shouldAutoStartDocTour ( ) : boolean {
private _shouldAutoStartDocTour ( ) : boolean {
if ( this . docModel. isTutorial ( ) ) {
if ( this . _disableAutoStartingTours || this . docModel. isTutorial ( ) ) {
return false ;
return false ;
}
}
@ -1454,7 +1463,7 @@ export class GristDoc extends DisposableWithEvents {
private _shouldAutoStartWelcomeTour ( ) : boolean {
private _shouldAutoStartWelcomeTour ( ) : boolean {
// If a doc tutorial or tour are available, leave the welcome tour for another
// If a doc tutorial or tour are available, leave the welcome tour for another
// doc (e.g. a new one).
// doc (e.g. a new one).
if ( this . docModel. isTutorial ( ) || this . docModel . hasDocTour ( ) ) {
if ( this . _disableAutoStartingTours || this . docModel. isTutorial ( ) || this . docModel . hasDocTour ( ) ) {
return false ;
return false ;
}
}