-
+
@@ -171,7 +161,7 @@
-
+
@@ -218,7 +210,7 @@
-
+
diff --git a/src/Ombi/ClientApp/app/requests/movierequests.component.ts b/src/Ombi/ClientApp/app/requests/movierequests.component.ts
index fe6f3b73f..0848daf53 100644
--- a/src/Ombi/ClientApp/app/requests/movierequests.component.ts
+++ b/src/Ombi/ClientApp/app/requests/movierequests.component.ts
@@ -9,7 +9,7 @@ import { Subject } from "rxjs/Subject";
import { AuthService } from "../auth/auth.service";
import { NotificationService, RadarrService, RequestService } from "../services";
-import { FilterType, IFilter, IIssueCategory, IMovieRequests, IPagenator, IRadarrProfile, IRadarrRootFolder } from "../interfaces";
+import { FilterType, IFilter, IIssueCategory, IMovieRequests, IPagenator, IRadarrProfile, IRadarrRootFolder, OrderType } from "../interfaces";
@Component({
selector: "movie-requests",
@@ -38,9 +38,9 @@ export class MovieRequestsComponent implements OnInit {
public filter: IFilter;
public filterType = FilterType;
- public order: string = "requestedDate";
- public reverse = true;
-
+ public orderType: OrderType = OrderType.RequestedDateDesc;
+ public OrderType = OrderType;
+
public totalMovies: number = 100;
private currentlyLoaded: number;
private amountToLoad: number;
@@ -75,20 +75,17 @@ export class MovieRequestsComponent implements OnInit {
public ngOnInit() {
this.amountToLoad = 10;
- this.currentlyLoaded = 10;
- this.loadInit();
- this.isAdmin = this.auth.hasRole("admin") || this.auth.hasRole("poweruser");
+ this.currentlyLoaded = 10;
this.filter = {
availabilityFilter: FilterType.None,
statusFilter: FilterType.None,
- count: this.amountToLoad,
- position: 0,
};
+ this.loadInit();
+ this.isAdmin = this.auth.hasRole("admin") || this.auth.hasRole("poweruser");
}
public paginate(event: IPagenator) {
- const skipAmount = event.first;
-
+ const skipAmount = event.first;
this.loadRequests(this.amountToLoad, skipAmount);
}
@@ -99,7 +96,7 @@ export class MovieRequestsComponent implements OnInit {
public removeRequest(request: IMovieRequests) {
this.requestService.removeMovieRequest(request);
this.removeRequestFromUi(request);
- this.loadRequests(1, this.currentlyLoaded);
+ this.loadRequests(this.amountToLoad, this.currentlyLoaded = 0);
}
public changeAvailability(request: IMovieRequests, available: boolean) {
@@ -183,38 +180,27 @@ export class MovieRequestsComponent implements OnInit {
public filterAvailability(filter: FilterType, el: any) {
this.filterActiveStyle(el);
this.filter.availabilityFilter = filter;
- this.requestService.filterMovies(this.filter)
- .subscribe(x => {
- this.totalMovies = x.total;
- this.setOverrides(x.collection);
- this.movieRequests = x.collection;
- });
+ this.loadInit();
}
public filterStatus(filter: FilterType, el: any) {
this.filterActiveStyle(el);
this.filter.statusFilter = filter;
- this.requestService.filterMovies(this.filter)
- .subscribe(x => {
- this.totalMovies = x.total;
- this.setOverrides(x.collection);
- this.movieRequests = x.collection;
- });
+ this.loadInit();
}
- public setOrder(value: string, el: any) {
+ public setOrder(value: OrderType, el: any) {
el = el.toElement || el.relatedTarget || el.target || el.srcElement;
const parent = el.parentElement;
const previousFilter = parent.querySelector(".active");
- if (this.order === value) {
- this.reverse = !this.reverse;
- } else {
- previousFilter.className = "";
- el.className = "active";
- }
- this.order = value;
+ previousFilter.className = "";
+ el.className = "active";
+
+ this.orderType = value;
+
+ this.loadInit();
}
public subscribe(request: IMovieRequests) {
@@ -252,26 +238,16 @@ export class MovieRequestsComponent implements OnInit {
}
private loadRequests(amountToLoad: number, currentlyLoaded: number) {
- if(this.filter.availabilityFilter === FilterType.None && this.filter.statusFilter === FilterType.None) {
- this.requestService.getMovieRequests(amountToLoad, currentlyLoaded + 1)
+ this.requestService.getMovieRequests(amountToLoad, currentlyLoaded, this.orderType, this.filter)
.subscribe(x => {
- this.setOverrides(x);
+ this.setOverrides(x.collection);
if(!this.movieRequests) {
this.movieRequests = [];
}
- this.movieRequests = x;
+ this.movieRequests = x.collection;
+ this.totalMovies = x.total;
this.currentlyLoaded = currentlyLoaded + amountToLoad;
});
- } else {
- this.filter.position = currentlyLoaded;
- this.requestService.filterMovies(this.filter)
- .subscribe(x => {
- this.setOverrides(x.collection);
- this.totalMovies = x.total;
- this.movieRequests = x.collection;
- this.currentlyLoaded = currentlyLoaded + amountToLoad;
- });
- }
}
private updateRequest(request: IMovieRequests) {
@@ -310,23 +286,25 @@ export class MovieRequestsComponent implements OnInit {
}
private loadInit() {
- this.requestService.getTotalMovies().subscribe(x => this.totalMovies = x);
- this.requestService.getMovieRequests(this.amountToLoad, 0)
+ this.requestService.getMovieRequests(this.amountToLoad, 0, this.orderType, this.filter)
.subscribe(x => {
- this.movieRequests = x;
+ this.movieRequests = x.collection;
+ this.totalMovies = x.total;
this.movieRequests.forEach((req) => {
- this.setBackground(req);
- this.setPoster(req);
- });
- this.radarrService.getQualityProfilesFromSettings().subscribe(c => {
- this.radarrProfiles = c;
- this.movieRequests.forEach((req) => this.setQualityOverrides(req));
- });
- this.radarrService.getRootFoldersFromSettings().subscribe(c => {
- this.radarrRootFolders = c;
- this.movieRequests.forEach((req) => this.setRootFolderOverrides(req));
+ this.setBackground(req);
+ this.setPoster(req);
});
+ if (this.isAdmin) {
+ this.radarrService.getQualityProfilesFromSettings().subscribe(c => {
+ this.radarrProfiles = c;
+ this.movieRequests.forEach((req) => this.setQualityOverrides(req));
+ });
+ this.radarrService.getRootFoldersFromSettings().subscribe(c => {
+ this.radarrRootFolders = c;
+ this.movieRequests.forEach((req) => this.setRootFolderOverrides(req));
+ });
+ }
});
}
diff --git a/src/Ombi/ClientApp/app/requests/tvrequests.component.ts b/src/Ombi/ClientApp/app/requests/tvrequests.component.ts
index 10b1b750e..202b6dbf6 100644
--- a/src/Ombi/ClientApp/app/requests/tvrequests.component.ts
+++ b/src/Ombi/ClientApp/app/requests/tvrequests.component.ts
@@ -240,8 +240,10 @@ export class TvRequestsComponent implements OnInit {
("url(https://image.tmdb.org/t/p/w1280" + val.data.background + ")");
} else {
this.imageService.getTvBanner(val.data.tvDbId).subscribe(x => {
- val.data.background = this.sanitizer.bypassSecurityTrustStyle
+ if(x) {
+ val.data.background = this.sanitizer.bypassSecurityTrustStyle
("url(" + x + ")");
+ }
});
}
}
diff --git a/src/Ombi/ClientApp/app/search/moviesearch.component.html b/src/Ombi/ClientApp/app/search/moviesearch.component.html
index a2b59df79..44dc345bc 100644
--- a/src/Ombi/ClientApp/app/search/moviesearch.component.html
+++ b/src/Ombi/ClientApp/app/search/moviesearch.component.html
@@ -65,7 +65,13 @@
-
+
diff --git a/src/Ombi/ClientApp/app/search/moviesearch.component.ts b/src/Ombi/ClientApp/app/search/moviesearch.component.ts
index c8c7514a7..ff570441a 100644
--- a/src/Ombi/ClientApp/app/search/moviesearch.component.ts
+++ b/src/Ombi/ClientApp/app/search/moviesearch.component.ts
@@ -79,6 +79,7 @@ export class MovieSearchComponent implements OnInit {
public request(searchResult: ISearchMovieResult) {
searchResult.requested = true;
searchResult.requestProcessing = true;
+ searchResult.showSubscribe = false;
if (this.authService.hasRole("admin") || this.authService.hasRole("AutoApproveMovie")) {
searchResult.approved = true;
}
@@ -103,6 +104,7 @@ export class MovieSearchComponent implements OnInit {
searchResult.approved = false;
searchResult.processed = false;
searchResult.requestProcessing = false;
+
}
});
} catch (e) {
@@ -162,6 +164,22 @@ export class MovieSearchComponent implements OnInit {
this.getExtraInfo();
});
}
+
+ public subscribe(r: ISearchMovieResult) {
+ r.subscribed = true;
+ this.requestService.subscribeToMovie(r.requestId)
+ .subscribe(x => {
+ this.notificationService.success("Subscribed To Movie!");
+ });
+ }
+
+ public unSubscribe(r: ISearchMovieResult) {
+ r.subscribed = false;
+ this.requestService.unSubscribeToMovie(r.requestId)
+ .subscribe(x => {
+ this.notificationService.success("Unsubscribed Movie!");
+ });
+ }
private getExtraInfo() {
diff --git a/src/Ombi/ClientApp/app/search/search.module.ts b/src/Ombi/ClientApp/app/search/search.module.ts
index 1b7f1310f..d5b8669ef 100644
--- a/src/Ombi/ClientApp/app/search/search.module.ts
+++ b/src/Ombi/ClientApp/app/search/search.module.ts
@@ -11,7 +11,7 @@ import { SearchComponent } from "./search.component";
import { SeriesInformationComponent } from "./seriesinformation.component";
import { TvSearchComponent } from "./tvsearch.component";
-import { SidebarModule, TreeTableModule } from "primeng/primeng";
+import { SidebarModule, TooltipModule, TreeTableModule } from "primeng/primeng";
import { RequestService } from "../services";
import { SearchService } from "../services";
@@ -33,6 +33,7 @@ const routes: Routes = [
TreeTableModule,
SharedModule,
SidebarModule,
+ TooltipModule,
],
declarations: [
SearchComponent,
diff --git a/src/Ombi/ClientApp/app/search/seriesinformation.component.ts b/src/Ombi/ClientApp/app/search/seriesinformation.component.ts
index c4a50ae38..f2eef3d57 100644
--- a/src/Ombi/ClientApp/app/search/seriesinformation.component.ts
+++ b/src/Ombi/ClientApp/app/search/seriesinformation.component.ts
@@ -52,7 +52,7 @@ export class SeriesInformationComponent implements OnInit {
const seasonsViewModel =
{seasonNumber: season.seasonNumber, episodes: []};
season.episodes.forEach(ep => {
if(!this.series.latestSeason || !this.series.requestAll || !this.series.firstSeason) {
- if(ep.requested) {
+ if(ep.selected) {
seasonsViewModel.episodes.push({episodeNumber: ep.episodeNumber});
}
}
diff --git a/src/Ombi/ClientApp/app/search/tvsearch.component.ts b/src/Ombi/ClientApp/app/search/tvsearch.component.ts
index cdb3e1c6e..8db75125c 100644
--- a/src/Ombi/ClientApp/app/search/tvsearch.component.ts
+++ b/src/Ombi/ClientApp/app/search/tvsearch.component.ts
@@ -138,9 +138,11 @@ export class TvSearchComponent implements OnInit {
public getExtraInfo() {
this.tvResults.forEach((val, index) => {
this.imageService.getTvBanner(val.data.id).subscribe(x => {
- val.data.background = this.sanitizer.
- bypassSecurityTrustStyle
- ("url(" + x + ")");
+ if(x) {
+ val.data.background = this.sanitizer.
+ bypassSecurityTrustStyle
+ ("url(" + x + ")");
+ }
});
this.searchService.getShowInformationTreeNode(val.data.id)
.subscribe(x => {
diff --git a/src/Ombi/ClientApp/app/services/request.service.ts b/src/Ombi/ClientApp/app/services/request.service.ts
index 2da0c1a8a..e52ab3057 100644
--- a/src/Ombi/ClientApp/app/services/request.service.ts
+++ b/src/Ombi/ClientApp/app/services/request.service.ts
@@ -6,7 +6,7 @@ import { Observable } from "rxjs/Rx";
import { TreeNode } from "primeng/primeng";
import { IRequestEngineResult } from "../interfaces";
-import { IChildRequests, IFilter, IFilterResult, IMovieRequestModel, IMovieRequests, IMovieUpdateModel, ITvRequests,ITvUpdateModel } from "../interfaces";
+import { IChildRequests, IFilter, IMovieRequestModel, IMovieRequests, IMovieUpdateModel, IRequestsViewModel, ITvRequests,ITvUpdateModel, OrderType } from "../interfaces";
import { ITvRequestViewModel } from "../interfaces";
import { ServiceHelpers } from "./service.helpers";
@@ -48,8 +48,8 @@ export class RequestService extends ServiceHelpers {
return this.http.post(`${this.url}Movie/unavailable`, JSON.stringify(movie), {headers: this.headers});
}
- public getMovieRequests(count: number, position: number): Observable {
- return this.http.get(`${this.url}movie/${count}/${position}`, {headers: this.headers});
+ public getMovieRequests(count: number, position: number, order: OrderType, filter: IFilter): Observable> {
+ return this.http.get>(`${this.url}movie/${count}/${position}/${order}/${filter.statusFilter}/${filter.availabilityFilter}`, {headers: this.headers});
}
public searchMovieRequests(search: string): Observable {
@@ -114,10 +114,7 @@ export class RequestService extends ServiceHelpers {
public deleteChild(child: IChildRequests): Observable {
return this.http.delete(`${this.url}tv/child/${child.id}`, {headers: this.headers});
}
- public filterMovies(filter: IFilter): Observable> {
- return this.http.post>(`${this.url}movie/filter`, JSON.stringify(filter), {headers: this.headers});
- }
-
+
public subscribeToMovie(requestId: number): Observable {
return this.http.post(`${this.url}movie/subscribe/${requestId}`, {headers: this.headers});
}
diff --git a/src/Ombi/ClientApp/app/settings/notifications/mattermost.component.ts b/src/Ombi/ClientApp/app/settings/notifications/mattermost.component.ts
index b512d6a86..cb0bf81c0 100644
--- a/src/Ombi/ClientApp/app/settings/notifications/mattermost.component.ts
+++ b/src/Ombi/ClientApp/app/settings/notifications/mattermost.component.ts
@@ -62,7 +62,7 @@ export class MattermostComponent implements OnInit {
this.testerService.mattermostTest(form.value).subscribe(x => {
if (x) {
- this.notificationService.success( "Successfully sent a Mattermost message, please check the discord channel");
+ this.notificationService.success( "Successfully sent a Mattermost message, please check the appropriate channel");
} else {
this.notificationService.error("There was an error when sending the Mattermost message. Please check your settings");
}
diff --git a/src/Ombi/ClientApp/app/settings/notifications/mobile.component.html b/src/Ombi/ClientApp/app/settings/notifications/mobile.component.html
index 3aad31ff8..5c82e03d5 100644
--- a/src/Ombi/ClientApp/app/settings/notifications/mobile.component.html
+++ b/src/Ombi/ClientApp/app/settings/notifications/mobile.component.html
@@ -39,7 +39,7 @@
diff --git a/src/Ombi/ClientApp/app/settings/notifications/mobile.component.ts b/src/Ombi/ClientApp/app/settings/notifications/mobile.component.ts
index b40b4aa94..61a0253c8 100644
--- a/src/Ombi/ClientApp/app/settings/notifications/mobile.component.ts
+++ b/src/Ombi/ClientApp/app/settings/notifications/mobile.component.ts
@@ -34,7 +34,7 @@ export class MobileComponent implements OnInit {
this.mobileService.getUserDeviceList().subscribe(x => {
if(x.length <= 0) {
this.userList = [];
- this.userList.push({username:"None",devices:0});
+ this.userList.push({username:"None",devices:0, userId:""});
} else {
this.userList = x;
}
diff --git a/src/Ombi/Controllers/ImagesController.cs b/src/Ombi/Controllers/ImagesController.cs
index 692966258..69ec9e328 100644
--- a/src/Ombi/Controllers/ImagesController.cs
+++ b/src/Ombi/Controllers/ImagesController.cs
@@ -35,6 +35,10 @@ namespace Ombi.Controllers
[HttpGet("tv/{tvdbid}")]
public async Task
GetTvBanner(int tvdbid)
{
+ if (tvdbid <= 0)
+ {
+ return string.Empty;
+ }
var key = await _cache.GetOrAdd(CacheKeys.FanartTv, async () => await Config.Get(Store.Entities.ConfigurationTypes.FanartTv), DateTime.Now.AddDays(1));
var images = await FanartTvApi.GetTvImages(tvdbid, key.Value);
@@ -90,6 +94,10 @@ namespace Ombi.Controllers
[HttpGet("poster/tv/{tvdbid}")]
public async Task GetTvPoster(int tvdbid)
{
+ if (tvdbid <= 0)
+ {
+ return string.Empty;
+ }
var key = await _cache.GetOrAdd(CacheKeys.FanartTv, async () => await Config.Get(Store.Entities.ConfigurationTypes.FanartTv), DateTime.Now.AddDays(1));
var images = await FanartTvApi.GetTvImages(tvdbid, key.Value);
@@ -145,6 +153,10 @@ namespace Ombi.Controllers
[HttpGet("background/tv/{tvdbid}")]
public async Task GetTvBackground(int tvdbid)
{
+ if (tvdbid <= 0)
+ {
+ return string.Empty;
+ }
var key = await _cache.GetOrAdd(CacheKeys.FanartTv, async () => await Config.Get(Store.Entities.ConfigurationTypes.FanartTv), DateTime.Now.AddDays(1));
var images = await FanartTvApi.GetTvImages(tvdbid, key.Value);
diff --git a/src/Ombi/Controllers/IssuesController.cs b/src/Ombi/Controllers/IssuesController.cs
index 507c04f78..7984785d4 100644
--- a/src/Ombi/Controllers/IssuesController.cs
+++ b/src/Ombi/Controllers/IssuesController.cs
@@ -133,7 +133,11 @@ namespace Ombi.Controllers
i.IssueCategory = null;
i.UserReportedId = (await _userManager.Users.FirstOrDefaultAsync(x => x.UserName == User.Identity.Name)).Id;
await _issues.Add(i);
-
+ var category = await _categories.GetAll().FirstOrDefaultAsync(x => i.IssueCategoryId == x.Id);
+ if (category != null)
+ {
+ i.IssueCategory = category;
+ }
var notificationModel = new NotificationOptions
{
RequestId = i.RequestId ?? 0,
@@ -142,7 +146,7 @@ namespace Ombi.Controllers
RequestType = i.RequestType,
Recipient = string.Empty,
AdditionalInformation = $"{i.Subject} | {i.Description}",
- UserId = i.UserReportedId
+ UserId = i.UserReportedId,
};
AddIssueNotificationSubstitutes(notificationModel, i, User.Identity.Name);
@@ -195,7 +199,7 @@ namespace Ombi.Controllers
{
var user = await _userManager.Users.Where(x => User.Identity.Name == x.UserName)
.FirstOrDefaultAsync();
- var issue = await _issues.GetAll().Include(x => x.UserReported).FirstOrDefaultAsync(x => x.Id == comment.IssueId);
+ var issue = await _issues.GetAll().Include(x => x.UserReported).Include(x => x.IssueCategory).FirstOrDefaultAsync(x => x.Id == comment.IssueId);
if (issue == null)
{
return null;
@@ -242,7 +246,7 @@ namespace Ombi.Controllers
{
var user = await _userManager.Users.Where(x => User.Identity.Name == x.UserName)
.FirstOrDefaultAsync();
- var issue = await _issues.GetAll().Include(x => x.UserReported).FirstOrDefaultAsync(x => x.Id == model.IssueId);
+ var issue = await _issues.GetAll().Include(x => x.UserReported).Include(x => x.IssueCategory).FirstOrDefaultAsync(x => x.Id == model.IssueId);
if (issue == null)
{
return false;
diff --git a/src/Ombi/Controllers/MobileController.cs b/src/Ombi/Controllers/MobileController.cs
index 95703351c..70a6f1053 100644
--- a/src/Ombi/Controllers/MobileController.cs
+++ b/src/Ombi/Controllers/MobileController.cs
@@ -68,6 +68,7 @@ namespace Ombi.Controllers
{
vm.Add(new MobileUsersViewModel
{
+ UserId = u.Id,
Username = u.UserAlias,
Devices = u.NotificationUserIds.Count
});
diff --git a/src/Ombi/Controllers/RequestController.cs b/src/Ombi/Controllers/RequestController.cs
index 0a56c32b6..47329a0ec 100644
--- a/src/Ombi/Controllers/RequestController.cs
+++ b/src/Ombi/Controllers/RequestController.cs
@@ -8,6 +8,7 @@ using System.Collections.Generic;
using System.Threading.Tasks;
using Ombi.Store.Entities.Requests;
using System.Diagnostics;
+using Ombi.Core.Models.UI;
using Ombi.Models;
using Ombi.Store.Entities;
@@ -32,10 +33,18 @@ namespace Ombi.Controllers
///
/// The count of items you want to return.
/// The position.
- [HttpGet("movie/{count:int}/{position:int}")]
- public async Task> GetRequests(int count, int position)
+ /// The way we want to order.
+ ///
+ ///
+ [HttpGet("movie/{count:int}/{position:int}/{orderType:int}/{statusType:int}/{availabilityType:int}")]
+ public async Task> GetRequests(int count, int position, int orderType, int statusType, int availabilityType)
{
- return await MovieRequestEngine.GetRequests(count, position);
+ return await MovieRequestEngine.GetRequests(count, position, new OrderFilterModel
+ {
+ OrderType = (OrderType)orderType,
+ AvailabilityFilter = (FilterType)availabilityType,
+ StatusFilter = (FilterType)statusType,
+ });
}
///
@@ -170,11 +179,19 @@ namespace Ombi.Controllers
///
/// The count of items you want to return.
/// The position.
+ ///
+ ///
+ ///
///
- [HttpGet("tv/{count:int}/{position:int}")]
- public async Task> GetTvRequests(int count, int position)
+ [HttpGet("tv/{count:int}/{position:int}/{orderType:int}/{statusFilterType:int}/{availabilityFilterType:int}")]
+ public async Task> GetTvRequests(int count, int position, int orderType, int statusType, int availabilityType)
{
- return await TvRequestEngine.GetRequests(count, position);
+ return await TvRequestEngine.GetRequests(count, position, new OrderFilterModel
+ {
+ OrderType = (OrderType)orderType,
+ AvailabilityFilter = (FilterType) availabilityType,
+ StatusFilter = (FilterType) statusType,
+ });
}
///
@@ -347,17 +364,6 @@ namespace Ombi.Controllers
return movies || tv;
}
- ///
- /// Returns a filtered list
- ///
- ///
- ///
- [HttpPost("movie/filter")]
- public async Task> Filter([FromBody] FilterViewModel vm)
- {
- return await MovieRequestEngine.Filter(vm);
- }
-
///
/// Subscribes for notifications to a movie request
///
diff --git a/src/Ombi/Models/MobileUsersViewModel.cs b/src/Ombi/Models/MobileUsersViewModel.cs
index e7d99569f..d10ed68bc 100644
--- a/src/Ombi/Models/MobileUsersViewModel.cs
+++ b/src/Ombi/Models/MobileUsersViewModel.cs
@@ -2,6 +2,7 @@
{
public class MobileUsersViewModel
{
+ public string UserId { get; set; }
public string Username { get; set; }
public int Devices { get; set; }
}
diff --git a/src/Ombi/wwwroot/translations/en.json b/src/Ombi/wwwroot/translations/en.json
index cb7c0fe8b..289db8be5 100644
--- a/src/Ombi/wwwroot/translations/en.json
+++ b/src/Ombi/wwwroot/translations/en.json
@@ -138,10 +138,12 @@
"Filter":"Filter",
"Sort":"Sort",
"SeasonNumberHeading":"Season: {seasonNumber}",
- "SortTitle":"Title",
- "SortRequestDate": "Request Date",
- "SortRequestedBy":"Requested By",
- "SortStatus":"Status"
+ "SortTitleAsc":"Title ▲",
+ "SortTitleDesc":"Title ▼",
+ "SortRequestDateAsc": "Request Date ▲",
+ "SortRequestDateDesc": "Request Date ▼",
+ "SortStatusAsc":"Status ▲",
+ "SortStatusDesc":"Status ▼"
},
"Issues":{
"Title":"Issues",