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