Skip to content

Commit 4fd5d78

Browse files
committed
Merge branch 'develop'
2 parents d02fe5f + dc2d0e1 commit 4fd5d78

22 files changed

+223
-69
lines changed

CHANGELOG.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,31 @@
11

2+
90000.0.0
3+
=========
4+
5+
NOTE: this version of Matterhorn requires server version 9.0 or greater.
6+
7+
Package changes:
8+
* Updated to use Vty 6 for crossplatform terminal support, meaning
9+
Matterhorn can now be built and run on Windows terminals. Please let
10+
us know if you try this and encounter any issues!
11+
12+
Enhancements:
13+
* Added support for a new "auto" mode to determine channel list width.
14+
There is now a new `auto` value for the `channelListWidth`
15+
configuration file setting. Its default is unchanged and it can still
16+
take an integer value specifying the channel list width in columns.
17+
If set to `auto`, its value is determined by Matterhorn, bounded by
18+
minimum and maximum values, as a function of window width. This is
19+
intended to give nicer results as font size decreases, up to a point.
20+
* Add a `/write-theme` command to write the current theme to an INI
21+
file.
22+
23+
Bug fixes:
24+
* Updated channel viewing book-keeping to work with changes in
25+
Mattermost 9.0.
26+
* Fixed an issue where terminal input provided right before the UI is
27+
initialized could cause the application to crash.
28+
229
50200.19.0
330
==========
431

matterhorn.cabal

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: matterhorn
2-
version: 50200.19.0
2+
version: 90000.0.0
33
synopsis: Terminal client for the Mattermost chat system
44
description: This is a terminal client for the Mattermost chat
55
system. Please see the README for a list of
@@ -170,31 +170,32 @@ library
170170
ghc-options: -fhide-source-paths
171171

172172
build-depends: base >=4.8 && <5
173-
, mattermost-api == 50200.15.0
173+
, mattermost-api == 90000.0.0
174174
, base-compat >= 0.9 && < 0.13
175175
, unordered-containers >= 0.2 && < 0.3
176176
, containers >= 0.5.7 && < 0.7
177177
, split >= 0.2 && < 0.3
178178
, data-clist >= 0.1.2 && < 0.2
179179
, semigroups >= 0.18 && < 0.20
180-
, connection >= 0.2 && < 0.4
181-
, text >= 1.2.5.0 && < 2.0
180+
, crypton-connection >= 0.3.1 && < 0.4
181+
, text >= 1.2.5.0 && < 2.1
182182
, bytestring >= 0.10 && < 0.12
183183
, stm >= 2.4 && < 2.6
184184
, config-ini >= 0.2.2.0 && < 0.3
185185
, process >= 1.4 && < 1.7
186186
, microlens-platform >= 0.3 && < 0.5
187-
, brick >= 1.8 && < 1.9
187+
, brick >= 2.0 && < 2.1
188188
, brick-skylighting >= 1.0 && < 1.1
189-
, vty >= 5.38 && < 5.39
189+
, vty >= 6.0 && < 6.1
190+
, vty-crossplatform >= 0.2.0.0 && < 0.3.0.0
190191
, word-wrap >= 0.4.0 && < 0.5
191-
, transformers >= 0.4 && < 0.6
192+
, transformers >= 0.4 && < 0.7
192193
, text-zipper >= 0.13 && < 0.14
193194
, time >= 1.6 && < 2.0
194195
, xdg-basedir >= 0.2 && < 0.3
195196
, filepath >= 1.4 && < 1.5
196197
, directory >= 1.3 && < 1.4
197-
, vector < 0.13
198+
, vector < 0.14
198199
, strict >= 0.3 && < 0.6
199200
, hashable >= 1.2 && < 1.5
200201
, commonmark >= 0.2.1 && < 0.3
@@ -207,7 +208,7 @@ library
207208
, mtl >= 2.2 && < 2.4
208209
, aspell-pipe >= 0.6 && < 0.7
209210
, stm-delay >= 0.1 && < 0.2
210-
, unix >= 2.7.1.0 && < 2.9
211+
, unix-compat >= 0.6 && < 0.8
211212
, skylighting-core >= 0.12 && < 0.13
212213
, timezone-olson >= 0.2 && < 0.3
213214
, timezone-series >= 0.1.6.1 && < 0.2

src/Matterhorn/App.hs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ import Matterhorn.Prelude
1010
import Brick
1111
import Control.Monad.Trans.Except ( runExceptT )
1212
import qualified Graphics.Vty as Vty
13+
import qualified Graphics.Vty.CrossPlatform as Vty
1314
import Text.Aspell ( stopAspell )
1415
import GHC.Conc (getNumProcessors, setNumCapabilities)
15-
import System.Posix.IO ( stdInput )
1616

1717
import Network.Mattermost
1818

@@ -32,11 +32,14 @@ app :: App ChatState MHEvent Name
3232
app =
3333
App { appDraw = draw
3434
, appHandleEvent = Events.onEvent
35-
, appStartEvent = return ()
3635
, appAttrMap = (^.csResources.crTheme)
3736
, appChooseCursor = \s cs -> do
3837
tId <- s^.csCurrentTeamId
3938
cursorByMode cs s tId (teamMode $ s^.csTeam(tId))
39+
, appStartEvent = do
40+
vty <- getVtyHandle
41+
(w, h) <- liftIO $ Vty.displayBounds $ Vty.outputIface vty
42+
runMHEvent $ Events.setWindowSize w h
4043
}
4144

4245
cursorByMode :: [CursorLocation Name] -> ChatState -> TeamId -> Mode -> Maybe (CursorLocation Name)
@@ -84,12 +87,7 @@ runMatterhorn opts config = do
8487
setupCpuUsage config
8588

8689
let mkVty = do
87-
mEraseChar <- Vty.getTtyEraseChar stdInput
88-
let addEraseChar cfg = case mEraseChar of
89-
Nothing -> cfg
90-
Just ch -> cfg { Vty.inputMap = (Nothing, [ch], Vty.EvKey Vty.KBS []) : Vty.inputMap cfg }
91-
92-
vty <- Vty.mkVty $ addEraseChar Vty.defaultConfig
90+
vty <- Vty.mkVty Vty.defaultConfig
9391
let output = Vty.outputIface vty
9492
Vty.setMode output Vty.BracketedPaste True
9593
Vty.setMode output Vty.Hyperlink $ configHyperlinkingMode config

src/Matterhorn/Config.hs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ fromIni = do
8080
configTeam <- fieldMbOf "team" stringField
8181
configPort <- fieldDefOf "port" number (configPort defaultConfig)
8282
configUrlPath <- fieldMbOf "urlPath" stringField
83-
configChannelListWidth <- fieldDefOf "channelListWidth" number
83+
configChannelListWidth <- fieldDefOf "channelListWidth" channelListWidthField
8484
(configChannelListWidth defaultConfig)
8585
configCpuUsagePolicy <- fieldDefOf "cpuUsagePolicy" cpuUsagePolicy
8686
(configCpuUsagePolicy defaultConfig)
@@ -260,6 +260,14 @@ defaultBindings =
260260
, (MoveCurrentTeamRightEvent , [ ])
261261
]
262262

263+
channelListWidthField :: Text -> Either String ChannelListWidth
264+
channelListWidthField t =
265+
case T.toLower t of
266+
"auto" -> return ChannelListWidthAuto
267+
_ -> case readMaybe (T.unpack t) of
268+
Nothing -> Left "Invalid value for channelListWidth"
269+
Just w -> Right $ ChannelListWidthFixed w
270+
263271
channelListOrientationField :: Text -> Either String ChannelListOrientation
264272
channelListOrientationField t =
265273
case T.toLower t of
@@ -416,7 +424,7 @@ defaultConfig = addDefaultKeys $
416424
, configAspellDictionary = Nothing
417425
, configUnsafeUseHTTP = False
418426
, configValidateServerCertificate = True
419-
, configChannelListWidth = 22
427+
, configChannelListWidth = ChannelListWidthFixed 22
420428
, configLogMaxBufferSize = 200
421429
, configShowOlderEdits = True
422430
, configUserKeys = newKeyConfig allEvents [] []

src/Matterhorn/Constants.hs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ module Matterhorn.Constants
88
, userSigil
99
, userSigilChar
1010
, editMarking
11+
, channelListMinAutoWidth
12+
, channelListMaxAutoWidth
1113
)
1214
where
1315

@@ -17,6 +19,14 @@ import Matterhorn.Prelude
1719
import qualified Data.Text as T
1820

1921

22+
-- | The minimum channel list width when the width is set to 'auto'.
23+
channelListMinAutoWidth :: Int
24+
channelListMinAutoWidth = 24
25+
26+
-- | The maximum channel list width when the width is set to 'auto'.
27+
channelListMaxAutoWidth :: Int
28+
channelListMaxAutoWidth = 44
29+
2030
-- | The number of rows to consider a "page" when scrolling
2131
pageAmount :: Int
2232
pageAmount = 15

src/Matterhorn/Draw/Autocomplete.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import Lens.Micro.Platform ( SimpleGetter, Lens' )
1818
import Network.Mattermost.Types ( User(..), Channel(..), TeamId )
1919

2020
import Matterhorn.Constants ( normalChannelSigil )
21+
import Matterhorn.Draw.ChannelList ( channelListWidth )
2122
import Matterhorn.Draw.Util ( mkChannelName )
2223
import Matterhorn.Themes
2324
import Matterhorn.Types
@@ -93,10 +94,9 @@ renderAutocompleteBox st tId mCurChan which ac =
9394
curUser = myUsername st
9495
cfg = st^.csResources.crConfiguration
9596
showingChanList = configShowChannelList cfg
96-
chanListWidth = configChannelListWidth cfg
9797
maybeLimit = fromMaybe id $ do
9898
let sub = if showingChanList
99-
then chanListWidth + 1
99+
then channelListWidth st + 1
100100
else 0
101101
threadNarrow = threadShowing && (cfg^.configThreadOrientationL `elem` [ThreadLeft, ThreadRight])
102102
threadShowing = isJust $ st^.csTeam(tId).tsThreadInterface

src/Matterhorn/Draw/ChannelList.hs

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,12 @@
1616
-- channels matching the entered text (and highlighting the
1717
-- matching portion).
1818

19-
module Matterhorn.Draw.ChannelList (renderChannelList, renderChannelListHeader) where
19+
module Matterhorn.Draw.ChannelList
20+
( renderChannelList
21+
, renderChannelListHeader
22+
, channelListWidth
23+
)
24+
where
2025

2126
import Prelude ()
2227
import Matterhorn.Prelude
@@ -34,6 +39,7 @@ import qualified Network.Mattermost.Types as MM
3439

3540
import Matterhorn.Draw.Util
3641
import Matterhorn.State.Channels
42+
import Matterhorn.Constants ( channelListMinAutoWidth, channelListMaxAutoWidth )
3743
import Matterhorn.Themes
3844
import Matterhorn.Types
3945
import Matterhorn.Types.Common ( sanitizeUserText )
@@ -54,10 +60,17 @@ data ChannelListEntryData =
5460
, entryUserStatus :: Maybe UserStatus
5561
}
5662

57-
sbRenderer :: ScrollbarRenderer n
63+
sbRenderer :: VScrollbarRenderer n
5864
sbRenderer =
59-
verticalScrollbarRenderer { renderScrollbarHandleBefore = str ""
60-
, renderScrollbarHandleAfter = str ""
65+
verticalScrollbarRenderer { renderVScrollbarHandleBefore = str ""
66+
, renderVScrollbarHandleAfter = str ""
67+
, scrollbarWidthAllocation = 2
68+
, renderVScrollbar =
69+
hLimit 1 $
70+
renderVScrollbar verticalScrollbarRenderer
71+
, renderVScrollbarTrough =
72+
hLimit 1 $
73+
renderVScrollbarTrough verticalScrollbarRenderer
6174
}
6275

6376
renderChannelListHeader :: ChatState -> MM.TeamId -> Widget Name
@@ -84,9 +97,9 @@ renderChannelList :: ChatState -> MM.TeamId -> Widget Name
8497
renderChannelList st tId =
8598
header <=> vpBody
8699
where
87-
(sbOrientation, sbPad) = case st^.csResources.crConfiguration.configChannelListOrientationL of
88-
ChannelListLeft -> (OnLeft, padLeft (Pad 1))
89-
ChannelListRight -> (OnRight, padRight (Pad 1))
100+
sbOrientation = case st^.csResources.crConfiguration.configChannelListOrientationL of
101+
ChannelListLeft -> OnLeft
102+
ChannelListRight -> OnRight
90103
myUsername_ = myUsername st
91104
channelName e = ClickableChannelListEntry $ channelListEntryChannelId e
92105
renderEntry s e = clickable (channelName e) $
@@ -96,7 +109,7 @@ renderChannelList st tId =
96109
withVScrollBars sbOrientation $
97110
withVScrollBarHandles $
98111
withClickableVScrollBars VScrollBar $
99-
viewport (ChannelListViewport tId) Vertical $ sbPad body
112+
viewport (ChannelListViewport tId) Vertical body
100113
body = case teamMode $ st^.csTeam(tId) of
101114
ChannelSelect ->
102115
let zipper = st^.csTeam(tId).tsChannelSelectState.channelSelectMatches
@@ -269,3 +282,16 @@ recentChannelSigil = "<"
269282

270283
returnChannelSigil :: String
271284
returnChannelSigil = "~"
285+
286+
channelListWidthAutoPercent :: Double
287+
channelListWidthAutoPercent = 0.2
288+
289+
channelListWidth :: ChatState -> Int
290+
channelListWidth st =
291+
case configChannelListWidth $ st^.csResources.crConfiguration of
292+
ChannelListWidthFixed w -> w
293+
ChannelListWidthAuto ->
294+
let calcWidth = round $ channelListWidthAutoPercent * (fromIntegral width :: Double)
295+
width = fst $ st^.csResources.crWindowSize
296+
in min channelListMaxAutoWidth $
297+
max channelListMinAutoWidth calcWidth

src/Matterhorn/Draw/Main.hs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import Network.Mattermost.Types ( Type(Direct, Private, Group)
2020
)
2121

2222

23-
import Matterhorn.Draw.ChannelList ( renderChannelList )
23+
import Matterhorn.Draw.ChannelList ( renderChannelList, channelListWidth )
2424
import Matterhorn.Draw.Messages
2525
import Matterhorn.Draw.MessageInterface
2626
import Matterhorn.Draw.Autocomplete
@@ -76,10 +76,9 @@ mainInterface st mode mtId =
7676
mainDisplay = maybeSubdue messageInterface
7777

7878
channelList = channelListMaybeVlimit mode $
79-
hLimit channelListWidth $ case mtId of
79+
hLimit (channelListWidth st) $ case mtId of
8080
Nothing -> fill ' '
8181
Just tId -> renderChannelList st tId
82-
channelListWidth = configChannelListWidth $ st^.csResources.crConfiguration
8382
channelListMaybeVlimit ChannelSelect w =
8483
Widget (hSize w) (vSize w) $ do
8584
ctx <- getContext

src/Matterhorn/Events.hs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
module Matterhorn.Events
22
( onEvent
3+
, setWindowSize
34
)
45
where
56

@@ -194,21 +195,26 @@ onVtyEvent =
194195
]
195196

196197
handleResizeEvent :: Vty.Event -> MH Bool
197-
handleResizeEvent (Vty.EvResize _ _) = do
198+
handleResizeEvent (Vty.EvResize w h) = do
199+
setWindowSize w h
200+
return True
201+
handleResizeEvent _ =
202+
return False
203+
204+
setWindowSize :: Int -> Int -> MH ()
205+
setWindowSize w h = do
198206
-- On resize, invalidate the entire rendering cache since many
199207
-- things depend on the window size.
200208
--
201209
-- Note: we fall through after this because it is sometimes
202210
-- important for modes to have their own additional logic to run
203211
-- when a resize occurs, so we don't want to stop processing here.
212+
csResources.crWindowSize .= (w, h)
213+
204214
mh invalidateCache
205215
withCurrentTeam $ \tId ->
206216
mh $ makeVisible $ SelectedChannelListEntry tId
207217

208-
return True
209-
handleResizeEvent _ =
210-
return False
211-
212218
handleTeamModeEvent :: Vty.Event -> MH Bool
213219
handleTeamModeEvent e = do
214220
withCurrentTeam $ \tId -> do

src/Matterhorn/Events/Websocket.hs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,9 +166,15 @@ handleWebsocketEvent we = do
166166
| otherwise -> return ()
167167

168168
WMChannelViewed
169-
| Just cId <- wepChannelId $ weData we -> refreshChannelById cId
169+
| Just cId <- wepChannelId $ weData we -> mhLog LogGeneral "WMChannelViewed received" >> refreshChannelById cId
170170
| otherwise -> return ()
171171

172+
WMMultipleChannelsViewed ->
173+
case wepChannelTimes $ weData we of
174+
Nothing -> return ()
175+
Just m ->
176+
forM_ (HM.keys m) refreshChannelById
177+
172178
WMChannelUpdated
173179
| Just cId <- webChannelId $ weBroadcast we -> do
174180
mChan <- preuse (csChannel(cId))

0 commit comments

Comments
 (0)