{-# Language TemplateHaskell #-} {-| Module : Client.State.Channel Description : IRC channel session state Copyright : (c) Eric Mertens, 2016 License : ISC Maintainer : emertens@gmail.com This module is responsible for tracking the state of an individual IRC channel while the client is connected to it. When the client joins a channel a new channel session is created and when the client leaves a channel is it destroyed. -} module Client.State.Channel ( -- * Channel state ChannelState(..) , chanTopic , chanTopicProvenance , chanUrl , chanUsers , chanModes , chanLists , chanCreation , chanQueuedModeration -- * Mask list entries , MaskListEntry(..) , maskListSetter , maskListTime -- * Topic information , TopicProvenance(..) , topicAuthor , topicTime -- * Channel manipulation , newChannel , setTopic , joinChannel , partChannel , nickChange ) where import Control.Lens import Data.HashMap.Strict import qualified Data.HashMap.Strict as HashMap import qualified Data.Map.Strict as Map import Data.Map.Strict (Map) import Data.Text (Text) import qualified Data.Text as Text import Data.Time import Irc.Identifier import Irc.RawIrcMsg (RawIrcMsg) import Irc.UserInfo -- | Dynamic information about the state of an IRC channel data ChannelState = ChannelState { _chanTopic :: !Text -- ^ topic text , _chanTopicProvenance :: !(Maybe TopicProvenance) -- ^ author and timestamp for topic , _chanUrl :: !(Maybe Text) -- ^ channel URL , _chanUsers :: !(HashMap Identifier String) -- ^ user list and sigils , _chanModes :: !(Map Char Text) -- ^ channel settings and parameters , _chanLists :: !(Map Char (HashMap Text MaskListEntry)) -- ^ mode, mask, setter, set time , _chanCreation :: !(Maybe UTCTime) -- ^ creation time of channel , _chanQueuedModeration :: ![RawIrcMsg] -- ^ delayed op messages } deriving Show data TopicProvenance = TopicProvenance { _topicAuthor :: !UserInfo , _topicTime :: !UTCTime } deriving Show data MaskListEntry = MaskListEntry { _maskListSetter :: {-# UNPACK #-} !Text , _maskListTime :: {-# UNPACK #-} !UTCTime } deriving Show makeLenses ''ChannelState makeLenses ''TopicProvenance makeLenses ''MaskListEntry -- | Construct an empty 'ChannelState' newChannel :: ChannelState newChannel = ChannelState { _chanTopic = Text.empty , _chanUrl = Nothing , _chanTopicProvenance = Nothing , _chanUsers = HashMap.empty , _chanModes = Map.empty , _chanLists = Map.empty , _chanCreation = Nothing , _chanQueuedModeration = [] } -- | Add a user to the user list joinChannel :: Identifier -> ChannelState -> ChannelState joinChannel nick = set (chanUsers . at nick) (Just "") -- | Remove a user from the user list partChannel :: Identifier -> ChannelState -> ChannelState partChannel = over chanUsers . sans -- | Rename a user in the user list nickChange :: Identifier -> Identifier -> ChannelState -> ChannelState nickChange fromNick toNick cs = set (chanUsers . at toNick) modes cs' where (modes, cs') = cs & chanUsers . at fromNick <<.~ Nothing -- | Set the channel topic setTopic :: Text -> ChannelState -> ChannelState setTopic = set chanTopic