glirc-2.38: src/Client/View/Mentions.hs
{-# Language BangPatterns #-}
{-|
Module : Client.View.Mentions
Description : Mentions view
Copyright : (c) Eric Mertens, 2016
License : ISC
Maintainer : emertens@gmail.com
This module provides the lines that have been highlighted
across the client in sorted order.
-}
module Client.View.Mentions
( mentionsViewLines
) where
import Client.Configuration (PaddingMode, configNickPadding)
import Client.Message
import Client.Image.Message
import Client.Image.PackedImage
import Client.Image.Palette (Palette)
import Client.Image.StatusLine
import Client.State
import Client.State.Focus
import Client.State.Window
import Control.Lens
import qualified Data.Map as Map
import Data.Time (UTCTime)
-- | Generate the list of message lines marked important ordered by
-- time. Each run of lines from the same channel will be grouped
-- together. Messages are headed by their window, network, and channel.
mentionsViewLines :: Int -> ClientState -> [Image']
mentionsViewLines w st = addMarkers w st entries
where
detail = view clientDetailView st
padAmt = view (clientConfig . configNickPadding) st
palette = clientPalette st
filt
| clientIsFiltered st = clientFilter st (view wlText)
| otherwise = filter (\x -> WLImportant == view wlImportance x)
entries = merge
[windowEntries filt palette w padAmt detail focus v
| (focus, v) <- Map.toList (view clientWindows st) ]
data MentionLine = MentionLine
{ mlTimestamp :: UTCTime -- ^ message timestamp for sorting
, mlFocus :: Focus -- ^ associated window
, mlImage :: [Image'] -- ^ wrapped rendered lines
}
-- | Insert channel name markers between messages from different channels
addMarkers ::
Int {- ^ draw width -} ->
ClientState {- ^ client state -} ->
[MentionLine] {- ^ list of mentions in time order -} ->
[Image'] {- ^ mention images and channel labels -}
addMarkers _ _ [] = []
addMarkers w !st (!ml : xs)
= minorStatusLineImage (mlFocus ml) FocusMessages w False st
: concatMap mlImage (ml:same)
++ addMarkers w st rest
where
isSame ml' = mlFocus ml == mlFocus ml'
(same,rest) = span isSame xs
windowEntries ::
([WindowLine] -> [WindowLine])
{- ^ filter -} ->
Palette {- ^ palette -} ->
Int {- ^ draw columns -} ->
PaddingMode {- ^ nick padding -} ->
Bool {- ^ detailed view -} ->
Focus {- ^ window focus -} ->
Window {- ^ window -} ->
[MentionLine]
windowEntries filt palette w padAmt detailed focus win =
[ MentionLine
{ mlTimestamp = views wlTimestamp unpackUTCTime l
, mlFocus = focus
, mlImage = case metadataImg (view wlSummary l) of
_ | detailed -> [view wlFullImage l]
Just (img, _, _) -> [img]
Nothing -> drawWindowLine palette w padAmt l
}
| l <- filt $ prefilt $ toListOf (winMessages . each) win
]
where
prefilt
| detailed = id
| otherwise = filter isChat
isChat msg =
case view wlSummary msg of
ChatSummary{} -> True
_ -> False
-- | Merge a list of sorted lists of mention lines into a single sorted list
-- in descending order.
merge :: [[MentionLine]] -> [MentionLine]
merge [] = []
merge [x] = x
merge xss = merge (merge2s xss)
merge2s :: [[MentionLine]] -> [[MentionLine]]
merge2s (x:y:z) = merge2 x y : merge2s z
merge2s xs = xs
merge2 :: [MentionLine] -> [MentionLine] -> [MentionLine]
merge2 [] ys = ys
merge2 xs [] = xs
merge2 xxs@(x:xs) yys@(y:ys)
| mlTimestamp x >= mlTimestamp y = x : merge2 xs yys
| otherwise = y : merge2 xxs ys