{-# LANGUAGE RankNTypes #-}
module Matterhorn.State.ListOverlay
( listOverlayActivateCurrent
, listOverlaySearchString
, listOverlayMove
, exitListOverlay
, enterListOverlayMode
, resetListOverlaySearch
, onEventListOverlay
)
where
import Prelude ()
import Matterhorn.Prelude
import qualified Brick.Widgets.List as L
import qualified Brick.Widgets.Edit as E
import qualified Data.Text.Zipper as Z
import qualified Data.Vector as Vec
import Lens.Micro.Platform ( Lens', (%=), (.=) )
import Network.Mattermost.Types ( Session )
import qualified Graphics.Vty as Vty
import Matterhorn.Types
import Matterhorn.State.Common
import Matterhorn.State.Editing ( editingKeybindings )
import Matterhorn.Events.Keybindings ( KeyConfig, KeyHandlerMap, handleKeyboardEvent )
listOverlayActivateCurrent :: Lens' ChatState (ListOverlayState a b) -> MH ()
listOverlayActivateCurrent which = do
mItem <- L.listSelectedElement <$> use (which.listOverlaySearchResults)
case mItem of
Nothing -> return ()
Just (_, val) -> do
handler <- use (which.listOverlayEnterHandler)
activated <- handler val
if activated
then setMode Main
else return ()
listOverlaySearchString :: Lens' ChatState (ListOverlayState a b) -> MH Text
listOverlaySearchString which =
(head . E.getEditContents) <$> use (which.listOverlaySearchInput)
listOverlayMove :: Lens' ChatState (ListOverlayState a b)
-> (L.List Name a -> L.List Name a)
-> MH ()
listOverlayMove which how = which.listOverlaySearchResults %= how
exitListOverlay :: Lens' ChatState (ListOverlayState a b)
-> MH ()
exitListOverlay which = do
st <- use which
newList <- use (which.listOverlayNewList)
which.listOverlaySearchResults .= newList mempty
which.listOverlayEnterHandler .= (const $ return False)
setMode (st^.listOverlayReturnMode)
enterListOverlayMode :: (Lens' ChatState (ListOverlayState a b))
-> Mode
-> b
-> (a -> MH Bool)
-> (b -> Session -> Text -> IO (Vec.Vector a))
-> MH ()
enterListOverlayMode which mode scope enterHandler fetcher = do
which.listOverlaySearchScope .= scope
which.listOverlaySearchInput.E.editContentsL %= Z.clearZipper
which.listOverlayEnterHandler .= enterHandler
which.listOverlayFetchResults .= fetcher
which.listOverlaySearching .= False
newList <- use (which.listOverlayNewList)
which.listOverlaySearchResults .= newList mempty
setMode mode
resetListOverlaySearch which
resetListOverlaySearch :: Lens' ChatState (ListOverlayState a b) -> MH ()
resetListOverlaySearch which = do
searchPending <- use (which.listOverlaySearching)
when (not searchPending) $ do
searchString <- listOverlaySearchString which
which.listOverlaySearching .= True
newList <- use (which.listOverlayNewList)
session <- getSession
scope <- use (which.listOverlaySearchScope)
fetcher <- use (which.listOverlayFetchResults)
doAsyncWith Preempt $ do
results <- fetcher scope session searchString
return $ Just $ do
which.listOverlaySearchResults .= newList results
which.listOverlaySearching .= False
afterSearchString <- listOverlaySearchString which
when (searchString /= afterSearchString) $ resetListOverlaySearch which
onEventListOverlay :: Lens' ChatState (ListOverlayState a b)
-> (KeyConfig -> KeyHandlerMap)
-> Vty.Event
-> MH Bool
onEventListOverlay which keybindings =
handleKeyboardEvent keybindings $ \e -> do
before <- listOverlaySearchString which
handled <- handleKeyboardEvent (editingKeybindings (which.listOverlaySearchInput)) (const $ return ()) e
when (not handled) $
mhHandleEventLensed (which.listOverlaySearchInput) E.handleEditorEvent e
after <- listOverlaySearchString which
when (before /= after) $ resetListOverlaySearch which