Commits

Luke Plant committed a4b80a5

Added showing of comment responses, and AJAX method for adding them

Comments (0)

Files changed (7)

src/Blog/Model.hs

                   , setPassword
                   , checkPassword
                   , setCommentVisible
+                  , setCommentResponse
                   ) where
 
 import Data.Digest.Pure.SHA (showDigest, sha1)
 setPasswordForUsernameQuery = "UPDATE users SET password = ? WHERE username = ?;"
 
 setCommentHiddenQuery      = "UPDATE comments SET hidden = ? WHERE id = ?;"
+setCommentResponseQuery    = "UPDATE comments SET response = ? WHERE id = ?;"
 
 ---- Constructors ----
 
                                                          , toSql commentId ]
                        )
     return ()
+
+setCommentResponse :: (IConnection conn) =>
+                      conn -> Int -> String -> IO ()
+setCommentResponse cn commentId response = do
+  withTransaction cn (\cn ->
+                          run cn setCommentResponseQuery [ toSql response
+                                                         , toSql commentId
+                                                         ]
+                     )
+  return ()

src/Blog/Routes.hs

          , "admin/post/new/" <+/> empty               //-> adminNewPost           $ [adminRequired]
          , "admin/post/edit/" <+/> anyParam           //-> adminEditPost          $ [adminRequired]
          , "admin/ajax/commentvisible/" <+/> empty    //-> adminCommentVisible    $ [adminRequired]
+         , "admin/ajax/commentresponse/" <+/> empty   //-> adminCommentResponse   $ [adminRequired]
          , "debug/" <+/> anyParam                     //-> debug                  $ []
          ]

src/Blog/Templates.hs

                                       , ("email", ToSElemD $ Cm.email cm)
                                       , ("uid", ToSElemD $ Cm.uid cm)
                                       , ("hidden", ToSElemD $ Cm.hidden cm)
+                                      , ("response", ToSElemD $ emptyToNothing $ Cm.response cm)
                                       ]
+
+emptyToNothing s = if null s then Nothing else Just s

src/Blog/Views.hs

 -- which has pure functions that generally return Html.
 
 import Blog.DB (connect)
+import Blog.Formats (Format(..), getFormatter)
 import Blog.Forms
 import Blog.Globals (mkCsrfField)
 import Blog.Links
 -- Admin AJAX
 
 -- TODO - proper JSON objects
-success = buildResponse [ addContent $ utf8 "success" ] utf8TextResponse
-failure = buildResponse [ addContent $ utf8 "failure" ] utf8TextResponse
+simpleMessage msg = buildResponse [ addContent $ utf8 msg ] utf8TextResponse
+success = simpleMessage "success"
+failure = simpleMessage "failure"
 
 adminCommentVisible req = do
+  let visible   = getPOST req "visible" `captureOrDefault` False
+  withValidComment req (\cn commentId -> setCommentVisible cn commentId visible)
+
+adminCommentResponse req = do
+  let response  = getPOST req "response" `captureOrDefault` "" :: String
+  let formattedResponse = getFormatter Plaintext $ response
+  withValidComment req (\cn commentId -> setCommentResponse cn commentId formattedResponse)
+  return $ Just $ simpleMessage formattedResponse
+  -- TODO - proper error handling
+
+-- Utility that pulls out common functionality of adminComment*
+withValidComment req action = do
   let commentId = getPOST req "id" `captureOrDefault` 0 :: Int
-  let visible   = getPOST req "visible" `captureOrDefault` False
   if commentId <= 0
-    then  return $ Just $ failure
-    else do
-      cn <- connect
-      setCommentVisible cn commentId visible
-      return $ Just $ success
+     then return $ Just $ failure
+     else do
+       cn <- connect
+       action cn commentId
+       return $ Just success
+
 
 createLoginCookies loginData timestamp =
   let username = fromJust $ Map.lookup "username" loginData

src/templates/comment.st

       <span class="commentid">$comment.uid$</span>
          $comment.textFormatted:noescape()$
       </div>
+      <div class="response">
+        $if(comment.response)$
+        <div class="responseinner">$comment.response$ <span class="responsename">— luke</span> </div>
+        $endif$
+      </div>
       <div class="commentControls">
         <a id="hidecomment$comment.uid$" href="#" $if(comment.hidden)$style="display:none;"$endif$>Hide</a>
         <a id="showcomment$comment.uid$" href="#" $if(!comment.hidden)$style="display:none;"$endif$>Show</a>

src/templates/pageend.st

           </ul>
         </div>
       </div>
+      <div id="loginlinks">
+        <a href="/blog/login/">Login</a><br/>
+        <a href="/blog/logout/">Logout</a><br/>
+      </div>
+      <div id="responsebox" style="display:none";>
+        <ul>
+          <li>Didn't read the post</li>
+          <li>Troll!</li>
+          <li>Off-topic</li>
+          <li>Already answered in comments</li>
+        </ul>
+        Custom: <input type="text" id="responseinput" size=50> <input type="submit" id="responsesubmit" value="Send"> <input type="submit" id="responsecancel" value="Cancel">
+        <input type="hidden" id="responsecommentid" value="">
+      </div>
     </div>
   </body>
 </html>

src/templates/pagestart.st

 }
 
 function respondToComment(cid, event) {
-
+    \$("#responsecommentid").val(cid.toString());
+    var p = \$("#respondtocomment" + cid.toString()).offset();
+    \$("#responseinput").val("");
+    \$("#responsebox").css('left', p.left).css('top', p.top + 15).show();
 }
 
 function deleteComment(cid, event) {
                                                               });
     });
     \$(".commentControls").show();
+    \$("#responsebox li").each(function() {
+                    var self = \$(this);
+                    self.click(function(ev) {
+                       \$("#responseinput").val(self.text());
+                       \$("#responsesubmit").click();
+                    })
+    });
+    \$("#responsesubmit").click(function(ev) {
+                    var cid = \$("#responsecommentid").val();
+                    \$.post("/blog/admin/ajax/commentresponse/",
+                      { id: cid,
+                        response: \$("#responseinput").val()
+                      },
+                      function(data) {
+                         // rather fragile way of find .response div...
+                         \$("#comment" + cid).parent().parent().find(".response").html('<div class="responseinner">' + data + ' <span class="responsename">— luke</span></div>');
+                      }
+                    )
+                    \$("#responsebox").hide();
+                    });
+
+    \$("#responsecancel").click(function(ev) {
+                    \$("#responsebox").hide();
+                    });
+
+
 }
 
 \$(document).ready(function() {