mirror of https://github.com/Ombi-app/Ombi
parent
873823017c
commit
c5f123b903
@ -1,171 +0,0 @@
|
|||||||
<div class="spinner-container">
|
|
||||||
<mat-spinner *ngIf="loading" [color]="'accent'"></mat-spinner>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="!loading" mat-dialog-content class="background">
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-4">
|
|
||||||
<a (click)="openDetails()">
|
|
||||||
<img id="cardImage" src="{{data.posterPath}}" class="poster" alt="{{data.title}}">
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="col-8">
|
|
||||||
<div class="row">
|
|
||||||
|
|
||||||
<div class="col-4 offset-8 text-right" id="icons">
|
|
||||||
<span *ngIf="movie">
|
|
||||||
<a *ngIf="movie.plexUrl" class="media-icons" href="{{movie.plexUrl}}" target="_blank">
|
|
||||||
<i matTooltip=" {{'Search.ViewOnPlex' | translate}}"
|
|
||||||
class="fas fa-play-circle fa-2x grow"></i>
|
|
||||||
</a>
|
|
||||||
<a *ngIf="movie.embyUrl" class="media-icons" href="{{movie.embyUrl}}" target="_blank">
|
|
||||||
<i matTooltip=" {{'Search.ViewOnEmby' | translate}}"
|
|
||||||
class="fas fa-play-circle fa-2x grow"></i>
|
|
||||||
</a>
|
|
||||||
<a *ngIf="movie.jellyfinUrl" class="media-icons" href="{{movie.jellyfinUrl}}" target="_blank">
|
|
||||||
<i matTooltip=" {{'Search.ViewOnJellyfin' | translate}}"
|
|
||||||
class="fas fa-play-circle fa-2x grow"></i>
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span *ngIf="tv">
|
|
||||||
<a *ngIf="tv.plexUrl" class="media-icons" href="{{tv.plexUrl}}" target="_blank">
|
|
||||||
<i matTooltip=" {{'Search.ViewOnPlex' | translate}}"
|
|
||||||
class="fas fa-play-circle fa-2x grow"></i>
|
|
||||||
</a>
|
|
||||||
<a *ngIf="tv.embyUrl" class="media-icons" href="{{tv.embyUrl}}" target="_blank">
|
|
||||||
<i matTooltip=" {{'Search.ViewOnEmby' | translate}}"
|
|
||||||
class="fas fa-play-circle fa-2x grow"></i>
|
|
||||||
</a>
|
|
||||||
<a *ngIf="tv.jellyfinUrl" class="media-icons" href="{{tv.jellyfinUrl}}" target="_blank">
|
|
||||||
<i matTooltip=" {{'Search.ViewOnJellyfin' | translate}}"
|
|
||||||
class="fas fa-play-circle fa-2x grow"></i>
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<a class="media-icons" (click)="close()">
|
|
||||||
<i class="fas fa-window-close fa-2x grow"></i>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-12">
|
|
||||||
<h3><strong>{{data.title}}</strong></h3>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="row top-spacing details">
|
|
||||||
<div class="col-6">
|
|
||||||
<strong>{{'Discovery.CardDetails.Availability' | translate}}: </strong> <small>
|
|
||||||
<ng-template [ngIf]="data.available"><span class="label label-success" id="availableLabel"
|
|
||||||
[translate]="'Common.Available'"></span></ng-template>
|
|
||||||
<ng-template [ngIf]="!data.available"><span class="label label-success" id="availableLabel"
|
|
||||||
[translate]="'Common.NotAvailable'"></span></ng-template>
|
|
||||||
</small>
|
|
||||||
</div>
|
|
||||||
<div class="col-6">
|
|
||||||
<strong *ngIf="movie">{{'Discovery.CardDetails.Studio' | translate}}: </strong>
|
|
||||||
<small *ngIf="movie">{{movie.productionCompanies[0].name}}</small>
|
|
||||||
<strong *ngIf="tv">{{'Discovery.CardDetails.Network' | translate}}: </strong>
|
|
||||||
<small *ngIf="tv && tv.network">{{tv.network.name}}</small>
|
|
||||||
<small *ngIf="tv && !tv.network">{{'Discovery.CardDetails.UnknownNetwork' | translate}}</small>
|
|
||||||
</div>
|
|
||||||
<div class="col-6" *ngIf="!data.available">
|
|
||||||
<strong>{{'Discovery.CardDetails.RequestStatus' | translate}}: </strong> <small>
|
|
||||||
<ng-template [ngIf]="data.approved && !data.available"><span class="label label-info"
|
|
||||||
id="processingRequestLabel" [translate]="'Common.ProcessingRequest'"></span>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template [ngIf]="data.requested && !data.approved && !data.available"><span
|
|
||||||
class="label label-warning" id="pendingApprovalLabel"
|
|
||||||
[translate]="'Common.PendingApproval'"></span></ng-template>
|
|
||||||
<ng-template [ngIf]="!data.requested && !data.available && !data.approved"><span
|
|
||||||
class="label label-danger" id="notRequestedLabel"
|
|
||||||
[translate]="'Common.NotRequested'"></span></ng-template>
|
|
||||||
</small>
|
|
||||||
</div>
|
|
||||||
<div class="col-6">
|
|
||||||
<strong *ngIf="movie">{{'Discovery.CardDetails.Director' | translate}}: </strong>
|
|
||||||
<small *ngIf="movie">{{movie.credits.crew[0].name}}</small>
|
|
||||||
<strong *ngIf="tvCreator">Director: </strong>
|
|
||||||
<small *ngIf="tvCreator">{{tvCreator}}</small>
|
|
||||||
</div>
|
|
||||||
<div class="col-6">
|
|
||||||
<strong *ngIf="movie">{{'Discovery.CardDetails.InCinemas' | translate}}: </strong>
|
|
||||||
<small *ngIf="movie">{{movie.releaseDate | amLocal | amDateFormat: 'LL'}}</small>
|
|
||||||
<strong *ngIf="tv">{{'Discovery.CardDetails.FirstAired' | translate}}: </strong>
|
|
||||||
<small *ngIf="tv">{{tv.firstAired | amLocal | amDateFormat: 'LL'}}</small>
|
|
||||||
</div>
|
|
||||||
<div class="col-6">
|
|
||||||
<strong *ngIf="movie">{{'Discovery.CardDetails.Writer' | translate}}: </strong>
|
|
||||||
<small *ngIf="movie">{{movie.credits.crew[1].name}}</small>
|
|
||||||
<strong *ngIf="tv">{{'Discovery.CardDetails.ExecProducer' | translate}}: </strong>
|
|
||||||
<small *ngIf="tv">{{tvProducer}}</small>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row top-spacing overview">
|
|
||||||
<div class="col-12">
|
|
||||||
{{data.overview}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div mat-dialog-actions>
|
|
||||||
<div class="action-buttons-right">
|
|
||||||
<div class="col-md-12" *ngIf="movie">
|
|
||||||
<button mat-raised-button class="btn-green btn-spacing" *ngIf="movie.available"> {{
|
|
||||||
'Common.Available' | translate }}</button>
|
|
||||||
<span *ngIf="!movie.available">
|
|
||||||
<span *ngIf="movie.requested || movie.approved; then requestedBtn else notRequestedBtn"></span>
|
|
||||||
<ng-template #requestedBtn>
|
|
||||||
<button mat-raised-button class="btn-spacing btn-orange" [disabled]><i class="fas fa-check"></i>
|
|
||||||
{{ 'Common.Requested' | translate }}</button>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template #notRequestedBtn>
|
|
||||||
<button mat-raised-button class="btn-spacing" color="primary" (click)="request()">
|
|
||||||
<i *ngIf="movie.requestProcessing" class="fas fa-circle-notch fa-spin fa-fw"></i> <i
|
|
||||||
*ngIf="!movie.requestProcessing && !movie.processed" class="fas fa-plus"></i>
|
|
||||||
<i *ngIf="movie.processed && !movie.requestProcessing" class="fas fa-check"></i> {{
|
|
||||||
'Common.Request' | translate }}</button>
|
|
||||||
</ng-template>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-12" *ngIf="tv">
|
|
||||||
|
|
||||||
<div *ngIf="!tv.fullyAvailable" class="dropdown">
|
|
||||||
<button mat-raised-button class="btn-orange btn-spacing" type="button" (click)="request()">
|
|
||||||
<i class="fas fa-plus"></i>
|
|
||||||
{{ 'Common.Request' | translate }}
|
|
||||||
<span class="caret"></span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button *ngIf="tv.fullyAvailable" mat-raised-button class="btn-spacing" color="accent" [disabled]>
|
|
||||||
<i class="fas fa-check"></i> {{'Common.Available' | translate }}</button>
|
|
||||||
<button *ngIf="tv.partlyAvailable && !tv.fullyAvailable" mat-raised-button class="btn-spacing" color="accent"
|
|
||||||
[disabled]>
|
|
||||||
<i class="fas fa-check"></i> {{'Common.PartiallyAvailable' | translate }}</button>
|
|
||||||
|
|
||||||
<span *ngIf="tv.available">
|
|
||||||
<a *ngIf="tv.plexUrl" mat-raised-button style="text-align: right" class="btn-spacing btn-greem"
|
|
||||||
href="{{tv.plexUrl}}" target="_blank"><i class="far fa-eye"></i> {{'Search.ViewOnPlex' |
|
|
||||||
translate}}</a>
|
|
||||||
<a *ngIf="tv.embyUrl" mat-raised-button class="btn-green btn-spacing" href="{{tv.embyUrl}}"
|
|
||||||
target="_blank"><i class="far fa-eye"></i> {{'Search.ViewOnEmby' |
|
|
||||||
translate}}</a>
|
|
||||||
<a *ngIf="tv.jellyfinUrl" mat-raised-button class="btn-green btn-spacing" href="{{tv.jellyfinUrl}}"
|
|
||||||
target="_blank"><i class="far fa-eye"></i> {{'Search.ViewOnJellyfin' |
|
|
||||||
translate}}</a>
|
|
||||||
</span>
|
|
||||||
<button mat-raised-button class="btn-green btn-spacing" (click)="openDetails()"> {{
|
|
||||||
'Common.ViewDetails' | translate }}</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
@ -1,45 +0,0 @@
|
|||||||
@import "~styles/variables.scss";
|
|
||||||
.poster {
|
|
||||||
max-width: 100%;
|
|
||||||
border-radius: 2%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.details {
|
|
||||||
padding: 2%;
|
|
||||||
border-radius: 10px;
|
|
||||||
background: $backgroundTint;
|
|
||||||
div.dark & {
|
|
||||||
background: $backgroundTint-dark;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.details strong {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
h3 strong {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.action-buttons-right {
|
|
||||||
width: 100%;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-spacing {
|
|
||||||
margin-right: 1%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.media-icons {
|
|
||||||
color: $primary;
|
|
||||||
padding: 2%;
|
|
||||||
div.dark & {
|
|
||||||
color: $warn-dark;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.overview {
|
|
||||||
height:300px;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
@ -1,86 +0,0 @@
|
|||||||
import { Component, Inject, OnInit, ViewEncapsulation } from "@angular/core";
|
|
||||||
import { MatDialogRef, MAT_DIALOG_DATA, MatDialog } from "@angular/material/dialog";
|
|
||||||
import { IDiscoverCardResult } from "../../interfaces";
|
|
||||||
import { SearchV2Service, RequestService, MessageService } from "../../../services";
|
|
||||||
import { RequestType } from "../../../interfaces";
|
|
||||||
import { ISearchMovieResultV2 } from "../../../interfaces/ISearchMovieResultV2";
|
|
||||||
import { ISearchTvResultV2 } from "../../../interfaces/ISearchTvResultV2";
|
|
||||||
import { Router } from "@angular/router";
|
|
||||||
import { EpisodeRequestComponent } from "../../../shared/episode-request/episode-request.component";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: "discover-card-details",
|
|
||||||
templateUrl: "./discover-card-details.component.html",
|
|
||||||
styleUrls: ["./discover-card-details.component.scss"],
|
|
||||||
encapsulation: ViewEncapsulation.None,
|
|
||||||
})
|
|
||||||
export class DiscoverCardDetailsComponent implements OnInit {
|
|
||||||
|
|
||||||
public movie: ISearchMovieResultV2;
|
|
||||||
public tv: ISearchTvResultV2;
|
|
||||||
public tvCreator: string;
|
|
||||||
public tvProducer: string;
|
|
||||||
public loading: boolean;
|
|
||||||
public RequestType = RequestType;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
public dialogRef: MatDialogRef<DiscoverCardDetailsComponent>,
|
|
||||||
@Inject(MAT_DIALOG_DATA) public data: IDiscoverCardResult, private searchService: SearchV2Service, private dialog: MatDialog,
|
|
||||||
private requestService: RequestService, public messageService: MessageService, private router: Router) { }
|
|
||||||
|
|
||||||
public async ngOnInit() {
|
|
||||||
this.loading = true;
|
|
||||||
if (this.data.type === RequestType.movie) {
|
|
||||||
this.movie = await this.searchService.getFullMovieDetailsPromise(+this.data.id);
|
|
||||||
} else if (this.data.type === RequestType.tvShow) {
|
|
||||||
this.tv = await this.searchService.getTvInfo(+this.data.id);
|
|
||||||
const creator = this.tv.crew.filter(tv => {
|
|
||||||
return tv.type === "Creator";
|
|
||||||
})[0];
|
|
||||||
if (creator && creator.person) {
|
|
||||||
this.tvCreator = creator.person.name;
|
|
||||||
}
|
|
||||||
const crewResult = this.tv.crew.filter(tv => {
|
|
||||||
return tv.type === "Executive Producer";
|
|
||||||
})[0]
|
|
||||||
if (crewResult && crewResult.person) {
|
|
||||||
this.tvProducer = crewResult.person.name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.loading = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public close(): void {
|
|
||||||
this.dialogRef.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public openDetails() {
|
|
||||||
if (this.data.type === RequestType.movie) {
|
|
||||||
this.router.navigate(['/details/movie/', this.data.id]);
|
|
||||||
} else if (this.data.type === RequestType.tvShow) {
|
|
||||||
this.router.navigate(['/details/tv/', this.data.id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.dialogRef.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async request() {
|
|
||||||
this.loading = true;
|
|
||||||
if (this.data.type === RequestType.movie) {
|
|
||||||
const result = await this.requestService.requestMovie({ theMovieDbId: +this.data.id, languageCode: "", requestOnBehalf: null }).toPromise();
|
|
||||||
this.loading = false;
|
|
||||||
|
|
||||||
if (result.result) {
|
|
||||||
this.movie.requested = true;
|
|
||||||
this.messageService.send(result.message, "Ok");
|
|
||||||
} else {
|
|
||||||
this.messageService.send(result.errorMessage, "Ok");
|
|
||||||
}
|
|
||||||
} else if (this.data.type === RequestType.tvShow) {
|
|
||||||
this.dialog.open(EpisodeRequestComponent, { width: "700px", data: {series: this.tv }, panelClass: 'modal-panel' })
|
|
||||||
}
|
|
||||||
this.loading = false;
|
|
||||||
|
|
||||||
this.dialogRef.close();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +1,21 @@
|
|||||||
import { Component } from "@angular/core";
|
import { Component, OnInit } from "@angular/core";
|
||||||
|
import { AuthService } from "../../../auth/auth.service";
|
||||||
import { DiscoverType } from "../carousel-list/carousel-list.component";
|
import { DiscoverType } from "../carousel-list/carousel-list.component";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "./discover.component.html",
|
templateUrl: "./discover.component.html",
|
||||||
styleUrls: ["./discover.component.scss"],
|
styleUrls: ["./discover.component.scss"],
|
||||||
})
|
})
|
||||||
export class DiscoverComponent {
|
export class DiscoverComponent implements OnInit {
|
||||||
|
|
||||||
|
|
||||||
public DiscoverType = DiscoverType;
|
public DiscoverType = DiscoverType;
|
||||||
|
public isAdmin: boolean;
|
||||||
|
|
||||||
constructor() { }
|
constructor(private authService: AuthService) { }
|
||||||
|
|
||||||
|
public ngOnInit(): void {
|
||||||
|
this.isAdmin = this.authService.isAdmin();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,168 +0,0 @@
|
|||||||
<!-- <div class="card-spacing" *ngIf="result">
|
|
||||||
<mat-card class="mat-elevation-z8 dark-card grow">
|
|
||||||
<a [routerLink]="result.type === RequestType.movie ? '/details/movie/' + result.id : '/details/tv/' + result.id">
|
|
||||||
<img id="cardImage" mat-card-image src="{{result.posterPath}}" class="card-poster" [ngClass]="getStatusClass()" alt="{{result.title}}">
|
|
||||||
</a>
|
|
||||||
<mat-card-content>
|
|
||||||
<h6 *ngIf="result.title.length <= 20">{{result.title}}</h6>
|
|
||||||
<h6 *ngIf="result.title.length > 20" matTooltip="{{result.title}}">{{result.title | truncate:20}}</h6>
|
|
||||||
<div class="fade-text">
|
|
||||||
<small class="overview-text">{{result.overview | truncate: 75}}</small>
|
|
||||||
</div>
|
|
||||||
</mat-card-content>
|
|
||||||
</mat-card>
|
|
||||||
</div> -->
|
|
||||||
|
|
||||||
|
|
||||||
<div class="top-spacing">
|
|
||||||
<mat-card class="mat-elevation-z8 dark-card backdrop" [style.background-image]="result.background">
|
|
||||||
<div class="row main-container">
|
|
||||||
<div class="col-md-2 col-12">
|
|
||||||
<img src="{{result.posterPath}}" class="card-poster" alt="{{result.title}}">
|
|
||||||
</div>
|
|
||||||
<div class="col-md-8 col-12">
|
|
||||||
<div class="row">
|
|
||||||
<h1>{{result.title}}</h1>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<mat-chip-list>
|
|
||||||
<mat-chip *ngIf="result.available" class="available">
|
|
||||||
{{'Common.Available' | translate}}
|
|
||||||
</mat-chip>
|
|
||||||
|
|
||||||
<mat-chip *ngIf="result.approved && !result.available" class="approved">
|
|
||||||
{{'Common.ProcessingRequest' | translate}}
|
|
||||||
</mat-chip>
|
|
||||||
|
|
||||||
<mat-chip *ngIf="result.denied" class="denied">
|
|
||||||
{{'Common.RequestDenied' | translate}}
|
|
||||||
</mat-chip>
|
|
||||||
|
|
||||||
<mat-chip *ngIf="result.requested && !result.approved && !result.available && !result.denied"
|
|
||||||
class="requested">
|
|
||||||
{{'Common.PendingApproval' | translate}}
|
|
||||||
</mat-chip>
|
|
||||||
<mat-chip *ngIf="movie && movie.plexUrl"> <a href="{{movie.plexUrl}}" target="_blank">
|
|
||||||
<mat-icon style="color:white" matTooltip=" {{'Search.ViewOnPlex' | translate}}">
|
|
||||||
play_circle_outline</mat-icon>
|
|
||||||
</a></mat-chip>
|
|
||||||
<mat-chip *ngIf="movie && movie.embyUrl"> <a href="{{movie.embyUrl}}" target="_blank">
|
|
||||||
<mat-icon style="color:white" matTooltip=" {{'Search.ViewOnEmby' | translate}}">
|
|
||||||
play_circle_outline</mat-icon>
|
|
||||||
</a></mat-chip>
|
|
||||||
<mat-chip *ngIf="movie && movie.jellyfinUrl"> <a href="{{movie.jellyfinUrl}}" target="_blank">
|
|
||||||
<mat-icon style="color:white" matTooltip=" {{'Search.ViewOnJellyfin' | translate}}">
|
|
||||||
play_circle_outline</mat-icon>
|
|
||||||
</a></mat-chip>
|
|
||||||
|
|
||||||
<mat-chip *ngIf="tv && tv.plexUrl"> <a href="{{tv.plexUrl}}" target="_blank">
|
|
||||||
<mat-icon style="color:white" matTooltip=" {{'Search.ViewOnPlex' | translate}}">
|
|
||||||
play_circle_outline</mat-icon>
|
|
||||||
</a></mat-chip>
|
|
||||||
<mat-chip *ngIf="tv &&tv.embyUrl"> <a href="{{movie.embyUrl}}" target="_blank">
|
|
||||||
<mat-icon style="color:white" matTooltip=" {{'Search.ViewOnEmby' | translate}}">
|
|
||||||
play_circle_outline</mat-icon>
|
|
||||||
</a></mat-chip>
|
|
||||||
<mat-chip *ngIf="tv &&tv.jellyfinUrl"> <a href="{{movie.jellyfinUrl}}" target="_blank">
|
|
||||||
<mat-icon style="color:white" matTooltip=" {{'Search.ViewOnJellyfin' | translate}}">
|
|
||||||
play_circle_outline</mat-icon>
|
|
||||||
</a></mat-chip>
|
|
||||||
</mat-chip-list>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
|
|
||||||
<mat-chip-list class="top-spacing">
|
|
||||||
<mat-chip *ngIf="movie && movie.productionCompanies[0]?.name">
|
|
||||||
{{'Discovery.CardDetails.Studio' | translate}}: {{movie.productionCompanies[0].name}}
|
|
||||||
</mat-chip>
|
|
||||||
|
|
||||||
<mat-chip *ngIf="tv && tv.network?.name">{{'Discovery.CardDetails.Network' | translate}}:
|
|
||||||
{{tv.network.name}}</mat-chip>
|
|
||||||
|
|
||||||
<mat-chip *ngIf="movie && movie.credits?.crew[0]?.name">
|
|
||||||
{{'Discovery.CardDetails.Director' | translate}}: {{movie.credits.crew[0].name}}</mat-chip>
|
|
||||||
|
|
||||||
<mat-chip *ngIf="tvCreator">Director: {{tvCreator}}</mat-chip>
|
|
||||||
|
|
||||||
<mat-chip *ngIf="movie">{{'Discovery.CardDetails.InCinemas' | translate}}:
|
|
||||||
{{movie.releaseDate | amLocal | amDateFormat: 'LL'}}</mat-chip>
|
|
||||||
|
|
||||||
<mat-chip *ngIf="tv">{{'Discovery.CardDetails.FirstAired' | translate}}:
|
|
||||||
{{tv.firstAired | amLocal | amDateFormat: 'LL'}}</mat-chip>
|
|
||||||
|
|
||||||
<mat-chip *ngIf="movie && movie.credits?.crew[1]?.name">
|
|
||||||
{{'Discovery.CardDetails.Writer' | translate}}: {{movie.credits.crew[1].name}}</mat-chip>
|
|
||||||
|
|
||||||
<mat-chip *ngIf="tv">{{'Discovery.CardDetails.ExecProducer' | translate}}: {{tvProducer}}
|
|
||||||
</mat-chip>
|
|
||||||
|
|
||||||
</mat-chip-list>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<p class="overview top-spacing">{{result.overview}}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-2 col-12">
|
|
||||||
<div style="float:right;">
|
|
||||||
<button mat-raised-button class="btn-green btn-spacing" (click)="openDetails()"> {{
|
|
||||||
'Common.ViewDetails' | translate }}</button>
|
|
||||||
<div *ngIf="movie">
|
|
||||||
<button mat-raised-button class="btn-green btn-spacing" *ngIf="movie.available"> {{
|
|
||||||
'Common.Available' | translate }}</button>
|
|
||||||
<span *ngIf="!movie.available">
|
|
||||||
<span
|
|
||||||
*ngIf="movie.requested || movie.approved; then requestedBtn else notRequestedBtn"></span>
|
|
||||||
<ng-template #requestedBtn>
|
|
||||||
<button mat-raised-button class="btn-spacing btn-orange" [disabled]><i
|
|
||||||
class="fas fa-check"></i>
|
|
||||||
{{ 'Common.Requested' | translate }}</button>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template #notRequestedBtn>
|
|
||||||
<button mat-raised-button class="btn-spacing" color="primary" (click)="request()">
|
|
||||||
<i *ngIf="movie.requestProcessing" class="fas fa-circle-notch fa-spin fa-fw"></i>
|
|
||||||
<i *ngIf="!movie.requestProcessing && !movie.processed" class="fas fa-plus"></i>
|
|
||||||
<i *ngIf="movie.processed && !movie.requestProcessing" class="fas fa-check"></i> {{
|
|
||||||
'Common.Request' | translate }}</button>
|
|
||||||
</ng-template>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div *ngIf="tv">
|
|
||||||
|
|
||||||
<div *ngIf="!tv.fullyAvailable" class="dropdown">
|
|
||||||
<button mat-raised-button class="btn-orange btn-spacing" type="button" (click)="request()">
|
|
||||||
<i class="fas fa-plus"></i>
|
|
||||||
{{ 'Common.Request' | translate }}
|
|
||||||
<span class="caret"></span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button *ngIf="tv.fullyAvailable" mat-raised-button class="btn-spacing" color="accent"
|
|
||||||
[disabled]>
|
|
||||||
<i class="fas fa-check"></i> {{'Common.Available' | translate }}</button>
|
|
||||||
<button *ngIf="tv.partlyAvailable && !tv.fullyAvailable" mat-raised-button class="btn-spacing"
|
|
||||||
color="accent" [disabled]>
|
|
||||||
<i class="fas fa-check"></i> {{'Common.PartiallyAvailable' | translate }}</button>
|
|
||||||
|
|
||||||
<span *ngIf="tv.available">
|
|
||||||
<a *ngIf="tv.plexUrl" mat-raised-button style="text-align: right"
|
|
||||||
class="btn-spacing btn-greem" href="{{tv.plexUrl}}" target="_blank"><i
|
|
||||||
class="far fa-eye"></i> {{'Search.ViewOnPlex' |
|
|
||||||
translate}}</a>
|
|
||||||
<a *ngIf="tv.embyUrl" mat-raised-button class="btn-green btn-spacing" href="{{tv.embyUrl}}"
|
|
||||||
target="_blank"><i class="far fa-eye"></i> {{'Search.ViewOnEmby' |
|
|
||||||
translate}}</a>
|
|
||||||
<a *ngIf="tv.jellyfinUrl" mat-raised-button class="btn-green btn-spacing" href="{{tv.jellyfinUrl}}"
|
|
||||||
target="_blank"><i class="far fa-eye"></i> {{'Search.ViewOnJellyfin' |
|
|
||||||
translate}}</a>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</mat-card>
|
|
||||||
</div>
|
|
@ -1,137 +0,0 @@
|
|||||||
$ombi-primary:#3f3f3f;
|
|
||||||
$card-background: #2b2b2b;
|
|
||||||
|
|
||||||
$blue: #1976D2;
|
|
||||||
$pink: #C2185B;
|
|
||||||
$green:#1DE9B6;
|
|
||||||
$orange:#F57C00;
|
|
||||||
|
|
||||||
.btn-blue {
|
|
||||||
background-color: $blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-pink {
|
|
||||||
background-color: $pink;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-green {
|
|
||||||
background-color: $green;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-orange {
|
|
||||||
background-color: $orange;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-spacing {
|
|
||||||
margin-top:10%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#cardImage {
|
|
||||||
border-radius: 5px 5px 0px 0px;
|
|
||||||
height: 75%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark-card {
|
|
||||||
border-radius: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Changed height to 100% to make all cards the same height
|
|
||||||
.top-spacing {
|
|
||||||
margin-top: 1%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-poster {
|
|
||||||
width: 100%;
|
|
||||||
border-radius: 8px 0px 0px 8px;
|
|
||||||
margin-top: -6.5%;
|
|
||||||
margin-bottom: -6.6%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-container {
|
|
||||||
margin-left: -2%;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.rating {
|
|
||||||
position: absolute;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
$border-width: 3px;
|
|
||||||
|
|
||||||
.available {
|
|
||||||
background-color: #1DE9B6 !important;
|
|
||||||
color: black !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.approved {
|
|
||||||
background-color: #ff5722 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.requested {
|
|
||||||
background-color: #ffd740 !important;
|
|
||||||
color: black !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.denied {
|
|
||||||
background-color: #C2185B !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.notrequested {
|
|
||||||
background-color: #303030 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.expand {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 1025px) {
|
|
||||||
|
|
||||||
// Changed height to 100% to make all cards the same height
|
|
||||||
.grow {
|
|
||||||
transition: all .2s ease-in-out;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grow:hover {
|
|
||||||
transform: scale(1.1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
::ng-deep mat-dialog-container.mat-dialog-container {
|
|
||||||
// background-color: $ombi-primary;
|
|
||||||
// color: white;
|
|
||||||
border-radius: 2%
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Title adjust for the Discover page */
|
|
||||||
.mat-card-content h6 {
|
|
||||||
overflow: hidden;
|
|
||||||
white-space: nowrap;
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 1.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Summary adjust for Discover page */
|
|
||||||
.small,
|
|
||||||
small {
|
|
||||||
font-size: 0.8rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 2000px) {
|
|
||||||
#cardImage {
|
|
||||||
height: 80%;
|
|
||||||
object-fit: cover;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.overview {
|
|
||||||
font-size: 1.2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.backdrop {
|
|
||||||
background-position: 50% 33%;
|
|
||||||
background-size: cover;
|
|
||||||
}
|
|
@ -1,154 +0,0 @@
|
|||||||
import { Component, OnInit, Input } from "@angular/core";
|
|
||||||
import { IDiscoverCardResult } from "../../interfaces";
|
|
||||||
import { RequestType, ISearchTvResult, ISearchMovieResult, ISearchMovieResultContainer } from "../../../interfaces";
|
|
||||||
import { ImageService, RequestService, SearchV2Service } from "../../../services";
|
|
||||||
import { MatDialog } from "@angular/material/dialog";
|
|
||||||
import { ISearchTvResultV2 } from "../../../interfaces/ISearchTvResultV2";
|
|
||||||
import { ISearchMovieResultV2 } from "../../../interfaces/ISearchMovieResultV2";
|
|
||||||
import { EpisodeRequestComponent, EpisodeRequestData } from "../../../shared/episode-request/episode-request.component";
|
|
||||||
import { MatSnackBar } from "@angular/material/snack-bar";
|
|
||||||
import { Router } from "@angular/router";
|
|
||||||
import { DomSanitizer } from "@angular/platform-browser";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: "discover-grid",
|
|
||||||
templateUrl: "./discover-grid.component.html",
|
|
||||||
styleUrls: ["./discover-grid.component.scss"],
|
|
||||||
})
|
|
||||||
export class DiscoverGridComponent implements OnInit {
|
|
||||||
|
|
||||||
@Input() public result: IDiscoverCardResult;
|
|
||||||
public RequestType = RequestType;
|
|
||||||
public requesting: boolean;
|
|
||||||
|
|
||||||
public tv: ISearchTvResultV2;
|
|
||||||
public tvCreator: string;
|
|
||||||
public tvProducer: string;
|
|
||||||
public movie: ISearchMovieResultV2;
|
|
||||||
|
|
||||||
constructor(private searchService: SearchV2Service, private dialog: MatDialog,
|
|
||||||
private requestService: RequestService, private notification: MatSnackBar,
|
|
||||||
private router: Router, private sanitizer: DomSanitizer, private imageService: ImageService) { }
|
|
||||||
|
|
||||||
public ngOnInit() {
|
|
||||||
if (this.result.type == RequestType.tvShow) {
|
|
||||||
this.getExtraTvInfo();
|
|
||||||
}
|
|
||||||
if (this.result.type == RequestType.movie) {
|
|
||||||
this.getExtraMovieInfo();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async getExtraTvInfo() {
|
|
||||||
this.tv = await this.searchService.getTvInfo(+this.result.id);
|
|
||||||
this.setTvDefaults(this.tv);
|
|
||||||
this.updateTvItem(this.tv);
|
|
||||||
const creator = this.tv.crew.filter(tv => {
|
|
||||||
return tv.type === "Creator";
|
|
||||||
})[0];
|
|
||||||
if (creator && creator.person) {
|
|
||||||
this.tvCreator = creator.person.name;
|
|
||||||
}
|
|
||||||
const crewResult = this.tv.crew.filter(tv => {
|
|
||||||
return tv.type === "Executive Producer";
|
|
||||||
})[0]
|
|
||||||
if (crewResult && crewResult.person) {
|
|
||||||
this.tvProducer = crewResult.person.name;
|
|
||||||
}
|
|
||||||
this.setTvBackground();
|
|
||||||
}
|
|
||||||
|
|
||||||
public openDetails() {
|
|
||||||
if (this.result.type === RequestType.movie) {
|
|
||||||
this.router.navigate(['/details/movie/', this.result.id]);
|
|
||||||
} else if (this.result.type === RequestType.tvShow) {
|
|
||||||
this.router.navigate(['/details/tv/', this.result.id]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public getStatusClass(): string {
|
|
||||||
if (this.result.available) {
|
|
||||||
return "available";
|
|
||||||
}
|
|
||||||
if (this.result.approved) {
|
|
||||||
return "approved";
|
|
||||||
}
|
|
||||||
if (this.result.requested) {
|
|
||||||
return "requested";
|
|
||||||
}
|
|
||||||
return "notrequested";
|
|
||||||
}
|
|
||||||
|
|
||||||
private getExtraMovieInfo() {
|
|
||||||
this.searchService.getFullMovieDetails(+this.result.id)
|
|
||||||
.subscribe(m => {
|
|
||||||
this.movie = m;
|
|
||||||
this.updateMovieItem(m);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.setMovieBackground()
|
|
||||||
}
|
|
||||||
|
|
||||||
private setMovieBackground(): void {
|
|
||||||
this.result.background = this.sanitizer.bypassSecurityTrustStyle
|
|
||||||
("linear-gradient( rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5) ), url(" + "https://image.tmdb.org/t/p/original" + this.result.background + ")");
|
|
||||||
}
|
|
||||||
|
|
||||||
private setTvBackground(): void {
|
|
||||||
if (this.result.background != null) {
|
|
||||||
this.result.background = this.sanitizer.bypassSecurityTrustStyle
|
|
||||||
("linear-gradient( rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5) ), url(https://image.tmdb.org/t/p/original" + this.result.background + ")");
|
|
||||||
} else {
|
|
||||||
this.imageService.getTvBanner(+this.result.id).subscribe(x => {
|
|
||||||
if (x) {
|
|
||||||
this.result.background = this.sanitizer.bypassSecurityTrustStyle
|
|
||||||
("linear-gradient( rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5) ), url(" + x + ")");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private updateMovieItem(updated: ISearchMovieResultV2) {
|
|
||||||
this.result.url = "http://www.imdb.com/title/" + updated.imdbId + "/";
|
|
||||||
this.result.available = updated.available;
|
|
||||||
this.result.requested = updated.requested;
|
|
||||||
this.result.requested = updated.requestProcessing;
|
|
||||||
this.result.rating = updated.voteAverage;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private setTvDefaults(x: ISearchTvResultV2) {
|
|
||||||
if (!x.imdbId) {
|
|
||||||
x.imdbId = "https://www.tvmaze.com/shows/" + x.seriesId;
|
|
||||||
} else {
|
|
||||||
x.imdbId = "http://www.imdb.com/title/" + x.imdbId + "/";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private updateTvItem(updated: ISearchTvResultV2) {
|
|
||||||
this.result.title = updated.title;
|
|
||||||
this.result.id = updated.id;
|
|
||||||
this.result.available = updated.fullyAvailable;
|
|
||||||
this.result.posterPath = updated.banner;
|
|
||||||
this.result.requested = updated.requested;
|
|
||||||
this.result.url = updated.imdbId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async request() {
|
|
||||||
this.requesting = true;
|
|
||||||
if (this.result.type === RequestType.movie) {
|
|
||||||
const result = await this.requestService.requestMovie({ theMovieDbId: +this.result.id, languageCode: "", requestOnBehalf: null }).toPromise();
|
|
||||||
|
|
||||||
if (result.result) {
|
|
||||||
this.result.requested = true;
|
|
||||||
this.notification.open(result.message, "Ok");
|
|
||||||
} else {
|
|
||||||
this.notification.open(result.errorMessage, "Ok");
|
|
||||||
}
|
|
||||||
} else if (this.result.type === RequestType.tvShow) {
|
|
||||||
this.dialog.open(EpisodeRequestComponent, { width: "700px", data: <EpisodeRequestData>{ series: this.tv, requestOnBehalf: null }, panelClass: 'modal-panel' })
|
|
||||||
}
|
|
||||||
this.requesting = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,82 @@
|
|||||||
|
|
||||||
|
|
||||||
|
<form [formGroup]="form" *ngIf="form">
|
||||||
|
<h1>Advanced Options</h1>
|
||||||
|
<div class="alert alert-info" role="alert">
|
||||||
|
You can configure the request here, once requested it will be send to your DVR application and will be auto approved!
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="max-width: 0; max-height: 0; overflow: hidden;">
|
||||||
|
<input autofocus="true" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- User area -->
|
||||||
|
<h3>{{'MediaDetails.RequestOnBehalf' | translate }}</h3>
|
||||||
|
<mat-form-field class="example-full-width" appearance="outline" floatLabel=auto>
|
||||||
|
<mat-label>{{ 'MediaDetails.PleaseSelectUser' | translate}}</mat-label>
|
||||||
|
<input type="text"
|
||||||
|
matInput
|
||||||
|
formControlName="username"
|
||||||
|
[matAutocomplete]="auto">
|
||||||
|
<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn">
|
||||||
|
<mat-option *ngFor="let option of filteredOptions | async" [value]="option">
|
||||||
|
{{displayFn(option)}}
|
||||||
|
</mat-option>
|
||||||
|
</mat-autocomplete>
|
||||||
|
</mat-form-field>
|
||||||
|
<!-- End User area -->
|
||||||
|
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<!-- Sonarr -->
|
||||||
|
<div *ngIf="data.type === RequestType.tvShow">
|
||||||
|
<div>
|
||||||
|
<h3>Sonarr Overrides</h3>
|
||||||
|
<mat-form-field appearance="outline" floatLabel=auto>
|
||||||
|
<mat-label>{{'MediaDetails.QualityProfilesSelect' | translate }}</mat-label>
|
||||||
|
<mat-select formControlName="sonarrPathId">
|
||||||
|
<mat-option *ngFor="let profile of sonarrProfiles" value="{{profile.id}}">{{profile.name}}</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
<div >
|
||||||
|
<mat-form-field appearance="outline" floatLabel=auto>
|
||||||
|
<mat-label>{{'MediaDetails.RootFolderSelect' | translate }}</mat-label>
|
||||||
|
<mat-select formControlName="sonarrFolderId">
|
||||||
|
<mat-option *ngFor="let profile of sonarrRootFolders" value="{{profile.id}}">{{profile.path}}</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- End Sonarr-->
|
||||||
|
|
||||||
|
<!-- Radarr -->
|
||||||
|
<div *ngIf="data.type === RequestType.movie">
|
||||||
|
<div>
|
||||||
|
<h3>Radarr Overrides</h3>
|
||||||
|
<mat-form-field appearance="outline" floatLabel=auto>
|
||||||
|
<mat-label>{{'MediaDetails.QualityProfilesSelect' | translate }}</mat-label>
|
||||||
|
<mat-select formControlName="radarrPathId">
|
||||||
|
<mat-option *ngFor="let profile of radarrProfiles" value="{{profile.id}}">{{profile.name}}</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
<div mat-dialog-content>
|
||||||
|
<mat-form-field appearance="outline" floatLabel=auto>
|
||||||
|
<mat-label>{{'MediaDetails.RootFolderSelect' | translate }}</mat-label>
|
||||||
|
<mat-select formControlName="radarrFolderId">
|
||||||
|
<mat-option *ngFor="let profile of radarrRootFolders" value="{{profile.id}}">{{profile.path}}</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- End Radarr-->
|
||||||
|
|
||||||
|
|
||||||
|
<div mat-dialog-actions>
|
||||||
|
<button mat-raised-button [mat-dialog-close]="" color="warn">{{ 'Common.Cancel' | translate }}</button>
|
||||||
|
<button mat-raised-button (click)="submitRequest()" color="accent">{{ 'Common.Request' | translate }}</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
@import "~styles/variables.scss";
|
||||||
|
|
||||||
|
.alert-info {
|
||||||
|
background: $accent;
|
||||||
|
border-color: $ombi-background-primary;
|
||||||
|
color:white;
|
||||||
|
}
|
@ -0,0 +1,124 @@
|
|||||||
|
import { Component, Inject, OnInit } from "@angular/core";
|
||||||
|
import { FormBuilder, FormGroup } from "@angular/forms";
|
||||||
|
import { MatDialogRef, MAT_DIALOG_DATA } from "@angular/material/dialog";
|
||||||
|
import { Observable } from "rxjs";
|
||||||
|
import { startWith, map } from "rxjs/operators";
|
||||||
|
import { IRadarrProfile, IRadarrRootFolder, ISonarrProfile, ISonarrRootFolder, IUserDropdown, RequestType } from "../../interfaces";
|
||||||
|
import { IdentityService, MessageService, RadarrService, RequestService, SonarrService } from "../../services";
|
||||||
|
import { RequestServiceV2 } from "../../services/requestV2.service";
|
||||||
|
|
||||||
|
export interface IAdminRequestDialogData {
|
||||||
|
type: RequestType,
|
||||||
|
id: number
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: "admin-request-dialog",
|
||||||
|
templateUrl: "admin-request-dialog.component.html",
|
||||||
|
styleUrls: [ "admin-request-dialog.component.scss" ]
|
||||||
|
})
|
||||||
|
export class AdminRequestDialogComponent implements OnInit {
|
||||||
|
constructor(
|
||||||
|
public dialogRef: MatDialogRef<AdminRequestDialogComponent>,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: IAdminRequestDialogData,
|
||||||
|
private requestServiceV2: RequestServiceV2,
|
||||||
|
private notificationService: MessageService,
|
||||||
|
private identityService: IdentityService,
|
||||||
|
private sonarrService: SonarrService,
|
||||||
|
private radarrService: RadarrService,
|
||||||
|
private requestService: RequestService,
|
||||||
|
private fb: FormBuilder
|
||||||
|
) {}
|
||||||
|
|
||||||
|
public form: FormGroup;
|
||||||
|
public RequestType = RequestType;
|
||||||
|
|
||||||
|
public options: IUserDropdown[];
|
||||||
|
public filteredOptions: Observable<IUserDropdown[]>;
|
||||||
|
public userId: string;
|
||||||
|
|
||||||
|
public radarrEnabled: boolean;
|
||||||
|
|
||||||
|
|
||||||
|
public sonarrProfiles: ISonarrProfile[];
|
||||||
|
public sonarrRootFolders: ISonarrRootFolder[];
|
||||||
|
public radarrProfiles: IRadarrProfile[];
|
||||||
|
public radarrRootFolders: IRadarrRootFolder[];
|
||||||
|
|
||||||
|
public async ngOnInit() {
|
||||||
|
|
||||||
|
this.form = this.fb.group({
|
||||||
|
username: [null],
|
||||||
|
sonarrPathId: [null],
|
||||||
|
sonarrFolderId: [null],
|
||||||
|
radarrPathId: [null],
|
||||||
|
radarrFolderId: [null]
|
||||||
|
})
|
||||||
|
|
||||||
|
this.options = await this.identityService.getUsersDropdown().toPromise();
|
||||||
|
|
||||||
|
this.filteredOptions = this.form.controls['username'].valueChanges.pipe(
|
||||||
|
startWith(""),
|
||||||
|
map((value) => this._filter(value))
|
||||||
|
);
|
||||||
|
|
||||||
|
if (this.data.type === RequestType.tvShow) {
|
||||||
|
this.sonarrService.getQualityProfilesWithoutSettings().subscribe(c => {
|
||||||
|
this.sonarrProfiles = c;
|
||||||
|
});
|
||||||
|
this.sonarrService.getRootFoldersWithoutSettings().subscribe(c => {
|
||||||
|
this.sonarrRootFolders = c;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (this.data.type === RequestType.movie) {
|
||||||
|
this.radarrEnabled = await this.radarrService.isRadarrEnabled();
|
||||||
|
if (this.radarrEnabled) {
|
||||||
|
this.radarrService.getQualityProfilesFromSettings().subscribe(c => {
|
||||||
|
this.radarrProfiles = c;
|
||||||
|
});
|
||||||
|
this.radarrService.getRootFoldersFromSettings().subscribe(c => {
|
||||||
|
this.radarrRootFolders = c;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public displayFn(user: IUserDropdown): string {
|
||||||
|
const username = user?.username ? user.username : "";
|
||||||
|
const email = user?.email ? `(${user.email})` : "";
|
||||||
|
return `${username} ${email}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _filter(value: string | IUserDropdown): IUserDropdown[] {
|
||||||
|
const filterValue =
|
||||||
|
typeof value === "string"
|
||||||
|
? value.toLowerCase()
|
||||||
|
: value.username.toLowerCase();
|
||||||
|
|
||||||
|
return this.options.filter((option) =>
|
||||||
|
option.username.toLowerCase().includes(filterValue)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async submitRequest() {
|
||||||
|
const model = this.form.value;
|
||||||
|
if (this.data.type === RequestType.movie) {
|
||||||
|
this.requestService.requestMovie({
|
||||||
|
qualityPathOverride: model.radarrPathId,
|
||||||
|
requestOnBehalf: model.username?.id,
|
||||||
|
rootFolderOverride: model.radarrFolderId,
|
||||||
|
theMovieDbId: this.data.id,
|
||||||
|
languageCode: null
|
||||||
|
}).subscribe((x) => {
|
||||||
|
if (x.result) {
|
||||||
|
this.notificationService.send(x.message, "Ok");
|
||||||
|
} else {
|
||||||
|
this.notificationService.send(x.errorMessage, "Ok");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dialogRef.close();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue