module Vimeta.UI.Term.TV
( tvSearch,
)
where
import Byline.Menu
import Network.API.TheMovieDB
import Vimeta.Core
import Vimeta.UI.Common.Util
import Vimeta.UI.Term.Common
newtype TVItem = TVItem TV
instance ToStylizedText TVItem where
toStylizedText :: TVItem -> Stylized Text
toStylizedText (TVItem TV
series) =
[Stylized Text] -> Stylized Text
forall a. Monoid a => [a] -> a
mconcat
[ Text -> Stylized Text
text (TV -> Text
tvName TV
series),
Text -> Stylized Text
text (Text -> Text
parens (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ Maybe Day -> Maybe Day -> Text
dayRange (TV -> Maybe Day
tvFirstAirDate TV
series) (TV -> Maybe Day
tvLastAirDate TV
series))
]
tvSearch :: MonadIO m => Vimeta m TV
tvSearch :: Vimeta m TV
tvSearch = do
let prompt :: Stylized Text
prompt = Text -> Stylized Text
text Text
"search (series name): "
mprompt :: Stylized Text
mprompt = Text -> Stylized Text
text Text
"Which is the correct TV series? "
sprompt :: Stylized Text
sprompt = Stylized Text
"a search term is required" Stylized Text -> Stylized Text -> Stylized Text
forall a. Semigroup a => a -> a -> a
<> Color -> Stylized Text
fg Color
red
eprompt :: Stylized Text
eprompt = Stylized Text
"please choose a TV series" Stylized Text -> Stylized Text -> Stylized Text
forall a. Semigroup a => a -> a -> a
<> Color -> Stylized Text
fg Color
red
mkMenu :: NonEmpty TVItem -> Menu TVItem
mkMenu = Stylized Text -> Menu TVItem -> Menu TVItem
forall b a. ToStylizedText b => b -> Menu a -> Menu a
menuBanner (Text -> Stylized Text
text Text
"Choose a TV series:") (Menu TVItem -> Menu TVItem)
-> (NonEmpty TVItem -> Menu TVItem)
-> NonEmpty TVItem
-> Menu TVItem
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty TVItem -> Menu TVItem
forall a. ToStylizedText a => NonEmpty a -> Menu a
menu
logID :: TV -> Vimeta m ()
logID TV
tv = Text -> Vimeta m ()
forall (m :: * -> *). MonadIO m => Text -> Vimeta m ()
verbose (Text -> Vimeta m ()) -> Text -> Vimeta m ()
forall a b. (a -> b) -> a -> b
$ Text
"using TV ID: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> ItemID -> Text
forall b a. (Show a, IsString b) => a -> b
show (TV -> ItemID
tvID TV
tv)
Text
name <- Stylized Text
-> Maybe Text
-> (Text -> Vimeta m (Either (Stylized Text) Text))
-> Vimeta m Text
forall (m :: * -> *) a e b.
(MonadByline m, ToStylizedText a, ToStylizedText e) =>
a -> Maybe Text -> (Text -> m (Either e b)) -> m b
askUntil Stylized Text
prompt Maybe Text
forall a. Maybe a
Nothing (Either (Stylized Text) Text
-> Vimeta m (Either (Stylized Text) Text)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either (Stylized Text) Text
-> Vimeta m (Either (Stylized Text) Text))
-> (Text -> Either (Stylized Text) Text)
-> Text
-> Vimeta m (Either (Stylized Text) Text)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Stylized Text -> Text -> Either (Stylized Text) Text
notBlank Stylized Text
sprompt)
NonEmpty TVItem
series <-
TheMovieDB [TV] -> Vimeta m [TV]
forall (m :: * -> *) a. MonadIO m => TheMovieDB a -> Vimeta m a
tmdb (Text -> TheMovieDB [TV]
searchTV Text
name)
Vimeta m [TV]
-> ([TV] -> Vimeta m (NonEmpty TVItem))
-> Vimeta m (NonEmpty TVItem)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ( [TV] -> Maybe (NonEmpty TV)
forall a. [a] -> Maybe (NonEmpty a)
nonEmpty ([TV] -> Maybe (NonEmpty TV))
-> (Maybe (NonEmpty TV) -> Vimeta m (NonEmpty TVItem))
-> [TV]
-> Vimeta m (NonEmpty TVItem)
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> \case
Maybe (NonEmpty TV)
Nothing -> String -> Vimeta m (NonEmpty TVItem)
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (String
"no matches for " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Text -> String
forall a. ToString a => a -> String
toString Text
name)
Just NonEmpty TV
xs -> NonEmpty TVItem -> Vimeta m (NonEmpty TVItem)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (TV -> TVItem
TVItem (TV -> TVItem) -> NonEmpty TV -> NonEmpty TVItem
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty TV
xs)
)
TVItem TV
tv <- Menu TVItem -> Stylized Text -> Stylized Text -> Vimeta m TVItem
forall (m :: * -> *) a b e.
(MonadByline m, ToStylizedText a, ToStylizedText b,
ToStylizedText e) =>
Menu a -> b -> e -> m a
askWithMenuRepeatedly (NonEmpty TVItem -> Menu TVItem
mkMenu NonEmpty TVItem
series) Stylized Text
mprompt Stylized Text
eprompt
TV -> Vimeta m ()
forall (m :: * -> *). MonadIO m => TV -> Vimeta m ()
logID TV
tv Vimeta m () -> Vimeta m TV -> Vimeta m TV
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TheMovieDB TV -> Vimeta m TV
forall (m :: * -> *) a. MonadIO m => TheMovieDB a -> Vimeta m a
tmdb (ItemID -> TheMovieDB TV
fetchFullTVSeries (TV -> ItemID
tvID TV
tv))