{-# Language OverloadedStrings #-}
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.List
import Irc.Identifier
import Irc.Message
import Irc.UserInfo
chatMessageImages :: Focus -> Int -> ClientState -> [Image']
chatMessageImages :: Focus -> Int -> ClientState -> [Image']
chatMessageImages Focus
focus Int
w ClientState
st =
case forall s (m :: * -> *) a.
MonadReader s m =>
Getting (First a) s a -> m (Maybe a)
preview (Lens' ClientState (Map Focus Window)
clientWindows forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall m. Ixed m => Index m -> Traversal' m (IxValue m)
ix Focus
focus) ClientState
st of
Maybe Window
Nothing -> []
Just Window
win ->
let msgs :: [WindowLine]
msgs = forall a s. Getting (Endo [a]) s a -> s -> [a]
toListOf forall s t a b. Each s t a b => Traversal s t a b
each (forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Lens' Window WindowLines
winMessages Window
win)
hideMeta :: Bool
hideMeta = forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Lens' Window Bool
winHideMeta Window
win in
if ClientState -> Bool
clientIsFiltered ClientState
st
then Bool -> [WindowLine] -> [Image']
windowLineProcessor Bool
hideMeta (forall a. ClientState -> (a -> Text) -> [a] -> [a]
clientFilter ClientState
st (forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getter WindowLine Text
wlText) [WindowLine]
msgs)
else
case forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Lens' Window (Maybe Int)
winMarker Window
win of
Maybe Int
Nothing -> Bool -> [WindowLine] -> [Image']
windowLineProcessor Bool
hideMeta [WindowLine]
msgs
Just Int
n ->
Bool -> [WindowLine] -> [Image']
windowLineProcessor Bool
hideMeta [WindowLine]
l forall a. [a] -> [a] -> [a]
++
[Image'
marker] forall a. [a] -> [a] -> [a]
++
Bool -> [WindowLine] -> [Image']
windowLineProcessor Bool
hideMeta [WindowLine]
r
where
([WindowLine]
l,[WindowLine]
r) = forall a. Int -> [a] -> ([a], [a])
splitAt Int
n [WindowLine]
msgs
where
palette :: Palette
palette = ClientState -> Palette
clientPalette ClientState
st
marker :: Image'
marker = Attr -> String -> Image'
string (forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Lens' Palette Attr
palLineMarker Palette
palette) (forall a. Int -> a -> [a]
replicate Int
w Char
'-')
windowLineProcessor :: Bool -> [WindowLine] -> [Image']
windowLineProcessor Bool
hideMeta
| forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Lens' ClientState Bool
clientDetailView ClientState
st =
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (forall a. [a] -> [a]
reverse forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Image' -> [Image']
fullLineWrap Int
w) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
if Bool
hideMeta
then ClientState -> [WindowLine] -> [Image']
detailedImagesWithoutMetadata ClientState
st
else forall a b. (a -> b) -> [a] -> [b]
map (forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Lens' WindowLine Image'
wlFullImage)
| Bool
otherwise = ClientState -> Int -> Bool -> [WindowLine] -> [Image']
windowLinesToImages ClientState
st Int
w Bool
hideMeta forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. WindowLine -> Bool
isNoisy)
isNoisy :: WindowLine -> Bool
isNoisy WindowLine
msg =
case forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Lens' WindowLine IrcSummary
wlSummary WindowLine
msg of
ReplySummary ReplyCode
code -> IrcMsg -> Bool
squelchIrcMsg (Text -> ReplyCode -> [Text] -> IrcMsg
Reply Text
"" ReplyCode
code [])
IrcSummary
_ -> Bool
False
detailedImagesWithoutMetadata :: ClientState -> [WindowLine] -> [Image']
detailedImagesWithoutMetadata :: ClientState -> [WindowLine] -> [Image']
detailedImagesWithoutMetadata ClientState
st [WindowLine]
wwls =
case ClientState
-> [WindowLine]
-> ([(Image', Identifier, Maybe Identifier)], [WindowLine])
gatherMetadataLines ClientState
st [WindowLine]
wwls of
([], []) -> []
([], WindowLine
w:[WindowLine]
ws) -> forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Lens' WindowLine Image'
wlFullImage WindowLine
w
forall a. a -> [a] -> [a]
: ClientState -> [WindowLine] -> [Image']
detailedImagesWithoutMetadata ClientState
st [WindowLine]
ws
((Image', Identifier, Maybe Identifier)
_:[(Image', Identifier, Maybe Identifier)]
_, [WindowLine]
wls) -> ClientState -> [WindowLine] -> [Image']
detailedImagesWithoutMetadata ClientState
st [WindowLine]
wls
windowLinesToImages ::
ClientState ->
Int ->
Bool ->
[WindowLine] ->
[Image']
windowLinesToImages :: ClientState -> Int -> Bool -> [WindowLine] -> [Image']
windowLinesToImages ClientState
st Int
w Bool
hideMeta [WindowLine]
wwls =
case ClientState
-> [WindowLine]
-> ([(Image', Identifier, Maybe Identifier)], [WindowLine])
gatherMetadataLines ClientState
st [WindowLine]
wwls of
([], []) -> []
([], WindowLine
wl:[WindowLine]
wls) -> Palette -> Int -> PaddingMode -> WindowLine -> [Image']
drawWindowLine Palette
palette Int
w PaddingMode
padAmt WindowLine
wl
forall a. [a] -> [a] -> [a]
++ ClientState -> Int -> Bool -> [WindowLine] -> [Image']
windowLinesToImages ClientState
st Int
w Bool
hideMeta [WindowLine]
wls
((Image'
img,Identifier
who,Maybe Identifier
mbnext):[(Image', Identifier, Maybe Identifier)]
mds, [WindowLine]
wls)
| Bool
hideMeta -> ClientState -> Int -> Bool -> [WindowLine] -> [Image']
windowLinesToImages ClientState
st Int
w Bool
hideMeta [WindowLine]
wls
| Bool
otherwise ->
Image' -> Image' -> [Image']
wrap
Image'
metaPad
(forall a. Monoid a => [a] -> a
mconcat
(forall a. a -> [a] -> [a]
intersperse Image'
" "
(Image' -> Maybe Identifier -> MetadataState
startMetadata Image'
img Maybe Identifier
mbnext Identifier
who [(Image', Identifier, Maybe Identifier)]
mds Palette
palette)))
forall a. [a] -> [a] -> [a]
++ ClientState -> Int -> Bool -> [WindowLine] -> [Image']
windowLinesToImages ClientState
st Int
w Bool
hideMeta [WindowLine]
wls
where
palette :: Palette
palette = ClientState -> Palette
clientPalette ClientState
st
config :: Configuration
config = forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Lens' ClientState Configuration
clientConfig ClientState
st
padAmt :: PaddingMode
padAmt = forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Lens' Configuration PaddingMode
configNickPadding Configuration
config
padNick :: Image' -> Image'
padNick = PaddingMode -> Image' -> Image'
nickPad PaddingMode
padAmt
metaPad :: Image'
metaPad = Image'
" " forall a. Semigroup a => a -> a -> a
<> Image' -> Image'
padNick Image'
""
wrap :: Image' -> Image' -> [Image']
wrap Image'
pfx Image'
body = forall a. [a] -> [a]
reverse (Int -> Image' -> Image' -> [Image']
lineWrapPrefix Int
w Image'
pfx Image'
body)
type MetadataState =
Identifier ->
[(Image',Identifier,Maybe Identifier)] ->
Palette ->
[Image']
startMetadata ::
Image' ->
Maybe Identifier ->
MetadataState
startMetadata :: Image' -> Maybe Identifier -> MetadataState
startMetadata Image'
img Maybe Identifier
mbnext Identifier
who [(Image', Identifier, Maybe Identifier)]
mds Palette
palette =
let acc :: Image'
acc = Palette -> Identifier -> Image'
quietIdentifier Palette
palette Identifier
who forall a. Semigroup a => a -> a -> a
<> Image'
img
in Image' -> Maybe Identifier -> MetadataState
transitionMetadata Image'
acc Maybe Identifier
mbnext Identifier
who [(Image', Identifier, Maybe Identifier)]
mds Palette
palette
transitionMetadata ::
Image' ->
Maybe Identifier ->
MetadataState
transitionMetadata :: Image' -> Maybe Identifier -> MetadataState
transitionMetadata Image'
acc Maybe Identifier
mbwho Identifier
who [(Image', Identifier, Maybe Identifier)]
mds Palette
palette =
case Maybe Identifier
mbwho of
Maybe Identifier
Nothing -> Image' -> MetadataState
continueMetadata Image'
acc Identifier
who [(Image', Identifier, Maybe Identifier)]
mds Palette
palette
Just Identifier
who' ->
let acc' :: Image'
acc' = Image'
acc forall a. Semigroup a => a -> a -> a
<> Palette -> Identifier -> Image'
quietIdentifier Palette
palette Identifier
who'
in Image' -> MetadataState
continueMetadata Image'
acc' Identifier
who' [(Image', Identifier, Maybe Identifier)]
mds Palette
palette
continueMetadata :: Image' -> MetadataState
continueMetadata :: Image' -> MetadataState
continueMetadata Image'
acc Identifier
_ [] Palette
_ = [Image'
acc]
continueMetadata Image'
acc Identifier
who1 ((Image'
img, Identifier
who2, Maybe Identifier
mbwho3):[(Image', Identifier, Maybe Identifier)]
mds) Palette
palette
| Identifier
who1 forall a. Eq a => a -> a -> Bool
/= Identifier
""
, Identifier
who1 forall a. Eq a => a -> a -> Bool
== Identifier
who2
, let acc' :: Image'
acc' = Image'
acc forall a. Semigroup a => a -> a -> a
<> Image'
img
= Image' -> Maybe Identifier -> MetadataState
transitionMetadata Image'
acc' Maybe Identifier
mbwho3 Identifier
who2 [(Image', Identifier, Maybe Identifier)]
mds Palette
palette
| Bool
otherwise = Image'
acc forall a. a -> [a] -> [a]
: Image' -> Maybe Identifier -> MetadataState
startMetadata Image'
img Maybe Identifier
mbwho3 Identifier
who2 [(Image', Identifier, Maybe Identifier)]
mds Palette
palette
gatherMetadataLines ::
ClientState ->
[WindowLine] ->
( [(Image', Identifier, Maybe Identifier)] , [ WindowLine ] )
gatherMetadataLines :: ClientState
-> [WindowLine]
-> ([(Image', Identifier, Maybe Identifier)], [WindowLine])
gatherMetadataLines ClientState
st = [(Image', Identifier, Maybe Identifier)]
-> [WindowLine]
-> ([(Image', Identifier, Maybe Identifier)], [WindowLine])
go []
where
go :: [(Image', Identifier, Maybe Identifier)]
-> [WindowLine]
-> ([(Image', Identifier, Maybe Identifier)], [WindowLine])
go [(Image', Identifier, Maybe Identifier)]
acc [WindowLine]
ws
| Just (Image'
img, [WindowLine]
ws') <- ClientState -> [WindowLine] -> Maybe (Image', [WindowLine])
bulkMetadata ClientState
st [WindowLine]
ws =
[(Image', Identifier, Maybe Identifier)]
-> [WindowLine]
-> ([(Image', Identifier, Maybe Identifier)], [WindowLine])
go ((Image'
img, Identifier
"", forall a. Maybe a
Nothing) forall a. a -> [a] -> [a]
: [(Image', Identifier, Maybe Identifier)]
acc) [WindowLine]
ws'
go [(Image', Identifier, Maybe Identifier)]
acc (WindowLine
w:[WindowLine]
ws)
| Just (Image'
img,Identifier
who,Maybe Identifier
mbnext) <- ClientState
-> WindowLine -> Maybe (Image', Identifier, Maybe Identifier)
metadataWindowLine ClientState
st WindowLine
w =
[(Image', Identifier, Maybe Identifier)]
-> [WindowLine]
-> ([(Image', Identifier, Maybe Identifier)], [WindowLine])
go ((Image'
img,Identifier
who,Maybe Identifier
mbnext) forall a. a -> [a] -> [a]
: [(Image', Identifier, Maybe Identifier)]
acc) [WindowLine]
ws
go [(Image', Identifier, Maybe Identifier)]
acc [WindowLine]
ws = ([(Image', Identifier, Maybe Identifier)]
acc,[WindowLine]
ws)
metadataWindowLine ::
ClientState ->
WindowLine ->
Maybe (Image', Identifier, Maybe Identifier)
metadataWindowLine :: ClientState
-> WindowLine -> Maybe (Image', Identifier, Maybe Identifier)
metadataWindowLine ClientState
st WindowLine
wl =
case forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Lens' WindowLine IrcSummary
wlSummary WindowLine
wl of
ChatSummary UserInfo
who -> (Palette -> Image'
ignoreImage Palette
pal, UserInfo -> Identifier
userNick UserInfo
who, forall a. Maybe a
Nothing) forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall (f :: * -> *). Alternative f => Bool -> f ()
guard (UserInfo -> ClientState -> Bool
identIgnored UserInfo
who ClientState
st)
IrcSummary
summary -> Palette
-> IrcSummary -> Maybe (Image', Identifier, Maybe Identifier)
metadataImg (ClientState -> Palette
clientPalette ClientState
st) IrcSummary
summary
where
pal :: Palette
pal = ClientState -> Palette
clientPalette ClientState
st
bulkMetadata ::
ClientState ->
[WindowLine] ->
Maybe (Image', [WindowLine])
bulkMetadata :: ClientState -> [WindowLine] -> Maybe (Image', [WindowLine])
bulkMetadata ClientState
st [WindowLine]
wls
| ([WindowLine]
quits, [WindowLine]
wls') <- forall a. (a -> Bool) -> [a] -> ([a], [a])
span WindowLine -> Bool
isMassQuit [WindowLine]
wls
, let n :: Int
n = forall (t :: * -> *) a. Foldable t => t a -> Int
length [WindowLine]
quits
, Int
n forall a. Ord a => a -> a -> Bool
> Int
10
= forall a. a -> Maybe a
Just (Attr -> String -> Image'
string (forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Lens' Palette Attr
palPart Palette
pal) (String
"(split:" forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show Int
n forall a. Semigroup a => a -> a -> a
<> String
")x"), [WindowLine]
wls')
where
pal :: Palette
pal = ClientState -> Palette
clientPalette ClientState
st
bulkMetadata ClientState
_ [WindowLine]
_ = forall a. Maybe a
Nothing
isMassQuit :: WindowLine -> Bool
isMassQuit :: WindowLine -> Bool
isMassQuit WindowLine
wl
| QuitSummary Identifier
_ QuitKind
MassQuit <- forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Lens' WindowLine IrcSummary
wlSummary WindowLine
wl = Bool
True
| Bool
otherwise = Bool
False