{-# LANGUAGE LambdaCase #-} -- | module Hum.Views.Common where import Hum.Types import Brick.Types import Brick.Widgets.Core import Brick.Widgets.Center import Brick.Widgets.Edit import Brick.Widgets.Border import Hum.Attributes import Hum.Utils import qualified Network.MPD as MPD import qualified Data.Map.Strict as Map import qualified Data.Text as T import Brick.Widgets.List import Control.Lens drawNowPlaying :: HState -> Widget Name drawNowPlaying st = reportExtent NowPlaying $ vLimit 5 . center $ maybe (txt "nothing.") nowPlaying (currentSong st) where nowPlaying song = txt "\n" <=> hCenter title <=> hCenter (artist <+> txt " - " <+> album) <=> progbar <=> (padRight Max playing <+> padLeft Max mode) where title = withAttr queueTitleAttr $ txt $ meta "" MPD.Title song album = withAttr queueAlbumAttr (txt $ meta "" MPD.Album song) <+> txt " (" <+> withAttr queueDateAttr (txt $ meta "????" MPD.Date song) <+> txt ")" artist = withAttr queueArtistAttr $ txt $ meta "" MPD.Artist song progbar = withAttr queueTimeAttr $ drawProgressBar st playing = txt $ maybe "[ ]" ((\t -> "[" <> t <> "]") . T.toLower . show . MPD.stState) (status st) formatMode t modeFun = maybe "-" ( (\case False -> "-" True -> t ) . modeFun ) (status st) repeatmpd = formatMode "r" MPD.stRepeat random = formatMode "z" MPD.stRandom single = formatMode "s" MPD.stSingle consume = formatMode "c" MPD.stConsume crossfade = formatMode "x" ((/= 0) . MPD.stXFadeWidth) mode = txt $ "[" <> repeatmpd <> random <> single <> consume <> crossfade <> "]" drawProgressBar :: HState -> Widget Name drawProgressBar st = case width of 0 -> txt $ Prelude.toText timeText _ -> bar where width = maybe 0 (fst . extentSize) (join (Map.lookup NowPlaying $ extentMap st)) songTime = fromMaybe (0, 1) (MPD.stTime =<< status st) timeText = toString . (\(i, j) -> secondsToTime (round i) <> "/" <> secondsToTime (round j)) $ songTime completed = (\w (i, j) -> round ((i / j) * fromIntegral w)) width songTime bar = str (zipWith (\a b -> if a `elem` ("1234567890/:" :: String) then a else b) (replicate (-5 + div width 2) ' ' ++ timeText ++ replicate (-3 + div width 2) ' ' ) (replicate completed '=' ++ replicate (width - completed) ' ') ) --drawEx :: HState -> Widget Name --drawEx st = data PerCol = Per Int | Col Int column :: Maybe PerCol -> Padding -> Padding -> Widget n -> Widget n column maxWidth left right w = case maxWidth of Nothing -> wpad Just (Per m) -> hLimitPercent m wpad Just (Col m) -> hLimit m wpad where wpad = padLeft left . padRight right $ w songSearch :: Text -> [MPD.Metadata] -> MPD.Song -> Bool songSearch text metadata song = let mtags = (T.toLower <$>) . (`mmeta` song) <$> metadata in or $ fromMaybe False <$> (T.isInfixOf (T.toLower text) <<$>> mtags) stringySearch :: MPD.ToString a => Text -> a -> Bool stringySearch text value = T.isInfixOf (T.toLower text) (T.toLower . MPD.toText $ value) drawPrompt :: HState -> Widget Name drawPrompt st = case st ^. promptsL . currentPromptL of PlSelectPrompt -> centerLayer . border . setAvailableSize (30, 10) . center $ (hCenter . txt $ st ^. promptsL . promptTitleL) <=> hBorder <=> renderListWithIndex choosePlRow True (st ^. promptsL . plSelectPromptL) TextPrompt -> centerLayer . border . setAvailableSize (30, 3) . center $ (hCenter . txt $ st ^. promptsL . promptTitleL) <=> hBorder <=> (center . setAvailableSize (25, 1) . withDefAttr editorAttr) (renderEditor (txt . T.unlines) True (st ^. promptsL . textPromptL)) YNPrompt -> centerLayer . border . hLimit 30 $ (hCenter . txt $ st ^. promptsL . promptTitleL) <=> (hCenter . txt $ "[y/n]") choosePlRow :: Int -> Bool -> Maybe MPD.PlaylistName -> Widget n choosePlRow i _ pl = if i==0 then str "New Playlist" <=> modifyDefAttr (const wobAttr) hBorder else str (MPD.toString $ fromMaybe "" pl)