matterhorn-50200.17.0: src/Matterhorn/State/Flagging.hs
module Matterhorn.State.Flagging
( loadFlaggedMessages
, updateMessageFlag
)
where
import Prelude ()
import Matterhorn.Prelude
import Data.Function ( on )
import qualified Data.Set as Set
import qualified Data.HashMap.Strict as HM
import Lens.Micro.Platform
import Network.Mattermost.Types
import Matterhorn.State.Common
import Matterhorn.Types
loadFlaggedMessages :: Seq FlaggedPost -> ChatState -> IO ()
loadFlaggedMessages prefs st = doAsyncWithIO Normal st $ do
return $ Just $ do
sequence_ [ updateMessageFlag (flaggedPostId fp) True
| fp <- toList prefs
, flaggedPostStatus fp
]
-- | Update the UI to reflect the flagged/unflagged state of a
-- message. This __does not__ talk to the Mattermost server, but
-- rather is the function we call when the Mattermost server notifies
-- us of flagged or unflagged messages.
updateMessageFlag :: PostId -> Bool -> MH ()
updateMessageFlag pId f = do
if f
then csResources.crFlaggedPosts %= Set.insert pId
else csResources.crFlaggedPosts %= Set.delete pId
msgMb <- use (csPostMap.at(pId))
case msgMb of
Just msg
| Just cId <- msg^.mChannelId -> withChannel cId $ \chan -> do
let isTargetMessage m = m^.mMessageId == Just (MessagePostId pId)
csChannelMessages(cId).traversed.filtered isTargetMessage.mFlagged .= f
csPostMap.ix(pId).mFlagged .= f
invalidateChannelRenderingCache cId
invalidateMessageRenderingCacheByPostId pId
let mTId = chan^.ccInfo.cdTeamId
updateTeam :: TeamId -> MH ()
updateTeam tId = do
-- Update the thread window for this team, if its channel
-- is the one that the post is in.
mTi <- preuse (threadInterface(tId))
case mTi of
Just ti | ti^.miChannelId == cId ->
threadInterface(tId).miMessages.traversed.filtered isTargetMessage.mFlagged .= f
_ -> return ()
-- We also want to update the post window if this happens
-- while we're we're observing it
mode <- getTeamMode tId
case mode of
PostListWindow PostListFlagged
| f ->
csTeam tId.tsPostListWindow.postListPosts %=
addMessage (msg & mFlagged .~ True)
-- deleting here is tricky, because it means that we
-- need to move the focus somewhere: we'll try moving
-- it _up_ unless we can't, in which case we'll try
-- moving it down.
| otherwise -> do
selId <- use (csTeam tId.tsPostListWindow.postListSelected)
posts <- use (csTeam tId.tsPostListWindow.postListPosts)
let nextId = case getNextPostId selId posts of
Nothing -> getPrevPostId selId posts
Just x -> Just x
csTeam tId.tsPostListWindow.postListSelected .= nextId
csTeam tId.tsPostListWindow.postListPosts %=
filterMessages (((/=) `on` _mMessageId) msg)
_ -> return ()
case mTId of
Nothing -> do
ts <- use csTeams
forM_ (HM.keys ts) updateTeam
Just tId -> updateTeam tId
_ -> return ()