import { PlatformLocation } from "@angular/common"; import { Component, Input, OnInit } from "@angular/core"; import { DomSanitizer } from "@angular/platform-browser"; import { Subject } from "rxjs"; import { debounceTime, distinctUntilChanged } from "rxjs/operators"; import { AuthService } from "../auth/auth.service"; import { FilterType, IFilter, IIssueCategory, IMovieRequests, IPagenator, IRadarrProfile, IRadarrRootFolder, OrderType } from "../interfaces"; import { NotificationService, RadarrService, RequestService } from "../services"; @Component({ selector: "movie-requests", templateUrl: "./movierequests.component.html", }) export class MovieRequestsComponent implements OnInit { public movieRequests: IMovieRequests[]; public defaultPoster: string; public searchChanged: Subject = new Subject(); public searchText: string; public isAdmin: boolean; // Also PowerUser public radarrProfiles: IRadarrProfile[]; public radarrRootFolders: IRadarrRootFolder[]; @Input() public issueCategories: IIssueCategory[]; @Input() public issuesEnabled: boolean; public issuesBarVisible = false; public issueRequest: IMovieRequests; public issueProviderId: string; public issueCategorySelected: IIssueCategory; public filterDisplay: boolean; public filter: IFilter; public filterType = FilterType; public orderType: OrderType = OrderType.RequestedDateDesc; public OrderType = OrderType; public denyDisplay: boolean; public requestToDeny: IMovieRequests; public rejectionReason: string; public totalMovies: number = 100; public currentlyLoaded: number; private amountToLoad: number; constructor( private requestService: RequestService, private auth: AuthService, private notificationService: NotificationService, private radarrService: RadarrService, private sanitizer: DomSanitizer, private readonly platformLocation: PlatformLocation) { this.searchChanged.pipe( debounceTime(600), // Wait Xms after the last event before emitting last event distinctUntilChanged(), // only emit if value is different from previous value ).subscribe(x => { this.searchText = x as string; if (this.searchText === "") { this.resetSearch(); return; } this.requestService.searchMovieRequests(this.searchText) .subscribe(m => { this.setOverrides(m); this.movieRequests = m; }); }); this.defaultPoster = "../../../images/default_movie_poster.png"; const base = this.platformLocation.getBaseHrefFromDOM(); if (base) { this.defaultPoster = "../../.." + base + "/images/default_movie_poster.png"; } } public ngOnInit() { this.amountToLoad = 10; this.currentlyLoaded = 10; this.filter = { availabilityFilter: FilterType.None, statusFilter: FilterType.None, }; this.loadInit(); this.isAdmin = this.auth.hasRole("admin") || this.auth.hasRole("poweruser"); } public paginate(event: IPagenator) { const skipAmount = event.first; this.loadRequests(this.amountToLoad, skipAmount); } public search(text: any) { this.searchChanged.next(text.target.value); } public removeRequest(request: IMovieRequests) { this.requestService.removeMovieRequest(request); this.removeRequestFromUi(request); this.loadRequests(this.amountToLoad, this.currentlyLoaded = 0); } public changeAvailability(request: IMovieRequests, available: boolean) { request.available = available; if (available) { this.requestService.markMovieAvailable({ id: request.id }).subscribe(x => { if (x.result) { this.notificationService.success( `${request.title} Is now available`); } else { this.notificationService.warning("Request Available", x.message ? x.message : x.errorMessage); request.approved = false; } }); } else { this.requestService.markMovieUnavailable({ id: request.id }).subscribe(x => { if (x.result) { this.notificationService.success( `${request.title} Is now unavailable`); } else { this.notificationService.warning("Request Available", x.message ? x.message : x.errorMessage); request.approved = false; } }); } } public approve(request: IMovieRequests) { request.approved = true; this.approveRequest(request); } public deny(request: IMovieRequests) { this.requestToDeny = request; this.denyDisplay = true; } public denyRequest() { this.requestService.denyMovie({ id: this.requestToDeny.id, reason: this.rejectionReason }) .subscribe(x => { this.denyDisplay = false; if (x.result) { this.notificationService.success( `Request for ${this.requestToDeny.title} has been denied successfully`); const index = this.movieRequests.indexOf(this.requestToDeny, 0); if (index > -1) { this.movieRequests[index].denied = true; } } else { this.notificationService.warning("Request Denied", x.message ? x.message : x.errorMessage); this.requestToDeny.denied = false; } }); } public selectRootFolder(searchResult: IMovieRequests, rootFolderSelected: IRadarrRootFolder, event: any) { event.preventDefault(); searchResult.rootPathOverride = rootFolderSelected.id; this.setOverride(searchResult); this.updateRequest(searchResult); } public selectQualityProfile(searchResult: IMovieRequests, profileSelected: IRadarrProfile, event: any) { event.preventDefault(); searchResult.qualityOverride = profileSelected.id; this.setOverride(searchResult); this.updateRequest(searchResult); } public reportIssue(catId: IIssueCategory, req: IMovieRequests) { this.issueRequest = req; this.issueCategorySelected = catId; this.issuesBarVisible = true; this.issueProviderId = req.theMovieDbId.toString(); } public ignore(event: any): void { event.preventDefault(); } public clearFilter(el: any) { el = el.toElement || el.relatedTarget || el.target || el.srcElement; el = el.parentElement; el = el.querySelectorAll("INPUT"); for (el of el) { el.checked = false; el.parentElement.classList.remove("active"); } this.filterDisplay = false; this.filter.availabilityFilter = FilterType.None; this.filter.statusFilter = FilterType.None; this.resetSearch(); } public filterAvailability(filter: FilterType, el: any) { this.filterActiveStyle(el); this.filter.availabilityFilter = filter; this.loadInit(); } public filterStatus(filter: FilterType, el: any) { this.filterActiveStyle(el); this.filter.statusFilter = filter; this.loadInit(); } public setOrder(value: OrderType, el: any) { el = el.toElement || el.relatedTarget || el.target || el.srcElement; const parent = el.parentElement; const previousFilter = parent.querySelector(".active"); previousFilter.className = ""; el.className = "active"; this.orderType = value; this.loadInit(); } public subscribe(request: IMovieRequests) { request.subscribed = true; this.requestService.subscribeToMovie(request.id) .subscribe(x => { this.notificationService.success("Subscribed To Movie!"); }); } public unSubscribe(request: IMovieRequests) { request.subscribed = false; this.requestService.unSubscribeToMovie(request.id) .subscribe(x => { this.notificationService.success("Unsubscribed Movie!"); }); } public isRequestUser(request: IMovieRequests) { if (request.requestedUser.userName === this.auth.claims().name) { return true; } return false; } private filterActiveStyle(el: any) { el = el.toElement || el.relatedTarget || el.target || el.srcElement; el = el.parentElement; //gets radio div el = el.parentElement; //gets form group div el = el.parentElement; //gets status filter div el = el.querySelectorAll("INPUT"); for (el of el) { if (el.checked) { if (!el.parentElement.classList.contains("active")) { el.parentElement.className += " active"; } } else { el.parentElement.classList.remove("active"); } } } private loadRequests(amountToLoad: number, currentlyLoaded: number) { this.requestService.getMovieRequests(amountToLoad, currentlyLoaded, this.orderType, this.filter) .subscribe(x => { this.setOverrides(x.collection); if (!this.movieRequests) { this.movieRequests = []; } this.movieRequests = x.collection; this.totalMovies = x.total; this.currentlyLoaded = currentlyLoaded + amountToLoad; }); } private updateRequest(request: IMovieRequests) { this.requestService.updateMovieRequest(request) .subscribe(x => { this.setOverride(x); request = x; }); } private approveRequest(request: IMovieRequests) { this.requestService.approveMovie({ id: request.id }) .subscribe(x => { request.approved = true; if (x.result) { this.notificationService.success( `Request for ${request.title} has been approved successfully`); } else { this.notificationService.warning("Request Approved", x.message ? x.message : x.errorMessage); request.approved = false; } }); } private loadInit() { this.requestService.getMovieRequests(this.amountToLoad, 0, this.orderType, this.filter) .subscribe(x => { this.movieRequests = x.collection; this.totalMovies = x.total; this.movieRequests.forEach((req) => { this.setBackground(req); this.setPoster(req); }); if (this.isAdmin) { this.radarrService.getQualityProfilesFromSettings().subscribe(c => { this.radarrProfiles = c; this.movieRequests.forEach((req) => this.setQualityOverrides(req)); }); this.radarrService.getRootFoldersFromSettings().subscribe(c => { this.radarrRootFolders = c; this.movieRequests.forEach((req) => this.setRootFolderOverrides(req)); }); } }); } private resetSearch() { this.currentlyLoaded = 5; this.loadInit(); } private removeRequestFromUi(key: IMovieRequests) { const index = this.movieRequests.indexOf(key, 0); if (index > -1) { this.movieRequests.splice(index, 1); } } private setOverrides(requests: IMovieRequests[]): void { requests.forEach((req) => { this.setOverride(req); }); } private setQualityOverrides(req: IMovieRequests): void { if (this.radarrProfiles) { const profile = this.radarrProfiles.filter((p) => { return p.id === req.qualityOverride; }); if (profile.length > 0) { req.qualityOverrideTitle = profile[0].name; } } } private setRootFolderOverrides(req: IMovieRequests): void { if (this.radarrRootFolders) { const path = this.radarrRootFolders.filter((folder) => { return folder.id === req.rootPathOverride; }); if (path.length > 0) { req.rootPathOverrideTitle = path[0].path; } } } private setOverride(req: IMovieRequests): void { this.setPoster(req); this.setBackground(req); this.setQualityOverrides(req); this.setRootFolderOverrides(req); } private setPoster(req: IMovieRequests): void { if (req.posterPath === null) { req.posterPath = this.defaultPoster; } else { req.posterPath = "https://image.tmdb.org/t/p/w300/" + req.posterPath; } } private setBackground(req: IMovieRequests): void { req.backgroundPath = this.sanitizer.bypassSecurityTrustStyle ("url(" + "https://image.tmdb.org/t/p/w1280" + req.background + ")"); } }