kino/src/UI.hs

95 lines
2.6 KiB
Haskell
Raw Normal View History

2021-09-06 21:02:39 +02:00
module UI where
2021-09-14 17:06:34 +02:00
import Data.Maybe (fromMaybe)
2021-09-06 21:02:39 +02:00
2021-09-14 17:06:34 +02:00
import Brick hiding (Direction(..))
import Graphics.Vty (defAttr)
import Graphics.Vty.Input.Events
import Graphics.Vty.Attributes (withStyle, reverseVideo)
import Control.Monad.IO.Class (liftIO)
import qualified Data.Text as T
import Lens.Micro
2021-09-06 21:02:39 +02:00
2021-09-14 17:06:34 +02:00
import JSONTypes
import Request
import Misc
import Widgets
import AppTypes
initialState :: AppS
initialState = AppS
{ _appMode = Browse
, _appCursor = 0
, _appExpanded = False
, _appPage = 1
, _appListing = Nothing
, _appDetails = Nothing
, _appError = Nothing
}
2021-09-06 21:02:39 +02:00
2021-09-13 19:00:26 +02:00
app :: App AppS () Ident
2021-09-06 21:02:39 +02:00
app = App
{ appDraw = draw
, appChooseCursor = chooseCursor
2021-09-13 19:00:26 +02:00
, appHandleEvent = eventHandler
, appStartEvent = startEvent
, appAttrMap = attributeMap
2021-09-06 21:02:39 +02:00
}
2021-09-13 19:00:26 +02:00
runApp :: IO AppS
runApp = defaultMain app initialState
2021-09-06 21:02:39 +02:00
2021-09-14 17:06:34 +02:00
startEvent :: AppS -> EventM Ident AppS
2021-09-14 18:24:05 +02:00
startEvent s = do
2021-09-14 17:06:34 +02:00
-- todo move unwrapping our response structure into a function
response <- liftIO getMovies
2021-09-14 18:24:05 +02:00
pure $ case response of
(Left msg) -> s & appError .~ Just (T.unpack msg)
(Right listing) -> s & appListing .~ Just listing
& appDetails .~ (movies listing !? s ^. appCursor)
2021-09-13 19:00:26 +02:00
draw :: AppS -> [Widget Ident]
2021-09-14 17:06:34 +02:00
draw s = pure $ case s ^. appMode of
Browse -> browseWidget s
Search -> searchWidget s
Error -> errorWidget s
2021-09-06 21:02:39 +02:00
2021-09-13 19:00:26 +02:00
chooseCursor :: AppS -> [CursorLocation Ident] -> Maybe (CursorLocation Ident)
chooseCursor = showFirstCursor -- replace if needed
2021-09-06 21:02:39 +02:00
2021-09-14 17:06:34 +02:00
-- todo: lenses? NO OVERFLOW
scroll :: ScrollDirection -> AppS -> AppS
scroll d s = s & appCursor %~ (\x -> max 0 (min upperLimit (new x)))
& appExpanded .~ False
where
upperLimit = fromMaybe 0 (subtract 1 . length . movies <$> s ^. appListing)
new = case d of { Up -> (subtract 1); Down -> (+1) }
eventHandler :: AppS -> BrickEvent Ident () -> EventM Ident (Next AppS)
eventHandler s (VtyEvent (EvKey k _)) = do
case s ^. appMode of
Error -> halt s
Search -> undefined
Browse -> case k of
(KChar 'q') -> halt s
2021-09-14 18:24:05 +02:00
(KEsc) -> halt s
2021-09-14 17:06:34 +02:00
(KChar 'j') -> continue (scroll Down s)
(KChar 'k') -> continue (scroll Up s)
2021-09-14 18:24:05 +02:00
(KDown) -> continue (scroll Down s)
(KUp) -> continue (scroll Up s)
2021-09-14 17:06:34 +02:00
(KChar ' ') -> continue (s & appExpanded %~ not)
2021-09-14 18:24:05 +02:00
(KEnter) -> continue (s & appExpanded %~ not)
(KChar '/') -> continue (s & appMode .~ Search)
(KChar 's') -> continue (s & appMode .~ Search)
2021-09-14 17:06:34 +02:00
_ -> continue s
eventHandler s _ = continue s
2021-09-06 21:02:39 +02:00
2021-09-14 17:06:34 +02:00
attributeMap :: AppS -> AttrMap
attributeMap = const $ attrMap defAttr [(attrName "selected", withStyle defAttr reverseVideo)]