{-# Language OverloadedStrings #-} {-| Module : Client.Image.UserList Description : Line renderers for channel user list view Copyright : (c) Eric Mertens, 2016 License : ISC Maintainer : emertens@gmail.com This module renders the lines used in the channel user list. -} module Client.Image.UserList where import Client.Configuration import Client.Image.Message import Client.Image.Palette import Client.State import Client.State.Channel import Client.State.Network import Control.Lens import qualified Data.HashMap.Strict as HashMap import qualified Data.Map.Strict as Map import Data.List import Data.Ord import Data.Text (Text) import qualified Data.Text as Text import Graphics.Vty.Image import Irc.Identifier import Irc.UserInfo -- | Render the lines used in a simple user list window. userListImages :: Text {- ^ network -} -> Identifier {- ^ channel -} -> ClientState -> [Image] userListImages network channel st = case preview (clientConnection network) st of Just cs -> userListImages' cs channel st Nothing -> [text' (view palError pal) "No connection"] where pal = view (clientConfig . configPalette) st userListImages' :: NetworkState -> Identifier -> ClientState -> [Image] userListImages' cs channel st = [countImage, horizCat (intersperse gap (map renderUser usersList))] where countImage = text' (view palLabel pal) "Users:" <|> sigilCountImage matcher = clientMatcher st myNicks = toListOf csNick cs renderUser (ident, sigils) = string (view palSigil pal) sigils <|> coloredIdentifier pal NormalIdentifier myNicks ident gap = char defAttr ' ' matcher' (ident,sigils) = matcher (Text.pack sigils `Text.append` idText ident) usersList = sortBy (comparing fst) $ filter matcher' $ HashMap.toList usersHashMap sigilCounts = Map.fromListWith (+) [ (take 1 sigil, 1::Int) | (_,sigil) <- usersList ] sigilCountImage = horizCat [ string (view palSigil pal) (' ':sigil) <|> string defAttr (show n) | (sigil,n) <- Map.toList sigilCounts ] pal = view (clientConfig . configPalette) st usersHashMap = view (csChannels . ix channel . chanUsers) cs -- | Render lines for detailed channel user list which shows full user info. userInfoImages :: Text {- ^ network -} -> Identifier {- ^ channel -} -> ClientState -> [Image] userInfoImages network channel st = case preview (clientConnection network) st of Just cs -> userInfoImages' cs channel st Nothing -> [text' (view palError pal) "No connection"] where pal = view (clientConfig . configPalette) st userInfoImages' :: NetworkState -> Identifier -> ClientState -> [Image] userInfoImages' cs channel st = renderEntry <$> usersList where matcher = clientMatcher st myNicks = toListOf csNick cs pal = view (clientConfig . configPalette) st renderEntry (info, sigils) = string (view palSigil pal) sigils <|> coloredUserInfo pal DetailedRender myNicks info matcher' (info,sigils) = matcher (Text.pack sigils `Text.append` renderUserInfo info) userInfos = view csUsers cs toInfo nick = case view (at nick) userInfos of Just (UserAndHost n h) -> UserInfo nick n h Nothing -> UserInfo nick "" "" usersList = sortBy (flip (comparing (userNick . fst))) $ filter matcher' $ map (over _1 toInfo) $ HashMap.toList usersHashMap usersHashMap = view (csChannels . ix channel . chanUsers) cs