module Client.View.Messages
( chatMessageImages
) where
import Client.Configuration
import Client.Image.LineWrap
import Client.Image.Message
import Client.Image.PackedImage
import Client.Image.Palette
import Client.Message
import Client.State
import Client.State.Focus
import Client.State.Network
import Client.State.Window
import Control.Lens
import Control.Monad
import Data.Semigroup
import Graphics.Vty.Attributes
import qualified Graphics.Vty.Image as Vty
import Irc.Identifier
import Irc.Message
chatMessageImages :: Focus -> Int -> ClientState -> [Vty.Image]
chatMessageImages focus w st =
case preview (clientWindows . ix focus) st of
Nothing -> []
Just win ->
let msgs = toListOf each (view winMessages win)
hideMeta = view winHideMeta win in
case clientMatcher st of
Just matcher -> windowLineProcessor hideMeta (filter (views wlText matcher) msgs)
Nothing ->
case view winMarker win of
Nothing -> windowLineProcessor hideMeta msgs
Just n ->
windowLineProcessor hideMeta l ++
[marker] ++
windowLineProcessor hideMeta r
where
(l,r) = splitAt n msgs
where
palette = clientPalette st
marker = Vty.string (view palLineMarker palette) (replicate w '-')
windowLineProcessor hideMeta
| view clientDetailView st =
if hideMeta
then detailedImagesWithoutMetadata st
else map (views wlFullImage unpackImage)
| otherwise = windowLinesToImages st w hideMeta . filter (not . isNoisy)
isNoisy msg =
case view wlSummary msg of
ReplySummary code -> squelchIrcMsg (Reply code [])
_ -> False
detailedImagesWithoutMetadata :: ClientState -> [WindowLine] -> [Vty.Image]
detailedImagesWithoutMetadata st wwls =
case gatherMetadataLines st wwls of
([], []) -> []
([], w:ws) -> views wlFullImage unpackImage w
: detailedImagesWithoutMetadata st ws
(_:_, wls) -> detailedImagesWithoutMetadata st wls
windowLinesToImages ::
ClientState ->
Int ->
Bool ->
[WindowLine] ->
[Vty.Image]
windowLinesToImages st w hideMeta wwls =
case gatherMetadataLines st wwls of
([], []) -> []
([], wl:wls) ->
map unpackImage
(lineWrapChat w
(view (clientConfig . configIndentWrapped) st)
(view wlImage wl))
++ windowLinesToImages st w hideMeta wls
((img,who,mbnext):mds, wls)
| hideMeta -> windowLinesToImages st w hideMeta wls
| otherwise ->
mkLines w (startMetadata img mbnext who mds palette)
++ windowLinesToImages st w hideMeta wls
where
palette = clientPalette st
mkLines :: Int -> [Vty.Image] -> [Vty.Image]
mkLines _ [] = []
mkLines w (x:xs) = reverse (mkLines1 w x xs)
mkLines1 :: Int -> Vty.Image -> [Vty.Image] -> [Vty.Image]
mkLines1 _ x [] = [x]
mkLines1 w x (y:ys)
| Vty.imageWidth x' <= w = mkLines1 w x' ys
| otherwise = x : mkLines1 w y ys
where
x' = x Vty.<|> Vty.char defAttr ' ' Vty.<|> y
type MetadataState =
Identifier ->
[(Image',Identifier,Maybe Identifier)] ->
Palette ->
[Vty.Image]
startMetadata ::
Image' ->
Maybe Identifier ->
MetadataState
startMetadata img mbnext who mds palette =
let acc = unpackImage (quietIdentifier palette who <> img)
in transitionMetadata acc mbnext who mds palette
transitionMetadata ::
Vty.Image ->
Maybe Identifier ->
MetadataState
transitionMetadata acc mbwho who mds palette =
case mbwho of
Nothing -> continueMetadata acc who mds palette
Just who' ->
let acc' = acc Vty.<|> unpackImage (quietIdentifier palette who')
in continueMetadata acc' who' mds palette
continueMetadata :: Vty.Image -> MetadataState
continueMetadata acc _ [] _ = [acc]
continueMetadata acc who1 ((img, who2, mbwho3):mds) palette
| who1 == who2 = let acc' = acc Vty.<|> unpackImage img
in transitionMetadata acc' mbwho3 who2 mds palette
| otherwise = acc : startMetadata img mbwho3 who2 mds palette
gatherMetadataLines ::
ClientState ->
[WindowLine] ->
( [(Image', Identifier, Maybe Identifier)] , [ WindowLine ] )
gatherMetadataLines st = go []
where
go acc (w:ws)
| Just (img,who,mbnext) <- metadataWindowLine st w =
go ((img,who,mbnext) : acc) ws
go acc ws = (acc,ws)
metadataWindowLine ::
ClientState ->
WindowLine ->
Maybe (Image', Identifier, Maybe Identifier)
metadataWindowLine st wl =
case view wlSummary wl of
ChatSummary who -> (ignoreImage, who, Nothing) <$ guard (identIgnored who st)
summary -> metadataImg summary