diff --git a/PlexRequests.Store/RequestedModel.cs b/PlexRequests.Store/RequestedModel.cs index 212f52203..1bba98a18 100644 --- a/PlexRequests.Store/RequestedModel.cs +++ b/PlexRequests.Store/RequestedModel.cs @@ -27,7 +27,7 @@ namespace PlexRequests.Store public string Status { get; set; } public bool Approved { get; set; } - [Obsolete("Use RequestedUsers")] + [Obsolete("Use RequestedUsers")] //TODO remove this obsolete property public string RequestedBy { get; set; } public DateTime RequestedDate { get; set; } @@ -44,6 +44,8 @@ namespace PlexRequests.Store public string ArtistId { get; set; } public int IssueId { get; set; } public List Episodes { get; set; } + public bool Denied { get; set; } + public string DeniedReason { get; set; } [JsonIgnore] public List AllUsers diff --git a/PlexRequests.UI/Content/requests.js b/PlexRequests.UI/Content/requests.js index 678fa60fd..4287f875e 100644 --- a/PlexRequests.UI/Content/requests.js +++ b/PlexRequests.UI/Content/requests.js @@ -373,6 +373,17 @@ $('#noteModal').on('show.bs.modal', function (event) { requestField.val(id); // Add ID to the hidden field }); +// Update deny reason modal +$('#denyReasonModal').on('show.bs.modal', function (event) { + var button = $(event.relatedTarget); // Button that triggered the modal + var id = button.data('identifier'); // Extract info from data-* attributes + + var modal = $(this); + modal.find('.denySaveReason').val(id); // Add ID to the button + var requestField = modal.find('input'); + requestField.val(id); // Add ID to the hidden field +}); + // Delete $(document).on("click", ".delete", function (e) { e.preventDefault(); @@ -403,28 +414,80 @@ $(document).on("click", ".delete", function (e) { // Approve single request $(document).on("click", ".approve", function (e) { e.preventDefault(); - var $this = $(this); - var $form = $this.parents('form').first(); + var $self = $(this); + var $form = $self.parents('form').first(); - if ($this.text() === " Loading...") { + if ($self.text() === " Loading...") { return; } - loadingButton($this.attr('id'), "success"); + loadingButton($self.attr('id'), "success"); approveRequest($form, null, function () { - $("#" + $this.attr('id') + "notapproved").prop("class", "fa fa-check"); + $("#" + $self.attr('id') + "notapproved").prop("class", "fa fa-check"); - var $group = $this.parent('.btn-split'); + var $group = $self.parent('.btn-split'); if ($group.length > 0) { $group.remove(); } else { - $this.remove(); + $self.remove(); } }); }); +// Deny single request +$(document).on("click", ".deny", function (e) { + e.preventDefault(); + var $self = $(this); + var $form = $self.parents('form').first(); + + if ($self.text() === " Loading...") { + return; + } + loadingButton($self.attr('id')+"deny", "success"); + + denyRequest($form, function () { + //$("#" + $self.attr('id') + "notapproved").prop("class", "fa fa-check"); + + var $group = $self.parent('.btn-split'); + if ($group.length > 0) { + $group.remove(); + } + else { + $self.remove(); + } + }); +}); + +// Deny single request with reason (modal) +$(document).on("click", ".denySaveReason", function (e) { + var comment = $("#denyReason").val(); + e.preventDefault(); + + var $form = $("#denyReasonForm"); + var data = $form.serialize(); + data = data + "&reason=" + comment; + + $.ajax({ + type: $form.prop("method"), + url: $form.prop("action"), + data: data, + dataType: "json", + success: function (response) { + if (checkJsonResponse(response)) { + generateNotify(response.message, "success"); + $("#denyReasonModal").modal("hide"); + } + }, + error: function (e) { + console.log(e); + generateNotify("Something went wrong!", "danger"); + } + }); +}); + + $(document).on("click", ".approve-with-quality", function (e) { e.preventDefault(); var $this = $(this); @@ -524,6 +587,35 @@ function approveRequest($form, qualityId, successCallback) { }); } +function denyRequest($form, successCallback) { + + var formData = $form.serialize(); + $.ajax({ + type: $form.prop('method'), + url: $form.prop('action'), + data: formData, + dataType: "json", + success: function (response) { + + if (checkJsonResponse(response)) { + if (response.message) { + generateNotify(response.message, "success"); + } else { + generateNotify("Success! Request Approved.", "success"); + } + + if (successCallback) { + successCallback(); + } + } + }, + error: function (e) { + console.log(e); + generateNotify("Something went wrong!", "danger"); + } + }); +} + function mixItUpConfig(activeState) { var conf = mixItUpDefault; @@ -556,6 +648,11 @@ function movieLoad() { var html = searchTemplate(context); $ml.append(html); }); + + + $('.customTooltip').tooltipster({ + contentCloning: true + }); } else { $ml.html(noResultsHtml.format("movie")); @@ -658,6 +755,8 @@ function buildRequestContext(result, type) { hasQualities: result.qualities && result.qualities.length > 0, artist: result.artistName, musicBrainzId: result.musicBrainzId, + denied: result.denied, + deniedReason: result.deniedReason, }; return context; diff --git a/PlexRequests.UI/Models/RequestViewModel.cs b/PlexRequests.UI/Models/RequestViewModel.cs index f4855106c..6d1ecb0c5 100644 --- a/PlexRequests.UI/Models/RequestViewModel.cs +++ b/PlexRequests.UI/Models/RequestViewModel.cs @@ -55,5 +55,7 @@ namespace PlexRequests.UI.Models public QualityModel[] Qualities { get; set; } public string ArtistName { get; set; } public Store.EpisodesModel[] Episodes { get; set; } + public bool Denied { get; set; } + public string DeniedReason { get; set; } } } diff --git a/PlexRequests.UI/Modules/ApprovalModule.cs b/PlexRequests.UI/Modules/ApprovalModule.cs index 9ad74aa83..478f8424c 100644 --- a/PlexRequests.UI/Modules/ApprovalModule.cs +++ b/PlexRequests.UI/Modules/ApprovalModule.cs @@ -65,6 +65,7 @@ namespace PlexRequests.UI.Modules HeadphoneApi = hpApi; Post["/approve", true] = async (x, ct) => await Approve((int)Request.Form.requestid, (string)Request.Form.qualityId); + Post["/deny", true] = async (x, ct) => await DenyRequest((int)Request.Form.requestid, (string)Request.Form.reason); Post["/approveall", true] = async (x, ct) => await ApproveAll(); Post["/approveallmovies", true] = async (x, ct) => await ApproveAllMovies(); Post["/approvealltvshows", true] = async (x, ct) => await ApproveAllTVShows(); @@ -262,7 +263,7 @@ namespace PlexRequests.UI.Modules { var requests = await Service.GetAllAsync(); - requests = requests.Where(x => x.CanApprove && x.Type == RequestType.Movie); + requests = requests.Where(x => x.CanApprove && x.Type == RequestType.Movie); var requestedModels = requests as RequestedModel[] ?? requests.ToArray(); if (!requestedModels.Any()) { @@ -491,6 +492,24 @@ namespace PlexRequests.UI.Modules } } + private async Task DenyRequest(int requestId, string reason) + { + // Get the request from the DB + var request = await Service.GetAsync(requestId); + + // Deny it + request.Denied = true; + request.DeniedReason = reason; + + // Update the new value + var result = await Service.UpdateRequestAsync(request); + + return result + ? Response.AsJson(new JsonResponseModel { Result = true, Message = "Request has been denied" }) + : Response.AsJson(new JsonResponseModel { Result = false, Message = "An error happened, could not update the DB" }); + + } + private bool SendMovie(CouchPotatoSettings settings, RequestedModel r, ICouchPotatoApi cp) { Log.Info("Adding movie to CP : {0}", r.Title); diff --git a/PlexRequests.UI/Modules/RequestsModule.cs b/PlexRequests.UI/Modules/RequestsModule.cs index 8a2a9821a..dc46b2473 100644 --- a/PlexRequests.UI/Modules/RequestsModule.cs +++ b/PlexRequests.UI/Modules/RequestsModule.cs @@ -178,6 +178,8 @@ namespace PlexRequests.UI.Modules Available = movie.Available, Admin = IsAdmin, IssueId = movie.IssueId, + Denied = movie.Denied, + DeniedReason = movie.DeniedReason, Qualities = qualities.ToArray() }).ToList(); @@ -249,6 +251,8 @@ namespace PlexRequests.UI.Modules Available = tv.Available, Admin = IsAdmin, IssueId = tv.IssueId, + Denied = tv.Denied, + DeniedReason = tv.DeniedReason, TvSeriesRequestType = tv.SeasonsRequested, Qualities = qualities.ToArray(), Episodes = tv.Episodes.ToArray(), @@ -290,6 +294,8 @@ namespace PlexRequests.UI.Modules Available = album.Available, Admin = IsAdmin, IssueId = album.IssueId, + Denied = album.Denied, + DeniedReason = album.DeniedReason, TvSeriesRequestType = album.SeasonsRequested, MusicBrainzId = album.MusicBrainzId, ArtistName = album.ArtistName diff --git a/PlexRequests.UI/Modules/UserWizardModule.cs b/PlexRequests.UI/Modules/UserWizardModule.cs index 1bfbbd679..a0a94bb4f 100644 --- a/PlexRequests.UI/Modules/UserWizardModule.cs +++ b/PlexRequests.UI/Modules/UserWizardModule.cs @@ -64,6 +64,7 @@ namespace PlexRequests.UI.Modules a.TrackEventAsync(Category.Wizard, Action.Start, "Started the wizard", Username, CookieHelper.GetAnalyticClientId(Cookies)); var settings = await PlexRequestSettings.GetSettingsAsync(); + if (settings.Wizard) { return Context.GetRedirect("~/search"); diff --git a/PlexRequests.UI/Views/Requests/Index.cshtml b/PlexRequests.UI/Views/Requests/Index.cshtml index d34c7432e..242163ed0 100644 --- a/PlexRequests.UI/Views/Requests/Index.cshtml +++ b/PlexRequests.UI/Views/Requests/Index.cshtml @@ -1,4 +1,5 @@ @using Nancy.Security +@using Nancy.Security @using PlexRequests.UI.Helpers @using PlexRequests.UI.Resources @{ @@ -136,13 +137,13 @@ {{#if episodes}}
{{#each episodes}} - Season: {{this.seasonNumber}} -
- Episodes Requested: - {{#each this.episodes}} - {{this}} - {{/each}} -
+ Season: {{this.seasonNumber}} +
+ Episodes Requested: + {{#each this.episodes}} + {{this}} + {{/each}} +
{{/each}}
{{/if}} @@ -170,12 +171,21 @@ {{status}}
+ {{#if denied}} +
+ Denied: + {{#if deniedReason}} + + {{/if}} +
+ + {{/if}} {{#if_eq releaseDate "01/01/0001 00:00:00"}}
@UI.Requests_ReleaseDate: {{releaseDate}}
{{else}}
@UI.Requests_ReleaseDate: {{releaseDate}}
{{/if_eq}} - + {{#unless denied}}
@UI.Common_Approved: {{#if_eq approved false}} @@ -185,6 +195,7 @@ {{/if_eq}}
+ {{/unless}}
@UI.Requests_Available {{#if_eq available false}} @@ -216,6 +227,7 @@
{{#if_eq admin true}} + {{#unless denied}} {{#if_eq approved false}}
@@ -236,7 +248,22 @@ {{/if_eq}}
+
+ + +
+ + + +
+
{{/if_eq}} + {{/unless}}
@@ -324,6 +351,12 @@
@UI.Requests_RequestedBy: {{requestedUsers}}
{{/if}}
@UI.Requests_RequestedDate: {{requestedDate}}
+ {{#if denied}} +
Denied:
+ {{#if deniedReason}} +
Reason: {{deniedReason}}
+ {{/if}} + {{/if}}
{{#if_eq admin true}} @@ -332,6 +365,20 @@ +
+ + +
+ + + +
+
{{/if_eq}}
@@ -393,6 +440,27 @@
+ + @Html.LoadRequestAssets()