import { Component , Injector , OnDestroy , OnInit } from '@angular/core' ; import { BehaviorSubject , Observable , of , Subscription , timer } from 'rxjs' ; import { OnboardingResponse , OnboardingV3Service , OnboardingStepName , OnboardingStep , RELEASED_GROUPS , } from '../onboarding-v3.service' ; import { OnboardingV3PanelService } from '../panel/onboarding-panel.service' ; import { ModalService } from '../../composer/components/modal/modal.service' ; import { ComposerService } from '../../composer/services/composer.service' ; import { FormToastService } from '../../../common/services/form-toast.service' ; import { catchError , scan , take , takeWhile , tap } from 'rxjs/operators' ; import { EmailConfirmationService } from '../../../common/components/email-confirmation/email-confirmation.service' ; import { EmailResendService } from '../../../common/services/email-resend.service' ; /**
 * Onboarding widget that tracks user progress through onboarding.
 */ @ Component ( { selector : 'm-onboardingProgressWidget' , templateUrl : './onboarding-widget.component.html' , styleUrls : [ './onboarding-widget.component.ng.scss' ] , providers : [ ComposerService ] , } ) export class OnboardingV3WidgetComponent implements OnInit , OnDestroy { private subscriptions : Subscription [ ] = [ ] ; /**
     * If true, widget will be collapsed.
     */ public collapsed = false ; /**
     * If true, all steps are completed.
     */ public completed$ : BehaviorSubject < boolean > = new BehaviorSubject < boolean > ( false ) ; constructor ( private onboarding , private panel , private composerModal , private injector , private toast , private emailResend ) { } ngOnInit ( ) { this . onboarding . load ( ) ; this . subscriptions . push ( this . progress$ . subscribe ( progress => { this . checkCompletion ( ) ; } ) ) ; } ngOnDestroy ( ) { for ( let subscription of this . subscriptions ) { subscription . unsubscribe ( ) ; } } returns get progress$ ( ) : Observable < OnboardingResponse > { return this . onboarding . progress$ ; } returns get loading$ ( ) : Observable < boolean > { return this . onboarding . loading$ ; } param { OnboardingStepName } returns { Promise < void > } public async onTaskClick ( step ) { try { this . subscriptions . push ( this . progress$ . pipe ( take ( 1 ) , catchError ( ( err ) => { console . error ( err ) ; return of ( null ) ; } ) , tap ( async ( progress ) => { switch ( step ) { case 'VerifyEmailStep' : if ( this . isStepComplete ( step , progress ) ) { this . toast . inform ( 'Your email address has already been confirmed.' ) ; break ; } this . resendEmailConfirmation ( ) ; break ; case 'CreatePostStep' : this . composerModal . setInjector ( this . injector ) . present ( ) . toPromise ( ) . then ( response => { if ( response ) { this . onboarding . forceCompletion ( 'CreatePostStep' ) ; this . checkCompletion ( ) ; } } ) ; break ; case 'VerifyUniquenessStep' : if ( this . isStepComplete ( step , progress ) ) { this . toast . inform ( 'You have already completed this step' ) ; break ; } default : this . panel . currentStep$ . next ( step ) ; try { await this . onboarding . open ( ) ; } catch ( e ) { if ( e === 'DismissedModalException' ) { await this . onboarding . load ( ) ; this . checkCompletion ( ) ; return ; } console . error ( e ) ; } break ; } } ) ) . subscribe ( ) ) ; } catch ( e ) { if ( e === 'DismissedModalException' ) { this . checkCompletion ( ) ; } console . error ( e ) ; } } param { 'show' | 'hide' } returns { void } public onHideClick ( option ) { if ( option === 'hide' ) { this . collapsed = true ; return ; } if ( option === 'show' ) { this . collapsed = false ; this . onboarding . load ( ) ; return ; } } returns { void } private checkCompletion ( ) { this . subscriptions . push ( this . progress$ . pipe ( take ( 1 ) , catchError ( e => { console . error ( e ) ; return of ( e ) ; } ) , tap ( ( progress ) => { if ( ! progress ) { return ; } if ( RELEASED_GROUPS . indexOf ( progress . id ) === - 1 ) { this . completed$ . next ( true ) ; return ; } if ( progress . is_completed ) { this . completed$ . next ( true ) ; } const completedSteps = this . getCompletedSteps ( progress ) ; if ( completedSteps . length === progress . steps . length ) { this . completed$ . next ( true ) ; return ; } } ) ) . subscribe ( ) ) ; } param { OnboardingResponse } progress returns { OnboardingStep [ ] } private getCompletedSteps ( progress ) { return progress . steps . filter ( ( progressStep ) => { return progressStep . is_completed ; } ) ; } param { OnboardingStepName } stepName param { OnboardingResponse } progress private isStepComplete ( stepName , progress ) { return ( this . getCompletedSteps ( progress ) . map ( step => { return step . id ; } ) . indexOf ( stepName ) !== - 1 ) ; } returns { Promise < boolean > } private async resendEmailConfirmation ( ) { this . emailResend . send ( ) ; } }