-- | Contains comment-related actions, like editing comments -- and performing moderator actions on posts. module Reddit.Actions.Comment ( getNewComments , getNewComments' , getMoreChildren , getCommentInfo , getCommentsInfo , editComment , deleteComment , removeComment ) where import Reddit.Types.Comment import Reddit.Types.Empty import Reddit.Types.Error import Reddit.Types.Listing import Reddit.Types.Options import Reddit.Types.Post import Reddit.Types.Reddit import Reddit.Types.Subreddit import qualified Reddit.Routes as Route import Data.Default.Class import Data.Text (Text) import Network.API.Builder (APIError(..)) -- | Get a 'CommentListing' for the most recent comments on the site overall. -- This maps to , or -- if the subreddit is not specified. -- Note that none of the comments returned will have any child comments. getNewComments :: Monad m => Maybe SubredditName -> RedditT m CommentListing getNewComments = getNewComments' def -- | Get a 'CommentListing' for the most recent comments with the specified 'Options' and -- 'SubredditName'. Note that none of the comments returned will have any child comments. -- If the 'Options' is 'def', then this function is identical to 'getNewComments'. getNewComments' :: Monad m => Options CommentID -> Maybe SubredditName -> RedditT m CommentListing getNewComments' opts r = runRoute $ Route.newComments opts r -- | Expand children comments that weren't fetched on initial load. -- Equivalent to the web UI's "load more comments" button. getMoreChildren :: Monad m => PostID -- ^ @PostID@ for the top-level -> [CommentID] -- ^ List of @CommentID@s to expand -> RedditT m [CommentReference] getMoreChildren _ [] = return [] getMoreChildren p cs = do let (now, next) = splitAt 20 cs POSTWrapped rs <- runRoute $ Route.moreChildren p now more <- getMoreChildren p next return $ rs ++ more -- | Given a 'CommentID', 'getCommentInfo' will return the full details for that comment. getCommentInfo :: Monad m => CommentID -> RedditT m Comment getCommentInfo c = do res <- getCommentsInfo [c] case res of Listing _ _ [comment] -> return comment _ -> failWith $ APIError InvalidResponseError -- | Given a list of 'CommentID's, 'getCommentsInfo' will return another list containing -- the full details for all the comments. Note that Reddit's -- API imposes a limitation of 100 comments per request, so this function will fail immediately if given a list of more than 100 IDs. getCommentsInfo :: Monad m => [CommentID] -> RedditT m CommentListing getCommentsInfo cs = if null $ drop 100 cs then do res <- runRoute $ Route.commentsInfo cs case res of Listing _ _ comments | sameLength comments cs -> return res _ -> failWith $ APIError InvalidResponseError else failWith $ APIError TooManyRequests where sameLength (_:xs) (_:ys) = sameLength xs ys sameLength [] [] = True sameLength _ _ = False -- | Edit a comment. editComment :: Monad m => CommentID -- ^ Comment to edit -> Text -- ^ New comment text -> RedditT m Comment editComment thing text = do POSTWrapped res <- runRoute $ Route.edit thing text return res -- | Deletes one of your own comments. Note that this is different from -- removing a comment as a moderator action. deleteComment :: Monad m => CommentID -> RedditT m () deleteComment = nothing . runRoute . Route.delete -- | Removes a comment (as a moderator action). Note that this is different -- from deleting a comment. removeComment :: Monad m => CommentID -> RedditT m () removeComment = nothing . runRoute . Route.removePost False