{-# Language OverloadedStrings, BangPatterns #-}
{-|
Module      : Client.Image.StatusLine
Description : Renderer for status line
Copyright   : (c) Eric Mertens, 2016
License     : ISC
Maintainer  : emertens@gmail.com

This module provides image renderers used to construct
the status image that sits between text input and the message
window.

-}
module Client.Image.StatusLine
  ( statusLineImage
  , minorStatusLineImage
  , clientTitle
  ) where

import           Client.Image.Message (cleanChar, cleanText)
import           Client.Image.PackedImage
import           Client.Image.Palette
import           Client.State
import           Client.State.Channel
import           Client.State.Focus
import           Client.State.Network
import           Client.State.Window
import           Control.Lens
import           Data.Foldable (for_)
import qualified Data.Map.Strict as Map
import           Data.Maybe
import           Data.HashMap.Strict (HashMap)
import           Data.Text (Text)
import qualified Data.Text as Text
import qualified Data.Text.Lazy as LText
import           Graphics.Vty.Attributes
import qualified Graphics.Vty.Image as Vty
import           Irc.Identifier (idText)
import           Numeric

clientTitle :: ClientState -> String
clientTitle :: ClientState -> String
clientTitle ClientState
st
  = (Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
cleanChar
  (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ Text -> String
LText.unpack
  (Text -> String) -> Text -> String
forall a b. (a -> b) -> a -> b
$ Text
"glirc - " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Image' -> Text
imageText (ClientState -> Focus -> Image'
viewFocusLabel ClientState
st (Getting Focus ClientState Focus -> ClientState -> Focus
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Focus ClientState Focus
Lens' ClientState Focus
clientFocus ClientState
st))

bar :: Image'
bar :: Image'
bar = Attr -> Char -> Image'
char (Attr -> Style -> Attr
withStyle Attr
defAttr Style
bold) Char
'─'


-- | Renders the status line between messages and the textbox.
statusLineImage ::
  Int         {- ^ draw width   -} ->
  ClientState {- ^ client state -} ->
  Vty.Image   {- ^ status bar   -}
statusLineImage :: Int -> ClientState -> Image
statusLineImage Int
w ClientState
st =
  Int -> [Image] -> Image
makeLines Int
w (Image
common Image -> [Image] -> [Image]
forall a. a -> [a] -> [a]
: [Image]
activity [Image] -> [Image] -> [Image]
forall a. [a] -> [a] -> [a]
++ [Image]
errorImgs)
  where
    common :: Image
common = [Image] -> Image
Vty.horizCat ([Image] -> Image) -> [Image] -> Image
forall a b. (a -> b) -> a -> b
$
      ClientState -> Image
myNickImage ClientState
st Image -> [Image] -> [Image]
forall a. a -> [a] -> [a]
:
      (Image' -> Image) -> [Image'] -> [Image]
forall a b. (a -> b) -> [a] -> [b]
map Image' -> Image
unpackImage
      [ Focus -> ClientState -> Image'
focusImage (Getting Focus ClientState Focus -> ClientState -> Focus
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Focus ClientState Focus
Lens' ClientState Focus
clientFocus ClientState
st) ClientState
st
      , Subfocus -> ClientState -> Image'
subfocusImage (Getting Subfocus ClientState Subfocus -> ClientState -> Subfocus
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Subfocus ClientState Subfocus
Lens' ClientState Subfocus
clientSubfocus ClientState
st) ClientState
st
      , ClientState -> Image'
detailImage ClientState
st
      , Focus -> ClientState -> Image'
nometaImage (Getting Focus ClientState Focus -> ClientState -> Focus
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Focus ClientState Focus
Lens' ClientState Focus
clientFocus ClientState
st) ClientState
st
      , ClientState -> Image'
scrollImage ClientState
st
      , ClientState -> Image'
filterImage ClientState
st
      , ClientState -> Image'
lockImage ClientState
st
      , Image'
latency
      ]

    latency :: Image'
latency
      | Getting Bool ClientState Bool -> ClientState -> Bool
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Bool ClientState Bool
Lens' ClientState Bool
clientShowPing ClientState
st = ClientState -> Image'
latencyImage ClientState
st
      | Bool
otherwise              = Image'
forall a. Monoid a => a
mempty

    activity :: [Image]
activity
      | Getting Bool ClientState Bool -> ClientState -> Bool
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Bool ClientState Bool
Lens' ClientState Bool
clientActivityBar ClientState
st = ClientState -> [Image]
activityBarImages ClientState
st
      | Bool
otherwise                 = [ClientState -> Image
activitySummary ClientState
st]

    errorImgs :: [Image]
errorImgs =
      Text -> Image
transientErrorImage (Text -> Image) -> [Text] -> [Image]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Text -> [Text]
forall a. Maybe a -> [a]
maybeToList (Getting (Maybe Text) ClientState (Maybe Text)
-> ClientState -> Maybe Text
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting (Maybe Text) ClientState (Maybe Text)
Lens' ClientState (Maybe Text)
clientErrorMsg ClientState
st)


-- Generates an error message notification image.
transientErrorImage ::
  Text  {- ^ @error-message@           -} ->
  Vty.Image {- ^ @─[error: error-message]@ -}
transientErrorImage :: Text -> Image
transientErrorImage Text
txt =
  Attr -> Text -> Image
Vty.text' Attr
defAttr Text
"─[" Image -> Image -> Image
Vty.<|>
  Attr -> Text -> Image
Vty.text' (Attr -> Color -> Attr
withForeColor Attr
defAttr Color
red) Text
"error: " Image -> Image -> Image
Vty.<|>
  Attr -> Text -> Image
Vty.text' Attr
defAttr (Text -> Text
cleanText Text
txt) Image -> Image -> Image
Vty.<|>
  Attr -> Text -> Image
Vty.text' Attr
defAttr Text
"]"


-- | The minor status line is used when rendering the @/splits@ and
-- @/mentions@ views to show the associated window name.
minorStatusLineImage ::
  Focus       {- ^ window name          -} ->
  Subfocus    {- ^ subfocus             -} ->
  Int         {- ^ draw width           -} ->
  Bool        {- ^ show hidemeta status -} ->
  ClientState {- ^ client state -} ->
  Image'
minorStatusLineImage :: Focus -> Subfocus -> Int -> Bool -> ClientState -> Image'
minorStatusLineImage Focus
focus Subfocus
subfocus Int
w Bool
showHideMeta ClientState
st =
  Image'
content Image' -> Image' -> Image'
forall a. Semigroup a => a -> a -> a
<> [Image'] -> Image'
forall a. Monoid a => [a] -> a
mconcat (Int -> Image' -> [Image']
forall a. Int -> a -> [a]
replicate Int
fillSize Image'
bar)
  where
    content :: Image'
content = Focus -> ClientState -> Image'
focusImage Focus
focus ClientState
st Image' -> Image' -> Image'
forall a. Semigroup a => a -> a -> a
<>
              Subfocus -> ClientState -> Image'
subfocusImage Subfocus
subfocus ClientState
st Image' -> Image' -> Image'
forall a. Semigroup a => a -> a -> a
<>
              if Bool
showHideMeta then Focus -> ClientState -> Image'
nometaImage Focus
focus ClientState
st else Image'
forall a. Monoid a => a
mempty

    fillSize :: Int
fillSize = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
0 (Int
w Int -> Int -> Int
forall a. Num a => a -> a -> a
- Image' -> Int
imageWidth Image'
content)


-- | Indicate when the client is scrolling and old messages are being shown.
scrollImage :: ClientState -> Image'
scrollImage :: ClientState -> Image'
scrollImage ClientState
st
  | Int
0 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Getting Int ClientState Int -> ClientState -> Int
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Int ClientState Int
Lens' ClientState Int
clientScroll ClientState
st = Image'
forall a. Monoid a => a
mempty
  | Bool
otherwise = Image' -> Image'
infoBubble (Attr -> String -> Image'
string Attr
attr String
"scroll")
  where
    pal :: Palette
pal  = ClientState -> Palette
clientPalette ClientState
st
    attr :: Attr
attr = Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palError Palette
pal


-- | Indicate when the client is potentially showing a subset of the
-- available chat messages.
filterImage :: ClientState -> Image'
filterImage :: ClientState -> Image'
filterImage ClientState
st
  | ClientState -> Bool
clientIsFiltered ClientState
st = Image' -> Image'
infoBubble (Attr -> String -> Image'
string Attr
attr String
"filtered")
  | Bool
otherwise           = Image'
forall a. Monoid a => a
mempty
  where
    pal :: Palette
pal  = ClientState -> Palette
clientPalette ClientState
st
    attr :: Attr
attr = Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palError Palette
pal

-- | Indicate when the client editor is locked
lockImage :: ClientState -> Image'
lockImage :: ClientState -> Image'
lockImage ClientState
st
  | Getting Bool ClientState Bool -> ClientState -> Bool
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Bool ClientState Bool
Lens' ClientState Bool
clientEditLock ClientState
st = Image' -> Image'
infoBubble (Attr -> String -> Image'
string Attr
attr String
"locked")
  | Bool
otherwise              = Image'
forall a. Monoid a => a
mempty
  where
    pal :: Palette
pal  = ClientState -> Palette
clientPalette ClientState
st
    attr :: Attr
attr = Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palError Palette
pal


-- | Indicate the current connection health. This will either indicate
-- that the connection is being established or that a ping has been
-- sent or long the previous ping round-trip was.
latencyImage :: ClientState -> Image'
latencyImage :: ClientState -> Image'
latencyImage ClientState
st = (Image' -> Image')
-> (Image' -> Image') -> Either Image' Image' -> Image'
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either Image' -> Image'
forall a. a -> a
id Image' -> Image'
forall a. a -> a
id (Either Image' Image' -> Image') -> Either Image' Image' -> Image'
forall a b. (a -> b) -> a -> b
$

  do Text
network <- -- no network -> no image
       case LensLike' (Const (Maybe Text)) ClientState Focus
-> (Focus -> Maybe Text) -> ClientState -> Maybe Text
forall s (m :: * -> *) r a.
MonadReader s m =>
LensLike' (Const r) s a -> (a -> r) -> m r
views LensLike' (Const (Maybe Text)) ClientState Focus
Lens' ClientState Focus
clientFocus Focus -> Maybe Text
focusNetwork ClientState
st of
         Maybe Text
Nothing  -> Image' -> Either Image' Text
forall a b. a -> Either a b
Left Image'
forall a. Monoid a => a
mempty
         Just Text
net -> Text -> Either Image' Text
forall a b. b -> Either a b
Right Text
net

     NetworkState
cs <- -- detect when offline
       case Getting (First NetworkState) ClientState NetworkState
-> ClientState -> Maybe NetworkState
forall s (m :: * -> *) a.
MonadReader s m =>
Getting (First a) s a -> m (Maybe a)
preview (Text -> Getting (First NetworkState) ClientState NetworkState
forall (f :: * -> *).
Applicative f =>
Text -> LensLike' f ClientState NetworkState
clientConnection Text
network) ClientState
st of
         Maybe NetworkState
Nothing -> Image' -> Either Image' NetworkState
forall a b. a -> Either a b
Left (Image' -> Image'
infoBubble (Attr -> String -> Image'
string (Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palError Palette
pal) String
"offline"))
         Just NetworkState
cs -> NetworkState -> Either Image' NetworkState
forall a b. b -> Either a b
Right NetworkState
cs

     -- render latency if one is stored
     Maybe NominalDiffTime
-> (NominalDiffTime -> Either Image' Any) -> Either Image' ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ (Getting
  (Maybe NominalDiffTime) NetworkState (Maybe NominalDiffTime)
-> NetworkState -> Maybe NominalDiffTime
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting
  (Maybe NominalDiffTime) NetworkState (Maybe NominalDiffTime)
Lens' NetworkState (Maybe NominalDiffTime)
csLatency NetworkState
cs) ((NominalDiffTime -> Either Image' Any) -> Either Image' ())
-> (NominalDiffTime -> Either Image' Any) -> Either Image' ()
forall a b. (a -> b) -> a -> b
$ \NominalDiffTime
latency ->
       Image' -> Either Image' Any
forall a b. a -> Either a b
Left (String -> Image'
latencyBubble (Maybe Int -> Double -> String -> String
forall a. RealFloat a => Maybe Int -> a -> String -> String
showFFloat (Int -> Maybe Int
forall a. a -> Maybe a
Just Int
2) (NominalDiffTime -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac NominalDiffTime
latency :: Double) String
"s"))

     Image' -> Either Image' Image'
forall a b. b -> Either a b
Right (Image' -> Either Image' Image') -> Image' -> Either Image' Image'
forall a b. (a -> b) -> a -> b
$ case Getting PingStatus NetworkState PingStatus
-> NetworkState -> PingStatus
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting PingStatus NetworkState PingStatus
Lens' NetworkState PingStatus
csPingStatus NetworkState
cs of

       PingSent {} -> String -> Image'
latencyBubble String
"wait"

       PingConnecting Int
n Maybe UTCTime
_ ConnectRestriction
_ ->
         Image' -> Image'
infoBubble (Attr -> String -> Image'
string (Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palLatency Palette
pal) String
"connecting" Image' -> Image' -> Image'
forall a. Semigroup a => a -> a -> a
<> Int -> Image'
forall a. (Ord a, Num a, Show a) => a -> Image'
retryImage Int
n)

       PingStatus
PingNone -> Image'
forall a. Monoid a => a
mempty -- just connected no ping sent yet

  where
    pal :: Palette
pal           = ClientState -> Palette
clientPalette ClientState
st
    latencyBubble :: String -> Image'
latencyBubble = Image' -> Image'
infoBubble (Image' -> Image') -> (String -> Image') -> String -> Image'
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Attr -> String -> Image'
string (Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palLatency Palette
pal)

    retryImage :: a -> Image'
retryImage a
n
      | a
n a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
0     = Image'
": " Image' -> Image' -> Image'
forall a. Semigroup a => a -> a -> a
<> Attr -> String -> Image'
string (Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palLabel Palette
pal) (String
"retry " String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
n)
      | Bool
otherwise = Image'
forall a. Monoid a => a
mempty


-- | Wrap some text in parentheses to make it suitable for inclusion in the
-- status line.
infoBubble :: Image' -> Image'
infoBubble :: Image' -> Image'
infoBubble Image'
img = Image'
bar Image' -> Image' -> Image'
forall a. Semigroup a => a -> a -> a
<> Image'
"(" Image' -> Image' -> Image'
forall a. Semigroup a => a -> a -> a
<> Image'
img Image' -> Image' -> Image'
forall a. Semigroup a => a -> a -> a
<> Image'
")"


-- | Indicate that the client is in the /detailed/ view.
detailImage :: ClientState -> Image'
detailImage :: ClientState -> Image'
detailImage ClientState
st
  | Getting Bool ClientState Bool -> ClientState -> Bool
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Bool ClientState Bool
Lens' ClientState Bool
clientDetailView ClientState
st = Image' -> Image'
infoBubble (Attr -> String -> Image'
string Attr
attr String
"detail")
  | Bool
otherwise = Image'
forall a. Monoid a => a
mempty
  where
    pal :: Palette
pal  = ClientState -> Palette
clientPalette ClientState
st
    attr :: Attr
attr = Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palLabel Palette
pal


-- | Indicate that the client isn't showing the metadata lines in /normal/
-- view.
nometaImage :: Focus -> ClientState -> Image'
nometaImage :: Focus -> ClientState -> Image'
nometaImage Focus
focus ClientState
st
  | Bool
metaHidden = Image' -> Image'
infoBubble (Attr -> String -> Image'
string Attr
attr String
"nometa")
  | Bool
otherwise  = Image'
forall a. Monoid a => a
mempty
  where
    pal :: Palette
pal        = ClientState -> Palette
clientPalette ClientState
st
    attr :: Attr
attr       = Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palLabel Palette
pal
    metaHidden :: Bool
metaHidden = Getting Any ClientState Bool -> ClientState -> Bool
forall s. Getting Any s Bool -> s -> Bool
orOf ((Map Focus Window -> Const Any (Map Focus Window))
-> ClientState -> Const Any ClientState
Lens' ClientState (Map Focus Window)
clientWindows ((Map Focus Window -> Const Any (Map Focus Window))
 -> ClientState -> Const Any ClientState)
-> ((Bool -> Const Any Bool)
    -> Map Focus Window -> Const Any (Map Focus Window))
-> Getting Any ClientState Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Index (Map Focus Window)
-> Traversal' (Map Focus Window) (IxValue (Map Focus Window))
forall m. Ixed m => Index m -> Traversal' m (IxValue m)
ix Index (Map Focus Window)
Focus
focus ((Window -> Const Any Window)
 -> Map Focus Window -> Const Any (Map Focus Window))
-> ((Bool -> Const Any Bool) -> Window -> Const Any Window)
-> (Bool -> Const Any Bool)
-> Map Focus Window
-> Const Any (Map Focus Window)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Bool -> Const Any Bool) -> Window -> Const Any Window
Lens' Window Bool
winHideMeta) ClientState
st

-- | Image for little box with active window names:
--
-- @-[15p]@
activitySummary :: ClientState -> Vty.Image
activitySummary :: ClientState -> Image
activitySummary ClientState
st
  | [Image] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Image]
indicators = Image
Vty.emptyImage
  | Bool
otherwise       = Image' -> Image
unpackImage Image'
bar Image -> Image -> Image
Vty.<|>
                      Attr -> String -> Image
Vty.string Attr
defAttr String
"[" Image -> Image -> Image
Vty.<|>
                      [Image] -> Image
Vty.horizCat [Image]
indicators Image -> Image -> Image
Vty.<|>
                      Attr -> String -> Image
Vty.string Attr
defAttr String
"]"
  where
    indicators :: [Image]
indicators = (Window -> [Image] -> [Image]) -> [Image] -> [Window] -> [Image]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Window -> [Image] -> [Image]
aux [] [Window]
windows
    windows :: [Window]
windows    = LensLike' (Const [Window]) ClientState (Map Focus Window)
-> (Map Focus Window -> [Window]) -> ClientState -> [Window]
forall s (m :: * -> *) r a.
MonadReader s m =>
LensLike' (Const r) s a -> (a -> r) -> m r
views LensLike' (Const [Window]) ClientState (Map Focus Window)
Lens' ClientState (Map Focus Window)
clientWindows Map Focus Window -> [Window]
forall k a. Map k a -> [a]
Map.elems ClientState
st

    aux :: Window -> [Image] -> [Image]
aux Window
w [Image]
rest =
      let name :: Char
name = case Getting (Maybe Char) Window (Maybe Char) -> Window -> Maybe Char
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting (Maybe Char) Window (Maybe Char)
Lens' Window (Maybe Char)
winName Window
w of
                   Maybe Char
Nothing -> Char
'?'
                   Just Char
i -> Char
i in
      if Getting Bool Window Bool -> Window -> Bool
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Bool Window Bool
Lens' Window Bool
winSilent Window
w then [Image]
rest else
      case Getting WindowLineImportance Window WindowLineImportance
-> Window -> WindowLineImportance
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting WindowLineImportance Window WindowLineImportance
Lens' Window WindowLineImportance
winMention Window
w of
        WindowLineImportance
WLImportant -> Attr -> Char -> Image
Vty.char (Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palMention  Palette
pal) Char
name Image -> [Image] -> [Image]
forall a. a -> [a] -> [a]
: [Image]
rest
        WindowLineImportance
WLNormal    -> Attr -> Char -> Image
Vty.char (Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palActivity Palette
pal) Char
name Image -> [Image] -> [Image]
forall a. a -> [a] -> [a]
: [Image]
rest
        WindowLineImportance
WLBoring    -> [Image]
rest
      where
        pal :: Palette
pal = ClientState -> Palette
clientPalette ClientState
st

-- | Multi-line activity information enabled by F3
activityBarImages :: ClientState -> [Vty.Image]
activityBarImages :: ClientState -> [Image]
activityBarImages ClientState
st
  = ((Focus, Window) -> Maybe Image) -> [(Focus, Window)] -> [Image]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (Focus, Window) -> Maybe Image
baraux
  ([(Focus, Window)] -> [Image]) -> [(Focus, Window)] -> [Image]
forall a b. (a -> b) -> a -> b
$ Map Focus Window -> [(Focus, Window)]
forall k a. Map k a -> [(k, a)]
Map.toAscList
  (Map Focus Window -> [(Focus, Window)])
-> Map Focus Window -> [(Focus, Window)]
forall a b. (a -> b) -> a -> b
$ Getting (Map Focus Window) ClientState (Map Focus Window)
-> ClientState -> Map Focus Window
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting (Map Focus Window) ClientState (Map Focus Window)
Lens' ClientState (Map Focus Window)
clientWindows ClientState
st

  where
    baraux :: (Focus, Window) -> Maybe Image
baraux (Focus
focus,Window
w)
      | Getting Bool Window Bool -> Window -> Bool
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Bool Window Bool
Lens' Window Bool
winSilent Window
w = Maybe Image
forall a. Maybe a
Nothing
      | Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = Maybe Image
forall a. Maybe a
Nothing -- todo: make configurable
      | Bool
otherwise = Image -> Maybe Image
forall a. a -> Maybe a
Just
                  (Image -> Maybe Image) -> Image -> Maybe Image
forall a b. (a -> b) -> a -> b
$ Image' -> Image
unpackImage Image'
bar Image -> Image -> Image
Vty.<|>
                    Attr -> Char -> Image
Vty.char Attr
defAttr Char
'[' Image -> Image -> Image
Vty.<|>
                    Image
jumpLabel Image -> Image -> Image
Vty.<|>
                    Attr -> Text -> Image
Vty.text' (Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palLabel Palette
pal) (Text -> Text
cleanText Text
focusText) Image -> Image -> Image
Vty.<|>
                    Attr -> Char -> Image
Vty.char Attr
defAttr Char
':' Image -> Image -> Image
Vty.<|>
                    Attr -> String -> Image
Vty.string Attr
attr (Int -> String
forall a. Show a => a -> String
show Int
n) Image -> Image -> Image
Vty.<|>
                    Attr -> Char -> Image
Vty.char Attr
defAttr Char
']'
      where
        jumpLabel :: Image
jumpLabel =
          case Getting (Maybe Char) Window (Maybe Char) -> Window -> Maybe Char
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting (Maybe Char) Window (Maybe Char)
Lens' Window (Maybe Char)
winName Window
w of
            Maybe Char
Nothing   -> Image
forall a. Monoid a => a
mempty
            Just Char
name -> Attr -> Char -> Image
Vty.char (Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palWindowName Palette
pal) Char
name Image -> Image -> Image
Vty.<|>
                         Attr -> Char -> Image
Vty.char Attr
defAttr Char
':'
        n :: Int
n   = Getting Int Window Int -> Window -> Int
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Int Window Int
Lens' Window Int
winUnread Window
w
        pal :: Palette
pal = ClientState -> Palette
clientPalette ClientState
st
        attr :: Attr
attr = case Getting WindowLineImportance Window WindowLineImportance
-> Window -> WindowLineImportance
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting WindowLineImportance Window WindowLineImportance
Lens' Window WindowLineImportance
winMention Window
w of
                 WindowLineImportance
WLImportant -> Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palMention Palette
pal
                 WindowLineImportance
_           -> Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palActivity Palette
pal
        focusText :: Text
focusText =
          case Focus
focus of
            Focus
Unfocused           -> String -> Text
Text.pack String
"*"
            NetworkFocus net    -> Text
net
            ChannelFocus _ chan -> Identifier -> Text
idText Identifier
chan


-- | Pack a list of images into a single image spanning possibly many lines.
-- The images will stack upward with the first element of the list being in
-- the bottom left corner of the image. Each line will have at least one
-- of the component images in it, which might truncate that image in extreme
-- cases.
makeLines ::
  Int     {- ^ window width       -} ->
  [Vty.Image] {- ^ components to pack -} ->
  Vty.Image
makeLines :: Int -> [Image] -> Image
makeLines Int
_ [] = Image
Vty.emptyImage
makeLines Int
w (Image
x:[Image]
xs) = Image -> [Image] -> Image
go Image
x [Image]
xs
  where
    go :: Image -> [Image] -> Image
go Image
acc (Image
y:[Image]
ys)
      | let acc' :: Image
acc' = Image
acc Image -> Image -> Image
Vty.<|> Image
y
      , Image -> Int
Vty.imageWidth Image
acc' Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
w
      = Image -> [Image] -> Image
go Image
acc' [Image]
ys

    go Image
acc [Image]
ys = Int -> [Image] -> Image
makeLines Int
w [Image]
ys
        Image -> Image -> Image
Vty.<-> Int -> Image -> Image
Vty.cropRight Int
w Image
acc
        Image -> Image -> Image
Vty.<|> Image' -> Image
unpackImage ([Image'] -> Image'
forall a. Monoid a => [a] -> a
mconcat (Int -> Image' -> [Image']
forall a. Int -> a -> [a]
replicate Int
fillsize Image'
bar))
      where
        fillsize :: Int
fillsize = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
0 (Int
w Int -> Int -> Int
forall a. Num a => a -> a -> a
- Image -> Int
Vty.imageWidth Image
acc)


myNickImage :: ClientState -> Vty.Image
myNickImage :: ClientState -> Image
myNickImage ClientState
st =
  case Getting Focus ClientState Focus -> ClientState -> Focus
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Focus ClientState Focus
Lens' ClientState Focus
clientFocus ClientState
st of
    NetworkFocus Text
network      -> Text -> Image
nickPart Text
network
    ChannelFocus Text
network Identifier
_    -> Text -> Image
nickPart Text
network
    Focus
Unfocused                 -> Image
Vty.emptyImage
  where
    pal :: Palette
pal = ClientState -> Palette
clientPalette ClientState
st
    nickPart :: Text -> Image
nickPart Text
network =
      case Getting (First NetworkState) ClientState NetworkState
-> ClientState -> Maybe NetworkState
forall s (m :: * -> *) a.
MonadReader s m =>
Getting (First a) s a -> m (Maybe a)
preview (Text -> Getting (First NetworkState) ClientState NetworkState
forall (f :: * -> *).
Applicative f =>
Text -> LensLike' f ClientState NetworkState
clientConnection Text
network) ClientState
st of
        Maybe NetworkState
Nothing -> Image
Vty.emptyImage
        Just NetworkState
cs -> Attr -> Text -> Image
Vty.text' Attr
attr (Text -> Text
cleanText (Identifier -> Text
idText Identifier
nick))
           Image -> Image -> Image
Vty.<|> Attr -> Image -> Image
parens Attr
defAttr
                     (Image' -> Image
unpackImage (Image' -> Image) -> Image' -> Image
forall a b. (a -> b) -> a -> b
$
                      HashMap Char Attr -> String -> Image'
modesImage (Getting (HashMap Char Attr) Palette (HashMap Char Attr)
-> Palette -> HashMap Char Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting (HashMap Char Attr) Palette (HashMap Char Attr)
Lens' Palette (HashMap Char Attr)
palUModes Palette
pal) (Getting String NetworkState String -> NetworkState -> String
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting String NetworkState String
Lens' NetworkState String
csModes NetworkState
cs) Image' -> Image' -> Image'
forall a. Semigroup a => a -> a -> a
<>
                      Image'
snomaskImage)
          where
            attr :: Attr
attr
              | Getting Bool NetworkState Bool -> NetworkState -> Bool
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Bool NetworkState Bool
Lens' NetworkState Bool
csAway NetworkState
cs = Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palAway Palette
pal
              | Bool
otherwise      = Attr
defAttr

            nick :: Identifier
nick = Getting Identifier NetworkState Identifier
-> NetworkState -> Identifier
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Identifier NetworkState Identifier
Lens' NetworkState Identifier
csNick NetworkState
cs

            snomaskImage :: Image'
snomaskImage
              | String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (Getting String NetworkState String -> NetworkState -> String
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting String NetworkState String
Lens' NetworkState String
csSnomask NetworkState
cs) = Image'
""
              | Bool
otherwise                = Image'
" " Image' -> Image' -> Image'
forall a. Semigroup a => a -> a -> a
<> HashMap Char Attr -> String -> Image'
modesImage (Getting (HashMap Char Attr) Palette (HashMap Char Attr)
-> Palette -> HashMap Char Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting (HashMap Char Attr) Palette (HashMap Char Attr)
Lens' Palette (HashMap Char Attr)
palSnomask Palette
pal) (Getting String NetworkState String -> NetworkState -> String
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting String NetworkState String
Lens' NetworkState String
csSnomask NetworkState
cs)

modesImage :: HashMap Char Attr -> String -> Image'
modesImage :: HashMap Char Attr -> String -> Image'
modesImage HashMap Char Attr
pal String
modes = Image'
"+" Image' -> Image' -> Image'
forall a. Semigroup a => a -> a -> a
<> (Char -> Image') -> String -> Image'
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Char -> Image'
modeImage String
modes
  where
    modeImage :: Char -> Image'
modeImage Char
m =
      Attr -> Char -> Image'
char (Attr -> Maybe Attr -> Attr
forall a. a -> Maybe a -> a
fromMaybe Attr
defAttr (Getting (Maybe Attr) (HashMap Char Attr) (Maybe Attr)
-> HashMap Char Attr -> Maybe Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view (Index (HashMap Char Attr)
-> Lens' (HashMap Char Attr) (Maybe (IxValue (HashMap Char Attr)))
forall m. At m => Index m -> Lens' m (Maybe (IxValue m))
at Char
Index (HashMap Char Attr)
m) HashMap Char Attr
pal)) Char
m

subfocusImage :: Subfocus -> ClientState -> Image'
subfocusImage :: Subfocus -> ClientState -> Image'
subfocusImage Subfocus
subfocus ClientState
st = (Image' -> Image') -> Maybe Image' -> Image'
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Image' -> Image'
infoBubble (Palette -> Subfocus -> Maybe Image'
viewSubfocusLabel Palette
pal Subfocus
subfocus)
  where
    pal :: Palette
pal         = ClientState -> Palette
clientPalette ClientState
st

focusImage :: Focus -> ClientState -> Image'
focusImage :: Focus -> ClientState -> Image'
focusImage Focus
focus ClientState
st =
  Image' -> Image'
infoBubble (Image' -> Image') -> Image' -> Image'
forall a b. (a -> b) -> a -> b
$
  case Getting (First Char) ClientState Char -> ClientState -> Maybe Char
forall s (m :: * -> *) a.
MonadReader s m =>
Getting (First a) s a -> m (Maybe a)
preview ((Map Focus Window -> Const (First Char) (Map Focus Window))
-> ClientState -> Const (First Char) ClientState
Lens' ClientState (Map Focus Window)
clientWindows ((Map Focus Window -> Const (First Char) (Map Focus Window))
 -> ClientState -> Const (First Char) ClientState)
-> ((Char -> Const (First Char) Char)
    -> Map Focus Window -> Const (First Char) (Map Focus Window))
-> Getting (First Char) ClientState Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Index (Map Focus Window)
-> Traversal' (Map Focus Window) (IxValue (Map Focus Window))
forall m. Ixed m => Index m -> Traversal' m (IxValue m)
ix Index (Map Focus Window)
Focus
focus ((Window -> Const (First Char) Window)
 -> Map Focus Window -> Const (First Char) (Map Focus Window))
-> ((Char -> Const (First Char) Char)
    -> Window -> Const (First Char) Window)
-> (Char -> Const (First Char) Char)
-> Map Focus Window
-> Const (First Char) (Map Focus Window)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe Char -> Const (First Char) (Maybe Char))
-> Window -> Const (First Char) Window
Lens' Window (Maybe Char)
winName ((Maybe Char -> Const (First Char) (Maybe Char))
 -> Window -> Const (First Char) Window)
-> ((Char -> Const (First Char) Char)
    -> Maybe Char -> Const (First Char) (Maybe Char))
-> (Char -> Const (First Char) Char)
-> Window
-> Const (First Char) Window
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Const (First Char) Char)
-> Maybe Char -> Const (First Char) (Maybe Char)
forall a b. Prism (Maybe a) (Maybe b) a b
_Just) ClientState
st of
    Maybe Char
Nothing -> Image'
label
    Just Char
n  -> Attr -> Char -> Image'
char (Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palWindowName Palette
pal) Char
n Image' -> Image' -> Image'
forall a. Semigroup a => a -> a -> a
<> Image'
":" Image' -> Image' -> Image'
forall a. Semigroup a => a -> a -> a
<> Image'
label
  where
    !pal :: Palette
pal        = ClientState -> Palette
clientPalette ClientState
st
    label :: Image'
label       = ClientState -> Focus -> Image'
viewFocusLabel ClientState
st Focus
focus

parens :: Attr -> Vty.Image -> Vty.Image
parens :: Attr -> Image -> Image
parens Attr
attr Image
i = Attr -> Char -> Image
Vty.char Attr
attr Char
'(' Image -> Image -> Image
Vty.<|> Image
i Image -> Image -> Image
Vty.<|> Attr -> Char -> Image
Vty.char Attr
attr Char
')'

viewFocusLabel :: ClientState -> Focus -> Image'
viewFocusLabel :: ClientState -> Focus -> Image'
viewFocusLabel ClientState
st Focus
focus =
  let !pal :: Palette
pal = ClientState -> Palette
clientPalette ClientState
st in
  case Focus
focus of
    Focus
Unfocused ->
      Attr -> Char -> Image'
char (Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palError Palette
pal) Char
'*'
    NetworkFocus Text
network ->
      Attr -> Text -> Image'
text' (Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palLabel Palette
pal) (Text -> Text
cleanText Text
network)
    ChannelFocus Text
network Identifier
channel ->
      Attr -> Text -> Image'
text' (Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palLabel Palette
pal) (Text -> Text
cleanText Text
network) Image' -> Image' -> Image'
forall a. Semigroup a => a -> a -> a
<>
      Attr -> Char -> Image'
char Attr
defAttr Char
':' Image' -> Image' -> Image'
forall a. Semigroup a => a -> a -> a
<>
      Attr -> String -> Image'
string (Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palSigil Palette
pal) (Char -> Char
cleanChar (Char -> Char) -> String -> String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String
sigils) Image' -> Image' -> Image'
forall a. Semigroup a => a -> a -> a
<>
      Attr -> Text -> Image'
text' (Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palLabel Palette
pal) (Text -> Text
cleanText (Identifier -> Text
idText Identifier
channel)) Image' -> Image' -> Image'
forall a. Semigroup a => a -> a -> a
<>
      Image'
channelModes

      where
        (String
sigils, Image'
channelModes) =
          case Getting (First NetworkState) ClientState NetworkState
-> ClientState -> Maybe NetworkState
forall s (m :: * -> *) a.
MonadReader s m =>
Getting (First a) s a -> m (Maybe a)
preview (Text -> Getting (First NetworkState) ClientState NetworkState
forall (f :: * -> *).
Applicative f =>
Text -> LensLike' f ClientState NetworkState
clientConnection Text
network) ClientState
st of
            Maybe NetworkState
Nothing -> (String
"", Image'
forall a. Monoid a => a
mempty)
            Just NetworkState
cs ->
               ( let nick :: Identifier
nick = Getting Identifier NetworkState Identifier
-> NetworkState -> Identifier
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Identifier NetworkState Identifier
Lens' NetworkState Identifier
csNick NetworkState
cs in
                 Getting String NetworkState String -> NetworkState -> String
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view ((HashMap Identifier ChannelState
 -> Const String (HashMap Identifier ChannelState))
-> NetworkState -> Const String NetworkState
Lens' NetworkState (HashMap Identifier ChannelState)
csChannels ((HashMap Identifier ChannelState
  -> Const String (HashMap Identifier ChannelState))
 -> NetworkState -> Const String NetworkState)
-> ((String -> Const String String)
    -> HashMap Identifier ChannelState
    -> Const String (HashMap Identifier ChannelState))
-> Getting String NetworkState String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Index (HashMap Identifier ChannelState)
-> Traversal'
     (HashMap Identifier ChannelState)
     (IxValue (HashMap Identifier ChannelState))
forall m. Ixed m => Index m -> Traversal' m (IxValue m)
ix Identifier
Index (HashMap Identifier ChannelState)
channel ((ChannelState -> Const String ChannelState)
 -> HashMap Identifier ChannelState
 -> Const String (HashMap Identifier ChannelState))
-> ((String -> Const String String)
    -> ChannelState -> Const String ChannelState)
-> (String -> Const String String)
-> HashMap Identifier ChannelState
-> Const String (HashMap Identifier ChannelState)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (HashMap Identifier String
 -> Const String (HashMap Identifier String))
-> ChannelState -> Const String ChannelState
Lens' ChannelState (HashMap Identifier String)
chanUsers ((HashMap Identifier String
  -> Const String (HashMap Identifier String))
 -> ChannelState -> Const String ChannelState)
-> ((String -> Const String String)
    -> HashMap Identifier String
    -> Const String (HashMap Identifier String))
-> (String -> Const String String)
-> ChannelState
-> Const String ChannelState
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Index (HashMap Identifier String)
-> Traversal'
     (HashMap Identifier String) (IxValue (HashMap Identifier String))
forall m. Ixed m => Index m -> Traversal' m (IxValue m)
ix Identifier
Index (HashMap Identifier String)
nick) NetworkState
cs

               , case Getting (First (Map Char Text)) NetworkState (Map Char Text)
-> NetworkState -> Maybe (Map Char Text)
forall s (m :: * -> *) a.
MonadReader s m =>
Getting (First a) s a -> m (Maybe a)
preview ((HashMap Identifier ChannelState
 -> Const (First (Map Char Text)) (HashMap Identifier ChannelState))
-> NetworkState -> Const (First (Map Char Text)) NetworkState
Lens' NetworkState (HashMap Identifier ChannelState)
csChannels ((HashMap Identifier ChannelState
  -> Const (First (Map Char Text)) (HashMap Identifier ChannelState))
 -> NetworkState -> Const (First (Map Char Text)) NetworkState)
-> ((Map Char Text
     -> Const (First (Map Char Text)) (Map Char Text))
    -> HashMap Identifier ChannelState
    -> Const (First (Map Char Text)) (HashMap Identifier ChannelState))
-> Getting (First (Map Char Text)) NetworkState (Map Char Text)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Index (HashMap Identifier ChannelState)
-> Traversal'
     (HashMap Identifier ChannelState)
     (IxValue (HashMap Identifier ChannelState))
forall m. Ixed m => Index m -> Traversal' m (IxValue m)
ix Identifier
Index (HashMap Identifier ChannelState)
channel ((ChannelState -> Const (First (Map Char Text)) ChannelState)
 -> HashMap Identifier ChannelState
 -> Const (First (Map Char Text)) (HashMap Identifier ChannelState))
-> ((Map Char Text
     -> Const (First (Map Char Text)) (Map Char Text))
    -> ChannelState -> Const (First (Map Char Text)) ChannelState)
-> (Map Char Text -> Const (First (Map Char Text)) (Map Char Text))
-> HashMap Identifier ChannelState
-> Const (First (Map Char Text)) (HashMap Identifier ChannelState)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Map Char Text -> Const (First (Map Char Text)) (Map Char Text))
-> ChannelState -> Const (First (Map Char Text)) ChannelState
Lens' ChannelState (Map Char Text)
chanModes) NetworkState
cs of
                    Just Map Char Text
modeMap | Bool -> Bool
not (Map Char Text -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null Map Char Text
modeMap) ->
                        Image'
" " Image' -> Image' -> Image'
forall a. Semigroup a => a -> a -> a
<> HashMap Char Attr -> String -> Image'
modesImage (Getting (HashMap Char Attr) Palette (HashMap Char Attr)
-> Palette -> HashMap Char Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting (HashMap Char Attr) Palette (HashMap Char Attr)
Lens' Palette (HashMap Char Attr)
palCModes Palette
pal) (Map Char Text -> String
forall k a. Map k a -> [k]
Map.keys Map Char Text
modeMap)
                    Maybe (Map Char Text)
_ -> Image'
forall a. Monoid a => a
mempty
               )

viewSubfocusLabel :: Palette -> Subfocus -> Maybe Image'
viewSubfocusLabel :: Palette -> Subfocus -> Maybe Image'
viewSubfocusLabel Palette
pal Subfocus
subfocus =
  case Subfocus
subfocus of
    Subfocus
FocusMessages     -> Maybe Image'
forall a. Maybe a
Nothing
    FocusWindows WindowsFilter
filt -> Image' -> Maybe Image'
forall a. a -> Maybe a
Just (Image' -> Maybe Image') -> Image' -> Maybe Image'
forall a b. (a -> b) -> a -> b
$ Attr -> String -> Image'
string (Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palLabel Palette
pal) String
"windows" Image' -> Image' -> Image'
forall a. Semigroup a => a -> a -> a
<>
                                Maybe Text -> Image'
opt (WindowsFilter -> Maybe Text
windowFilterName WindowsFilter
filt)
    Subfocus
FocusInfo         -> Image' -> Maybe Image'
forall a. a -> Maybe a
Just (Image' -> Maybe Image') -> Image' -> Maybe Image'
forall a b. (a -> b) -> a -> b
$ Attr -> String -> Image'
string (Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palLabel Palette
pal) String
"info"
    Subfocus
FocusUsers        -> Image' -> Maybe Image'
forall a. a -> Maybe a
Just (Image' -> Maybe Image') -> Image' -> Maybe Image'
forall a b. (a -> b) -> a -> b
$ Attr -> String -> Image'
string (Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palLabel Palette
pal) String
"users"
    Subfocus
FocusMentions     -> Image' -> Maybe Image'
forall a. a -> Maybe a
Just (Image' -> Maybe Image') -> Image' -> Maybe Image'
forall a b. (a -> b) -> a -> b
$ Attr -> String -> Image'
string (Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palLabel Palette
pal) String
"mentions"
    Subfocus
FocusDCC          -> Image' -> Maybe Image'
forall a. a -> Maybe a
Just (Image' -> Maybe Image') -> Image' -> Maybe Image'
forall a b. (a -> b) -> a -> b
$ Attr -> String -> Image'
string (Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palLabel Palette
pal) String
"dcc"
    Subfocus
FocusPalette      -> Image' -> Maybe Image'
forall a. a -> Maybe a
Just (Image' -> Maybe Image') -> Image' -> Maybe Image'
forall a b. (a -> b) -> a -> b
$ Attr -> String -> Image'
string (Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palLabel Palette
pal) String
"palette"
    Subfocus
FocusDigraphs     -> Image' -> Maybe Image'
forall a. a -> Maybe a
Just (Image' -> Maybe Image') -> Image' -> Maybe Image'
forall a b. (a -> b) -> a -> b
$ Attr -> String -> Image'
string (Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palLabel Palette
pal) String
"digraphs"
    Subfocus
FocusKeyMap       -> Image' -> Maybe Image'
forall a. a -> Maybe a
Just (Image' -> Maybe Image') -> Image' -> Maybe Image'
forall a b. (a -> b) -> a -> b
$ Attr -> String -> Image'
string (Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palLabel Palette
pal) String
"keymap"
    FocusHelp Maybe Text
mb      -> Image' -> Maybe Image'
forall a. a -> Maybe a
Just (Image' -> Maybe Image') -> Image' -> Maybe Image'
forall a b. (a -> b) -> a -> b
$ Attr -> String -> Image'
string (Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palLabel Palette
pal) String
"help" Image' -> Image' -> Image'
forall a. Semigroup a => a -> a -> a
<> Maybe Text -> Image'
opt Maybe Text
mb
    Subfocus
FocusIgnoreList   -> Image' -> Maybe Image'
forall a. a -> Maybe a
Just (Image' -> Maybe Image') -> Image' -> Maybe Image'
forall a b. (a -> b) -> a -> b
$ Attr -> String -> Image'
string (Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palLabel Palette
pal) String
"ignores"
    Subfocus
FocusRtsStats     -> Image' -> Maybe Image'
forall a. a -> Maybe a
Just (Image' -> Maybe Image') -> Image' -> Maybe Image'
forall a b. (a -> b) -> a -> b
$ Attr -> String -> Image'
string (Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palLabel Palette
pal) String
"rtsstats"
    FocusCert{}       -> Image' -> Maybe Image'
forall a. a -> Maybe a
Just (Image' -> Maybe Image') -> Image' -> Maybe Image'
forall a b. (a -> b) -> a -> b
$ Attr -> String -> Image'
string (Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palLabel Palette
pal) String
"cert"
    FocusMasks Char
m      -> Image' -> Maybe Image'
forall a. a -> Maybe a
Just (Image' -> Maybe Image') -> Image' -> Maybe Image'
forall a b. (a -> b) -> a -> b
$ [Image'] -> Image'
forall a. Monoid a => [a] -> a
mconcat
      [ Attr -> String -> Image'
string (Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palLabel Palette
pal) String
"masks"
      , Attr -> Char -> Image'
char Attr
defAttr Char
':'
      , Attr -> Char -> Image'
char (Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palLabel Palette
pal) Char
m
      ]
  where
    opt :: Maybe Text -> Image'
opt = (Text -> Image') -> Maybe Text -> Image'
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (\Text
cmd -> Attr -> Char -> Image'
char Attr
defAttr Char
':' Image' -> Image' -> Image'
forall a. Semigroup a => a -> a -> a
<>
                           Attr -> Text -> Image'
text' (Getting Attr Palette Attr -> Palette -> Attr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Attr Palette Attr
Lens' Palette Attr
palLabel Palette
pal) Text
cmd)

windowFilterName :: WindowsFilter -> Maybe Text
windowFilterName :: WindowsFilter -> Maybe Text
windowFilterName WindowsFilter
x =
  case WindowsFilter
x of
    WindowsFilter
AllWindows     -> Maybe Text
forall a. Maybe a
Nothing
    WindowsFilter
NetworkWindows -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"networks"
    WindowsFilter
ChannelWindows -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"channels"
    WindowsFilter
UserWindows    -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"users"