mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-08-20 13:23:20 -07:00
Merge branch 'DotNetCore' of https://github.com/tidusjar/Ombi into DotNetCore
This commit is contained in:
commit
179280a282
16 changed files with 914 additions and 340 deletions
16
Ombi/Ombi.Core/Engine/ITvRequestEngine.cs
Normal file
16
Ombi/Ombi.Core/Engine/ITvRequestEngine.cs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Ombi.Core.Models.Requests;
|
||||||
|
using Ombi.Core.Models.Search;
|
||||||
|
|
||||||
|
namespace Ombi.Core.Engine
|
||||||
|
{
|
||||||
|
public interface ITvRequestEngine
|
||||||
|
{
|
||||||
|
Task<IEnumerable<TvRequestModel>> GetTvRequests(int count, int position);
|
||||||
|
Task RemoveTvRequest(int requestId);
|
||||||
|
Task<RequestEngineResult> RequestTvShow(SearchTvShowViewModel tv);
|
||||||
|
Task<IEnumerable<TvRequestModel>> SearchTvRequest(string search);
|
||||||
|
Task<TvRequestModel> UpdateTvRequest(TvRequestModel request);
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,7 +6,7 @@ using Ombi.Store.Entities;
|
||||||
|
|
||||||
namespace Ombi.Core.Engine
|
namespace Ombi.Core.Engine
|
||||||
{
|
{
|
||||||
public interface IRequestEngine
|
public interface IMovieRequestEngine
|
||||||
{
|
{
|
||||||
Task<RequestEngineResult> RequestMovie(SearchMovieViewModel model);
|
Task<RequestEngineResult> RequestMovie(SearchMovieViewModel model);
|
||||||
bool ShouldAutoApprove(RequestType requestType);
|
bool ShouldAutoApprove(RequestType requestType);
|
|
@ -17,17 +17,15 @@ using Ombi.Notifications.Models;
|
||||||
|
|
||||||
namespace Ombi.Core.Engine
|
namespace Ombi.Core.Engine
|
||||||
{
|
{
|
||||||
public class RequestEngine : BaseMediaEngine, IRequestEngine
|
public class MovieRequestEngine : BaseMediaEngine, IMovieRequestEngine
|
||||||
{
|
{
|
||||||
public RequestEngine(IMovieDbApi movieApi, ITvMazeApi tvApi, IRequestServiceMain requestService, IPrincipal user, INotificationService notificationService) : base(user, requestService)
|
public MovieRequestEngine(IMovieDbApi movieApi, IRequestServiceMain requestService, IPrincipal user, INotificationService notificationService) : base(user, requestService)
|
||||||
{
|
{
|
||||||
MovieApi = movieApi;
|
MovieApi = movieApi;
|
||||||
TvApi = tvApi;
|
|
||||||
NotificationService = notificationService;
|
NotificationService = notificationService;
|
||||||
}
|
}
|
||||||
private IMovieDbApi MovieApi { get; }
|
private IMovieDbApi MovieApi { get; }
|
||||||
private INotificationService NotificationService { get; }
|
private INotificationService NotificationService { get; }
|
||||||
private ITvMazeApi TvApi { get; }
|
|
||||||
public async Task<RequestEngineResult> RequestMovie(SearchMovieViewModel model)
|
public async Task<RequestEngineResult> RequestMovie(SearchMovieViewModel model)
|
||||||
{
|
{
|
||||||
var movieInfo = await MovieApi.GetMovieInformation(model.Id);
|
var movieInfo = await MovieApi.GetMovieInformation(model.Id);
|
||||||
|
@ -161,40 +159,6 @@ namespace Ombi.Core.Engine
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<RequestEngineResult> RequestTvShow(SearchTvShowViewModel tv)
|
|
||||||
{
|
|
||||||
|
|
||||||
var showInfo = await TvApi.ShowLookupByTheTvDbId(tv.Id);
|
|
||||||
DateTime.TryParse(showInfo.premiered, out DateTime firstAir);
|
|
||||||
|
|
||||||
string fullShowName = $"{showInfo.name} ({firstAir.Year})";
|
|
||||||
// For some reason the poster path is always http
|
|
||||||
var posterPath = showInfo.image?.medium.Replace("http:", "https:");
|
|
||||||
var model = new TvRequestModel
|
|
||||||
{
|
|
||||||
Type = RequestType.TvShow,
|
|
||||||
Overview = showInfo.summary.RemoveHtml(),
|
|
||||||
PosterPath = posterPath,
|
|
||||||
Title = showInfo.name,
|
|
||||||
ReleaseDate = firstAir,
|
|
||||||
Status = showInfo.status,
|
|
||||||
RequestedDate = DateTime.UtcNow,
|
|
||||||
Approved = false,
|
|
||||||
RequestedUsers = new List<string> { Username },
|
|
||||||
Issues = IssueState.None,
|
|
||||||
ImdbId = showInfo.externals?.imdb ?? string.Empty,
|
|
||||||
TvDbId = tv.Id.ToString(),
|
|
||||||
ProviderId = tv.Id,
|
|
||||||
SeasonsNumbersRequested = tv.SeasonNumbersRequested,
|
|
||||||
RequestAll = tv.RequestAll
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
var existingRequest = await TvRequestService.CheckRequestAsync(model.Id);
|
|
||||||
existingRequest?.ChildRequests.Add(model);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private IEnumerable<EpisodesModel> GetListDifferences(IEnumerable<EpisodesModel> existing, IEnumerable<EpisodesModel> request)
|
private IEnumerable<EpisodesModel> GetListDifferences(IEnumerable<EpisodesModel> existing, IEnumerable<EpisodesModel> request)
|
||||||
{
|
{
|
192
Ombi/Ombi.Core/Engine/TvRequestEngine.cs
Normal file
192
Ombi/Ombi.Core/Engine/TvRequestEngine.cs
Normal file
|
@ -0,0 +1,192 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.Principal;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Hangfire;
|
||||||
|
using Ombi.Api.TvMaze;
|
||||||
|
using Ombi.Core.Models.Requests;
|
||||||
|
using Ombi.Core.Models.Search;
|
||||||
|
using Ombi.Store.Entities;
|
||||||
|
using Ombi.Helpers;
|
||||||
|
using Ombi.Notifications;
|
||||||
|
using Ombi.Notifications.Models;
|
||||||
|
|
||||||
|
namespace Ombi.Core.Engine
|
||||||
|
{
|
||||||
|
public class TvRequestEngine : BaseMediaEngine, ITvRequestEngine
|
||||||
|
{
|
||||||
|
public TvRequestEngine(ITvMazeApi tvApi, IRequestServiceMain requestService, IPrincipal user, INotificationService notificationService) : base(user, requestService)
|
||||||
|
{
|
||||||
|
TvApi = tvApi;
|
||||||
|
NotificationService = notificationService;
|
||||||
|
}
|
||||||
|
private INotificationService NotificationService { get; }
|
||||||
|
private ITvMazeApi TvApi { get; }
|
||||||
|
|
||||||
|
public async Task<RequestEngineResult> RequestTvShow(SearchTvShowViewModel tv)
|
||||||
|
{
|
||||||
|
|
||||||
|
var showInfo = await TvApi.ShowLookupByTheTvDbId(tv.Id);
|
||||||
|
DateTime.TryParse(showInfo.premiered, out DateTime firstAir);
|
||||||
|
|
||||||
|
// For some reason the poster path is always http
|
||||||
|
var posterPath = showInfo.image?.medium.Replace("http:", "https:");
|
||||||
|
var model = new TvRequestModel
|
||||||
|
{
|
||||||
|
Type = RequestType.TvShow,
|
||||||
|
Overview = showInfo.summary.RemoveHtml(),
|
||||||
|
PosterPath = posterPath,
|
||||||
|
Title = showInfo.name,
|
||||||
|
ReleaseDate = firstAir,
|
||||||
|
Status = showInfo.status,
|
||||||
|
RequestedDate = DateTime.UtcNow,
|
||||||
|
Approved = false,
|
||||||
|
RequestedUsers = new List<string> { Username },
|
||||||
|
Issues = IssueState.None,
|
||||||
|
ImdbId = showInfo.externals?.imdb ?? string.Empty,
|
||||||
|
TvDbId = tv.Id.ToString(),
|
||||||
|
ProviderId = tv.Id,
|
||||||
|
SeasonsNumbersRequested = tv.SeasonNumbersRequested,
|
||||||
|
RequestAll = tv.RequestAll
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var existingRequest = await TvRequestService.CheckRequestAsync(model.Id);
|
||||||
|
if (existingRequest != null)
|
||||||
|
{
|
||||||
|
return await AddExistingRequest(model, existingRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is a new request
|
||||||
|
return await AddRequest(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<TvRequestModel>> GetTvRequests(int count, int position)
|
||||||
|
{
|
||||||
|
var allRequests = await TvRequestService.GetAllAsync(count, position);
|
||||||
|
return allRequests;
|
||||||
|
}
|
||||||
|
public async Task<IEnumerable<TvRequestModel>> SearchTvRequest(string search)
|
||||||
|
{
|
||||||
|
var allRequests = await TvRequestService.GetAllAsync();
|
||||||
|
var results = allRequests.Where(x => x.Title.Contains(search, CompareOptions.IgnoreCase));
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
public async Task<TvRequestModel> UpdateTvRequest(TvRequestModel request)
|
||||||
|
{
|
||||||
|
var allRequests = await TvRequestService.GetAllAsync();
|
||||||
|
var results = allRequests.FirstOrDefault(x => x.Id == request.Id);
|
||||||
|
|
||||||
|
results.Approved = request.Approved;
|
||||||
|
results.Available = request.Available;
|
||||||
|
results.Denied = request.Denied;
|
||||||
|
results.DeniedReason = request.DeniedReason;
|
||||||
|
results.AdminNote = request.AdminNote;
|
||||||
|
results.ImdbId = request.ImdbId;
|
||||||
|
results.IssueId = request.IssueId;
|
||||||
|
results.Issues = request.Issues;
|
||||||
|
results.OtherMessage = request.OtherMessage;
|
||||||
|
results.Overview = request.Overview;
|
||||||
|
results.PosterPath = request.PosterPath;
|
||||||
|
results.RequestedUsers = request.RequestedUsers?.ToList() ?? new List<string>();
|
||||||
|
|
||||||
|
var model = TvRequestService.UpdateRequest(results);
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task RemoveTvRequest(int requestId)
|
||||||
|
{
|
||||||
|
await TvRequestService.DeleteRequestAsync(requestId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<RequestEngineResult> AddExistingRequest(TvRequestModel newRequest, TvRequestModel existingRequest)
|
||||||
|
{
|
||||||
|
var episodeDifference = new List<EpisodesModel>();
|
||||||
|
if (existingRequest.HasChildRequests)
|
||||||
|
{
|
||||||
|
// Let's check if this has already been requested as a child!
|
||||||
|
foreach (var children in existingRequest.ChildRequests)
|
||||||
|
{
|
||||||
|
var difference = GetListDifferences(children.Episodes, newRequest.Episodes).ToList();
|
||||||
|
if (difference.Any())
|
||||||
|
{
|
||||||
|
episodeDifference = difference;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (episodeDifference.Any())
|
||||||
|
{
|
||||||
|
// This is where there are some episodes that have been requested, but this list contains the 'new' requests
|
||||||
|
newRequest.Episodes = episodeDifference;
|
||||||
|
}
|
||||||
|
|
||||||
|
existingRequest.ChildRequests.Add(newRequest);
|
||||||
|
|
||||||
|
TvRequestService.UpdateRequest(existingRequest);
|
||||||
|
|
||||||
|
if (ShouldAutoApprove(RequestType.TvShow))
|
||||||
|
{
|
||||||
|
// TODO Auto Approval Code
|
||||||
|
}
|
||||||
|
return await AddRequest(newRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerable<EpisodesModel> GetListDifferences(IEnumerable<EpisodesModel> existing, IEnumerable<EpisodesModel> request)
|
||||||
|
{
|
||||||
|
var newRequest = request
|
||||||
|
.Select(r =>
|
||||||
|
new EpisodesModel
|
||||||
|
{
|
||||||
|
SeasonNumber = r.SeasonNumber,
|
||||||
|
EpisodeNumber = r.EpisodeNumber
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
return newRequest.Except(existing);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<RequestEngineResult> AddRequest(TvRequestModel model)
|
||||||
|
{
|
||||||
|
await TvRequestService.AddRequestAsync(model);
|
||||||
|
|
||||||
|
if (ShouldSendNotification(model.Type))
|
||||||
|
{
|
||||||
|
var notificationModel = new NotificationModel
|
||||||
|
{
|
||||||
|
Title = model.Title,
|
||||||
|
User = Username,
|
||||||
|
DateTime = DateTime.Now,
|
||||||
|
NotificationType = NotificationType.NewRequest,
|
||||||
|
RequestType = model.Type,
|
||||||
|
ImgSrc = model.PosterPath
|
||||||
|
};
|
||||||
|
|
||||||
|
BackgroundJob.Enqueue(() => NotificationService.Publish(notificationModel).Wait());
|
||||||
|
}
|
||||||
|
|
||||||
|
//var limit = await RequestLimitRepo.GetAllAsync();
|
||||||
|
//var usersLimit = limit.FirstOrDefault(x => x.Username == Username && x.RequestType == model.Type);
|
||||||
|
//if (usersLimit == null)
|
||||||
|
//{
|
||||||
|
// await RequestLimitRepo.InsertAsync(new RequestLimit
|
||||||
|
// {
|
||||||
|
// Username = Username,
|
||||||
|
// RequestType = model.Type,
|
||||||
|
// FirstRequestDate = DateTime.UtcNow,
|
||||||
|
// RequestCount = 1
|
||||||
|
// });
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
// usersLimit.RequestCount++;
|
||||||
|
// await RequestLimitRepo.UpdateAsync(usersLimit);
|
||||||
|
//}
|
||||||
|
|
||||||
|
return new RequestEngineResult { RequestAdded = true };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -46,7 +46,8 @@ namespace Ombi.DependencyInjection
|
||||||
public static IServiceCollection RegisterEngines(this IServiceCollection services)
|
public static IServiceCollection RegisterEngines(this IServiceCollection services)
|
||||||
{
|
{
|
||||||
services.AddTransient<IMovieEngine, MovieSearchEngine>();
|
services.AddTransient<IMovieEngine, MovieSearchEngine>();
|
||||||
services.AddTransient<IRequestEngine, RequestEngine>();
|
services.AddTransient<IMovieRequestEngine, MovieRequestEngine>();
|
||||||
|
services.AddTransient<ITvRequestEngine, TvRequestEngine>();
|
||||||
services.AddTransient<ITvSearchEngine, TvSearchEngine>();
|
services.AddTransient<ITvSearchEngine, TvSearchEngine>();
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,49 +11,77 @@ namespace Ombi.Controllers
|
||||||
[Authorize]
|
[Authorize]
|
||||||
public class RequestController : BaseV1ApiController
|
public class RequestController : BaseV1ApiController
|
||||||
{
|
{
|
||||||
public RequestController(IRequestEngine engine)
|
public RequestController(IMovieRequestEngine engine, ITvRequestEngine tvRequestEngine)
|
||||||
{
|
{
|
||||||
RequestEngine = engine;
|
MovieRequestEngine = engine;
|
||||||
|
TvRequestEngine = tvRequestEngine;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IRequestEngine RequestEngine { get; }
|
private IMovieRequestEngine MovieRequestEngine { get; }
|
||||||
|
private ITvRequestEngine TvRequestEngine { get; }
|
||||||
|
|
||||||
|
|
||||||
[HttpGet("movie/{count:int}/{position:int}", Name = "GetRequestsByCount")]
|
[HttpGet("movie/{count:int}/{position:int}")]
|
||||||
public async Task<IEnumerable<MovieRequestModel>> GetRequests(int count, int position)
|
public async Task<IEnumerable<MovieRequestModel>> GetRequests(int count, int position)
|
||||||
{
|
{
|
||||||
return await RequestEngine.GetMovieRequests(count, position);
|
return await MovieRequestEngine.GetMovieRequests(count, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("movie")]
|
[HttpPost("movie")]
|
||||||
public async Task<RequestEngineResult> RequestMovie([FromBody]SearchMovieViewModel movie)
|
public async Task<RequestEngineResult> RequestMovie([FromBody]SearchMovieViewModel movie)
|
||||||
{
|
{
|
||||||
return await RequestEngine.RequestMovie(movie);
|
return await MovieRequestEngine.RequestMovie(movie);
|
||||||
}
|
}
|
||||||
|
|
||||||
//[HttpPost("tv")]
|
|
||||||
//public async Task<RequestEngineResult> RequestTv([FromBody]SearchTvShowViewModel tv)
|
|
||||||
//{
|
|
||||||
// return await RequestEngine.RequestMovie();
|
|
||||||
//}
|
|
||||||
|
|
||||||
[HttpGet("movie/search/{searchTerm}")]
|
[HttpGet("movie/search/{searchTerm}")]
|
||||||
public async Task<IEnumerable<MovieRequestModel>> Search(string searchTerm)
|
public async Task<IEnumerable<MovieRequestModel>> Search(string searchTerm)
|
||||||
{
|
{
|
||||||
|
|
||||||
return await RequestEngine.SearchMovieRequest(searchTerm);
|
return await MovieRequestEngine.SearchMovieRequest(searchTerm);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpDelete("movie/{requestId:int}")]
|
[HttpDelete("movie/{requestId:int}")]
|
||||||
public async Task DeleteRequest(int requestId)
|
public async Task DeleteRequest(int requestId)
|
||||||
{
|
{
|
||||||
await RequestEngine.RemoveMovieRequest(requestId);
|
await MovieRequestEngine.RemoveMovieRequest(requestId);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPut("movie")]
|
[HttpPut("movie")]
|
||||||
public async Task<MovieRequestModel> UpdateRequest([FromBody]MovieRequestModel model)
|
public async Task<MovieRequestModel> UpdateRequest([FromBody]MovieRequestModel model)
|
||||||
{
|
{
|
||||||
return await RequestEngine.UpdateMovieRequest(model);
|
return await MovieRequestEngine.UpdateMovieRequest(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("tv/{count:int}/{position:int}")]
|
||||||
|
public async Task<IEnumerable<TvRequestModel>> GetTvRequests(int count, int position)
|
||||||
|
{
|
||||||
|
return await TvRequestEngine.GetTvRequests(count, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("tv")]
|
||||||
|
public async Task<RequestEngineResult> RequestTv([FromBody]SearchTvShowViewModel tv)
|
||||||
|
{
|
||||||
|
return await TvRequestEngine.RequestTvShow(tv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[HttpGet("tv/search/{searchTerm}")]
|
||||||
|
public async Task<IEnumerable<TvRequestModel>> SearchTv(string searchTerm)
|
||||||
|
{
|
||||||
|
|
||||||
|
return await TvRequestEngine.SearchTvRequest(searchTerm);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpDelete("tv/{requestId:int}")]
|
||||||
|
public async Task DeleteTvRequest(int requestId)
|
||||||
|
{
|
||||||
|
await TvRequestEngine.RemoveTvRequest(requestId);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPut("tv")]
|
||||||
|
public async Task<TvRequestModel> UpdateRequest([FromBody]TvRequestModel model)
|
||||||
|
{
|
||||||
|
return await TvRequestEngine.UpdateTvRequest(model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,28 @@
|
||||||
<Content Update="wwwroot\app\interfaces\ISearchTvResult.ts">
|
<Content Update="wwwroot\app\interfaces\ISearchTvResult.ts">
|
||||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
<Content Update="wwwroot\app\requests\movierequests - Copy.component.html">
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Update="wwwroot\app\requests\tvrequests.component.js">
|
||||||
|
<DependentUpon>tvrequests.component.ts</DependentUpon>
|
||||||
|
</Content>
|
||||||
|
<Content Update="wwwroot\app\requests\movierequests - Copy.component.js">
|
||||||
|
<DependentUpon>movierequests - Copy.component.ts</DependentUpon>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Update="wwwroot\app\requests\tvrequests.component.ts">
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Update="wwwroot\app\requests\request - Copy.component.js">
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Update="wwwroot\app\requests\request - Copy.component.js.map">
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Update="wwwroot\app\requests\request - Copy.component.ts">
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
<Content Update="wwwroot\app\search\moviesearch - Copy.component.html">
|
<Content Update="wwwroot\app\search\moviesearch - Copy.component.html">
|
||||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
|
|
@ -11,10 +11,16 @@ import { HttpModule } from '@angular/http';
|
||||||
import { InfiniteScrollModule } from 'ngx-infinite-scroll'
|
import { InfiniteScrollModule } from 'ngx-infinite-scroll'
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
|
// Search
|
||||||
import { SearchComponent } from './search/search.component';
|
import { SearchComponent } from './search/search.component';
|
||||||
import { MovieSearchComponent } from './search/moviesearch.component';
|
import { MovieSearchComponent } from './search/moviesearch.component';
|
||||||
import { TvSearchComponent } from './search/tvsearch.component';
|
import { TvSearchComponent } from './search/tvsearch.component';
|
||||||
|
|
||||||
|
// Request
|
||||||
import { RequestComponent } from './requests/request.component';
|
import { RequestComponent } from './requests/request.component';
|
||||||
|
import { MovieRequestsComponent } from './requests/movierequests.component';
|
||||||
|
import { TvRequestsComponent } from './requests/tvrequests.component';
|
||||||
|
|
||||||
import { LoginComponent } from './login/login.component';
|
import { LoginComponent } from './login/login.component';
|
||||||
import { LandingPageComponent } from './landingpage/landingpage.component';
|
import { LandingPageComponent } from './landingpage/landingpage.component';
|
||||||
import { UserManagementComponent } from './usermanagement/usermanagement.component';
|
import { UserManagementComponent } from './usermanagement/usermanagement.component';
|
||||||
|
@ -76,7 +82,9 @@ const routes: Routes = [
|
||||||
MovieSearchComponent,
|
MovieSearchComponent,
|
||||||
TvSearchComponent,
|
TvSearchComponent,
|
||||||
LandingPageComponent,
|
LandingPageComponent,
|
||||||
UserManagementComponent
|
UserManagementComponent,
|
||||||
|
MovieRequestsComponent,
|
||||||
|
TvRequestsComponent
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
SearchService,
|
SearchService,
|
||||||
|
|
178
Ombi/Ombi/wwwroot/app/requests/movierequests.component.html
Normal file
178
Ombi/Ombi/wwwroot/app/requests/movierequests.component.html
Normal file
|
@ -0,0 +1,178 @@
|
||||||
|
<div class="form-group">
|
||||||
|
<div>
|
||||||
|
<input type="text" class="form-control form-control-custom" placeholder="Search" (keyup)="search($event)">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
<div infinite-scroll
|
||||||
|
[infiniteScrollDistance]="1"
|
||||||
|
[infiniteScrollThrottle]="100"
|
||||||
|
(scrolled)="loadMore()">
|
||||||
|
|
||||||
|
|
||||||
|
<div *ngFor="let request of movieRequests">
|
||||||
|
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-2">
|
||||||
|
|
||||||
|
<img *ngIf="request.type == 1" class="img-responsive" src="https://image.tmdb.org/t/p/w150/{{request.posterPath}}" alt="poster">
|
||||||
|
<img *ngIf="request.type == 2" class="img-responsive" src="https://image.tmdb.org/t/p/w150/{{request.posterPath}}" alt="poster">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-5 ">
|
||||||
|
<div>
|
||||||
|
<a href="http://www.imdb.com/title/{{request.imdbId}}/" target="_blank">
|
||||||
|
<h4 class="request-title">{{request.title}} ({{request.releaseDate | date: 'yyyy'}})</h4>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<div>
|
||||||
|
<span>Status: </span>
|
||||||
|
<span class="label label-success">{{request.status}}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<span>Request status: </span>
|
||||||
|
<span *ngIf="request.available" class="label label-success">Available</span>
|
||||||
|
<span *ngIf="request.approved && !request.available" class="label label-info">Processing Request</span>
|
||||||
|
<span *ngIf="request.denied" class="label label-danger">Request Denied</span>
|
||||||
|
<span *ngIf="request.deniedReason" title="{{request.deniedReason}}"><i class="fa fa-info-circle"></i></span>
|
||||||
|
<span *ngIf="!request.approved && !request.availble && !request.denied" class="label label-warning">Pending Approval</span>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div *ngIf="request.denied">
|
||||||
|
Denied: <i style="color:red;" class="fa fa-check"></i>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div>Release Date: {{request.releaseDate | date}}</div>
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
<!--{{#if_eq type "tv"}}
|
||||||
|
{{#if episodes}}
|
||||||
|
Episodes: <span class="customTooltip" data-tooltip-content="#{{requestId}}toolTipContent"><i class="fa fa-info-circle"></i></span>
|
||||||
|
{{else}}
|
||||||
|
<div>@UI.Requests_SeasonsRequested: {{seriesRequested}}</div>
|
||||||
|
|
||||||
|
{{/if}}
|
||||||
|
{{/if_eq}}-->
|
||||||
|
<div *ngIf="request.requestedUsers">Requested By: <span *ngFor="let user of request.requestedUsers">{{user}} </span></div>
|
||||||
|
|
||||||
|
<div>Requested Date: {{request.requestedDate | date}}</div>
|
||||||
|
<!--{{#if admin}}
|
||||||
|
{{#if currentRootPath}}
|
||||||
|
<div class="{{requestId}}rootPathMain">Root Path: <span id="{{requestId}}currentRootPath">{{currentRootPath}}</span></div>
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
|
<div>
|
||||||
|
{{#if_eq issueId 0}}
|
||||||
|
@*Nothing*@
|
||||||
|
{{else}}
|
||||||
|
@UI.Issues_Issue: <a href="@formAction/issues/{{issueId}}"><i class="fa fa-check"></i></a>
|
||||||
|
{{/if_eq}}
|
||||||
|
</div>-->
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-3 col-sm-push-3">
|
||||||
|
<div *ngIf="isAdmin">
|
||||||
|
<div *ngIf="!request.approved">
|
||||||
|
<form>
|
||||||
|
<input name="requestId" type="text" value="{{request.requestId}}" hidden="hidden" />
|
||||||
|
<div *ngIf="request.hasQualities" class="btn-group btn-split">
|
||||||
|
<button type="button" (click)="approve(request)" class="btn btn-sm btn-success-outline approve"><i class="fa fa-plus"></i> Approve</button>
|
||||||
|
<button type="button" class="btn btn-success-outline dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
|
<span class="caret"></span>
|
||||||
|
<span class="sr-only">Toggle Dropdown</span>
|
||||||
|
</button>
|
||||||
|
<!--<ul class="dropdown-menu">
|
||||||
|
{{#each qualities}}
|
||||||
|
<li><a href="#" class="approve-with-quality" id="{{id}}">{{name}}</a></li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>-->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<button *ngIf="!request.hasQualities" (click)="approve(request)" style="text-align: right" class="btn btn-sm btn-success-outline approve" type="submit"><i class="fa fa-plus"></i> Approve</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!--<form method="POST" action="@formAction/requests/changeRootFolder{{#if_eq type "tv"}}tv{{else}}movie{{/if_eq}}" id="changeFolder{{requestId}}">
|
||||||
|
<input name="requestId" type="text" value="{{requestId}}" hidden="hidden"/>
|
||||||
|
{{#if_eq hasRootFolders true}}
|
||||||
|
<div class="btn-group btn-split">
|
||||||
|
<button type="button" class="btn btn-sm btn-success-outline" id="changeRootFolderBtn{{requestId}}" custom-button="{{requestId}}">@*<i class="fa fa-plus"></i>*@ Change Root Folder</button>
|
||||||
|
<button type="button" class="btn btn-success-outline dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
|
<span class="caret"></span>
|
||||||
|
<span class="sr-only">@UI.Requests_ToggleDropdown</span>
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
{{#each rootFolders}}
|
||||||
|
<li><a href="#" class="change-root-folder" id="{{id}}" requestId="{{requestId}}">{{path}}</a></li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{{/if_eq}}
|
||||||
|
</form>-->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div *ngIf="!request.denied">
|
||||||
|
<form>
|
||||||
|
<input name="requestId" type="text" value="{{request.requestId}}" hidden="hidden"/>
|
||||||
|
<input name="reason" type="text" hidden="hidden"/>
|
||||||
|
<div class="btn-group btn-split">
|
||||||
|
<button type="button" (click)="deny(request)" class="btn btn-sm btn-danger-outline deny"><i class="fa fa-times"></i> Deny</button>
|
||||||
|
<button type="button" class="btn btn-danger-outline dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
|
<span class="caret"></span>
|
||||||
|
<span class="sr-only">@UI.Requests_ToggleDropdown</span>
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
<li><a class="deny-with-reason" id="denyReason{{request.requestId}}" href="#" data-toggle="modal" data-target="#denyReasonModal">Deny with a reason</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<form>
|
||||||
|
<button (click)="removeRequest(request)" style="text-align: right" class="btn btn-sm btn-danger-outline delete"><i class="fa fa-minus"></i> Remove</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<form>
|
||||||
|
<button *ngIf="request.available" (click)="changeAvailability(request, false)" style="text-align: right" value="false" class="btn btn-sm btn-info-outline change"><i class="fa fa-minus"></i> Mark Unavailable</button>
|
||||||
|
<button *ngIf="!request.available" (click)="changeAvailability(request, true)" style="text-align: right" value="true" class="btn btn-sm btn-success-outline change"><i class="fa fa-plus"></i> Mark Available</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<input name="requestId" type="text" value="{{request.requestId}}" hidden="hidden" />
|
||||||
|
<div class="dropdown">
|
||||||
|
<button id="{{request.requestId}}" class="btn btn-sm btn-primary-outline dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
||||||
|
<i class="fa fa-plus"></i> Report Issue
|
||||||
|
<span class="caret"></span>
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
|
||||||
|
<li><a issue-select="0">@UI.Issues_WrongAudio</a></li>
|
||||||
|
<li><a issue-select="1">@UI.Issues_NoSubs</a></li>
|
||||||
|
<li><a issue-select="2">@UI.Issues_WrongContent</a></li>
|
||||||
|
<li><a issue-select="3">@UI.Issues_Playback</a></li>
|
||||||
|
<li><a issue-select="4" data-toggle="modal" data-target="#myModal">@UI.Issues_Other</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
109
Ombi/Ombi/wwwroot/app/requests/movierequests.component.ts
Normal file
109
Ombi/Ombi/wwwroot/app/requests/movierequests.component.ts
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { Subject } from 'rxjs/Subject';
|
||||||
|
import 'rxjs/add/operator/debounceTime';
|
||||||
|
import 'rxjs/add/operator/distinctUntilChanged';
|
||||||
|
import 'rxjs/add/operator/map';
|
||||||
|
|
||||||
|
|
||||||
|
import 'rxjs/add/operator/debounceTime';
|
||||||
|
import 'rxjs/add/operator/distinctUntilChanged';
|
||||||
|
import 'rxjs/add/operator/map';
|
||||||
|
|
||||||
|
import { RequestService } from '../services/request.service';
|
||||||
|
import { IdentityService } from '../services/identity.service';
|
||||||
|
|
||||||
|
import { IMovieRequestModel } from '../interfaces/IRequestModel';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'movie-requests',
|
||||||
|
moduleId: module.id,
|
||||||
|
templateUrl: './movierequests.component.html'
|
||||||
|
})
|
||||||
|
export class MovieRequestsComponent implements OnInit {
|
||||||
|
constructor(private requestService: RequestService, private identityService: IdentityService) {
|
||||||
|
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.resetSearch();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.requestService.searchMovieRequests(this.searchText).subscribe(m => this.movieRequests = m);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
movieRequests: IMovieRequestModel[];
|
||||||
|
|
||||||
|
searchChanged: Subject<string> = new Subject<string>();
|
||||||
|
searchText: string;
|
||||||
|
|
||||||
|
isAdmin : boolean;
|
||||||
|
|
||||||
|
private currentlyLoaded: number;
|
||||||
|
private amountToLoad : number;
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.amountToLoad = 5;
|
||||||
|
this.currentlyLoaded = 5;
|
||||||
|
this.loadInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
loadMore() {
|
||||||
|
this.requestService.getMovieRequests(this.amountToLoad, this.currentlyLoaded + 1).subscribe(x => {
|
||||||
|
this.movieRequests.push.apply(this.movieRequests, x);
|
||||||
|
this.currentlyLoaded = this.currentlyLoaded + this.amountToLoad;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
search(text: any) {
|
||||||
|
this.searchChanged.next(text.target.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
removeRequest(request: IMovieRequestModel) {
|
||||||
|
this.requestService.removeMovieRequest(request);
|
||||||
|
this.removeRequestFromUi(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
changeAvailability(request: IMovieRequestModel, available: boolean) {
|
||||||
|
request.available = available;
|
||||||
|
|
||||||
|
this.updateRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
approve(request: IMovieRequestModel) {
|
||||||
|
request.approved = true;
|
||||||
|
request.denied = false;
|
||||||
|
this.updateRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
deny(request: IMovieRequestModel) {
|
||||||
|
request.approved = false;
|
||||||
|
request.denied = true;
|
||||||
|
this.updateRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateRequest(request: IMovieRequestModel) {
|
||||||
|
this.requestService.updateMovieRequest(request).subscribe(x => request = x);
|
||||||
|
}
|
||||||
|
|
||||||
|
private loadInit() {
|
||||||
|
this.requestService.getMovieRequests(this.amountToLoad, 0).subscribe(x => this.movieRequests = x);
|
||||||
|
this.isAdmin = this.identityService.hasRole("Admin");
|
||||||
|
}
|
||||||
|
|
||||||
|
private resetSearch() {
|
||||||
|
this.currentlyLoaded = 5;
|
||||||
|
this.loadInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
private removeRequestFromUi(key: IMovieRequestModel) {
|
||||||
|
var index = this.movieRequests.indexOf(key, 0);
|
||||||
|
if (index > -1) {
|
||||||
|
this.movieRequests.splice(index, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,180 +1,25 @@
|
||||||
<h1 id="searchTitle">Requests</h1>
|
<h1 id="searchTitle">Requests</h1>
|
||||||
<h4>Below you can see yours and all other requests, as well as their download and approval status.</h4>
|
<h4>Below you can see yours and all other requests, as well as their download and approval status.</h4>
|
||||||
<div class="form-group">
|
|
||||||
<div>
|
|
||||||
<input type="text" class="form-control form-control-custom" placeholder="Search" (keyup)="search($event)">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<br/>
|
|
||||||
|
|
||||||
<div infinite-scroll
|
|
||||||
[infiniteScrollDistance]="1"
|
|
||||||
[infiniteScrollThrottle]="100"
|
|
||||||
(scrolled)="loadMore()">
|
|
||||||
|
|
||||||
|
|
||||||
<div *ngFor="let request of movieRequests">
|
|
||||||
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-2">
|
|
||||||
|
|
||||||
<img *ngIf="request.type == 1" class="img-responsive" src="https://image.tmdb.org/t/p/w150/{{request.posterPath}}" alt="poster">
|
|
||||||
<img *ngIf="request.type == 2" class="img-responsive" src="https://image.tmdb.org/t/p/w150/{{request.posterPath}}" alt="poster">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-sm-5 ">
|
|
||||||
<div>
|
|
||||||
<a href="http://www.imdb.com/title/{{request.imdbId}}/" target="_blank">
|
|
||||||
<h4 class="request-title">{{request.title}} ({{request.releaseDate | date: 'yyyy'}})</h4>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<br />
|
|
||||||
<div>
|
|
||||||
<span>Status: </span>
|
|
||||||
<span class="label label-success">{{request.status}}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<span>Request status: </span>
|
|
||||||
<span *ngIf="request.available" class="label label-success">Available</span>
|
|
||||||
<span *ngIf="request.approved && !request.available" class="label label-info">Processing Request</span>
|
|
||||||
<span *ngIf="request.denied" class="label label-danger">Request Denied</span>
|
|
||||||
<span *ngIf="request.deniedReason" title="{{request.deniedReason}}"><i class="fa fa-info-circle"></i></span>
|
|
||||||
<span *ngIf="!request.approved && !request.availble && !request.denied" class="label label-warning">Pending Approval</span>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div *ngIf="request.denied">
|
|
||||||
Denied: <i style="color:red;" class="fa fa-check"></i>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div>Release Date: {{request.releaseDate | date}}</div>
|
|
||||||
<br/>
|
|
||||||
|
|
||||||
<!--{{#if_eq type "tv"}}
|
|
||||||
{{#if episodes}}
|
|
||||||
Episodes: <span class="customTooltip" data-tooltip-content="#{{requestId}}toolTipContent"><i class="fa fa-info-circle"></i></span>
|
|
||||||
{{else}}
|
|
||||||
<div>@UI.Requests_SeasonsRequested: {{seriesRequested}}</div>
|
|
||||||
|
|
||||||
{{/if}}
|
|
||||||
{{/if_eq}}-->
|
|
||||||
<div *ngIf="request.requestedUsers">Requested By: <span *ngFor="let user of request.requestedUsers">{{user}} </span></div>
|
|
||||||
|
|
||||||
<div>Requested Date: {{request.requestedDate | date}}</div>
|
|
||||||
<!--{{#if admin}}
|
|
||||||
{{#if currentRootPath}}
|
|
||||||
<div class="{{requestId}}rootPathMain">Root Path: <span id="{{requestId}}currentRootPath">{{currentRootPath}}</span></div>
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
|
||||||
<div>
|
|
||||||
{{#if_eq issueId 0}}
|
|
||||||
@*Nothing*@
|
|
||||||
{{else}}
|
|
||||||
@UI.Issues_Issue: <a href="@formAction/issues/{{issueId}}"><i class="fa fa-check"></i></a>
|
|
||||||
{{/if_eq}}
|
|
||||||
</div>-->
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-3 col-sm-push-3">
|
|
||||||
<div *ngIf="isAdmin">
|
|
||||||
<div *ngIf="!request.approved">
|
|
||||||
<form>
|
|
||||||
<input name="requestId" type="text" value="{{request.requestId}}" hidden="hidden" />
|
|
||||||
<div *ngIf="request.hasQualities" class="btn-group btn-split">
|
|
||||||
<button type="button" (click)="approve(request)" class="btn btn-sm btn-success-outline approve"><i class="fa fa-plus"></i> Approve</button>
|
|
||||||
<button type="button" class="btn btn-success-outline dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
|
||||||
<span class="caret"></span>
|
|
||||||
<span class="sr-only">Toggle Dropdown</span>
|
|
||||||
</button>
|
|
||||||
<!--<ul class="dropdown-menu">
|
|
||||||
{{#each qualities}}
|
|
||||||
<li><a href="#" class="approve-with-quality" id="{{id}}">{{name}}</a></li>
|
|
||||||
{{/each}}
|
|
||||||
</ul>-->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<button *ngIf="!request.hasQualities" (click)="approve(request)" style="text-align: right" class="btn btn-sm btn-success-outline approve" type="submit"><i class="fa fa-plus"></i> Approve</button>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!--<form method="POST" action="@formAction/requests/changeRootFolder{{#if_eq type "tv"}}tv{{else}}movie{{/if_eq}}" id="changeFolder{{requestId}}">
|
<ul id="nav-tabs" class="nav nav-tabs" role="tablist">
|
||||||
<input name="requestId" type="text" value="{{requestId}}" hidden="hidden"/>
|
<li role="presentation" class="active">
|
||||||
{{#if_eq hasRootFolders true}}
|
<a id="movieTabButton" aria-controls="home" role="tab" data-toggle="tab" (click)="selectTab()"><i class="fa fa-film"></i> Movies</a>
|
||||||
<div class="btn-group btn-split">
|
</li>
|
||||||
<button type="button" class="btn btn-sm btn-success-outline" id="changeRootFolderBtn{{requestId}}" custom-button="{{requestId}}">@*<i class="fa fa-plus"></i>*@ Change Root Folder</button>
|
<li role="presentation">
|
||||||
<button type="button" class="btn btn-success-outline dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
<a id="tvTabButton" aria-controls="profile" role="tab" data-toggle="tab" (click)="selectTab()"><i class="fa fa-television"></i> TV Shows</a>
|
||||||
<span class="caret"></span>
|
|
||||||
<span class="sr-only">@UI.Requests_ToggleDropdown</span>
|
</li>
|
||||||
</button>
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
{{#each rootFolders}}
|
|
||||||
<li><a href="#" class="change-root-folder" id="{{id}}" requestId="{{requestId}}">{{path}}</a></li>
|
|
||||||
{{/each}}
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<!-- Tab panes -->
|
||||||
|
<div class="tab-content">
|
||||||
|
<div [hidden]="!showMovie">
|
||||||
|
<movie-requests></movie-requests>
|
||||||
</div>
|
</div>
|
||||||
{{/if_eq}}
|
<div [hidden]="!showTv">
|
||||||
</form>-->
|
<tv-requests></tv-requests>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div *ngIf="!request.denied">
|
|
||||||
<form>
|
|
||||||
<input name="requestId" type="text" value="{{request.requestId}}" hidden="hidden"/>
|
|
||||||
<input name="reason" type="text" hidden="hidden"/>
|
|
||||||
<div class="btn-group btn-split">
|
|
||||||
<button type="button" (click)="deny(request)" class="btn btn-sm btn-danger-outline deny"><i class="fa fa-times"></i> Deny</button>
|
|
||||||
<button type="button" class="btn btn-danger-outline dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
|
||||||
<span class="caret"></span>
|
|
||||||
<span class="sr-only">@UI.Requests_ToggleDropdown</span>
|
|
||||||
</button>
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
<li><a class="deny-with-reason" id="denyReason{{request.requestId}}" href="#" data-toggle="modal" data-target="#denyReasonModal">Deny with a reason</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<form>
|
|
||||||
<button (click)="removeRequest(request)" style="text-align: right" class="btn btn-sm btn-danger-outline delete"><i class="fa fa-minus"></i> Remove</button>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<form>
|
|
||||||
<button *ngIf="request.available" (click)="changeAvailability(request, false)" style="text-align: right" value="false" class="btn btn-sm btn-info-outline change"><i class="fa fa-minus"></i> Mark Unavailable</button>
|
|
||||||
<button *ngIf="!request.available" (click)="changeAvailability(request, true)" style="text-align: right" value="true" class="btn btn-sm btn-success-outline change"><i class="fa fa-plus"></i> Mark Available</button>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<input name="requestId" type="text" value="{{request.requestId}}" hidden="hidden" />
|
|
||||||
<div class="dropdown">
|
|
||||||
<button id="{{request.requestId}}" class="btn btn-sm btn-primary-outline dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
|
||||||
<i class="fa fa-plus"></i> Report Issue
|
|
||||||
<span class="caret"></span>
|
|
||||||
</button>
|
|
||||||
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
|
|
||||||
<li><a issue-select="0">@UI.Issues_WrongAudio</a></li>
|
|
||||||
<li><a issue-select="1">@UI.Issues_NoSubs</a></li>
|
|
||||||
<li><a issue-select="2">@UI.Issues_WrongContent</a></li>
|
|
||||||
<li><a issue-select="3">@UI.Issues_Playback</a></li>
|
|
||||||
<li><a issue-select="4" data-toggle="modal" data-target="#myModal">@UI.Issues_Other</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<hr />
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
|
@ -1,110 +1,18 @@
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { Subject } from 'rxjs/Subject';
|
|
||||||
import 'rxjs/add/operator/debounceTime';
|
|
||||||
import 'rxjs/add/operator/distinctUntilChanged';
|
|
||||||
import 'rxjs/add/operator/map';
|
|
||||||
|
|
||||||
|
|
||||||
import 'rxjs/add/operator/debounceTime';
|
|
||||||
import 'rxjs/add/operator/distinctUntilChanged';
|
|
||||||
import 'rxjs/add/operator/map';
|
|
||||||
|
|
||||||
import { RequestService } from '../services/request.service';
|
|
||||||
import { IdentityService } from '../services/identity.service';
|
|
||||||
|
|
||||||
import { IMovieRequestModel, ITvRequestModel } from '../interfaces/IRequestModel';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ombi',
|
selector: 'ombi',
|
||||||
moduleId: module.id,
|
moduleId: module.id,
|
||||||
templateUrl: './request.component.html'
|
templateUrl: './request.component.html'
|
||||||
})
|
})
|
||||||
export class RequestComponent implements OnInit {
|
export class RequestComponent {
|
||||||
constructor(private requestService: RequestService, private identityService: IdentityService) {
|
|
||||||
this.searchChanged
|
showMovie = true;
|
||||||
.debounceTime(600) // Wait Xms afterthe last event before emitting last event
|
showTv = false;
|
||||||
.distinctUntilChanged() // only emit if value is different from previous value
|
|
||||||
.subscribe(x => {
|
selectTab() {
|
||||||
this.searchText = x as string;
|
this.showMovie = !this.showMovie;
|
||||||
if (this.searchText === "") {
|
this.showTv = !this.showTv;
|
||||||
this.resetSearch();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.requestService.searchRequests(this.searchText).subscribe(x => this.movieRequests = x);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
movieRequests: IMovieRequestModel[];
|
|
||||||
tvRequests: ITvRequestModel[];
|
|
||||||
|
|
||||||
searchChanged: Subject<string> = new Subject<string>();
|
|
||||||
searchText: string;
|
|
||||||
|
|
||||||
isAdmin : boolean;
|
|
||||||
|
|
||||||
private currentlyLoaded: number;
|
|
||||||
private amountToLoad : number;
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.amountToLoad = 5;
|
|
||||||
this.currentlyLoaded = 5;
|
|
||||||
this.loadInit();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
loadMore() {
|
|
||||||
this.requestService.getRequests(this.amountToLoad, this.currentlyLoaded + 1).subscribe(x => {
|
|
||||||
this.movieRequests.push.apply(this.movieRequests, x);
|
|
||||||
this.currentlyLoaded = this.currentlyLoaded + this.amountToLoad;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
search(text: any) {
|
|
||||||
this.searchChanged.next(text.target.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
removeRequest(request: IMovieRequestModel) {
|
|
||||||
this.requestService.removeMovieRequest(request);
|
|
||||||
this.removeRequestFromUi(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
changeAvailability(request: IMovieRequestModel, available: boolean) {
|
|
||||||
request.available = available;
|
|
||||||
|
|
||||||
this.updateRequest(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
approve(request: IMovieRequestModel) {
|
|
||||||
request.approved = true;
|
|
||||||
request.denied = false;
|
|
||||||
this.updateRequest(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
deny(request: IMovieRequestModel) {
|
|
||||||
request.approved = false;
|
|
||||||
request.denied = true;
|
|
||||||
this.updateRequest(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
private updateRequest(request: IMovieRequestModel) {
|
|
||||||
this.requestService.updateRequest(request).subscribe(x => request = x);
|
|
||||||
}
|
|
||||||
|
|
||||||
private loadInit() {
|
|
||||||
this.requestService.getRequests(this.amountToLoad, 0).subscribe(x => this.movieRequests = x);
|
|
||||||
this.isAdmin = this.identityService.hasRole("Admin");
|
|
||||||
}
|
|
||||||
|
|
||||||
private resetSearch() {
|
|
||||||
this.currentlyLoaded = 5;
|
|
||||||
this.loadInit();
|
|
||||||
}
|
|
||||||
|
|
||||||
private removeRequestFromUi(key: IMovieRequestModel) {
|
|
||||||
var index = this.movieRequests.indexOf(key, 0);
|
|
||||||
if (index > -1) {
|
|
||||||
this.movieRequests.splice(index, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
178
Ombi/Ombi/wwwroot/app/requests/tvrequests.component.html
Normal file
178
Ombi/Ombi/wwwroot/app/requests/tvrequests.component.html
Normal file
|
@ -0,0 +1,178 @@
|
||||||
|
<div class="form-group">
|
||||||
|
<div>
|
||||||
|
<input type="text" class="form-control form-control-custom" placeholder="Search" (keyup)="search($event)">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
<div infinite-scroll
|
||||||
|
[infiniteScrollDistance]="1"
|
||||||
|
[infiniteScrollThrottle]="100"
|
||||||
|
(scrolled)="loadMore()">
|
||||||
|
|
||||||
|
|
||||||
|
<div *ngFor="let request of tvRequests">
|
||||||
|
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-2">
|
||||||
|
|
||||||
|
<img *ngIf="request.type == 1" class="img-responsive" src="https://image.tmdb.org/t/p/w150/{{request.posterPath}}" alt="poster">
|
||||||
|
<img *ngIf="request.type == 2" class="img-responsive" src="https://image.tmdb.org/t/p/w150/{{request.posterPath}}" alt="poster">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-5 ">
|
||||||
|
<div>
|
||||||
|
<a href="http://www.imdb.com/title/{{request.imdbId}}/" target="_blank">
|
||||||
|
<h4 class="request-title">{{request.title}} ({{request.releaseDate | date: 'yyyy'}})</h4>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<div>
|
||||||
|
<span>Status: </span>
|
||||||
|
<span class="label label-success">{{request.status}}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<span>Request status: </span>
|
||||||
|
<span *ngIf="request.available" class="label label-success">Available</span>
|
||||||
|
<span *ngIf="request.approved && !request.available" class="label label-info">Processing Request</span>
|
||||||
|
<span *ngIf="request.denied" class="label label-danger">Request Denied</span>
|
||||||
|
<span *ngIf="request.deniedReason" title="{{request.deniedReason}}"><i class="fa fa-info-circle"></i></span>
|
||||||
|
<span *ngIf="!request.approved && !request.availble && !request.denied" class="label label-warning">Pending Approval</span>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div *ngIf="request.denied">
|
||||||
|
Denied: <i style="color:red;" class="fa fa-check"></i>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div>Release Date: {{request.releaseDate | date}}</div>
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
<!--{{#if_eq type "tv"}}
|
||||||
|
{{#if episodes}}
|
||||||
|
Episodes: <span class="customTooltip" data-tooltip-content="#{{requestId}}toolTipContent"><i class="fa fa-info-circle"></i></span>
|
||||||
|
{{else}}
|
||||||
|
<div>@UI.Requests_SeasonsRequested: {{seriesRequested}}</div>
|
||||||
|
|
||||||
|
{{/if}}
|
||||||
|
{{/if_eq}}-->
|
||||||
|
<div *ngIf="request.requestedUsers">Requested By: <span *ngFor="let user of request.requestedUsers">{{user}} </span></div>
|
||||||
|
|
||||||
|
<div>Requested Date: {{request.requestedDate | date}}</div>
|
||||||
|
<!--{{#if admin}}
|
||||||
|
{{#if currentRootPath}}
|
||||||
|
<div class="{{requestId}}rootPathMain">Root Path: <span id="{{requestId}}currentRootPath">{{currentRootPath}}</span></div>
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
|
<div>
|
||||||
|
{{#if_eq issueId 0}}
|
||||||
|
@*Nothing*@
|
||||||
|
{{else}}
|
||||||
|
@UI.Issues_Issue: <a href="@formAction/issues/{{issueId}}"><i class="fa fa-check"></i></a>
|
||||||
|
{{/if_eq}}
|
||||||
|
</div>-->
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-3 col-sm-push-3">
|
||||||
|
<div *ngIf="isAdmin">
|
||||||
|
<div *ngIf="!request.approved">
|
||||||
|
<form>
|
||||||
|
<input name="requestId" type="text" value="{{request.requestId}}" hidden="hidden" />
|
||||||
|
<div *ngIf="request.hasQualities" class="btn-group btn-split">
|
||||||
|
<button type="button" (click)="approve(request)" class="btn btn-sm btn-success-outline approve"><i class="fa fa-plus"></i> Approve</button>
|
||||||
|
<button type="button" class="btn btn-success-outline dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
|
<span class="caret"></span>
|
||||||
|
<span class="sr-only">Toggle Dropdown</span>
|
||||||
|
</button>
|
||||||
|
<!--<ul class="dropdown-menu">
|
||||||
|
{{#each qualities}}
|
||||||
|
<li><a href="#" class="approve-with-quality" id="{{id}}">{{name}}</a></li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>-->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<button *ngIf="!request.hasQualities" (click)="approve(request)" style="text-align: right" class="btn btn-sm btn-success-outline approve" type="submit"><i class="fa fa-plus"></i> Approve</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!--<form method="POST" action="@formAction/requests/changeRootFolder{{#if_eq type "tv"}}tv{{else}}movie{{/if_eq}}" id="changeFolder{{requestId}}">
|
||||||
|
<input name="requestId" type="text" value="{{requestId}}" hidden="hidden"/>
|
||||||
|
{{#if_eq hasRootFolders true}}
|
||||||
|
<div class="btn-group btn-split">
|
||||||
|
<button type="button" class="btn btn-sm btn-success-outline" id="changeRootFolderBtn{{requestId}}" custom-button="{{requestId}}">@*<i class="fa fa-plus"></i>*@ Change Root Folder</button>
|
||||||
|
<button type="button" class="btn btn-success-outline dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
|
<span class="caret"></span>
|
||||||
|
<span class="sr-only">@UI.Requests_ToggleDropdown</span>
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
{{#each rootFolders}}
|
||||||
|
<li><a href="#" class="change-root-folder" id="{{id}}" requestId="{{requestId}}">{{path}}</a></li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{{/if_eq}}
|
||||||
|
</form>-->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div *ngIf="!request.denied">
|
||||||
|
<form>
|
||||||
|
<input name="requestId" type="text" value="{{request.requestId}}" hidden="hidden"/>
|
||||||
|
<input name="reason" type="text" hidden="hidden"/>
|
||||||
|
<div class="btn-group btn-split">
|
||||||
|
<button type="button" (click)="deny(request)" class="btn btn-sm btn-danger-outline deny"><i class="fa fa-times"></i> Deny</button>
|
||||||
|
<button type="button" class="btn btn-danger-outline dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
|
<span class="caret"></span>
|
||||||
|
<span class="sr-only">@UI.Requests_ToggleDropdown</span>
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
<li><a class="deny-with-reason" id="denyReason{{request.requestId}}" href="#" data-toggle="modal" data-target="#denyReasonModal">Deny with a reason</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<form>
|
||||||
|
<button (click)="removeRequest(request)" style="text-align: right" class="btn btn-sm btn-danger-outline delete"><i class="fa fa-minus"></i> Remove</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<form>
|
||||||
|
<button *ngIf="request.available" (click)="changeAvailability(request, false)" style="text-align: right" value="false" class="btn btn-sm btn-info-outline change"><i class="fa fa-minus"></i> Mark Unavailable</button>
|
||||||
|
<button *ngIf="!request.available" (click)="changeAvailability(request, true)" style="text-align: right" value="true" class="btn btn-sm btn-success-outline change"><i class="fa fa-plus"></i> Mark Available</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<input name="requestId" type="text" value="{{request.requestId}}" hidden="hidden" />
|
||||||
|
<div class="dropdown">
|
||||||
|
<button id="{{request.requestId}}" class="btn btn-sm btn-primary-outline dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
||||||
|
<i class="fa fa-plus"></i> Report Issue
|
||||||
|
<span class="caret"></span>
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
|
||||||
|
<li><a issue-select="0">@UI.Issues_WrongAudio</a></li>
|
||||||
|
<li><a issue-select="1">@UI.Issues_NoSubs</a></li>
|
||||||
|
<li><a issue-select="2">@UI.Issues_WrongContent</a></li>
|
||||||
|
<li><a issue-select="3">@UI.Issues_Playback</a></li>
|
||||||
|
<li><a issue-select="4" data-toggle="modal" data-target="#myModal">@UI.Issues_Other</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
109
Ombi/Ombi/wwwroot/app/requests/tvrequests.component.ts
Normal file
109
Ombi/Ombi/wwwroot/app/requests/tvrequests.component.ts
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { Subject } from 'rxjs/Subject';
|
||||||
|
import 'rxjs/add/operator/debounceTime';
|
||||||
|
import 'rxjs/add/operator/distinctUntilChanged';
|
||||||
|
import 'rxjs/add/operator/map';
|
||||||
|
|
||||||
|
|
||||||
|
import 'rxjs/add/operator/debounceTime';
|
||||||
|
import 'rxjs/add/operator/distinctUntilChanged';
|
||||||
|
import 'rxjs/add/operator/map';
|
||||||
|
|
||||||
|
import { RequestService } from '../services/request.service';
|
||||||
|
import { IdentityService } from '../services/identity.service';
|
||||||
|
|
||||||
|
import { ITvRequestModel } from '../interfaces/IRequestModel';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'tv-requests',
|
||||||
|
moduleId: module.id,
|
||||||
|
templateUrl: './tvrequests.component.html'
|
||||||
|
})
|
||||||
|
export class TvRequestsComponent implements OnInit {
|
||||||
|
constructor(private requestService: RequestService, private identityService: IdentityService) {
|
||||||
|
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.resetSearch();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.requestService.searchTvRequests(this.searchText).subscribe(m => this.tvRequests = m);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
tvRequests: ITvRequestModel[];
|
||||||
|
|
||||||
|
searchChanged = new Subject<string>();
|
||||||
|
searchText: string;
|
||||||
|
|
||||||
|
isAdmin : boolean;
|
||||||
|
|
||||||
|
private currentlyLoaded: number;
|
||||||
|
private amountToLoad : number;
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.amountToLoad = 5;
|
||||||
|
this.currentlyLoaded = 5;
|
||||||
|
this.loadInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
loadMore() {
|
||||||
|
this.requestService.getTvRequests(this.amountToLoad, this.currentlyLoaded + 1).subscribe(x => {
|
||||||
|
this.tvRequests.push.apply(this.tvRequests, x);
|
||||||
|
this.currentlyLoaded = this.currentlyLoaded + this.amountToLoad;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
search(text: any) {
|
||||||
|
this.searchChanged.next(text.target.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
removeRequest(request: ITvRequestModel) {
|
||||||
|
this.requestService.removeTvRequest(request);
|
||||||
|
this.removeRequestFromUi(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
changeAvailability(request: ITvRequestModel, available: boolean) {
|
||||||
|
request.available = available;
|
||||||
|
|
||||||
|
this.updateRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
approve(request: ITvRequestModel) {
|
||||||
|
request.approved = true;
|
||||||
|
request.denied = false;
|
||||||
|
this.updateRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
deny(request: ITvRequestModel) {
|
||||||
|
request.approved = false;
|
||||||
|
request.denied = true;
|
||||||
|
this.updateRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateRequest(request: ITvRequestModel) {
|
||||||
|
this.requestService.updateTvRequest(request).subscribe(x => request = x);
|
||||||
|
}
|
||||||
|
|
||||||
|
private loadInit() {
|
||||||
|
this.requestService.getTvRequests(this.amountToLoad, 0).subscribe(x => this.tvRequests = x);
|
||||||
|
this.isAdmin = this.identityService.hasRole("Admin");
|
||||||
|
}
|
||||||
|
|
||||||
|
private resetSearch() {
|
||||||
|
this.currentlyLoaded = 5;
|
||||||
|
this.loadInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
private removeRequestFromUi(key: ITvRequestModel) {
|
||||||
|
var index = this.tvRequests.indexOf(key, 0);
|
||||||
|
if (index > -1) {
|
||||||
|
this.tvRequests.splice(index, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,7 +6,7 @@ import { ServiceAuthHelpers } from './service.helpers';
|
||||||
import { IRequestEngineResult } from '../interfaces/IRequestEngineResult';
|
import { IRequestEngineResult } from '../interfaces/IRequestEngineResult';
|
||||||
import { ISearchMovieResult } from '../interfaces/ISearchMovieResult';
|
import { ISearchMovieResult } from '../interfaces/ISearchMovieResult';
|
||||||
import { ISearchTvResult } from '../interfaces/ISearchTvResult';
|
import { ISearchTvResult } from '../interfaces/ISearchTvResult';
|
||||||
import { IMovieRequestModel } from '../interfaces/IRequestModel';
|
import { IMovieRequestModel, ITvRequestModel } from '../interfaces/IRequestModel';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class RequestService extends ServiceAuthHelpers {
|
export class RequestService extends ServiceAuthHelpers {
|
||||||
|
@ -22,11 +22,11 @@ export class RequestService extends ServiceAuthHelpers {
|
||||||
return this.http.post(`${this.url}/TV/`, JSON.stringify(tv), { headers: this.headers }).map(this.extractData);
|
return this.http.post(`${this.url}/TV/`, JSON.stringify(tv), { headers: this.headers }).map(this.extractData);
|
||||||
}
|
}
|
||||||
|
|
||||||
getRequests(count: number, position: number): Observable<IMovieRequestModel[]> {
|
getMovieRequests(count: number, position: number): Observable<IMovieRequestModel[]> {
|
||||||
return this.http.get(`${this.url}/movie/${count}/${position}`).map(this.extractData);
|
return this.http.get(`${this.url}/movie/${count}/${position}`).map(this.extractData);
|
||||||
}
|
}
|
||||||
|
|
||||||
searchRequests(search: string): Observable<IMovieRequestModel[]> {
|
searchMovieRequests(search: string): Observable<IMovieRequestModel[]> {
|
||||||
return this.http.get(`${this.url}/movie/search/${search}`).map(this.extractData);
|
return this.http.get(`${this.url}/movie/search/${search}`).map(this.extractData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,23 @@ export class RequestService extends ServiceAuthHelpers {
|
||||||
this.http.delete(`${this.url}/movie/${request.id}`).map(this.extractData).subscribe();
|
this.http.delete(`${this.url}/movie/${request.id}`).map(this.extractData).subscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
updateRequest(request: IMovieRequestModel): Observable<IMovieRequestModel> {
|
updateMovieRequest(request: IMovieRequestModel): Observable<IMovieRequestModel> {
|
||||||
return this.http.post(`${this.url}/movie/`, JSON.stringify(request), { headers: this.headers }).map(this.extractData);
|
return this.http.post(`${this.url}/movie/`, JSON.stringify(request), { headers: this.headers }).map(this.extractData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getTvRequests(count: number, position: number): Observable<ITvRequestModel[]> {
|
||||||
|
return this.http.get(`${this.url}/tv/${count}/${position}`).map(this.extractData);
|
||||||
|
}
|
||||||
|
|
||||||
|
searchTvRequests(search: string): Observable<ITvRequestModel[]> {
|
||||||
|
return this.http.get(`${this.url}/tv/search/${search}`).map(this.extractData);
|
||||||
|
}
|
||||||
|
|
||||||
|
removeTvRequest(request: ITvRequestModel) {
|
||||||
|
this.http.delete(`${this.url}/tv/${request.id}`).map(this.extractData).subscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
updateTvRequest(request: ITvRequestModel): Observable<ITvRequestModel> {
|
||||||
|
return this.http.post(`${this.url}/tv/`, JSON.stringify(request), { headers: this.headers }).map(this.extractData);
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue