mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-08-20 21:33:15 -07:00
parent
d1da6ca9b4
commit
4215c77620
7 changed files with 188 additions and 132 deletions
|
@ -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>
|
||||
<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">
|
||||
|
||||
<div *ngFor="let result of tvResults">
|
||||
<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">
|
||||
|
||||
<img *ngIf="result.banner" class="img-responsive poster" width="150" [src]="result.banner" alt="poster">
|
||||
</div>
|
||||
<div class="col-sm-8">
|
||||
<div>
|
||||
|
||||
</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 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>
|
||||
</a>
|
||||
<span *ngIf="node.data.status" class="label label-primary" target="_blank">{{node.data.status}}</span>
|
||||
|
||||
|
||||
<span *ngIf="result.firstAired" class="label label-info" target="_blank">Air Date: {{result.firstAired}}</span>
|
||||
<span *ngIf="node.data.firstAired" class="label label-info" target="_blank">Air Date: {{node.data.firstAired}}</span>
|
||||
|
||||
|
||||
<span *ngIf="result.releaseDate" class="label label-info" target="_blank">Release Date: {{result.releaseDate | date: 'dd/MM/yyyy'}}</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.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>
|
||||
<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="!result.available" class="label label-danger">Not Yet Requested</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>
|
||||
<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>
|
||||
<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…
Add table
Add a link
Reference in a new issue