From 5c14400d48a4a3d0a2801c211a2a1b01ced377cc Mon Sep 17 00:00:00 2001 From: tmont Date: Tue, 15 Feb 2011 01:18:23 +0000 Subject: [PATCH] reporting quotes works --- Src/VideoGameQuotes.Api/Quote.cs | 10 ++- Src/VideoGameQuotes.Api/QuoteFlagType.cs | 7 +- .../Controllers/QuoteController.cs | 16 ++++ Src/VideoGameQuotes.Web/Global.asax.cs | 2 +- Src/VideoGameQuotes.Web/Models/ReportModel.cs | 11 +++ .../VideoGameQuotes.Web.csproj | 1 + Src/VideoGameQuotes.Web/media/css/quote.css | 4 + Src/VideoGameQuotes.Web/media/js/vgquotes.js | 73 ++++++++++++++++++- 8 files changed, 117 insertions(+), 7 deletions(-) create mode 100644 Src/VideoGameQuotes.Web/Models/ReportModel.cs diff --git a/Src/VideoGameQuotes.Api/Quote.cs b/Src/VideoGameQuotes.Api/Quote.cs index 2ad5976..0c81665 100644 --- a/Src/VideoGameQuotes.Api/Quote.cs +++ b/Src/VideoGameQuotes.Api/Quote.cs @@ -36,8 +36,14 @@ namespace VideoGameQuotes.Api { categories.Clear(); } - public virtual Quote AddFlag(QuoteFlag flag) { - flags.Add(flag); + public virtual Quote AddFlag(string comment, QuoteFlagType type, User user) { + flags.Add(new QuoteFlag { + Comment = comment, + Type = type, + User = user, + Quote = this + }); + return this; } diff --git a/Src/VideoGameQuotes.Api/QuoteFlagType.cs b/Src/VideoGameQuotes.Api/QuoteFlagType.cs index 56bb1fc..0358fc1 100644 --- a/Src/VideoGameQuotes.Api/QuoteFlagType.cs +++ b/Src/VideoGameQuotes.Api/QuoteFlagType.cs @@ -1,8 +1,9 @@ namespace VideoGameQuotes.Api { public enum QuoteFlagType { + Other = 0, Inaccurate = 1, - Spam = 2, - Fake = 3, - Other = 4 + Duplicate = 2, + Spam = 3, + Fake = 4 } } \ No newline at end of file diff --git a/Src/VideoGameQuotes.Web/Controllers/QuoteController.cs b/Src/VideoGameQuotes.Web/Controllers/QuoteController.cs index 9f139b2..adbdb96 100644 --- a/Src/VideoGameQuotes.Web/Controllers/QuoteController.cs +++ b/Src/VideoGameQuotes.Web/Controllers/QuoteController.cs @@ -22,6 +22,22 @@ namespace VideoGameQuotes.Web.Controllers { this.currentUserProvider = currentUserProvider; } + [HttpPost, IsValidUser] + public JsonResult Report(ReportModel model) { + if (!ModelState.IsValid) { + return Json(this.CreateJsonErrorResponse("Invalid request")); + } + + try { + var quote = quoteService.GetQuote(model.QuoteId); + quote.AddFlag(model.Comment, model.FlagType, currentUserProvider.CurrentUser); + quoteService.SaveQuote(quote); + return Json(this.CreateJsonResponse()); + } catch { + return Json(this.CreateJsonErrorResponse("Unable to create your report")); + } + } + [HttpPost, IsValidUser] public JsonResult Vote(VoteModel model) { if (!ModelState.IsValid) { diff --git a/Src/VideoGameQuotes.Web/Global.asax.cs b/Src/VideoGameQuotes.Web/Global.asax.cs index 1292ee0..0138f7a 100644 --- a/Src/VideoGameQuotes.Web/Global.asax.cs +++ b/Src/VideoGameQuotes.Web/Global.asax.cs @@ -39,7 +39,7 @@ namespace VideoGameQuotes.Web { routes.MapRoute("home", "{action}", new { controller = "Home", action = "Index" }, new { action = "about|contact" }); routes.MapRoute("best", "best/{start}-{end}/", new { controller = "Quote", action = "Best" }, new { start = @"\d+", end = @"\d+" }); - routes.MapRoute("quote", "{action}", new { controller = "Quote" }, new { action = "submit|search|recent|random|best|browse|vote" }); + routes.MapRoute("quote", "{action}", new { controller = "Quote" }, new { action = "submit|search|recent|random|best|browse|vote|report" }); routes.MapRoute("individual-quote", "quote/{id}/{*text}", new { controller = "Quote", action = "Quote" }, new { id = @"\d+" }); routes.MapRoute("create-category", "category/create", new { controller = "Quote", action = "CreateCategory" }); diff --git a/Src/VideoGameQuotes.Web/Models/ReportModel.cs b/Src/VideoGameQuotes.Web/Models/ReportModel.cs new file mode 100644 index 0000000..db2670f --- /dev/null +++ b/Src/VideoGameQuotes.Web/Models/ReportModel.cs @@ -0,0 +1,11 @@ +using Portoa.Validation.DataAnnotations; +using VideoGameQuotes.Api; + +namespace VideoGameQuotes.Web.Models { + public class ReportModel { + [GreaterThanZero] + public int QuoteId { get; set; } + public QuoteFlagType FlagType { get; set; } + public string Comment { get; set; } + } +} \ No newline at end of file diff --git a/Src/VideoGameQuotes.Web/VideoGameQuotes.Web.csproj b/Src/VideoGameQuotes.Web/VideoGameQuotes.Web.csproj index 7fe8962..4f93c51 100644 --- a/Src/VideoGameQuotes.Web/VideoGameQuotes.Web.csproj +++ b/Src/VideoGameQuotes.Web/VideoGameQuotes.Web.csproj @@ -88,6 +88,7 @@ + diff --git a/Src/VideoGameQuotes.Web/media/css/quote.css b/Src/VideoGameQuotes.Web/media/css/quote.css index 72a690d..20eaa43 100644 --- a/Src/VideoGameQuotes.Web/media/css/quote.css +++ b/Src/VideoGameQuotes.Web/media/css/quote.css @@ -32,4 +32,8 @@ .quote-report-link { float: right; +} + +.report-dialog { + width: 400px; } \ No newline at end of file diff --git a/Src/VideoGameQuotes.Web/media/js/vgquotes.js b/Src/VideoGameQuotes.Web/media/js/vgquotes.js index 7eec974..fbf1f59 100644 --- a/Src/VideoGameQuotes.Web/media/js/vgquotes.js +++ b/Src/VideoGameQuotes.Web/media/js/vgquotes.js @@ -1,5 +1,17 @@ (function($, window, undefined){ + + $.fn.center = function () { + this.css("top", ($(window).height() - this.height()) / 2 + $(window).scrollTop() + "px"); + this.css("left", ($(window).width() - this.width()) / 2 + $(window).scrollLeft() + "px"); + return this; + } + $(document).ready(function() { + var getQuoteId = function($container) { + return $container.find("input.quote-id").val(); + }; + + var voting = false; $(".vote-for, .vote-against").live("click", function() { if (voting) { @@ -11,7 +23,7 @@ var $votingLink = $(this); var $container = $votingLink.parents(".quote-container"); var direction = $votingLink.hasClass("vote-for") ? 1 : 0; - var quoteId = $container.find("input.quote-id").val(); + var quoteId = getQuoteId($container); $.ajax("/vote", { type: "POST", data: { @@ -56,5 +68,64 @@ return false; }); + + //report link + $(".quote-report-link").click(function() { + if ($(".report-dialog").length > 0) { + return false; + } + var $link = $(this); + var $container = $link.parents(".quote-container"); + var quoteId = getQuoteId($container); + + var $row = $(""); + var flagTypes = [ [1, "Inaccurate"], [2, "Duplicate"], [3, "Spam"], [4, "Fake"], [0, "Other"] ]; + for (var i = 0; i < flagTypes.length; i++) { + var html = "" + + ""; + + $row.append($(html)); + } + + var $dialog = $("
").addClass("dialog report-dialog"); + + var $submit = $("") + .attr("type", "button") + .attr("value", "Submit Report") + .click(function() { + $.ajax("/report", { + type: "POST", + data: { QuoteId: quoteId, Comment: $dialog.find("textarea").val(), FlagType: $dialog.find("input[name='flagType']:checked").val() }, + complete: function() { $dialog.remove(); }, + success: function(data, status, $xhr) { + if (data.Error !== null) { + alert(data.Error); + return; + } + } + }); + }); + + var $cancel = $("") + .attr("type", "button") + .attr("value", "Cancel") + .click(function() { $dialog.remove(); }); + + $dialog + .append($("

").text("Flag as:")) + .append($("").append($row)) + .append($("

").text("Comment")) + .append($("