Done the movie searching

pull/1350/head^2
tidusjar 8 years ago
parent 1c301f2c54
commit e80f0bc601

@ -0,0 +1,15 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Ombi.Core.Models.Search;
namespace Ombi.Core
{
public interface IMovieEngine
{
Task<IEnumerable<SearchMovieViewModel>> NowPlayingMovies();
Task<IEnumerable<SearchMovieViewModel>> PopularMovies();
Task<IEnumerable<SearchMovieViewModel>> ProcessMovieSearch(string search);
Task<IEnumerable<SearchMovieViewModel>> TopRatedMovies();
Task<IEnumerable<SearchMovieViewModel>> UpcomingMovies();
}
}

@ -0,0 +1,54 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2017 Jamie Rees
// File: SearchMovieViewModel.cs
// Created By: Jamie Rees
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ************************************************************************/
#endregion
using System;
using System.Collections.Generic;
namespace Ombi.Core.Models.Search
{
public class SearchMovieViewModel : SearchViewModel
{
public bool Adult { get; set; }
public string BackdropPath { get; set; }
public List<int> GenreIds { get; set; }
public int Id { get; set; }
public string OriginalLanguage { get; set; }
public string OriginalTitle { get; set; }
public string Overview { get; set; }
public double Popularity { get; set; }
public string PosterPath { get; set; }
public DateTime? ReleaseDate { get; set; }
public string Title { get; set; }
public bool Video { get; set; }
public double VoteAverage { get; set; }
public int VoteCount { get; set; }
public bool AlreadyInCp { get; set; }
public string Trailer { get; set; }
public string Homepage { get; set; }
public string ImdbId { get; set; }
}
}

@ -0,0 +1,36 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2017 Jamie Rees
// File: SearchViewModel.cs
// Created By: Jamie Rees
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ************************************************************************/
#endregion
namespace Ombi.Core.Models.Search
{
public class SearchViewModel
{
public bool Approved { get; set; }
public bool Requested { get; set; }
public bool Available { get; set; }
public string PlexUrl { get; set; }
}
}

@ -0,0 +1,163 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Ombi.Core.Models.Search;
using Ombi.TheMovieDbApi.Models;
namespace Ombi.Core
{
public class MovieEngine : IMovieEngine
{
public async Task<IEnumerable<SearchMovieViewModel>> ProcessMovieSearch(string search)
{
var api = new TheMovieDbApi.TheMovieDbApi();
var result = await api.SearchMovie(search);
if (result != null)
{
return await TransformMovieResultsToResponse(result.results);
}
return null;
}
public async Task<IEnumerable<SearchMovieViewModel>> PopularMovies()
{
var api = new TheMovieDbApi.TheMovieDbApi();
var result = await api.PopularMovies();
if (result != null)
{
return await TransformMovieResultsToResponse(result.results);
}
return null;
}
public async Task<IEnumerable<SearchMovieViewModel>> TopRatedMovies()
{
var api = new TheMovieDbApi.TheMovieDbApi();
var result = await api.TopRated();
if (result != null)
{
return await TransformMovieResultsToResponse(result.results);
}
return null;
}
public async Task<IEnumerable<SearchMovieViewModel>> UpcomingMovies()
{
var api = new TheMovieDbApi.TheMovieDbApi();
var result = await api.Upcoming();
if (result != null)
{
return await TransformMovieResultsToResponse(result.results);
}
return null;
}
public async Task<IEnumerable<SearchMovieViewModel>> NowPlayingMovies()
{
var api = new TheMovieDbApi.TheMovieDbApi();
var result = await api.NowPlaying();
if (result != null)
{
return await TransformMovieResultsToResponse(result.results);
}
return null;
}
private async Task<List<SearchMovieViewModel>> TransformMovieResultsToResponse(IEnumerable<SearchResult> movies)
{
await Task.Yield();
var viewMovies = new List<SearchMovieViewModel>();
var counter = 0;
//Dictionary<int, RequestedModel> dbMovies = await RequestedMovies();
foreach (var movie in movies)
{
var viewMovie = new SearchMovieViewModel
{
Adult = movie.adult,
BackdropPath = movie.backdrop_path,
Id = movie.id,
OriginalLanguage = movie.original_language,
OriginalTitle = movie.original_title,
Overview = movie.overview,
Popularity = movie.popularity,
PosterPath = movie.poster_path,
ReleaseDate = string.IsNullOrEmpty(movie.release_date) ? DateTime.MinValue : DateTime.Parse(movie.release_date),
Title = movie.title,
Video = movie.video,
VoteAverage = movie.vote_average,
VoteCount = movie.vote_count
};
viewMovies.Add(viewMovie);
//if (counter <= 5) // Let's only do it for the first 5 items
//{
// var movieInfo = MovieApi.GetMovieInformationWithVideos(movie.Id);
// // TODO needs to be careful about this, it's adding extra time to search...
// // https://www.themoviedb.org/talk/5807f4cdc3a36812160041f2
// viewMovie.ImdbId = movieInfo?.imdb_id;
// viewMovie.Homepage = movieInfo?.homepage;
// var videoId = movieInfo?.video ?? false
// ? movieInfo?.videos?.results?.FirstOrDefault()?.key
// : string.Empty;
// viewMovie.Trailer = string.IsNullOrEmpty(videoId)
// ? string.Empty
// : $"https://www.youtube.com/watch?v={videoId}";
// counter++;
//}
// var canSee = CanUserSeeThisRequest(viewMovie.Id, Security.HasPermissions(User, Permissions.UsersCanViewOnlyOwnRequests), dbMovies);
// var plexSettings = await PlexService.GetSettingsAsync();
// var embySettings = await EmbySettings.GetSettingsAsync();
// if (plexSettings.Enable)
// {
// var content = PlexContentRepository.GetAll();
// var plexMovies = PlexChecker.GetPlexMovies(content);
// var plexMovie = PlexChecker.GetMovie(plexMovies.ToArray(), movie.Title,
// movie.ReleaseDate?.Year.ToString(),
// viewMovie.ImdbId);
// if (plexMovie != null)
// {
// viewMovie.Available = true;
// viewMovie.PlexUrl = plexMovie.Url;
// }
// }
// if (embySettings.Enable)
// {
// var embyContent = EmbyContentRepository.GetAll();
// var embyMovies = EmbyChecker.GetEmbyMovies(embyContent);
// var embyMovie = EmbyChecker.GetMovie(embyMovies.ToArray(), movie.Title,
// movie.ReleaseDate?.Year.ToString(), viewMovie.ImdbId);
// if (embyMovie != null)
// {
// viewMovie.Available = true;
// }
// }
// if (dbMovies.ContainsKey(movie.Id) && canSee) // compare to the requests db
// {
// var dbm = dbMovies[movie.Id];
// viewMovie.Requested = true;
// viewMovie.Approved = dbm.Approved;
// viewMovie.Available = dbm.Available;
// }
// else if (canSee)
// {
// bool exists = IsMovieInCache(movie, viewMovie.ImdbId);
// viewMovie.Approved = exists;
// viewMovie.Requested = exists;
// }
// viewMovies.Add(viewMovie);
//}
}
return viewMovies;
}
}
}

@ -1,8 +0,0 @@
using System;
namespace Ombi.Core
{
public class MovieProcessor
{
}
}

@ -1,7 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.4</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Ombi.TheMovieDbApi\Ombi.TheMovieDbApi.csproj" />
</ItemGroup>
</Project>

@ -13,7 +13,7 @@ namespace Ombi.TheMovieDbApi
Api = new Api.Api();
}
private const string ApiToken = "b8eabaf5608b88d0298aa189dd90bf00";
private static readonly Uri BaseUri = new Uri("https://api.themoviedb.org/3/");
private static readonly Uri BaseUri = new Uri("http://api.themoviedb.org/3/");
public Api.Api Api { get; }
public async Task<MovieResponse> GetMovieInformation(int movieId)
@ -31,6 +31,34 @@ namespace Ombi.TheMovieDbApi
return await Api.Get<TheMovieDbContainer<SearchResult>>(url);
}
public async Task<TheMovieDbContainer<SearchResult>> PopularMovies()
{
var url = BaseUri.ChangePath("movie/popular");
url = AddHeaders(url);
return await Api.Get<TheMovieDbContainer<SearchResult>>(url);
}
public async Task<TheMovieDbContainer<SearchResult>> TopRated()
{
var url = BaseUri.ChangePath("movie/top_rated");
url = AddHeaders(url);
return await Api.Get<TheMovieDbContainer<SearchResult>>(url);
}
public async Task<TheMovieDbContainer<SearchResult>> Upcoming()
{
var url = BaseUri.ChangePath("movie/upcoming");
url = AddHeaders(url);
return await Api.Get<TheMovieDbContainer<SearchResult>>(url);
}
public async Task<TheMovieDbContainer<SearchResult>> NowPlaying()
{
var url = BaseUri.ChangePath("movie/now_playing");
url = AddHeaders(url);
return await Api.Get<TheMovieDbContainer<SearchResult>>(url);
}
private Uri AddHeaders(Uri url)
{
return url.AddQueryParameter("api_key", ApiToken);

@ -3,20 +3,48 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Ombi.TheMovieDbApi.Models;
using Ombi.Core;
using Ombi.Core.Models.Search;
namespace Ombi.Controllers
{
public class SearchController : BaseApiController
{
public SearchController(IMovieEngine movie)
{
MovieEngine = movie;
}
private IMovieEngine MovieEngine { get; }
[HttpGet("movie/{searchTerm}")]
public async Task<List<SearchResult>> SearchMovie(string searchTerm)
public async Task<IEnumerable<SearchMovieViewModel>> SearchMovie(string searchTerm)
{
var api = new TheMovieDbApi.TheMovieDbApi();
var result = await api.SearchMovie(searchTerm);
return result.results;
return await MovieEngine.ProcessMovieSearch(searchTerm);
}
[HttpGet("movie/popular")]
public async Task<IEnumerable<SearchMovieViewModel>> Popular()
{
return await MovieEngine.PopularMovies();
}
[HttpGet("movie/nowplaying")]
public async Task<IEnumerable<SearchMovieViewModel>> NowPlayingMovies()
{
return await MovieEngine.NowPlayingMovies();
}
[HttpGet("movie/toprated")]
public async Task<IEnumerable<SearchMovieViewModel>> TopRatedMovies()
{
return await MovieEngine.TopRatedMovies();
}
[HttpGet("movie/upcoming")]
public async Task<IEnumerable<SearchMovieViewModel>> UpcomingMovies()
{
return await MovieEngine.UpcomingMovies();
}
}
}

@ -17,10 +17,12 @@
</ItemGroup>
<ItemGroup>
<Folder Include="ViewModels\" />
<Folder Include="wwwroot\**" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Ombi.Core\Ombi.Core.csproj" />
<ProjectReference Include="..\Ombi.TheMovieDbApi\Ombi.TheMovieDbApi.csproj" />
</ItemGroup>
</Project>

@ -11,6 +11,7 @@ using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Logging;
using Ombi.Core;
namespace Ombi
{
@ -33,6 +34,7 @@ namespace Ombi
{
// Add framework services.
services.AddMvc();
services.AddTransient<IMovieEngine, MovieEngine>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.

@ -13,7 +13,7 @@
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li ><a [routerLink]="['/search']"><i class="fa fa-search"></i> search</a></li>
<li ><a [routerLink]="['/search']"><i class="fa fa-search"></i> Search</a></li>
</ul>
</div>
</div>

@ -1,16 +0,0 @@
export interface IMovieResult {
poster_path: string,
adult: boolean,
overview: string,
release_date: string,
genre_ids: number[],
id: number,
original_title: string,
original_language: string,
title: string,
backdrop_path: string,
popularity: number,
vote_count: number,
video: boolean,
vote_average:number
}

@ -0,0 +1,20 @@
export interface ISearchMovieResult {
backdropPath: string,
adult: boolean,
overview: string,
releaseDate: Date,
genreIds: number[],
id: number,
originalTitle: string,
originalLanguage: string,
title: string,
posterPath: string,
popularity: number,
voteCount: number,
video: boolean,
voteAverage: number,
alreadyInCp: boolean,
trailer: string,
homepage: string,
imdbId:string
}

@ -1,48 +1,50 @@
 <h1 id="searchTitle">Search</h1>
<h1 id="searchTitle">Search</h1>
<h4>Search Paragraph</h4>
<br />
<!-- Nav tabs -->
<ul id="nav-tabs" class="nav nav-tabs" role="tablist">
<li role="presentation" class="active">
<a id="movieTabButton" href="#MoviesTab" aria-controls="home" role="tab" data-toggle="tab"><i class="fa fa-film"></i> Movies</a>
</li>
<li role="presentation">
<a id="actorTabButton" href="#ActorsTab" aria-controls="profile" role="tab" data-toggle="tab"><i class="fa fa-users"></i> Actors</a>
</li>
<li role="presentation">
<a id="tvTabButton" href="#TvShowTab" aria-controls="profile" role="tab" data-toggle="tab"><i class="fa fa-television"></i> TV Shows</a>
</li>
<!--
<li role="presentation">
<a href="#MusicTab" aria-controls="profile" role="tab" data-toggle="tab"><i class="fa fa-music"></i> Albums</a>
</li>-->
<!--
<li role="presentation">
<a href="#MusicTab" aria-controls="profile" role="tab" data-toggle="tab"><i class="fa fa-music"></i> Albums</a>
</li>-->
</ul>
<!-- Tab panes -->
<!-- Tab panes -->
<div class="tab-content">
<!-- Movie tab -->
<div role="tabpanel" class="tab-pane active" id="MoviesTab">
<div class="input-group">
<input id="movieSearchContent" type="text" class="form-control form-control-custom form-control-search form-control-withbuttons" (change)="search($event)">
<input id="movieSearchContent" type="text" class="form-control form-control-custom form-control-search form-control-withbuttons" (keyup)="search($event)">
<div class="input-group-addon">
<div class="btn-group">
<a href="#" class="btn btn-sm btn-primary-outline dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
@UI.Search_Suggestions
Suggestions
<i class="fa fa-chevron-down"></i>
</a>
<ul class="dropdown-menu">
<li><a id="moviesComingSoon" href="#">@UI.Search_ComingSoon</a></li>
<li><a id="moviesInTheaters" href="#">@UI.Search_InTheaters</a></li>
<li><a (click)="popularMovies()">Popular Movies</a></li>
<li><a (click)="upcomingMovies()">Upcoming Movies</a></li>
<li><a (click)="topRatedMovies()">Top Rated Movies</a></li>
<li><a (click)="nowPlayingMovies()">Now Playing Movies</a></li>
</ul>
</div>
<i id="movieSearchButton" class="fa fa-search"></i>
@ -85,7 +87,7 @@
<i class="fa fa-chevron-down"></i>
</a>
<ul class="dropdown-menu">
<li><a id="popularShows" href="#">Popular Shows</a></li>
<li><a id="popularShows" >Popular Shows</a></li>
<li><a id="trendingShows" href="#">Trending Shows</a></li>
<li><a id="mostWatchedShows" href="#">Most Watched Shows</a></li>
<li><a id="anticipatedShows" href="#">Most Anticipated Shows</a></li>
@ -101,17 +103,146 @@
</div>
<!-- Music tab -->
<!-- <div role="tabpanel" class="tab-pane" id="MusicTab">
<div class="input-group">
<input id="musicSearchContent" type="text" class="form-control form-control-custom form-control-search">
<div class="input-group-addon">
<i id="musicSearchButton" class="fa fa-search"></i>
<!-- <div role="tabpanel" class="tab-pane" id="MusicTab">
<div class="input-group">
<input id="musicSearchContent" type="text" class="form-control form-control-custom form-control-search">
<div class="input-group-addon">
<i id="musicSearchButton" class="fa fa-search"></i>
</div>
</div>
<br />
<br />
<div id="musicList">
</div>
</div>
<br />
<br />
<div id="musicList">
-->
<div *ngFor="let result of movieResults">
<div class="row">
<div id="{{id}}imgDiv" class="col-sm-2">
<img *ngIf="result.posterPath" class="img-responsive" src="https://image.tmdb.org/t/p/w150/{{result.posterPath}}" alt="poster">
</div>
<div class="col-sm-8">
<div>
<a href="https://www.themoviedb.org/movie/{{result.id}}/" target="_blank">
<h4>{{result.title}} ({{result.releaseDate}})</h4>
</a>
<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}}</span>
<span *ngIf="result.available" class="label label-success">@UI.Search_Available</span>
<span *ngIf="result.approved" class="label label-info">@UI.Search_Processing_Request</span>
<div *ngIf="result.requested; then requested else notRequested"></div>
<template #requested>
<span class="label label-warning">Pending Approval</span>
</template>
<template #notRequested>
<span class="label label-danger">Not Yet Requested</span>
</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 />
</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.available">
<button style="text-align: right" class="btn btn-success-outline disabled" disabled><i class="fa fa-check"></i> Available</button>
<div *ngIf="result.url">
<br />
<br />
<a style="text-align: right" class="btn btn-sm btn-primary-outline" href="{{result.url}}" target="_blank"><i class="fa fa-eye"></i> View In Plex</a>
</div>
</div>
<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 id="{{id}}" class="btn {{#if available}}btn-success-outline{{else}}btn-primary-outline{{/if}} dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
<i class="fa fa-plus"></i> {{#if available}}@UI.Search_Available{{else}}@UI.Search_Request {{/if}}
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
<li><a id="{{id}}" season-select="0" class="dropdownTv " href="#">@UI.Search_AllSeasons</a></li>
{{#if_eq disableTvRequestsBySeason false}}
<li><a id="{{id}}" season-select="1" class="dropdownTv" href="#">@UI.Search_FirstSeason</a></li>
<li><a id="{{id}}" season-select="2" class="dropdownTv" href="#">@UI.Search_LatestSeason</a></li>
<li><a id="SeasonSelect" data-identifier="{{id}}" data-toggle="modal" data-target="#seasonsModal" href="#">@UI.Search_SelectSeason...</a></li>
{{/if_eq}}
{{#if_eq disableTvRequestsByEpisode false}}
<li><a id="EpisodeSelect" data-identifier="{{id}}" data-toggle="modal" data-target="#episodesModal" href="#">@UI.Search_SelectEpisode...</a></li>
{{/if_eq}}
</ul>
</div>
{{/if_eq}}
{{#if available}}
{{#if url}}
<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>
{{/if}}
{{/if}}
{{/if_eq}}
{{/if_eq}}-->
<br />
<div *ngIf="result.available">
<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> @UI.Search_ReportIssue
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
<li><a issue-select="0" class="dropdownIssue" href="#">@UI.Issues_WrongAudio</a></li>
<li><a issue-select="1" class="dropdownIssue" href="#">@UI.Issues_NoSubs</a></li>
<li><a issue-select="2" class="dropdownIssue" href="#">@UI.Issues_WrongContent</a></li>
<li><a issue-select="3" class="dropdownIssue" href="#">@UI.Issues_Playback</a></li>
<li><a issue-select="4" class="dropdownIssue" href="#" data-toggle="modal" data-target="#issuesModal">@UI.Issues_Other</a></li>
</ul>
</div>
</div>
</div>
</div>
<hr />
</div>
-->

@ -6,7 +6,7 @@ import 'rxjs/add/operator/map';
import { SearchService } from '../services/search.service';
import { IMovieResult } from './interfaces/IMovieResult';
import { ISearchMovieResult } from './interfaces/ISearchMovieResult';
@Component({
selector: 'ombi',
@ -18,16 +18,20 @@ export class SearchComponent implements OnInit {
searchText: string;
searchChanged: Subject<string> = new Subject<string>();
movieResults: IMovieResult[];
movieResults: ISearchMovieResult[];
constructor(private searchService: SearchService) {
//this.searchChanged
// .debounceTime(300) // wait 300ms after the last event before emitting last event
// .distinctUntilChanged() // only emit if value is different from previous value
// .subscribe(x => {
// this.searchText = x as string;
//
// });
this.searchChanged
.debounceTime(600) // Wait Xms afterthe last event before emitting last event
.distinctUntilChanged() // only emit if value is different from previous value
.subscribe(x => {
this.searchText = x as string;
if (this.searchText === "") {
this.clearResults();
return;
}
this.searchService.searchMovie(this.searchText).subscribe(x => this.movieResults = x);
});
}
ngOnInit(): void {
@ -36,8 +40,32 @@ export class SearchComponent implements OnInit {
}
search(text: any) {
//this.searchChanged.next(text);
this.searchService.searchMovie(text.target.value).subscribe(x => this.movieResults = x);
this.searchChanged.next(text.target.value);
}
request(searchResult: ISearchMovieResult) {
console.log(searchResult);
}
popularMovies() {
this.clearResults();
this.searchService.popularMovies().subscribe(x => this.movieResults = x);
}
nowPlayingMovies() {
this.clearResults();
this.searchService.nowPlayingMovies().subscribe(x => this.movieResults = x);
}
topRatedMovies() {
this.clearResults();
this.searchService.topRatedMovies().subscribe(x => this.movieResults = x);
}
upcomingMovies() {
this.clearResults();
this.searchService.upcomignMovies().subscribe(x => this.movieResults = x);
}
private clearResults() {
this.movieResults = [];
}
}

@ -3,14 +3,27 @@ import { Http } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import { ServiceHelpers } from './service.helpers';
import { IMovieResult } from '../search/interfaces/IMovieResult';
import { ISearchMovieResult } from '../search/interfaces/ISearchMovieResult';
@Injectable()
export class SearchService {
constructor(private http: Http) {
}
searchMovie(searchTerm: string): Observable<IMovieResult[]> {
searchMovie(searchTerm: string): Observable<ISearchMovieResult[]> {
return this.http.get('/api/Search/Movie/' + searchTerm).map(ServiceHelpers.extractData);
}
popularMovies(): Observable<ISearchMovieResult[]> {
return this.http.get('/api/Search/Movie/Popular').map(ServiceHelpers.extractData);
}
upcomignMovies(): Observable<ISearchMovieResult[]> {
return this.http.get('/api/Search/Movie/upcoming').map(ServiceHelpers.extractData);
}
nowPlayingMovies(): Observable<ISearchMovieResult[]> {
return this.http.get('/api/Search/Movie/nowplaying').map(ServiceHelpers.extractData);
}
topRatedMovies(): Observable<ISearchMovieResult[]> {
return this.http.get('/api/Search/Movie/toprated').map(ServiceHelpers.extractData);
}
}
Loading…
Cancel
Save