Make Episode picker similar to Requests Child view. #1457 #1463

pull/1496/head
Dhruv Bhavsar 7 years ago
parent d1da6ca9b4
commit 4215c77620

@ -4,12 +4,20 @@
</div> </div>
</div> </div>
<br /> <br />
<!--TODO: I believe this +1 is causing off by one error skipping loading of tv shows
When removed and scrolling very slowly everything works as expected, however
if you scroll really quickly then you start getting duplicates of movies
since it's async and some subsequent results return first and then incrementer
is increased so you see movies which had already been gotten show up...
<div infinite-scroll Removing infinte-scroll and setting max to 1000 till we work out some sort of fix
-->
<!--<div infinite-scroll
[infiniteScrollDistance]="1" [infiniteScrollDistance]="1"
[infiniteScrollThrottle]="100" [infiniteScrollThrottle]="100"
(scrolled)="loadMore()"> (scrolled)="loadMore()">-->
<!--<div>--> <div>
<p-treeTable [value]="tvRequests"> <p-treeTable [value]="tvRequests">
<!--<p-column> <!--<p-column>
<ng-template let-col let-node="rowData" pTemplate="body"> <ng-template let-col let-node="rowData" pTemplate="body">
@ -27,7 +35,7 @@
<div class="row"> <div class="row">
<div class="col-sm-2"> <div class="col-sm-2">
<img class="img-responsive poster" src="{{node.data.posterPath}}" alt="poster"> <img class="img-responsive poster" src="{{node.data.posterPath || null}}" alt="poster">
</div> </div>

@ -107,17 +107,22 @@ export class TvRequestsComponent implements OnInit, OnDestroy {
return items; return items;
} }
ngOnInit() { ngOnInit() {
this.amountToLoad = 5; this.amountToLoad = 1000;
this.currentlyLoaded = 5; this.currentlyLoaded = 5;
this.tvRequests = []; this.tvRequests = [];
this.loadInit(); this.loadInit();
} }
public loadMore() { public loadMore() {
this.requestService.getTvRequests(this.amountToLoad, this.currentlyLoaded + 1) //TODO: I believe this +1 is causing off by one error skipping loading of tv shows
//When removed and scrolling very slowly everything works as expected, however
//if you scroll really quickly then you start getting duplicates of movies
//since it's async and some subsequent results return first and then incrementer
//is increased so you see movies which had already been gotten show up...
this.requestService.getTvRequests(this.amountToLoad, this.currentlyLoaded +1)
.takeUntil(this.subscriptions) .takeUntil(this.subscriptions)
.subscribe(x => { .subscribe(x => {
this.tvRequests.push.apply(this.tvRequests, x); this.tvRequests.push.apply(this.tvRequests, this.transformData(x));
this.currentlyLoaded = this.currentlyLoaded + this.amountToLoad; this.currentlyLoaded = this.currentlyLoaded + this.amountToLoad;
}); });
} }

@ -10,6 +10,8 @@ import { MovieSearchComponent } from './moviesearch.component';
import { TvSearchComponent } from './tvsearch.component'; import { TvSearchComponent } from './tvsearch.component';
import { SeriesInformationComponent } from './seriesinformation.component'; import { SeriesInformationComponent } from './seriesinformation.component';
import { TreeTableModule } from 'primeng/primeng';
import { SearchService } from '../services/search.service'; import { SearchService } from '../services/search.service';
import { RequestService } from '../services/request.service'; import { RequestService } from '../services/request.service';
@ -26,12 +28,13 @@ const routes: Routes = [
FormsModule, FormsModule,
RouterModule.forChild(routes), RouterModule.forChild(routes),
NgbModule.forRoot(), NgbModule.forRoot(),
TreeTableModule
], ],
declarations: [ declarations: [
SearchComponent, SearchComponent,
MovieSearchComponent, MovieSearchComponent,
TvSearchComponent, TvSearchComponent,
SeriesInformationComponent SeriesInformationComponent,
], ],
exports: [ exports: [
RouterModule RouterModule

@ -8,14 +8,8 @@
} }
</style> </style>
<div *ngIf="series"> <div *ngIf="series">
<!--<div class="row"> <button class="btn btn-sm btn-success pull-right" (click)="submitRequests()" title="Go to top">Submit Request</button>
<div class="col-md-6 col-md-push-2">
<div id="bannerimage" style="background-image: url('https://thetvdb.com/banners/graphical/121361-g19.jpg');">
</div>
</div>
</div>-->
<ngb-tabset> <ngb-tabset>
<div *ngFor="let season of series.seasonRequests"> <div *ngFor="let season of series.seasonRequests">
@ -84,8 +78,4 @@
</div> </div>
</ngb-tabset> </ngb-tabset>
<button id="requestFloatingBtn" class="btn btn-sm btn-success" (click)="submitRequests()" title="Go to top">Submit Request</button>
</div> </div>

@ -1,5 +1,5 @@
import { Component, OnInit, OnDestroy } from '@angular/core'; import { Component, OnInit, OnDestroy, Input} from '@angular/core';
import { ActivatedRoute } from '@angular/router'; //import { ActivatedRoute } from '@angular/router';
import { Subject } from 'rxjs/Subject'; import { Subject } from 'rxjs/Subject';
import "rxjs/add/operator/takeUntil"; import "rxjs/add/operator/takeUntil";
@ -13,24 +13,19 @@ import { IRequestEngineResult } from '../interfaces/IRequestEngineResult';
import { IEpisodesRequests } from "../interfaces/IRequestModel"; import { IEpisodesRequests } from "../interfaces/IRequestModel";
@Component({ @Component({
selector: 'seriesinformation',
templateUrl: './seriesinformation.component.html', templateUrl: './seriesinformation.component.html',
styleUrls: ['./seriesinformation.component.scss'] styleUrls: ['./seriesinformation.component.scss']
}) })
export class SeriesInformationComponent implements OnInit, OnDestroy { export class SeriesInformationComponent implements OnInit, OnDestroy {
constructor(private searchService: SearchService, private route: ActivatedRoute, constructor(private searchService: SearchService, private requestService: RequestService, private notificationService: NotificationService) {
private requestService: RequestService, private notificationService: NotificationService) {
this.route.params
.takeUntil(this.subscriptions)
.subscribe(params => {
this.seriesId = +params['id']; // (+) converts string 'id' to a number
});
} }
private subscriptions = new Subject<void>(); private subscriptions = new Subject<void>();
public result : IRequestEngineResult; public result : IRequestEngineResult;
private seriesId: number; @Input() private seriesId: number;
public series: ISearchTvResult; public series: ISearchTvResult;
requestedEpisodes: IEpisodesRequests[] = []; requestedEpisodes: IEpisodesRequests[] = [];

@ -32,68 +32,72 @@
<div *ngIf="searchApplied && tvResults?.length <= 0" class='no-search-results'> <div *ngIf="searchApplied && tvResults?.length <= 0" class='no-search-results'>
<i class='fa fa-film no-search-results-icon'></i><div class='no-search-results-text'>Sorry, we didn't find any results!</div> <i class='fa fa-film no-search-results-icon'></i><div class='no-search-results-text'>Sorry, we didn't find any results!</div>
</div> </div>
<p-treeTable [value]="tvResults">
<div *ngFor="let result of tvResults"> <p-column>
<ng-template let-col let-node="rowData" pTemplate="header">
Results
</ng-template>
<ng-template let-col let-node="rowData" pTemplate="body">
<!--This is the section that holds the parent level search results set-->
<div *ngIf="!node.leaf">
<div class="row"> <div class="row">
<div class="col-sm-2"> <div class="col-sm-2">
<img *ngIf="result.banner" class="img-responsive poster" width="150" [src]="result.banner" alt="poster"> <img *ngIf="node.data.banner" class="img-responsive poster" width="150" [src]="node.data.banner" alt="poster">
</div> </div>
<div class="col-sm-8"> <div class="col-sm-8">
<div> <div>
<a href="http://www.imdb.com/title/{{result.imdbId}}/" target="_blank"> <a href="http://www.imdb.com/title/{{node.data.imdbId}}/" target="_blank">
<h4>{{result.title}} ({{result.firstAired | date: 'yyyy'}})</h4> <h4>{{node.data.title}} ({{node.data.firstAired | date: 'yyyy'}})</h4>
</a> </a>
<span *ngIf="node.data.status" class="label label-primary" target="_blank">{{node.data.status}}</span>
<span *ngIf="result.status" class="label label-primary" target="_blank">{{result.status}}</span>
<span *ngIf="node.data.firstAired" class="label label-info" target="_blank">Air Date: {{node.data.firstAired}}</span>
<span *ngIf="result.firstAired" class="label label-info" target="_blank">Air Date: {{result.firstAired}}</span>
<span *ngIf="node.data.releaseDate" class="label label-info" target="_blank">Release Date: {{node.data.releaseDate | date: 'dd/MM/yyyy'}}</span>
<span *ngIf="result.releaseDate" class="label label-info" target="_blank">Release Date: {{result.releaseDate | date: 'dd/MM/yyyy'}}</span> <span *ngIf="node.data.available" class="label label-success">Available</span>
<span *ngIf="node.data.approved && !node.data.available" class="label label-info">Processing Request</span>
<span *ngIf="result.available" class="label label-success">Available</span> <div *ngIf="node.data.requested && !node.data.available; then requested else notRequested"></div>
<span *ngIf="result.approved && !result.available" class="label label-info">Processing Request</span>
<div *ngIf="result.requested && !result.available; then requested else notRequested"></div>
<ng-template #requested> <ng-template #requested>
<span *ngIf="!result.available" class="label label-warning">Pending Approval</span> <span *ngIf="!node.data.available" class="label label-warning">Pending Approval</span>
</ng-template> </ng-template>
<ng-template #notRequested> <ng-template #notRequested>
<span *ngIf="!result.available" class="label label-danger">Not Yet Requested</span> <span *ngIf="!node.data.available" class="label label-danger">Not Yet Requested</span>
</ng-template> </ng-template>
<span id="{{id}}netflixTab"></span> <span id="{{id}}netflixTab"></span>
<a *ngIf="result.homepage" href="{{result.homepage}}" target="_blank"><span class="label label-info">HomePage</span></a> <a *ngIf="node.data.homepage" href="{{node.data.homepage}}" target="_blank"><span class="label label-info">HomePage</span></a>
<a *ngIf="result.trailer" href="{{result.trailer}}" target="_blank"><span class="label label-info">Trailer</span></a> <a *ngIf="node.data.trailer" href="{{node.data.trailer}}" target="_blank"><span class="label label-info">Trailer</span></a>
<br/> <br />
<br/> <br />
</div> </div>
<p style="font-size: 0.9rem !important">{{result.overview}}</p> <p style="font-size: 0.9rem !important">{{node.data.overview}}</p>
</div> </div>
<div class="col-sm-2"> <div class="col-sm-2">
<input name="{{type}}Id" type="text" value="{{result.id}}" hidden="hidden"/> <input name="{{type}}Id" type="text" value="{{node.data.id}}" hidden="hidden" />
<!--<div *ngIf="result.requested; then requestedBtn else notRequestedBtn"></div> <!--<div *ngIf="node.data.requested; then requestedBtn else notRequestedBtn"></div>
<template #requestedBtn> <template #requestedBtn>
<button style="text-align: right" class="btn btn-primary-outline disabled" [disabled]><i class="fa fa-check"></i> Requested</button> <button style="text-align: right" class="btn btn-primary-outline disabled" [disabled]><i class="fa fa-check"></i> Requested</button>
</template> </template>
<template #notRequestedBtn> <template #notRequestedBtn>
<button id="{{result.id}}" style="text-align: right" class="btn btn-primary-outline" (click)="request(result)"><i class="fa fa-plus"></i> Request</button> <button id="{{node.data.id}}" style="text-align: right" class="btn btn-primary-outline" (click)="request(result)"><i class="fa fa-plus"></i> Request</button>
</template>--> </template>-->
<!--{{#if_eq type "tv"}} <!--{{#if_eq type "tv"}}
{{#if_eq tvFullyAvailable true}} {{#if_eq tvFullyAvailable true}}
@*//TODO Not used yet*@ @*//TODO Not used yet*@
@ -109,10 +113,10 @@
<span class="caret"></span> <span class="caret"></span>
</button> </button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1"> <ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
<li><a (click)="allSeasons(result)">All Seasons</a></li> <li><a (click)="allSeasons(node.data)">All Seasons</a></li>
<li><a (click)="firstSeason(result)">First Season</a></li> <li><a (click)="firstSeason(node.data)">First Season</a></li>
<li><a (click)="latestSeason(result)">Latest Season</a></li> <li><a (click)="latestSeason(node.data)">Latest Season</a></li>
<li><a (click)="selectSeason(result)">Select ...</a></li> <li><a (click)="openClosestTab($event)">Select ...</a></li>
</ul> </ul>
</div> </div>
@ -123,9 +127,9 @@
--> -->
<br/> <br />
<div *ngIf="result.available"> <div *ngIf="node.data.available">
<a *ngIf="result.plexUrl" style="text-align: right" class="btn btn-sm btn-success-outline" href="{{result.plexUrl}}" target="_blank"><i class="fa fa-eye"></i> View On Plex</a> <a *ngIf="node.data.plexUrl" style="text-align: right" class="btn btn-sm btn-success-outline" href="{{node.data.plexUrl}}" target="_blank"><i class="fa fa-eye"></i> View On Plex</a>
<!--<input name="providerId" type="text" value="{{id}}" hidden="hidden"/> <!--<input name="providerId" type="text" value="{{id}}" hidden="hidden"/>
<input name="type" type="text" value="{{type}}" hidden="hidden"/> <input name="type" type="text" value="{{type}}" hidden="hidden"/>
@ -147,8 +151,14 @@
</div> </div>
</div> </div>
<hr/> <hr />
</div> </div>
<!--This is the section that holds the child seasons if they want to specify specific episodes-->
<div *ngIf="node.leaf">
<seriesinformation [seriesId]="node.data.id"></seriesinformation>
</div>
</ng-template>
</p-column>
</p-treeTable>
</div> </div>
</div> </div>

@ -1,4 +1,4 @@
import { Component, OnInit, OnDestroy } from '@angular/core'; import { Component, OnInit, OnDestroy, ViewEncapsulation } from '@angular/core';
import {Router} from '@angular/router'; import {Router} from '@angular/router';
import { Subject } from 'rxjs/Subject'; import { Subject } from 'rxjs/Subject';
import 'rxjs/add/operator/debounceTime'; import 'rxjs/add/operator/debounceTime';
@ -12,10 +12,16 @@ import { NotificationService } from '../services/notification.service';
import { ISearchTvResult } from '../interfaces/ISearchTvResult'; import { ISearchTvResult } from '../interfaces/ISearchTvResult';
import { IRequestEngineResult } from '../interfaces/IRequestEngineResult'; import { IRequestEngineResult } from '../interfaces/IRequestEngineResult';
import { TreeNode } from "primeng/primeng";
@Component({ @Component({
selector: 'tv-search', selector: 'tv-search',
templateUrl: './tvsearch.component.html', templateUrl: './tvsearch.component.html',
styleUrls: ['./../requests/tvrequests.component.scss'],
//Was required to turn off encapsulation since CSS only should be overridden for this component
//However when encapsulation is on angular injects prefixes to all classes so css selectors
//Stop working
encapsulation: ViewEncapsulation.None
}) })
export class TvSearchComponent implements OnInit, OnDestroy { export class TvSearchComponent implements OnInit, OnDestroy {
@ -41,11 +47,50 @@ export class TvSearchComponent implements OnInit, OnDestroy {
this.searchService.searchTv(this.searchText) this.searchService.searchTv(this.searchText)
.takeUntil(this.subscriptions) .takeUntil(this.subscriptions)
.subscribe(x => { .subscribe(x => {
this.tvResults = x; this.tvResults = this.transformData(x);
this.searchApplied = true; this.searchApplied = true;
}); });
}); });
} }
openClosestTab(el: any): void {
var rowclass = "undefined";
el = el.toElement;
while (el.className != rowclass) {
// Increment the loop to the parent node until we find the row we need
el = el.parentNode;
if (!el) {
}
}
// At this point, the while loop has stopped and `el` represents the element that has
// the class you specified
// Then we loop through the children to find the caret which we want to click
var caretright = "ui-treetable-toggler fa fa-fw ui-c fa-caret-right";
var caretdown = "ui-treetable-toggler fa fa-fw ui-c fa-caret-down";
for (var value of el.children) {
// the caret from the ui has 2 class selectors depending on if expanded or not
// we search for both since we want to still toggle the clicking
if (value.className === caretright || value.className === caretdown) {
// Then we tell JS to click the element even though we hid it from the UI
value.click();
//Break from loop since we no longer need to continue looking
break;
}
};
}
transformData(datain: ISearchTvResult[]): any {
var temp: TreeNode[] = [];
datain.forEach(function (value) {
temp.push({
"data": value,
"children": [{
"data": value, leaf: true
}],
leaf: false
});
}, this)
return <TreeNode[]>temp;
}
ngOnInit(): void { ngOnInit(): void {
this.searchText = ""; this.searchText = "";

Loading…
Cancel
Save