{-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE FlexibleContexts #-} ------------------------------------------------------------------------------- -- | -- Module : Yesod.Comments.Core -- Copyright : (c) Patrick Brisbin 2010 -- License : as-is -- -- Maintainer : pbrisbin@gmail.com -- Stability : unstable -- Portability : unportable -- ------------------------------------------------------------------------------- module Yesod.Comments.Core ( Comment(..) , CommentForm(..) , CommentId , ThreadId , YesodComments (..) , commentFromForm , commentForm , commentFormAuth , commentFormEdit , handleForm , handleFormEdit , addStyling , showComment , showCommentAuth , getNextCommentId , isCommentingUser ) where import Yesod import Yesod.Auth import Yesod.Goodies.Gravatar import Yesod.Goodies.Markdown import Yesod.Goodies.Time import Control.Applicative ((<$>), (<*>)) import Data.Time (UTCTime, getCurrentTime) import Network.Wai (remoteHost) import qualified Data.Text as T type ThreadId = T.Text type CommentId = Int class Yesod m => YesodComments m where -- | Find a specific comment getComment :: ThreadId -> CommentId -> GHandler s m (Maybe Comment) -- | Store a new comment storeComment :: Comment -> GHandler s m () -- | Update a comment updateComment :: Comment -> Comment -> GHandler s m () -- | Remove a comment deleteComment :: Comment -> GHandler s m () -- | Load all comments, possibly filtered to a single thread. loadComments :: Maybe ThreadId -> GHandler s m [Comment] -- | If using Auth, provide the function to get from a user id to -- the string to use as the commenter's username. This should -- return something friendly probably pulled from the user's -- profile on your site. displayUser :: AuthId m -> GHandler s m T.Text displayUser _ = return "" -- fixme: use toSinglePiece in new auth pkg -- | If using Auth, provide the function to get from a user id to -- the string to use as the commenter's email. displayEmail :: AuthId m -> GHandler s m T.Text displayEmail _ = return "" data Comment = Comment { threadId :: ThreadId , commentId :: CommentId , timeStamp :: UTCTime , ipAddress :: T.Text , userName :: T.Text , userEmail :: T.Text , content :: Markdown , isAuth :: Bool } instance Eq Comment where a == b = (threadId a == threadId b) && (commentId a == commentId b) data CommentForm = CommentForm { formUser :: T.Text , formEmail :: T.Text , formComment :: Markdown , formIsAuth :: Bool } -- | Cleanse form input and create a 'Comment' to be stored commentFromForm :: YesodComments m => ThreadId -> CommentForm -> GHandler s m Comment commentFromForm tid cf = do now <- liftIO getCurrentTime ip <- return . show . remoteHost =<< waiRequest cid <- getNextCommentId tid return Comment { threadId = tid , commentId = cid , timeStamp = now , ipAddress = T.pack ip , userName = formUser cf , userEmail = formEmail cf , content = formComment cf , isAuth = formIsAuth cf } -- | The comment form itself commentForm :: RenderMessage m FormMessage => Html -> Form s m (FormResult CommentForm, GWidget s m ()) commentForm fragment = do (user , fiUser ) <- mreq textField "name:" Nothing (email , fiEmail ) <- mreq emailField "email:" Nothing (comment, fiComment) <- mreq markdownField "comment:" Nothing return (CommentForm <$> user <*> email <*> comment <*> FormSuccess False, [whamlet| #{fragment}