src/app/view-more-activity/view-more-activity.component.ts
                OnInit
    
| selector | app-view-more-activity | 
| styleUrls | ./view-more-activity.component.scss | 
| templateUrl | ./view-more-activity.component.html | 
| constructor(contentService: ContentService, eventBusService: EventsBusService, courseService: CourseService, preferences: SharedPreferences, events: Events, ngZone: NgZone, courseUtilService: CourseUtilService, commonUtilService: CommonUtilService, telemetryGeneratorService: TelemetryGeneratorService, headerService: AppHeaderService, route: ActivatedRoute, router: Router, location: Location, platform: Platform, zone: NgZone, appGlobalService: AppGlobalService, popoverCtrl: PopoverController, navService: NavigationService) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 
                                    Parameters :
                                     
 | 
| course | |
| Type : any | |
| env | |
| Type : string | |
| index | |
| Type : number | |
| layoutName | |
| Type : string | |
| Contains layout name  | |
| onProfile | |
| Type : boolean | |
| Default value : false | |
| pageName | |
| Type : string | |
| sectionName | |
| Type : string | |
| cancelDownload | 
| cancelDownload() | 
| 
                        Returns :          void | 
| Async checkRetiredOpenBatch | 
| checkRetiredOpenBatch(content: any, layoutName?: string, payload?: any) | 
| 
                        Returns :          any | 
| Private generateImpressionEvent | 
| generateImpressionEvent() | 
| 
                        Returns :          void | 
| Private generateLogEvent | ||||
| generateLogEvent(searchResult) | ||||
| 
                        Parameters :
                        
                         
 
                        Returns :          void | 
| getContentDetails | ||||
| getContentDetails(content) | ||||
| 
                        Parameters :
                        
                         
 
                        Returns :          void | 
| getContentImg | ||||
| getContentImg(content) | ||||
| 
                        Parameters :
                        
                         
 
                        Returns :          any | 
| getEnrolledCourse | 
| getEnrolledCourse() | 
| Get enrolled courses 
                        Returns :          void | 
| getEnrolledCourses | ||||||||
| getEnrolledCourses(returnRefreshedCourses: boolean) | ||||||||
| 
                        Parameters :
                        
                         
 
                        Returns :          void | 
| handleBackButton | 
| handleBackButton() | 
| 
                        Returns :          void | 
| importContent | ||||||
| importContent(identifiers, isChild) | ||||||
| 
                        Parameters :
                        
                         
 
                        Returns :          void | 
| ionViewWillEnter | 
| ionViewWillEnter() | 
| Ionic default life cycle hook 
                        Returns :          void | 
| ionViewWillLeave | 
| ionViewWillLeave() | 
| Ionic life cycle hook 
                        Returns :          void | 
| loadMore | 
| loadMore() | 
| Load more result 
                        Returns :          void | 
| Async mapper | 
| mapper() | 
| Mapper to call api based on page.Layout name 
                        Returns :          any | 
| Private Async navigateToBatchListPopup | |||||||||||||||
| navigateToBatchListPopup(content: any, layoutName?: string, retiredBatches?: any, payload?: any) | |||||||||||||||
| 
                        Parameters :
                        
                         
 
                        Returns :          any | 
| navigateToDetailPage | ||||||
| navigateToDetailPage(content: any) | ||||||
| 
                        Parameters :
                        
                         
 
                        Returns :          boolean | 
| Private Async navigateToDetailsPage | |||||||||
| navigateToDetailsPage(content: any, layoutName) | |||||||||
| 
                        Parameters :
                        
                         
 
                        Returns :          any | 
| ngOnInit | 
| ngOnInit() | 
| Angular life cycle hooks 
                        Returns :          void | 
| openCourseDetails | ||||||
| openCourseDetails(course, index) | ||||||
| 
                        Parameters :
                        
                         
 
                        Returns :          void | 
| Async search | 
| search() | 
| Search content 
                        Returns :          any | 
| showDisabled | ||||
| showDisabled(resource) | ||||
| 
                        Parameters :
                        
                         
 
                        Returns :          boolean | 
| subscribeSdkEvent | 
| subscribeSdkEvent() | 
| 
                        Returns :          void | 
| subscribeUtilityEvents | 
| subscribeUtilityEvents() | 
| 
                        Returns :          void | 
| audience | 
| Type : any | 
| backButtonFunc | 
| Type : Subscription | 
| Flag to switch between view-more-card in view | 
| defaultImg | 
| Type : string | 
| didViewLoad | 
| Type : boolean | 
| downloadPercentage | 
| Type : number | 
| Default value : 0 | 
| downloadsOnlyToggle | 
| Default value : false | 
| value for downloads only toggle button, may have true/false | 
| enrolledCourses | 
| Type : any | 
| Private eventSubscription | 
| Type : Subscription | 
| guestUser | 
| Type : any | 
| headerTitle | 
| Type : string | 
| identifier | 
| Type : string | 
| isLoading | 
| Default value : false | 
| isLoadMore | 
| Default value : false | 
| loader | 
| Type : any | 
| loadMoreBtn | 
| Default value : true | 
| Flag to show / hide button | 
| objId | 
| objType | 
| objVer | 
| offset | 
| Type : number | 
| Default value : 0 | 
| pageType | 
| Type : string | 
| Default value : 'library' | 
| Public platform | 
| Type : Platform | 
| queuedIdentifiers | 
| Type : Array<any> | 
| Default value : [] | 
| requestParams | 
| Type : any | 
| resumeContentData | 
| Type : any | 
| searchLimit | 
| Type : number | 
| Default value : 10 | 
| searchList | 
| Type : any | 
| searchQuery | 
| Type : any | 
| showLoader | 
| Type : any | 
| showOverlay | 
| Default value : false | 
| source | 
| Type : string | 
| Default value : '' | 
| tabBarElement | 
| Type : any | 
| Contains tab bar element ref | 
| title | 
| Type : any | 
| totalCount | 
| Type : number | 
| uid | 
| Type : any | 
| userId | 
| Type : any | 
import { Location } from '@angular/common';
import { Component, Inject, Input, NgZone, OnInit } from '@angular/core';
import { ActivatedRoute, NavigationExtras, Router } from '@angular/router';
import { BatchConstants, ContentCard, PreferenceKey, RouterLinks, ViewMore } from '@app/app/app.constant';
import { AppGlobalService } from '@app/services/app-global-service.service';
import { AppHeaderService } from '@app/services/app-header.service';
import { CommonUtilService } from '@app/services/common-util.service';
import { CourseUtilService } from '@app/services/course-util.service';
import { NavigationService } from '@app/services/navigation-handler.service';
import {
  CorReleationDataType, Environment,
  ImpressionType,
  InteractSubtype,
  InteractType,
  PageId
} from '@app/services/telemetry-constants';
import { TelemetryGeneratorService } from '@app/services/telemetry-generator.service';
import { ContentUtil } from '@app/util/content-util';
import { Platform, PopoverController } from '@ionic/angular';
import { Events } from '@app/util/events';
import { Subscription } from 'rxjs';
import {
  Batch, Content,
  ContentEventType,
  ContentImportRequest,
  ContentImportResponse,
  ContentImportStatus,
  ContentSearchCriteria,
  ContentSearchResult,
  ContentService,
  CorrelationData, Course,
  CourseBatchesRequest, CourseBatchStatus, CourseEnrollmentType, CourseService,
  DownloadEventType,
  DownloadProgress,
  EventsBusEvent,
  EventsBusService,
  FetchEnrolledCourseRequest, LogLevel, SearchType,
  SharedPreferences,
  SortOrder
} from 'sunbird-sdk';
import { EnrollmentDetailsComponent } from '../components/enrollment-details/enrollment-details.component';
@Component({
  selector: 'app-view-more-activity',
  templateUrl: './view-more-activity.component.html',
  styleUrls: ['./view-more-activity.component.scss'],
})
export class ViewMoreActivityComponent implements OnInit {
  searchQuery: any;
  title: any;
  searchList: any;
  showLoader: any;
  /**
   * Contains tab bar element ref
   */
  tabBarElement: any;
  /**
   * Flag to show / hide button
   */
  loadMoreBtn = true;
  /**
   * value for downloads only toggle button, may have true/false
   */
  downloadsOnlyToggle = false;
  offset = 0;
  searchLimit = 10;
  totalCount: number;
  isLoadMore = false;
  /**
   * Flag to switch between view-more-card in view
   */
  backButtonFunc: Subscription;
  headerTitle: string;
  pageType = 'library';
  source = '';
  queuedIdentifiers: Array<any> = [];
  downloadPercentage = 0;
  showOverlay = false;
  resumeContentData: any;
  uid: any;
  audience: any;
  defaultImg: string;
  private eventSubscription: Subscription;
  enrolledCourses: any;
  guestUser: any;
  userId: any;
  requestParams: any;
  @Input() course: any;
  /**
   * Contains layout name
   *
   * @example layoutName = In-progress / popular
   */
  @Input() layoutName: string;
  @Input() pageName: string;
  @Input() onProfile = false;
  @Input() index: number;
  @Input() sectionName: string;
  @Input() env: string;
  identifier: string;
  didViewLoad: boolean;
  objId;
  objType;
  objVer;
  loader: any;
  isLoading = false;
  constructor(
    @Inject('CONTENT_SERVICE') private contentService: ContentService,
    @Inject('EVENTS_BUS_SERVICE') private eventBusService: EventsBusService,
    @Inject('COURSE_SERVICE') private courseService: CourseService,
    @Inject('SHARED_PREFERENCES') private preferences: SharedPreferences,
    private events: Events,
    private ngZone: NgZone,
    private courseUtilService: CourseUtilService,
    private commonUtilService: CommonUtilService,
    private telemetryGeneratorService: TelemetryGeneratorService,
    private headerService: AppHeaderService,
    private route: ActivatedRoute,
    private router: Router,
    private location: Location,
    public platform: Platform,
    private zone: NgZone,
    private appGlobalService: AppGlobalService,
    private popoverCtrl: PopoverController,
    private navService: NavigationService
  ) {
    this.route.queryParams.subscribe(params => {
      if (this.router.getCurrentNavigation().extras.state) {
        console.log('params from state : ', this.router.getCurrentNavigation().extras.state);
        this.uid = this.router.getCurrentNavigation().extras.state.uid;
        this.title = this.router.getCurrentNavigation().extras.state.headerTitle;
        this.userId = this.router.getCurrentNavigation().extras.state.userId;
        this.pageName = this.router.getCurrentNavigation().extras.state.pageName;
        this.guestUser = this.router.getCurrentNavigation().extras.state.guestUser;
        this.searchQuery = this.router.getCurrentNavigation().extras.state.requestParams;
        this.audience = this.router.getCurrentNavigation().extras.state.audience;
        this.enrolledCourses = this.router.getCurrentNavigation().extras.state.enrolledCourses;
        if (this.router.getCurrentNavigation().extras.state.sectionName) {
          this.sectionName = this.router.getCurrentNavigation().extras.state.sectionName;
        }
        if (this.headerTitle !== this.title) {
          this.offset = 0;
          this.loadMoreBtn = true;
          this.mapper();
        }
      }
    });
    this.defaultImg = this.commonUtilService.convertFileSrc('assets/imgs/ic_launcher.png');
    this.subscribeUtilityEvents();
  }
  /**
   * Angular life cycle hooks
   */
  ngOnInit() {
    this.tabBarElement = document.querySelector('.tabbar.show-tabbar');
    if (this.tabBarElement) {
      this.tabBarElement.style.display = 'none';
    }
  }
  /**
   * Ionic default life cycle hook
   */
  ionViewWillEnter(): void {
    this.zone.run(() => {
      this.headerService.showHeaderWithBackButton();
      if (this.tabBarElement) {
        this.tabBarElement.style.display = 'none';
      }
      this.handleBackButton();
    });
  }
  subscribeUtilityEvents() {
    this.events.subscribe('viewMore:Courseresume', (data) => {
      this.resumeContentData = data.content;
      this.getContentDetails(data.content);
    });
  }
  handleBackButton() {
    this.backButtonFunc = this.platform.backButton.subscribeWithPriority(10, () => {
      this.location.back();
      this.backButtonFunc.unsubscribe();
    });
  }
  /**
   * Search content
   */
  async search() {
    this.isLoading = true;
    const selectedLanguage = await this.preferences.getString(PreferenceKey.SELECTED_LANGUAGE_CODE).toPromise();
    const searchCriteria: ContentSearchCriteria = {
      searchType: SearchType.FILTER,
      languageCode: selectedLanguage
    };
    this.searchQuery.request['searchType'] = SearchType.FILTER;
    this.searchQuery.request['offset'] = this.offset;
    this.contentService.searchContent(searchCriteria, this.searchQuery).toPromise()
      .then((data: ContentSearchResult) => {
        this.ngZone.run(() => {
          if (data && data.contentDataList) {
            this.loadMoreBtn = data.contentDataList.length >= this.searchLimit;
            if (this.isLoadMore) {
              data.contentDataList.forEach((value) => {
                this.searchList.push(value);
              });
            } else {
              this.searchList = data.contentDataList;
            }
          } else {
            this.loadMoreBtn = false;
          }
          this.isLoading = false;
        });
        this.generateImpressionEvent();
        this.generateLogEvent(data);
      })
      .catch(() => {
        console.error('Error: while fetching view more content');
        this.isLoading = false;
      });
  }
  /**
   * Load more result
   */
  loadMore() {
    this.isLoadMore = true;
    this.offset = this.offset + this.searchLimit;
    if (!this.commonUtilService.networkInfo.isNetworkAvailable) {
      this.commonUtilService.showToast(this.commonUtilService.translateMessage('NO_INTERNET_TITLE'));
    } else {
      this.mapper();
    }
  }
  /**
   * Mapper to call api based on page.Layout name
   */
  async mapper() {
    const pageName = this.pageName;
    switch (pageName) {
      case ViewMore.PAGE_COURSE_ENROLLED:
        this.pageType = 'enrolledCourse';
        this.loadMoreBtn = false;
        this.getEnrolledCourse();
        break;
      case ViewMore.PAGE_COURSE_POPULAR:
        this.pageType = 'popularCourses';
        this.search();
        break;
      case ViewMore.PAGE_TV_PROGRAMS:
        this.pageType = 'tvPrograms';
        this.search();
        break;
      default:
        this.search();
    }
    console.log('search List =>', this.searchList);
  }
  /**
   * Get enrolled courses
   */
  getEnrolledCourse() {
    this.isLoading = true;
    this.pageType = 'enrolledCourse';
    const option = {
      userId: this.userId,
      returnFreshCourses: true
    };
    this.courseService.getEnrolledCourses(option).toPromise()
      .then((data: Course[]) => {
        if (data) {
          this.searchList = data;
          this.loadMoreBtn = false;
          for (const course of data) {
            course.completionPercentage = course.completionPercentage || 0;
          }
        }
        this.isLoading = false;
      })
      .catch((error: any) => {
        console.error('error while loading enrolled courses', error);
        this.isLoading = false;
      });
  }
  getContentDetails(content) {
    const identifier = content.contentId || content.identifier;
    this.contentService.getContentDetails({ contentId: identifier, objectType: content.objectType }).toPromise()
      .then((data: Content) => {
        if (Boolean(data.isAvailableLocally)) {
          const contentDetailsParams: NavigationExtras = {
            state: {
              content: { identifier: content.lastReadContentId },
              depth: '1',
              contentState: {
                batchId: content.batchId ? content.batchId : '',
                courseId: identifier
              },
              isResumedCourse: true,
              isChildContent: true,
              resumedCourseCardData: this.resumeContentData
            }
          };
          this.router.navigate([RouterLinks.COLLECTION_DETAILS], contentDetailsParams);
        } else {
          this.subscribeSdkEvent();
          this.showOverlay = true;
          this.importContent([identifier], false);
        }
      })
      .catch((error: any) => {
        console.log(error);
      });
  }
  importContent(identifiers, isChild) {
    this.queuedIdentifiers.length = 0;
    const option: ContentImportRequest = {
      contentImportArray: this.courseUtilService.getImportContentRequestBody(identifiers, isChild),
      contentStatusArray: [],
      fields: ['appIcon', 'name', 'subject', 'size', 'gradeLevel']
    };
    this.contentService.importContent(option).toPromise()
      .then((data: ContentImportResponse[]) => {
        this.ngZone.run(() => {
          if (data && data.length) {
            data.forEach((value) => {
              if (value.status === ContentImportStatus.ENQUEUED_FOR_DOWNLOAD) {
                this.queuedIdentifiers.push(value.identifier);
              }
            });
            if (this.queuedIdentifiers.length === 0) {
              this.showOverlay = false;
              this.downloadPercentage = 0;
              this.commonUtilService.showToast('ERROR_CONTENT_NOT_AVAILABLE');
            }
          }
        });
      })
      .catch(() => {
        this.ngZone.run(() => {
          this.showOverlay = false;
          this.commonUtilService.showToast('ERROR_CONTENT_NOT_AVAILABLE');
        });
      });
  }
  subscribeSdkEvent() {
    this.eventSubscription = this.eventBusService.events().subscribe((event: EventsBusEvent) => {
      this.ngZone.run(() => {
        if (event.type === DownloadEventType.PROGRESS) {
          const downloadEvent = event as DownloadProgress;
          this.downloadPercentage = downloadEvent.payload.progress === -1 ? 0 : downloadEvent.payload.progress;
        }
        if (event.payload && event.type === ContentEventType.IMPORT_COMPLETED && this.downloadPercentage === 100) {
          this.showOverlay = false;
          const contentDetailsParams: NavigationExtras = {
            state: {
              content: { identifier: this.resumeContentData.lastReadContentId },
              depth: '1',
              contentState: {
                batchId: this.resumeContentData.batchId ? this.resumeContentData.batchId : '',
                courseId: this.resumeContentData.contentId || this.resumeContentData.identifier
              },
              isResumedCourse: true,
              isChildContent: true,
              resumedCourseCardData: this.resumeContentData
            }
          };
          this.router.navigate([RouterLinks.COLLECTION_DETAILS], contentDetailsParams);
        }
      });
    }) as any;
  }
  cancelDownload() {
    this.ngZone.run(() => {
      this.contentService.cancelDownload(this.resumeContentData.contentId || this.resumeContentData.identifier)
        .toPromise().then(() => {
          this.showOverlay = false;
        }).catch(() => {
          this.showOverlay = false;
        });
    });
  }
  showDisabled(resource) {
    return !resource.isAvailableLocally && !this.commonUtilService.networkInfo.isNetworkAvailable;
  }
  /**
   * Ionic life cycle hook
   */
  ionViewWillLeave() {
    this.ngZone.run(() => {
      if (this.eventSubscription) {
        this.eventSubscription.unsubscribe();
      }
      if (this.tabBarElement) {
        this.tabBarElement.style.display = 'flex';
      }
      this.isLoadMore = false;
      this.showOverlay = false;
      this.backButtonFunc.unsubscribe();
    });
  }
  private generateImpressionEvent() {
    this.telemetryGeneratorService.generateImpressionTelemetry(
      ImpressionType.SEARCH, '',
      PageId.VIEW_MORE,
      Environment.HOME, '', '', '');
  }
  private generateLogEvent(searchResult) {
    if (searchResult != null) {
      const contentArray: Array<any> = searchResult.contentDataList;
      const params = new Array<any>();
      const paramsMap = new Map();
      paramsMap['SearchResults'] = contentArray.length;
      paramsMap['SearchCriteria'] = searchResult.request;
      params.push(paramsMap);
      this.telemetryGeneratorService.generateLogEvent(LogLevel.INFO,
        PageId.VIEW_MORE,
        Environment.HOME,
        ImpressionType.SEARCH, params);
    }
  }
  navigateToDetailPage(content: any): boolean {
    if (!content.isAvailableLocally && !this.commonUtilService.networkInfo.isNetworkAvailable) {
      return false;
    }
    const values = new Map();
    values['sectionName'] = this.sectionName;
    values['positionClicked'] = this.index;
    this.telemetryGeneratorService.generateInteractTelemetry(InteractType.TOUCH,
      InteractSubtype.CONTENT_CLICKED,
      this.env,
      PageId.VIEW_MORE,
      ContentUtil.getTelemetryObject(content),
      values);
    this.navService.navigateToDetailPage(content, { content });
  }
  getContentImg(content) {
    const img = this.commonUtilService.getContentImg(content);
    return img;
  }
  openCourseDetails(course, index) {
    this.index = index;
    const payload = {
      guestUser: this.guestUser,
      enrolledCourses: this.enrolledCourses
    };
    this.checkRetiredOpenBatch(course, this.pageType, payload);
  }
  async checkRetiredOpenBatch(content: any, layoutName?: string, payload?: any) {
    this.loader = await this.commonUtilService.getLoader();
    await this.loader.present();
    let anyOpenBatch = false;
    const enrolledCourses = payload.enrolledCourses || [];
    let retiredBatches: Array<any> = [];
    if (layoutName !== ContentCard.LAYOUT_INPROGRESS) {
      retiredBatches = enrolledCourses.filter((element) => {
        if (element.contentId === content.identifier && element.batch.status === 1 && element.cProgress !== 100) {
          anyOpenBatch = true;
          content.batch = element.batch;
        }
        if (element.contentId === content.identifier && element.batch.status === 2 && element.cProgress !== 100) {
          return element;
        }
      });
    }
    if (anyOpenBatch || !retiredBatches.length) {
      // open the batch directly
      this.navigateToDetailsPage(content, layoutName);
    } else if (retiredBatches.length) {
      this.navigateToBatchListPopup(content, layoutName, retiredBatches, payload);
    }
    await this.loader.dismiss();
  }
  private async navigateToBatchListPopup(content: any, layoutName?: string, retiredBatches?: any, payload?: any) {
    const ongoingBatches = [];
    const courseBatchesRequest: CourseBatchesRequest = {
      filters: {
        courseId: layoutName === ContentCard.LAYOUT_INPROGRESS ? content.contentId : content.identifier,
        enrollmentType: CourseEnrollmentType.OPEN,
        status: [CourseBatchStatus.IN_PROGRESS]
      },
      sort_by: { createdDate: SortOrder.DESC },
      fields: BatchConstants.REQUIRED_FIELDS
    };
    const reqvalues = new Map();
    reqvalues['enrollReq'] = courseBatchesRequest;
    if (this.commonUtilService.networkInfo.isNetworkAvailable) {
      if (!payload.guestUser) {
        this.loader = await this.commonUtilService.getLoader();
        await this.loader.present();
        this.courseService.getCourseBatches(courseBatchesRequest).toPromise()
          .then((res: Batch[]) => {
            this.zone.run(async () => {
              const batches = res;
              if (batches.length) {
                batches.forEach((batch, key) => {
                  if (batch.status === 1) {
                    ongoingBatches.push(batch);
                  }
                });
                this.telemetryGeneratorService.generateInteractTelemetry(InteractType.TOUCH,
                  'showing-enrolled-ongoing-batch-popup',
                  Environment.HOME,
                  PageId.CONTENT_DETAIL, undefined,
                  reqvalues);
                await this.loader.dismiss();
                const popover = await this.popoverCtrl.create({
                  component: EnrollmentDetailsComponent,
                  componentProps: {
                    upcommingBatches: [],
                    ongoingBatches,
                    retiredBatches,
                    content
                  },
                  cssClass: 'enrollement-popover'
                });
                await popover.present();
                const { data } = await popover.onDidDismiss();
                if (data && data.isEnrolled) {
                  this.getEnrolledCourses();
                }
              } else {
                await this.loader.dismiss();
                this.navigateToDetailsPage(content, layoutName);
                this.commonUtilService.showToast('NO_BATCHES_AVAILABLE');
              }
            });
          })
          .catch((error: any) => {
            console.log('error while fetching course batches ==>', error);
          });
      } else {
        this.router.navigate([RouterLinks.COURSE_BATCHES]);
      }
    } else {
      this.commonUtilService.showToast('ERROR_NO_INTERNET_MESSAGE');
    }
  }
  private async navigateToDetailsPage(content: any, layoutName) {
    const identifier = content.contentId || content.identifier;
    const corRelationList: Array<CorrelationData> = [{
      id: this.sectionName,
      type: CorReleationDataType.SECTION
    }, {
      id: identifier || '',
      type: CorReleationDataType.ROOT_ID
    }];
    const values = new Map();
    values['sectionName'] = this.sectionName;
    values['positionClicked'] = this.index;
    this.telemetryGeneratorService.generateInteractTelemetry(InteractType.TOUCH,
      InteractSubtype.CONTENT_CLICKED,
      this.env,
      PageId.VIEW_MORE,
      ContentUtil.getTelemetryObject(content),
      values,
      ContentUtil.generateRollUp(undefined, identifier),
      this.commonUtilService.deDupe(corRelationList, 'type'));
    this.zone.run(async () => {
      if (layoutName === 'enrolledCourse') {
        this.navService.navigateToTrackableCollection({ content });
      } else {
        this.navService.navigateToDetailPage(
          content,
          { content }
        );
      }
    });
  }
  getEnrolledCourses(returnRefreshedCourses: boolean = false): void {
    const option: FetchEnrolledCourseRequest = {
      userId: this.userId,
      returnFreshCourses: returnRefreshedCourses
    };
    this.courseService.getEnrolledCourses(option).toPromise()
      .then((enrolledCourses) => {
        if (enrolledCourses) {
          this.zone.run(() => {
            this.enrolledCourses = enrolledCourses;
            if (this.enrolledCourses.length > 0) {
              const courseList: Array<Course> = [];
              for (const course of this.enrolledCourses) {
                course.completionPercentage = course.completionPercentage || 0;
                courseList.push(course);
              }
              this.appGlobalService.setEnrolledCourseList(courseList);
            }
            this.showLoader = false;
          });
        }
      }, (err) => {
        this.showLoader = false;
      });
  }
}
<ion-content overflow-scroll="true" [ngClass]="{'ui-container': !platform.is('ios')}">
  <div class="ui-container" *ngIf="platform.is('ios')"></div>
  <div class="ui-content">
    <div class="empty-search-result ion-text-center ion-padding-top" *ngIf="!showLoader && searchList && searchList.length === 0">
      {{ 'EMPTY_SEARCH_RESULTS' | translate }}
    </div>
    <div>
      <div class="view-more-course-bg">
        <p class="title" role="heading" aria-level="1" *ngIf="pageType === 'enrolledCourse'">{{'COURSES_IN_PROGRESS' | translate}}</p>
        <p class="title" role="heading" aria-level="1" *ngIf="pageType === 'popularCourses' || pageType === 'tvPrograms'">{{title}}</p>
        <p *ngIf="searchList && searchList.length" class="count-text">
          {{'SHOWING_ITEMS' | translate:{'%s': searchList.length} }}</p>
        <ng-container *ngIf="!isLoading">
          <div *ngFor="let item of searchList; let i = index" class="mb-8">
            <sb-my-course-card *ngIf="pageType === 'enrolledCourse'" [course]="item" [section]="null"
              [cardImg]="getContentImg(item)" (click)="openCourseDetails(item, i)" [hideProgress]="true">
            </sb-my-course-card>
            <sb-course-card *ngIf="pageType === 'popularCourses'" [course]="item" [section]="null"
              [cardImg]="getContentImg(item)" (click)="openCourseDetails(item, i)"></sb-course-card>
            <sb-library-card *ngIf="pageType === 'tvPrograms'" [isOffline]="!commonUtilService.networkInfo.isNetworkAvailable" [content]="item"
              [type]="'mobile_textbook'" (cardClick)="navigateToDetailPage(item)" [isLoading]="isLoading"
              [cardImg]="item?.appIcon || defaultAppIcon">
            </sb-library-card>
          </div>
        </ng-container>
        <ng-container *ngIf="isLoading">
          <div *ngFor="let item of [0,1,2,3,4,5,6,7,8,9,10,11,12,13]" class="mb-8 mt-8">
            <sb-my-course-card *ngIf="pageType === 'enrolledCourse'" [isLoading]="isLoading">
            </sb-my-course-card>
            <sb-course-card *ngIf="pageType === 'popularCourses'" [isLoading]="isLoading"></sb-course-card>
            <sb-library-card *ngIf="pageType === 'tvPrograms'" [isOffline]="!commonUtilService.networkInfo.isNetworkAvailable" [content]="item"
              [type]="'mobile_textbook'" (cardClick)="navigateToDetailPage(item)" [isLoading]="isLoading"
              [cardImg]="item?.appIcon || defaultAppIcon">
            </sb-library-card>
          </div>
        </ng-container>
      </div>
    </div>
    <div class="px-5">
      <ion-button expand="block" class="custom-btn-txt-transform-none"  *ngIf="searchList && searchList.length && loadMoreBtn" (click)="loadMore();">
        {{ 'FRMELEMNTS_BTN_VIEW_MORE' | translate }}
      </ion-button>
    </div>
  </div>
</ion-content>
<ion-backdrop class="loading-backdrop ion-text-center" *ngIf="showOverlay">
  <div class="backdrop-container">
    <span *ngIf="downloadPercentage !== 100">
      <ion-label>{{ 'LOADING_CONTENT' | translate }} {{ downloadPercentage ? (downloadPercentage) : '0' }} %</ion-label>
      <app-pb-horizontal [progress]="downloadPercentage" isOnBoardCard="false"></app-pb-horizontal>
    </span>
    <ion-label *ngIf="downloadPercentage === 100">{{ 'LOADING_CONTENT' | translate }}</ion-label>
  </div>
  <div class="backdrop-footer" *ngIf="downloadPercentage !== 100">
    <ion-button size="small" (click)="cancelDownload()">{{'CANCEL' | translate}}</ion-button>
  </div>
</ion-backdrop>
                    ./view-more-activity.component.scss
                
@import "src/assets/styles/variables";
@import "src/assets/styles/_custom-mixins";
@import "src/assets/styles/fonts";
@import "src/assets/styles/_variables.scss";
:host {
  button {
    border-radius: 5px !important;
  }
  .empty-search-result {
    font-size: 1.2rem;
  }
  .loading-backdrop {
    .backdrop-container {
      width: 100%;
      padding: 16px;
      text-align: center;
      position: absolute;
      top: 50%;
      margin-top: -50px;
    }
    .backdrop-footer {
      position: absolute;
      width: 100%;
      bottom: 0;
      padding-bottom: 16px;
    }
 
    background-color: map-get($colors, white);
    height: 100%;
    z-index: 1000;
    opacity: 1 !important;
  }
  .downloads-only {
    background: map-get($colors, white_f8);
    @include margin(-16px, -16px, 16px, -16px);
    @include padding(0, 16px);
  }
  .sb-view-all-container {
    width: 100%;
    .sb-view-all-items {
      background-color: $primary-color;
      height: ($base-block-space * 10);
      width: 100%;
      position: relative;
      display: flex;
      align-items: center;
      @include padding(0, ($base-block-space * 2));
      .sb-view-all-title {
        color: $white-color;
        .page-heading {
          font-size: $font-size-base + 0.125;
          font-weight: bold;
          line-height: 1.375rem;
        }
        .page-info {
          display: block;
          font-size: $font-size-base - 0.125;
          line-height: 0.938rem;
        }
      }
      .sb-card-scroll-container {
        overflow-x: auto;
        padding: 0 0 8px 0;
      }
    }
  }
  .view-more-course-bg {
    background: linear-gradient(#008840, #008840 100px, white 100px, white 100%);
    padding: 8px;
    .title {
      color: map-get($colors, white);
      font-family: "Noto Sans", sans-serif;
      font-size: 1rem;
      font-weight: bold;
      margin: 12px 0 0;
    }
    .count-text {
      color: map-get($colors, white_fa);
      font-family: "Noto Sans", sans-serif;
      font-size: 0.75rem;
      margin: 0 0 12px;
    }
    sb-my-course-card, my-course-card {
      margin-bottom: 8px;
      border-radius: 2px;
      box-shadow: 0 2px 7px 0 rgba(0,0,0,0.16)
     }
  }
}