{-# Language BangPatterns, TemplateHaskell #-}
module Client.State.Window
(
Window(..)
, winMessages
, winUnread
, winTotal
, winMention
, WindowLine(..)
, wlBody
, wlText
, wlImage
, wlFullImage
, wlImportance
, wlTimestamp
, WindowLineImportance(..)
, emptyWindow
, addToWindow
, windowSeen
) where
import Client.Message
import Control.Lens
import Data.Text (Text)
import Data.Time (UTCTime)
import Graphics.Vty.Image (Image)
data WindowLine = WindowLine
{ _wlBody :: !MessageBody
, _wlText :: {-# UNPACK #-} !Text
, _wlImage :: !Image
, _wlFullImage :: !Image
, _wlImportance :: !WindowLineImportance
, _wlTimestamp :: {-# UNPACK #-} !UTCTime
}
data Window = Window
{ _winMessages :: ![WindowLine]
, _winUnread :: !Int
, _winTotal :: !Int
, _winMention :: !Bool
}
data WindowLineImportance
= WLBoring
| WLNormal
| WLImportant
deriving (Eq, Show)
makeLenses ''Window
makeLenses ''WindowLine
-- | A window with no messages
emptyWindow :: Window
emptyWindow = Window
{ _winMessages = []
, _winUnread = 0
, _winTotal = 0
, _winMention = False
}
-- | Adds a given line to a window as the newest message. Window's
-- unread count will be updated according to the given importance.
addToWindow :: WindowLine -> Window -> Window
addToWindow !msg !win = Window
{ _winMessages = msg : view winMessages win
, _winTotal = view winTotal win + 1
, _winUnread = view winUnread win
+ (if view wlImportance msg == WLBoring then 0 else 1)
, _winMention = view winMention win
|| view wlImportance msg == WLImportant
}
-- | Update the window clearing the unread count and important flag.
windowSeen :: Window -> Window
windowSeen = set winUnread 0
. set winMention False