{-# LANGUAGE OverloadedStrings #-} {-| Module : Kino.UI.Widgets Description : This is the code which builds the Brick frontend This is the code which builds the Brick frontend -} module Kino.UI.Widgets (messageWidget, searchWidget, browseWidget) where import Data.Maybe (fromMaybe) import Brick import Brick.Widgets.Center import Brick.Widgets.Border import Brick.Widgets.Edit import Lens.Micro import qualified Data.Text as T import Kino.Types import Kino.Misc import Kino.Torrent -- | Wrap a widget in the selected attribute select :: Widget Ident -> Widget Ident select = withAttr (attrName "selected") -- | Given a movie and a tuple of widgets and state, append the -- movie to the widgets. Used by movieWidgets widgetCons :: JSONMovie -> (Widget Ident, AppS) -> (Widget Ident, AppS) widgetCons m (w, s) = embed $ if Just m == (s ^. appDetails) then select . visible $ if s ^. appExpanded then expandedWidget m else movieWidget m else movieWidget m where embed x = (x <=> w, s) -- | Returns a big list of all movies movieWidgets :: AppS -> Widget Ident movieWidgets s = let (items, _) = foldr widgetCons (emptyWidget, s) (moviesMovies (s ^. appListing)) in items -- | Returns a single movie listing movieWidget :: JSONMovie -> Widget Ident movieWidget m = txt (movieTitle m) <+> padLeft Max (str (show (movieYear m))) -- | Returns an expanded movie listing showing additional info expandedWidget :: JSONMovie -> Widget Ident expandedWidget m = movieWidget m <=> (padRight (Pad 3) (str "Rating") <+> str (show (movieRating m))) <=> (padRight (Pad 1) (str "Language") <+> txt (movieLanguage m)) <=> (padRight (Pad 3) (str "Genres") <+> txt (T.intercalate ", " (movieGenres m))) <=> (padRight (Pad 2) (str "Runtime") <+> str (show hours <> "h " <> show minutes <> "m")) <=> (padRight (Pad 2) (str "Magnets") <+> str (listTorrents m)) <=> (padRight (Pad 2) (str "Summary") <+> txtWrap (movieSummary m)) where (hours, minutes) = divMod (movieRuntime m) 60 -- | The search mode widget. Uses the brick built in Editor widget searchWidget :: AppS -> Widget Ident searchWidget s = center $ border $ padAll 1 (editorRenderer (s ^. appEditor)) <=> padAll 1 (hCenter (str "[Press enter to search]")) -- | Takes an editor and returns a widget to represent it editorRenderer :: Editor T.Text Ident -> Widget Ident editorRenderer = renderEditor txtRender True where txtRender :: [T.Text] -> Widget Ident txtRender [] = txt "Enter query term" $> withAttr editAttr txtRender [""] = txt "Enter query term" $> withAttr editAttr txtRender (t:_) = txt t -- | The browse mode widget which returns a full listing of movies -- or reports that there are no movies to list browseWidget :: AppS -> Widget Ident browseWidget s = str "Title" <+> padLeft Max (str "Year") <=> viewport Listing Vertical (movieWidgets s) -- | The message widget which simply shows a message and informs -- the user of how to escape messageWidget :: AppS -> Widget Ident messageWidget s = center $ border $ padAll 1 (hCenter (str (fromMaybe "Unkown Error!" (s ^. appMessage)))) <=> padAll 1 (hCenter (str ("[Press any key to " <> action <> "]"))) where action = if s ^. appContinue then "continue" else "exit"