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>
<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...
Removing infinte-scroll and setting max to 1000 till we work out some sort of fix
<div infinite-scroll
-->
<!--<div infinite-scroll
[infiniteScrollDistance]="1"
[infiniteScrollThrottle]="100"
(scrolled)="loadMore()">
<!--<div>-->
(scrolled)="loadMore()">-->
<div>
<p-treeTable [value]="tvRequests">
<!--<p-column>
<ng-template let-col let-node="rowData" pTemplate="body">
@ -27,7 +35,7 @@
<div class="row">
<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>

@ -107,17 +107,22 @@ export class TvRequestsComponent implements OnInit, OnDestroy {
return items;
}
ngOnInit() {
this.amountToLoad = 5;
this.amountToLoad = 1000;
this.currentlyLoaded = 5;
this.tvRequests = [];
this.loadInit();
}
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)
.subscribe(x => {
this.tvRequests.push.apply(this.tvRequests, x);
this.tvRequests.push.apply(this.tvRequests, this.transformData(x));
this.currentlyLoaded = this.currentlyLoaded + this.amountToLoad;
});
}

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

@ -8,14 +8,8 @@
}
</style>
<div *ngIf="series">
<!--<div class="row">
<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>-->
<button class="btn btn-sm btn-success pull-right" (click)="submitRequests()" title="Go to top">Submit Request</button>
<ngb-tabset>
<div *ngFor="let season of series.seasonRequests">
@ -83,9 +77,5 @@
</ngb-tab>
</div>
</ngb-tabset>
<button id="requestFloatingBtn" class="btn btn-sm btn-success" (click)="submitRequests()" title="Go to top">Submit Request</button>
</div>

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

@ -32,123 +32,133 @@
<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>
</div>
<div *ngFor="let result of tvResults">
<div class="row">
<div class="col-sm-2">
<img *ngIf="result.banner" class="img-responsive poster" width="150" [src]="result.banner" alt="poster">
</div>
<div class="col-sm-8">
<div>
<a href="http://www.imdb.com/title/{{result.imdbId}}/" target="_blank">
<h4>{{result.title}} ({{result.firstAired | date: 'yyyy'}})</h4>
</a>
<span *ngIf="result.status" class="label label-primary" target="_blank">{{result.status}}</span>
<span *ngIf="result.firstAired" class="label label-info" target="_blank">Air Date: {{result.firstAired}}</span>
<span *ngIf="result.releaseDate" class="label label-info" target="_blank">Release Date: {{result.releaseDate | date: 'dd/MM/yyyy'}}</span>
<span *ngIf="result.available" class="label label-success">Available</span>
<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>
<span *ngIf="!result.available" class="label label-warning">Pending Approval</span>
</ng-template>
<ng-template #notRequested>
<span *ngIf="!result.available" class="label label-danger">Not Yet Requested</span>
</ng-template>
<span id="{{id}}netflixTab"></span>
<a *ngIf="result.homepage" href="{{result.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>
<br/>
<br/>
<p-treeTable [value]="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="col-sm-2">
<img *ngIf="node.data.banner" class="img-responsive poster" width="150" [src]="node.data.banner" alt="poster">
</div>
<div class="col-sm-8">
<div>
<a href="http://www.imdb.com/title/{{node.data.imdbId}}/" target="_blank">
<h4>{{node.data.title}} ({{node.data.firstAired | date: 'yyyy'}})</h4>
</a>
<span *ngIf="node.data.status" class="label label-primary" target="_blank">{{node.data.status}}</span>
<span *ngIf="node.data.firstAired" class="label label-info" target="_blank">Air Date: {{node.data.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="node.data.available" class="label label-success">Available</span>
<span *ngIf="node.data.approved && !node.data.available" class="label label-info">Processing Request</span>
<div *ngIf="node.data.requested && !node.data.available; then requested else notRequested"></div>
<ng-template #requested>
<span *ngIf="!node.data.available" class="label label-warning">Pending Approval</span>
</ng-template>
<ng-template #notRequested>
<span *ngIf="!node.data.available" class="label label-danger">Not Yet Requested</span>
</ng-template>
<span id="{{id}}netflixTab"></span>
<a *ngIf="node.data.homepage" href="{{node.data.homepage}}" target="_blank"><span class="label label-info">HomePage</span></a>
<a *ngIf="node.data.trailer" href="{{node.data.trailer}}" target="_blank"><span class="label label-info">Trailer</span></a>
<br />
<br />
</div>
<p style="font-size: 0.9rem !important">{{node.data.overview}}</p>
</div>
<div class="col-sm-2">
<input name="{{type}}Id" type="text" value="{{node.data.id}}" hidden="hidden" />
<!--<div *ngIf="node.data.requested; then requestedBtn else notRequestedBtn"></div>
<template #requestedBtn>
<button style="text-align: right" class="btn btn-primary-outline disabled" [disabled]><i class="fa fa-check"></i> Requested</button>
</template>
<template #notRequestedBtn>
<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>-->
<!--{{#if_eq type "tv"}}
{{#if_eq tvFullyAvailable true}}
@*//TODO Not used yet*@
<button style="text-align: right" class="btn btn-success-outline disabled" disabled><i class="fa fa-check"></i> @UI.Search_Available</button><br/>
{{else}}
{{#if_eq enableTvRequestsForOnlySeries true}}
<button id="{{id}}" style="text-align: right" class="btn {{#if available}}btn-success-outline{{else}}btn-primary-outline dropdownTv{{/if}} btn-primary-outline" season-select="0" type="button" {{#if available}} disabled{{/if}}><i class="fa fa-plus"></i> {{#if available}}@UI.Search_Available{{else}}@UI.Search_Request{{/if}}</button>
{{else}}
-->
<div class="dropdown">
<button class="btn btn-primary-outline dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
<i class="fa fa-plus"></i> Request
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
<li><a (click)="allSeasons(node.data)">All Seasons</a></li>
<li><a (click)="firstSeason(node.data)">First Season</a></li>
<li><a (click)="latestSeason(node.data)">Latest Season</a></li>
<li><a (click)="openClosestTab($event)">Select ...</a></li>
</ul>
</div>
<!--
<br/>
<a style="text-align: right" class="btn btn-sm btn-primary-outline" href="{{url}}" target="_blank"><i class="fa fa-eye"></i> @UI.Search_ViewInPlex</a>
-->
<br />
<div *ngIf="node.data.available">
<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="type" type="text" value="{{type}}" hidden="hidden"/>
<div class="dropdown">
<button class="btn btn-sm btn-danger-outline dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
<i class="fa fa-exclamation"></i> Report Issue
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
<li><a issue-select="0" class="dropdownIssue" href="#">WrongAudio</a></li>
<li><a issue-select="1" class="dropdownIssue" href="#">NoSubs</a></li>
<li><a issue-select="2" class="dropdownIssue" href="#">WrongContent</a></li>
<li><a issue-select="3" class="dropdownIssue" href="#">Playback</a></li>
<li><a issue-select="4" class="dropdownIssue" href="#" data-toggle="modal" data-target="#issuesModal">Other</a></li>
</ul>
</div>-->
</div>
</div>
</div>
<hr />
</div>
<p style="font-size: 0.9rem !important">{{result.overview}}</p>
</div>
<div class="col-sm-2">
<input name="{{type}}Id" type="text" value="{{result.id}}" hidden="hidden"/>
<!--<div *ngIf="result.requested; then requestedBtn else notRequestedBtn"></div>
<template #requestedBtn>
<button style="text-align: right" class="btn btn-primary-outline disabled" [disabled]><i class="fa fa-check"></i> Requested</button>
</template>
<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>
</template>-->
<!--{{#if_eq type "tv"}}
{{#if_eq tvFullyAvailable true}}
@*//TODO Not used yet*@
<button style="text-align: right" class="btn btn-success-outline disabled" disabled><i class="fa fa-check"></i> @UI.Search_Available</button><br/>
{{else}}
{{#if_eq enableTvRequestsForOnlySeries true}}
<button id="{{id}}" style="text-align: right" class="btn {{#if available}}btn-success-outline{{else}}btn-primary-outline dropdownTv{{/if}} btn-primary-outline" season-select="0" type="button" {{#if available}} disabled{{/if}}><i class="fa fa-plus"></i> {{#if available}}@UI.Search_Available{{else}}@UI.Search_Request{{/if}}</button>
{{else}}
-->
<div class="dropdown">
<button class="btn btn-primary-outline dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
<i class="fa fa-plus"></i> Request
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
<li><a (click)="allSeasons(result)">All Seasons</a></li>
<li><a (click)="firstSeason(result)">First Season</a></li>
<li><a (click)="latestSeason(result)">Latest Season</a></li>
<li><a (click)="selectSeason(result)">Select ...</a></li>
</ul>
<!--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>
<!--
<br/>
<a style="text-align: right" class="btn btn-sm btn-primary-outline" href="{{url}}" target="_blank"><i class="fa fa-eye"></i> @UI.Search_ViewInPlex</a>
-->
<br/>
<div *ngIf="result.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>
<!--<input name="providerId" type="text" value="{{id}}" hidden="hidden"/>
<input name="type" type="text" value="{{type}}" hidden="hidden"/>
<div class="dropdown">
<button class="btn btn-sm btn-danger-outline dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
<i class="fa fa-exclamation"></i> Report Issue
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
<li><a issue-select="0" class="dropdownIssue" href="#">WrongAudio</a></li>
<li><a issue-select="1" class="dropdownIssue" href="#">NoSubs</a></li>
<li><a issue-select="2" class="dropdownIssue" href="#">WrongContent</a></li>
<li><a issue-select="3" class="dropdownIssue" href="#">Playback</a></li>
<li><a issue-select="4" class="dropdownIssue" href="#" data-toggle="modal" data-target="#issuesModal">Other</a></li>
</ul>
</div>-->
</div>
</div>
</div>
<hr/>
</div>
</ng-template>
</p-column>
</p-treeTable>
</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 { Subject } from 'rxjs/Subject';
import 'rxjs/add/operator/debounceTime';
@ -12,10 +12,16 @@ import { NotificationService } from '../services/notification.service';
import { ISearchTvResult } from '../interfaces/ISearchTvResult';
import { IRequestEngineResult } from '../interfaces/IRequestEngineResult';
import { TreeNode } from "primeng/primeng";
@Component({
selector: 'tv-search',
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 {
@ -41,11 +47,50 @@ export class TvSearchComponent implements OnInit, OnDestroy {
this.searchService.searchTv(this.searchText)
.takeUntil(this.subscriptions)
.subscribe(x => {
this.tvResults = x;
this.tvResults = this.transformData(x);
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 {
this.searchText = "";

Loading…
Cancel
Save