{-# LANGUAGE RecordWildCards #-} -- | Main.hs -- Main program module. import Buffers import Config import Help import Jabber import UI import Network import Control.Concurrent import Control.Concurrent.MVar import qualified Data.Map as M import Graphics.Vty import Graphics.Vty.Widgets.All import qualified Widgets.Tree as T import qualified Widgets.EditBox as E -- | Read configs and start main loop. main = withSocketsDo $ do -- read config (config, buffers) <- readConfig ".matsurirc" vty <- mkVty mev <- newEmptyMVar -- main loop forkIO $ loopGetEvent mev vty rerender mev vty (defaultUI buffers) config buffers -- disconnect all accounts mapM_ disconnect $ [acc | BufAccount acc <- (M.elems buffers)] -- shutdown && exiting shutdown vty where loopGetEvent mev vty = do event <- next_event vty putMVar mev (VtyEvent event) loopGetEvent mev vty -- | Get event and process it. mainLoop mev vty st@(UIState {..}) config buffers = do event <- takeMVar mev case event of InsBuffer k buffer -> insElem' k buffer --- NewMsg k msg -> case getBuf k buffers of BufChat chat -> do let contents = msg:(chatContents chat) insElem' k $ BufChat chat{chatContents=contents} _ -> skip --- NewStatus k status' -> case getBuf k buffers of BufChat chat -> insElem' k $ BufChat chat{status=status'} _ -> skip --- VtyEvent event' -> case event' of -- tree EvKey (KASCII 'p') [MCtrl] -> rerender' $ st { roster = T.moveUp roster } EvKey (KASCII 'n') [MCtrl] -> rerender' $ st { roster = T.moveDn roster } EvKey KEnter [] | E.contents edit == "" -> case getAccount cur buffers of Just acc -> let buf = BufAccount acc{accCollapsed = not $ accCollapsed acc} in insElem' cur buf _ -> skip -- show/hide EvKey (KASCII 'v') [MCtrl] -> let isShow = getCF "show_roster" config isShow' = if null isShow then "1" else "" config' = setCF "show_roster" isShow' config in rerender mev vty st config' buffers -- edit box EvKey (KASCII c ) [] -> rerender' $ st { edit = E.insert c edit } EvKey (KASCII 'a') [MCtrl] -> rerender' $ st { edit = E.moveToHome edit } EvKey (KASCII 'f') [MCtrl] -> rerender' $ st { edit = E.moveRight edit } EvKey (KASCII 'b') [MCtrl] -> rerender' $ st { edit = E.moveLeft edit } EvKey (KASCII 'e') [MCtrl] -> rerender' $ st { edit = E.moveToEnd edit } EvKey KBS [] -> rerender' $ st { edit = E.backSpace edit } EvKey KDel [] -> rerender' $ st { edit = E.delete edit } -- parse command || send message EvKey KEnter [] -> case E.contents edit of "/q" -> return () ('/':cmd) -> do buffers' <- parseCmd cmd let st' = st { edit = E.empty , roster = mkTree roster buffers' } rerender mev vty st' config buffers' msg -> case getBuf cur buffers of BufChat chat -> do buffer <- sendChatMessage chat (E.contents edit) let buffers' = insElem cur buffer buffers st' = st { edit = E.empty } rerender mev vty st' config buffers' _ -> skip -- other EvResize w h -> rerender' st EvKey (KASCII 'q') [MCtrl] -> return () _ -> skip where skip = mainLoop mev vty st config buffers rerender' st = rerender mev vty st config buffers -- insert new element in buffer (or simply replace old element) -- and re-create roster tree insElem' k buffer = let buffers' = insElem k buffer buffers st' = st { roster = mkTree roster buffers' } in rerender mev vty st' config buffers' -- connect parseCmd "c" = case getAccount cur buffers of Just acc -> do buffer <- connect mev config acc return $ insElem (accName acc) buffer buffers _ -> ins2help (InfoMsg "can't connect: not an account") -- disconnect parseCmd "d" = case getAccount cur buffers of Just acc -> do buffer <- disconnect acc let buffers' = insElem cur buffer buffers buffers'' = killBuffers (accName acc++"|") buffers' return buffers'' _ -> ins2help (InfoMsg "can't disconnect: not an account") where cur = T.cur roster -- help parseCmd "help" = ins2help (InfoMsg help_all) parseCmd unknown_cmd = ins2help (InfoMsg $ "unknown `"++unknown_cmd++ "' command, try `/help'") --- cur = T.cur roster ins2help cnt = return $ case getBuf "help" buffers of BufHelp cnts -> insElem "help" (BufHelp $ cnt:cnts) buffers _ -> buffers rerender mev vty st config buffers = mkImage vty (mkUI st config buffers) >>= update vty . pic_for_image >> mainLoop mev vty st config buffers