pull/3895/head
TidusJar 6 years ago
commit 9d02f5e551

@ -30,7 +30,7 @@ namespace Ombi.Core.Models.Search.V2
public string Homepage { get; set; } public string Homepage { get; set; }
public int RootPathOverride { get; set; } public int RootPathOverride { get; set; }
public string Status { get; set; } public string Status { get; set; }
public List<VideoResults> Videos { get; set; } public Videos Videos { get; set; }
public CreditsViewModel Credits { get; set; } public CreditsViewModel Credits { get; set; }
public int QualityOverride { get; set; } public int QualityOverride { get; set; }
public override RequestType Type => RequestType.Movie; public override RequestType Type => RequestType.Movie;
@ -54,7 +54,12 @@ namespace Ombi.Core.Models.Search.V2
public string origin_country { get; set; } public string origin_country { get; set; }
} }
public class VideoResults public class Videos
{
public VideoResultsDetails[] results { get; set; }
}
public class VideoResultsDetails
{ {
public string id { get; set; } public string id { get; set; }
public string iso_639_1 { get; set; } public string iso_639_1 { get; set; }

@ -99,7 +99,9 @@ namespace Ombi.DependencyInjection
public static void RegisterEnginesV2(this IServiceCollection services) public static void RegisterEnginesV2(this IServiceCollection services)
{ {
services.AddTransient<IMultiSearchEngine, MultiSearchEngine>(); services.AddTransient<IMultiSearchEngine, MultiSearchEngine>();
services.AddTransient<IMovieEngineV2, MovieSearchEngineV2>();
} }
public static void RegisterHttp(this IServiceCollection services) public static void RegisterHttp(this IServiceCollection services)
{ {
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

@ -1,4 +1,5 @@
using AutoMapper; using System.Collections.Generic;
using AutoMapper;
using Ombi.Api.TheMovieDb.Models; using Ombi.Api.TheMovieDb.Models;
using Ombi.Core.Models.Search; using Ombi.Core.Models.Search;
using Ombi.Core.Models.Search.V2; using Ombi.Core.Models.Search.V2;
@ -76,9 +77,14 @@ namespace Ombi.Mapping.Profiles
CreateMap<FullMovieInfo, SearchMovieViewModel>().ReverseMap(); CreateMap<FullMovieInfo, SearchMovieViewModel>().ReverseMap();
CreateMap<ProductionCompanies, Production_Companies>().ReverseMap(); CreateMap<ProductionCompanies, Production_Companies>().ReverseMap();
CreateMap<VideoResults, Videos>().ReverseMap();
CreateMap<CreditsViewModel, Credits>().ReverseMap(); CreateMap<CreditsViewModel, Credits>().ReverseMap();
CreateMap<MovieFullInfoViewModel, FullMovieInfo>(); CreateMap<MovieFullInfoViewModel, FullMovieInfo>().ReverseMap();
CreateMap<Ombi.Api.TheMovieDb.Models.Genre, Ombi.Core.Models.Search.V2.GenreViewModel>().ReverseMap();
CreateMap<Ombi.Api.TheMovieDb.Models.Production_Companies, Ombi.Core.Models.Search.V2.ProductionCompaniesViewModel>().ReverseMap();
CreateMap<Ombi.Api.TheMovieDb.Models.Videos, Ombi.Core.Models.Search.V2.Videos>().ReverseMap();
CreateMap<Ombi.Api.TheMovieDb.Models.Result, Ombi.Core.Models.Search.V2.VideoResultsDetails>().ReverseMap();
CreateMap<Ombi.Api.TheMovieDb.Models.FullMovieCast, Ombi.Core.Models.Search.V2.FullMovieCastViewModel>().ReverseMap();
CreateMap<Ombi.Api.TheMovieDb.Models.FullMovieCrew, Ombi.Core.Models.Search.V2.FullMovieCrewViewModel>().ReverseMap();
} }
} }
} }

@ -27,7 +27,7 @@
requestId: number; requestId: number;
available: boolean; available: boolean;
status: string; status: string;
videos: IVideoResult[]; videos: IVideos;
credits: ICreditsViewModel; credits: ICreditsViewModel;
releaseDates: IReleaseDatesDto; releaseDates: IReleaseDatesDto;
similar: IOtherMovies; similar: IOtherMovies;
@ -45,6 +45,10 @@
background: any; background: any;
} }
export interface IVideos {
results: IVideoResult[];
}
export interface IGenresViewModel { export interface IGenresViewModel {
id: number; id: number;
name: string; name: string;

@ -6,6 +6,7 @@ import { SearchService } from "../services";
import { SharedModule } from "../shared/shared.module"; import { SharedModule } from "../shared/shared.module";
import { MovieDetailsComponent } from "./movie-details.component"; import { MovieDetailsComponent } from "./movie-details.component";
import { PipeModule } from "../pipes/pipe.module"; import { PipeModule } from "../pipes/pipe.module";
import { MovieDetailsTrailerComponent } from "./movie-details-trailer.component";
const routes: Routes = [ const routes: Routes = [
{ path: "movie/:movieDbId", component: MovieDetailsComponent }, { path: "movie/:movieDbId", component: MovieDetailsComponent },
@ -18,10 +19,14 @@ const routes: Routes = [
], ],
declarations: [ declarations: [
MovieDetailsComponent, MovieDetailsComponent,
MovieDetailsTrailerComponent
], ],
exports: [ exports: [
RouterModule, RouterModule,
], ],
entryComponents: [
MovieDetailsTrailerComponent
],
providers: [ providers: [
SearchService SearchService
], ],

@ -0,0 +1,2 @@
<iframe width="100%" height="315px" [src]="'https://www.youtube.com/embed/' + data.videos.results[0].key | safe" frameborder="0"
allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

@ -0,0 +1,15 @@
import { Component, Inject } from "@angular/core";
import { MatDialogRef, MAT_DIALOG_DATA } from "@angular/material";
import { ISearchMovieResultV2 } from "../interfaces/ISearchMovieResultV2";
@Component({
selector: "movie-trailer",
templateUrl: "./movie-details-trailer.component.html",
})
export class MovieDetailsTrailerComponent {
constructor(
public dialogRef: MatDialogRef<MovieDetailsTrailerComponent>,
@Inject(MAT_DIALOG_DATA) public data: ISearchMovieResultV2) {}
}

@ -9,9 +9,11 @@
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<div class="col-lg-10 offset-lg-2 col-md-8 offset-md-4 col-sm-7 offset-sm-5 col-6 offset-6"> <div class="col-lg-10 offset-lg-2 col-md-8 offset-md-4 col-sm-7 offset-sm-5 col-6 offset-6">
<h1>{{movie.title}} <span *ngIf="movie.releaseDate" class="year align-middle">({{movie.releaseDate <h1>{{movie.title}} <span *ngIf="movie.releaseDate" class="grey-text align-middle">({{movie.releaseDate
| date:'yyyy'}})</span> | date:'yyyy'}})</span>
</h1> </h1>
<h5 class="tagline grey-text">{{movie.tagline}}</h5>
</div> </div>
</div> </div>
</div> </div>
@ -22,7 +24,7 @@
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<div class="col-md-2 col-sm-3 hidden-xs"> <div class="col-md-2 col-sm-3 hidden-xs">
<div class="sidebar affixable affix-top" style="width: 173px;"> <div class="sidebar sidebar-poster affixable affix-top" style="width: 173px;">
<div class="poster"> <div class="poster">
<img class="real" src="https://image.tmdb.org/t/p/w300/{{movie.posterPath}}" alt="Poster" <img class="real" src="https://image.tmdb.org/t/p/w300/{{movie.posterPath}}" alt="Poster"
style="display: block;"> style="display: block;">
@ -34,7 +36,6 @@
<!--Next to poster--> <!--Next to poster-->
</div> </div>
<div class="row"> <div class="row">
@ -57,6 +58,19 @@
<small *ngIf="movie.voteCount"><strong>Votes:</strong> {{movie.voteCount | <small *ngIf="movie.voteCount"><strong>Votes:</strong> {{movie.voteCount |
thousandShort: 1}}</small> thousandShort: 1}}</small>
</div> </div>
<div>
<small><strong>Status:</strong> {{movie.status}}</small>
</div>
<div>
<small><strong>Runtime:</strong> {{movie.runtime}} Minutes</small>
</div>
<div>
<small *ngIf="movie.revenue"><strong>Revenue:</strong> {{movie.revenue | currency:
'USD'}}</small>
</div>
<div>
<small *ngIf="movie.budget"><strong>Budget:</strong> {{movie.budget | currency: 'USD'}}</small>
</div>
</mat-card-content> </mat-card-content>
</mat-card> </mat-card>
@ -79,17 +93,101 @@
</div> </div>
<div class="row card-spacer"> <div class="row card-spacer">
<div class="col-md-2"> <div class="col-md-2">
<div> <div><div>
<a *ngIf="movie.homepage" class="btn-spacing" href="{{movie.homepage}}" target="_blank" mat-raised-button color="accent">Home Page</a> <a *ngIf="movie.homepage" class="btn-spacing" href="{{movie.homepage}}" target="_blank"
<a *ngIf="movie.theMovieDbId" href="https://www.themoviedb.org/movie/{{movie.theMovieDbId}}" target="_blank" mat-raised-button class="btn-blue btn-spacing">The Movie DB</a> mat-raised-button color="accent">Home Page</a></div>
<a *ngIf="movie.imdbId" href="https://www.imdb.com/title/tt1727824/{{movie.imdbId}}" target="_blank" mat-raised-button class="imdb-color btn-spacing">IMDb</a> <div>
<a *ngIf="movie.id" href="https://www.themoviedb.org/movie/{{movie.id}}"
target="_blank" mat-raised-button class="btn-blue btn-spacing">The Movie DB</a></div>
<div>
<a *ngIf="movie.imdbId" href="https://www.imdb.com/title/tt1727824/{{movie.imdbId}}" target="_blank"
mat-raised-button class="imdb-color btn-spacing">IMDb</a></div>
<div>
<a *ngIf="movie.videos.results.length > 0" mat-raised-button class="btn-blue btn-spacing"
(click)="openDialog()">Trailer</a></div>
</div> </div>
</div> </div>
</div> </div>
<div class="row card-spacer">
<div class="col-12">
<mat-accordion>
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
Recommendations
</mat-panel-title>
</mat-expansion-panel-header>
<div class="row card-spacer" *ngIf="movie.recommendations.results.length > 0">
<div class="col-md-2" *ngFor="let r of movie.recommendations.results">
<div class="sidebar affixable affix-top preview-poster">
<div class="poster">
<a [routerLink]="'/details/movie/'+r.id">
<img class="real grow" matTooltip="{{r.title}}" src="https://image.tmdb.org/t/p/w300/{{r.poster_path}}"
alt="Poster" style="display: block;">
</a>
</div>
</div>
</div>
</div>
</mat-expansion-panel>
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
Similar
</mat-panel-title>
</mat-expansion-panel-header>
<div class="row card-spacer" *ngIf="movie.similar.results.length > 0">
<div class="col-md-2" *ngFor="let r of movie.similar.results">
<div class="sidebar affixable affix-top preview-poster">
<div class="poster ">
<a [routerLink]="'/details/movie/'+r.id">
<img class="real grow" matTooltip="{{r.title}}" src="https://image.tmdb.org/t/p/w300/{{r.poster_path}}"
alt="Poster" style="display: block;">
</a>
</div>
</div>
</div>
</div>
</mat-expansion-panel>
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
Videos
</mat-panel-title>
</mat-expansion-panel-header>
<div class="row card-spacer" *ngIf="movie.videos.results.length > 0">
<div class="col-md-6" *ngFor="let video of movie.videos.results">
<iframe width="100%" height="315px" [src]="'https://www.youtube.com/embed/' + video.key | safe"
frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen></iframe>
</div>
</div>
</mat-expansion-panel>
</mat-accordion>
</div>
</div>
</div> </div>
</section> </section>
<!-- THIS IS THE YOUTUBE VIDEOS
<div *ngFor="let video of movie.videos.results">
<iframe width="560" height="315" [src]="'https://www.youtube.com/embed/' + video.key | safe" frameborder="0"
allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div> -->

@ -87,9 +87,9 @@
position: relative; position: relative;
} }
#summary-wrapper .summary .container h1 .year,
.summary-wrapper .summary .container h1 .year { .grey-text {
color: #999; color:#999;
} }
#summary-wrapper .summary .container h1, #summary-wrapper .summary .container h1,
@ -111,7 +111,7 @@ section {
position: relative !important; position: relative !important;
} }
#info-wrapper .sidebar { #info-wrapper .sidebar-poster {
margin-top: -180px; margin-top: -180px;
} }
@ -147,4 +147,20 @@ section {
.btn-spacing { .btn-spacing {
margin-top:10px; margin-top:10px;
}
.tagline {
margin-top: 10px;
margin-left: 10px;
}
.preview-poster {
width: 173px;
}
.grow {
transition: all .2s ease-in-out;
}
.grow:hover {
transform: scale(1.1);
} }

@ -3,6 +3,8 @@ import { ImageService, SearchV2Service } from "../services";
import { ActivatedRoute } from "@angular/router"; import { ActivatedRoute } from "@angular/router";
import { DomSanitizer } from "@angular/platform-browser"; import { DomSanitizer } from "@angular/platform-browser";
import { ISearchMovieResultV2 } from "../interfaces/ISearchMovieResultV2"; import { ISearchMovieResultV2 } from "../interfaces/ISearchMovieResultV2";
import { MatDialog } from "@angular/material";
import { MovieDetailsTrailerComponent } from "./movie-details-trailer.component";
@Component({ @Component({
templateUrl: "./movie-details.component.html", templateUrl: "./movie-details.component.html",
@ -13,7 +15,8 @@ export class MovieDetailsComponent {
private theMovidDbId: number; private theMovidDbId: number;
constructor(private searchService: SearchV2Service, private route: ActivatedRoute, constructor(private searchService: SearchV2Service, private route: ActivatedRoute,
private sanitizer: DomSanitizer, private imageService: ImageService) { private sanitizer: DomSanitizer, private imageService: ImageService,
public dialog: MatDialog) {
this.route.params.subscribe((params: any) => { this.route.params.subscribe((params: any) => {
this.theMovidDbId = params.movieDbId; this.theMovidDbId = params.movieDbId;
this.load(); this.load();
@ -23,7 +26,6 @@ export class MovieDetailsComponent {
public load() { public load() {
this.searchService.getFullMovieDetails(this.theMovidDbId).subscribe(x => { this.searchService.getFullMovieDetails(this.theMovidDbId).subscribe(x => {
this.movie = x; this.movie = x;
this.imageService.getMovieBanner(this.theMovidDbId.toString()).subscribe(x => { this.imageService.getMovieBanner(this.theMovidDbId.toString()).subscribe(x => {
this.movie.background = this.sanitizer.bypassSecurityTrustStyle this.movie.background = this.sanitizer.bypassSecurityTrustStyle
("url(" + x + ")"); ("url(" + x + ")");
@ -31,4 +33,11 @@ export class MovieDetailsComponent {
}); });
} }
public openDialog() {
this.dialog.open(MovieDetailsTrailerComponent, {
width: '560px',
data: this.movie
});
}
} }

@ -0,0 +1,12 @@
import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer } from "@angular/platform-browser";
@Pipe({ name: 'safe' })
export class SafePipe implements PipeTransform {
constructor(private sanitizer: DomSanitizer) { }
transform(url) {
return this.sanitizer.bypassSecurityTrustResourceUrl(url);
}
}

@ -1,11 +1,12 @@
import { ModuleWithProviders, NgModule } from "@angular/core"; import { ModuleWithProviders, NgModule } from "@angular/core";
import { HumanizePipe } from "./HumanizePipe"; import { HumanizePipe } from "./HumanizePipe";
import { ThousandShortPipe } from "./ThousandShortPipe"; import { ThousandShortPipe } from "./ThousandShortPipe";
import { SafePipe } from "./SafePipe";
@NgModule({ @NgModule({
imports: [], imports: [],
declarations: [HumanizePipe, ThousandShortPipe], declarations: [HumanizePipe, ThousandShortPipe, SafePipe],
exports: [HumanizePipe, ThousandShortPipe], exports: [HumanizePipe, ThousandShortPipe, SafePipe],
}) })
export class PipeModule { export class PipeModule {

@ -6,7 +6,7 @@ import { Observable } from "rxjs";
import { IMultiSearchResult, ISearchMovieResult, ISearchTvResult } from "../interfaces"; import { IMultiSearchResult, ISearchMovieResult, ISearchTvResult } from "../interfaces";
import { ServiceHelpers } from "./service.helpers"; import { ServiceHelpers } from "./service.helpers";
+
import { ISearchMovieResultV2 } from "../interfaces/ISearchMovieResultV2"; import { ISearchMovieResultV2 } from "../interfaces/ISearchMovieResultV2";
@Injectable() @Injectable()

Loading…
Cancel
Save