matterhorn-50200.18.0: src/Matterhorn/Events/MessageInterface.hs
{-# LANGUAGE RankNTypes #-}
module Matterhorn.Events.MessageInterface
( handleMessageInterfaceEvent
, messageInterfaceKeyHandlers
, extraEditorKeyHandlers
)
where
import Prelude ()
import Matterhorn.Prelude
import Brick ( BrickEvent(VtyEvent) )
import Brick.Keybindings
import Brick.Widgets.Edit ( handleEditorEvent )
import qualified Graphics.Vty as Vty
import Lens.Micro.Platform ( Lens' )
import Network.Mattermost.Types ( TeamId )
import Matterhorn.Types
import Matterhorn.Events.SaveAttachmentWindow
import Matterhorn.Events.ManageAttachments
import Matterhorn.Events.MessageSelect
import Matterhorn.Events.UrlSelect
import Matterhorn.State.Attachments
import Matterhorn.State.Editing
import Matterhorn.State.UrlSelect
import Matterhorn.State.MessageSelect
import Matterhorn.State.Channels
handleMessageInterfaceEvent :: TeamId
-> Lens' ChatState (MessageInterface Name i)
-> Vty.Event
-> MH Bool
handleMessageInterfaceEvent tId which ev = do
mode <- use (which.miMode)
case mode of
Compose ->
handleEventWith [ mhHandleKeyboardEvent (extraEditorKeybindings which)
, mhHandleKeyboardEvent (messageInterfaceKeybindings which)
, \e -> do
case e of
(Vty.EvPaste bytes) -> handlePaste (which.miEditor) bytes
_ -> handleEditingInput (which.miEditor) e
return True
] ev
MessageSelect ->
onEventMessageSelect tId which ev
ShowUrlList ->
onEventUrlSelect which ev
SaveAttachment {} ->
onEventSaveAttachmentWindow which ev
ManageAttachments ->
onEventAttachmentList which ev
BrowseFiles ->
onEventBrowseFile which ev
messageInterfaceKeybindings :: Lens' ChatState (MessageInterface n i)
-> KeyConfig KeyEvent
-> KeyDispatcher KeyEvent MH
messageInterfaceKeybindings which kc =
unsafeKeyDispatcher kc (messageInterfaceKeyHandlers which)
messageInterfaceKeyHandlers :: Lens' ChatState (MessageInterface n i)
-> [MHKeyEventHandler]
messageInterfaceKeyHandlers which =
[ onEvent EnterSelectModeEvent
"Select a message to edit/reply/delete" $
beginMessageSelect which
, onEvent PageUpEvent "Page up in the message list (enters message select mode)" $ do
beginMessageSelect which
, onEvent SelectOldestMessageEvent "Scroll to top of message list" $ do
beginMessageSelect which
messageSelectFirst which
, onEvent EnterOpenURLModeEvent "Select and open a URL from the current message list" $
startUrlSelect which
]
extraEditorKeybindings :: Lens' ChatState (MessageInterface Name i)
-> KeyConfig KeyEvent
-> KeyDispatcher KeyEvent MH
extraEditorKeybindings which kc =
unsafeKeyDispatcher kc (extraEditorKeyHandlers which)
extraEditorKeyHandlers :: Lens' ChatState (MessageInterface Name i)
-> [MHKeyEventHandler]
extraEditorKeyHandlers which =
let editWhich :: Lens' ChatState (EditState Name)
editWhich = which.miEditor
in [ onEvent ToggleMultiLineEvent "Toggle multi-line message compose mode" $
toggleMultilineEditing editWhich
, onEvent CancelEvent "Cancel autocomplete, message reply, or edit, in that order" $
cancelAutocompleteOrReplyOrEdit editWhich
, onEvent
InvokeEditorEvent
"Invoke `$EDITOR` to edit the current message" $
invokeExternalEditor editWhich
, onKey (bind '\t')
"Tab-complete forward" $
tabComplete editWhich Forwards
, onKey (bind Vty.KBackTab)
"Tab-complete backward" $
tabComplete editWhich Backwards
, onEvent ShowAttachmentListEvent "Show the attachment list" $
showAttachmentList which
, onKey (bind Vty.KEnter)
"Send the current message" $ do
isMultiline <- use (editWhich.esEphemeral.eesMultiline)
case isMultiline of
-- Normally, this event causes the current message to
-- be sent. But in multiline mode we want to insert a
-- newline instead.
True -> handleEditingInput editWhich (Vty.EvKey Vty.KEnter [])
False -> do
content <- getEditorContent editWhich
handleInputSubmission editWhich content
, onEvent
ScrollUpEvent
"Scroll up in the channel input history" $ do
-- Up in multiline mode does the usual thing; otherwise we
-- navigate the history.
isMultiline <- use (editWhich.esEphemeral.eesMultiline)
case isMultiline of
True -> mhZoom (editWhich.esEditor) handleEditorEvent
(VtyEvent $ Vty.EvKey Vty.KUp [])
False -> inputHistoryBackward which
, onEvent
ScrollDownEvent
"Scroll down in the channel input history" $ do
-- Down in multiline mode does the usual thing; otherwise
-- we navigate the history.
isMultiline <- use (editWhich.esEphemeral.eesMultiline)
case isMultiline of
True -> mhZoom (editWhich.esEditor) handleEditorEvent
(VtyEvent $ Vty.EvKey Vty.KDown [])
False -> inputHistoryForward which
, onEvent
ReplyRecentEvent "Reply to the most recent message" $
replyToLatestMessage which
]