import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit, OnDestroy } from '@angular/core';
import { FavouriteMoviesService } from '../services/favourite-movies.service';
import { MoviedbApiService } from '../services/moviedb-api.service';
import { MoviesListenerService } from '../services/movies-listener.service';
import { StorageService } from '../services/storage.service';
import { environment } from '../../environments/environment';
import { Observable, from, of, Subscription } from 'rxjs';
import { map } from 'rxjs/operators';
@Component({
selector: 'app-tab3',
templateUrl: 'tab3.page.html',
styleUrls: ['tab3.page.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class Tab3Page implements OnInit, OnDestroy {
public favouritesObj$: Observable<any>;
public configObj: Subscription;
public favouritesExist: boolean;
public config: any = {};
public selectedGenre: string;
public parsedFavourites: Array<any> = [];
private favouritesInDescendingOrder: Array<any> = [];
public sectionType = 'Favourites';
private STORAGE_KEY: string = environment.keys.storage.myMovies;
/**
* Creates an instance of Tab3Page.
*/
constructor(private favourites: FavouriteMoviesService,
private movies: MoviedbApiService,
private movieListener: MoviesListenerService,
private storage: StorageService,
private cdr: ChangeDetectorRef) {}
/**
* Angular lifecycle hook - triggered once on component initialization
* Here we bootstrap the page with triggering the following methods:
* 1. getConfiguration
* 2. listenForRemovedMovies
*/
ngOnInit() {
this.getConfiguration();
this.listenForRemovedMovies();
}
/**
* Ionic lifecyclehook - triggered AFTER the component view has entered.
* Here we trigger the doWeHaveExistingFavourites method for rendering
* any saved favourite movies to the component template
*/
ionViewDidEnter() {
this.doWeHaveExistingFavourites();
this.cdr.detectChanges();
}
/**
* Angular lifecycle hook - triggered when component is destroyed.
* Here we remove any subscriptions/perform garbage collection
*/
ngOnDestroy() {
this.configObj.unsubscribe();
}
/**
* Listens for movies that have been removed and updates the saved favourites accordingly
* whilst also saving that back to Ionic Storage for persistence
*/
private listenForRemovedMovies(): void {
this.movieListener.resultListener$.subscribe((data: Array<any>) => {
if (this.parsedFavourites.length > 0) {
this.favouritesObj$ = of(data).pipe(
map(val => {
this.parsedFavourites = [...val];
this.favouritesInDescendingOrder = [...val].reverse();
this.storage.set(this.STORAGE_KEY, JSON.stringify(this.parsedFavourites));
return val;
})
);
}
});
}
/**
* Retrieves the API URL and API Key details
*/
private getConfiguration(): void {
this.configObj = this.movies
.getConfiguration()
.subscribe((data: any) => {
this.config = data;
});
}
/**
* Determines if there are existing favourites, if there are they are then parsed and rendered
* into the component template
*/
private doWeHaveExistingFavourites(): void {
this.parsedFavourites = [];
this.favouritesObj$ = from(this.favourites.doWeHaveExistingFavourites())
.pipe(
map(val => {
let items = val;
if (items === null) {
this.favouritesExist = false;
items = [];
} else {
this.favouritesExist = true;
this.parsedFavourites = [...items];
this.favouritesInDescendingOrder = [...items].reverse();
this.movieListener.moviesToBeParsed(this.parsedFavourites);
}
return items;
})
);
}
/**
* Allows the saved favourites to display films in ascending or descending order
*/
public displayFilmsInFollowingOrder(ev: any): void {
console.dir(ev);
const displayOrder = ev.detail.value;
if (displayOrder === 'asc') {
this.favouritesObj$ = of(this.parsedFavourites);
} else {
this.favouritesObj$ = of(this.favouritesInDescendingOrder);
}
}
/**
* Allows the saved favourites to only display those movies belonging to a specific genre
*/
public filterMoviesByselectedGenre(selectedGenre: string): void {
const movies = [];
this.parsedFavourites.filter(item => {
if (item.genres.includes(selectedGenre)) {
movies.push(item);
}
});
this.favouritesObj$ = of(movies);
}
}