1module Matterhorn.Draw.Util
2  ( withBrackets
3  , renderTime
4  , renderDate
5  , renderKeybindingHelp
6  , insertDateMarkers
7  , getDateFormat
8  , mkChannelName
9  , userSigilFromInfo
10  , multilineHeightLimit
11  )
12where
13
14import           Prelude ()
15import           Matterhorn.Prelude
16
17import           Brick
18import           Data.List ( intersperse )
19import qualified Data.Set as Set
20import qualified Data.Text as T
21import           Network.Mattermost.Types
22
23import           Matterhorn.Constants ( userSigil, normalChannelSigil )
24import           Matterhorn.Themes
25import           Matterhorn.TimeUtils
26import           Matterhorn.Types
27import           Matterhorn.Types.KeyEvents
28import           Matterhorn.Events.Keybindings ( getFirstDefaultBinding )
29
30
31defaultTimeFormat :: Text
32defaultTimeFormat = "%R"
33
34defaultDateFormat :: Text
35defaultDateFormat = "%Y-%m-%d"
36
37multilineHeightLimit :: Int
38multilineHeightLimit = 5
39
40getTimeFormat :: ChatState -> Text
41getTimeFormat st =
42    maybe defaultTimeFormat id (st^.csResources.crConfiguration.configTimeFormatL)
43
44getDateFormat :: ChatState -> Text
45getDateFormat st =
46    maybe defaultDateFormat id (st^.csResources.crConfiguration.configDateFormatL)
47
48renderTime :: ChatState -> UTCTime -> Widget Name
49renderTime st = renderUTCTime (getTimeFormat st) (st^.timeZone)
50
51renderDate :: ChatState -> UTCTime -> Widget Name
52renderDate st = renderUTCTime (getDateFormat st) (st^.timeZone)
53
54renderUTCTime :: Text -> TimeZoneSeries -> UTCTime -> Widget a
55renderUTCTime fmt tz t =
56    if T.null fmt
57    then emptyWidget
58    else withDefAttr timeAttr (txt $ localTimeText fmt $ asLocalTime tz t)
59
60renderKeybindingHelp :: Text -> [KeyEvent] -> Widget Name
61renderKeybindingHelp label evs =
62  let ppEv ev = withDefAttr clientEmphAttr $ txt (ppBinding (getFirstDefaultBinding ev))
63  in hBox $ (intersperse (txt "/") $ ppEv <$> evs) <> [txt (":" <> label)]
64
65-- | Generates a local matterhorn-only client message that creates a
66-- date marker.  The server date is converted to a local time (via
67-- timezone), and midnight of that timezone used to generate date
68-- markers.  Note that the actual time of the server and this client
69-- are still not synchronized, but no manipulations here actually use
70-- the client time.
71insertDateMarkers :: Messages -> Text -> TimeZoneSeries -> Messages
72insertDateMarkers ms datefmt tz = foldr (addMessage . dateMsg) ms dateRange
73    where dateRange = foldr checkDateChange Set.empty ms
74          checkDateChange m = let msgDay = startOfDay (Just tz) (withServerTime (m^.mDate))
75                              in if m^.mDeleted then id else Set.insert msgDay
76          dateMsg d = let t = localTimeText datefmt $ asLocalTime tz d
77                      in newMessageOfType t (C DateTransition) (ServerTime d)
78
79
80withBrackets :: Widget a -> Widget a
81withBrackets w = hBox [str "[", w, str "]"]
82
83userSigilFromInfo :: UserInfo -> Char
84userSigilFromInfo u = case u^.uiStatus of
85    Offline      -> ' '
86    Online       -> '+'
87    Away         -> '-'
88    DoNotDisturb -> '×'
89    Other _      -> '?'
90
91mkChannelName :: ChatState -> ChannelInfo -> Text
92mkChannelName st c = T.append sigil t
93    where
94        t = case c^.cdDMUserId >>= flip userById st of
95            Nothing -> c^.cdName
96            Just u -> u^.uiName
97        sigil = case c^.cdType of
98            Private   -> mempty
99            Ordinary  -> normalChannelSigil
100            Group     -> mempty
101            Direct    -> userSigil
102            Unknown _ -> mempty
103