{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}

-- | Message components
module Discord.Internal.Types.Components
  ( ActionRow (..),
    Button (..),
    ButtonStyle (..),
    mkButton,
    SelectMenu (..),
    mkSelectMenu,
    SelectOption (..),
    mkSelectOption,
    TextInput (..),
    mkTextInput,
  )
where

import Data.Aeson
import Data.Aeson.Types (Parser)
import Data.Foldable (Foldable (toList))
import Data.Scientific (Scientific)
import qualified Data.Text as T
import Discord.Internal.Types.Emoji (Emoji)
import Discord.Internal.Types.Prelude (objectFromMaybes, (.==), (.=?))

-- | Container for other message Components
data ActionRow = ActionRowButtons [Button] | ActionRowSelectMenu SelectMenu
  deriving (Int -> ActionRow -> ShowS
[ActionRow] -> ShowS
ActionRow -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ActionRow] -> ShowS
$cshowList :: [ActionRow] -> ShowS
show :: ActionRow -> String
$cshow :: ActionRow -> String
showsPrec :: Int -> ActionRow -> ShowS
$cshowsPrec :: Int -> ActionRow -> ShowS
Show, ReadPrec [ActionRow]
ReadPrec ActionRow
Int -> ReadS ActionRow
ReadS [ActionRow]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [ActionRow]
$creadListPrec :: ReadPrec [ActionRow]
readPrec :: ReadPrec ActionRow
$creadPrec :: ReadPrec ActionRow
readList :: ReadS [ActionRow]
$creadList :: ReadS [ActionRow]
readsPrec :: Int -> ReadS ActionRow
$creadsPrec :: Int -> ReadS ActionRow
Read, ActionRow -> ActionRow -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ActionRow -> ActionRow -> Bool
$c/= :: ActionRow -> ActionRow -> Bool
== :: ActionRow -> ActionRow -> Bool
$c== :: ActionRow -> ActionRow -> Bool
Eq, Eq ActionRow
ActionRow -> ActionRow -> Bool
ActionRow -> ActionRow -> Ordering
ActionRow -> ActionRow -> ActionRow
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ActionRow -> ActionRow -> ActionRow
$cmin :: ActionRow -> ActionRow -> ActionRow
max :: ActionRow -> ActionRow -> ActionRow
$cmax :: ActionRow -> ActionRow -> ActionRow
>= :: ActionRow -> ActionRow -> Bool
$c>= :: ActionRow -> ActionRow -> Bool
> :: ActionRow -> ActionRow -> Bool
$c> :: ActionRow -> ActionRow -> Bool
<= :: ActionRow -> ActionRow -> Bool
$c<= :: ActionRow -> ActionRow -> Bool
< :: ActionRow -> ActionRow -> Bool
$c< :: ActionRow -> ActionRow -> Bool
compare :: ActionRow -> ActionRow -> Ordering
$ccompare :: ActionRow -> ActionRow -> Ordering
Ord)

instance FromJSON ActionRow where
  parseJSON :: Value -> Parser ActionRow
parseJSON =
    forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject
      String
"ActionRow"
      ( \Object
cs -> do
          Int
t <- Object
cs forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"type" :: Parser Int
          case Int
t of
            Int
1 -> do
              Array
a <- Object
cs forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"components" :: Parser Array
              let a' :: [Value]
a' = forall (t :: * -> *) a. Foldable t => t a -> [a]
toList Array
a
              case [Value]
a' of
                [] -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ [Button] -> ActionRow
ActionRowButtons []
                (Value
c : [Value]
_) ->
                  forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject
                    String
"ActionRow item"
                    ( \Object
v -> do
                        Int
t' <- Object
v forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"type" :: Parser Int
                        case Int
t' of
                          Int
2 -> [Button] -> ActionRow
ActionRowButtons forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM forall a. FromJSON a => Value -> Parser a
parseJSON [Value]
a'
                          Int
3 -> SelectMenu -> ActionRow
ActionRowSelectMenu forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. FromJSON a => Value -> Parser a
parseJSON Value
c
                          Int
_ -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"unknown component type: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
t
                    )
                    Value
c
            Int
_ -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"expected action row type (1), got: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
t
      )

instance ToJSON ActionRow where
  toJSON :: ActionRow -> Value
toJSON (ActionRowButtons [Button]
bs) = [Pair] -> Value
object [(Key
"type", Scientific -> Value
Number Scientific
1), (Key
"components", forall a. ToJSON a => a -> Value
toJSON [Button]
bs)]
  toJSON (ActionRowSelectMenu SelectMenu
bs) = [Pair] -> Value
object [(Key
"type", Scientific -> Value
Number Scientific
1), (Key
"components", forall a. ToJSON a => a -> Value
toJSON [SelectMenu
bs])]

-- | Component type for a button, split into URL button and not URL button.
--
-- Don't directly send button components - they need to be within an action row.
data Button
  = Button
      { -- | Dev indentifier
        Button -> Text
buttonCustomId :: T.Text,
        -- | Whether the button is disabled
        Button -> Bool
buttonDisabled :: Bool,
        -- | What is the style of the button
        Button -> ButtonStyle
buttonStyle :: ButtonStyle,
        -- | What is the user-facing label of the button
        Button -> Maybe Text
buttonLabel :: Maybe T.Text,
        -- | What emoji is displayed on the button
        Button -> Maybe Emoji
buttonEmoji :: Maybe Emoji
      }
  | ButtonUrl
      { -- | The url for the button. If this is not a valid url, everything will
        -- break
        Button -> Text
buttonUrl :: T.Text,
        -- | Whether the button is disabled
        buttonDisabled :: Bool,
        -- | What is the user-facing label of the button
        buttonLabel :: Maybe T.Text,
        -- | What emoji is displayed on the button
        buttonEmoji :: Maybe Emoji
      }
  deriving (Int -> Button -> ShowS
[Button] -> ShowS
Button -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Button] -> ShowS
$cshowList :: [Button] -> ShowS
show :: Button -> String
$cshow :: Button -> String
showsPrec :: Int -> Button -> ShowS
$cshowsPrec :: Int -> Button -> ShowS
Show, ReadPrec [Button]
ReadPrec Button
Int -> ReadS Button
ReadS [Button]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Button]
$creadListPrec :: ReadPrec [Button]
readPrec :: ReadPrec Button
$creadPrec :: ReadPrec Button
readList :: ReadS [Button]
$creadList :: ReadS [Button]
readsPrec :: Int -> ReadS Button
$creadsPrec :: Int -> ReadS Button
Read, Button -> Button -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Button -> Button -> Bool
$c/= :: Button -> Button -> Bool
== :: Button -> Button -> Bool
$c== :: Button -> Button -> Bool
Eq, Eq Button
Button -> Button -> Bool
Button -> Button -> Ordering
Button -> Button -> Button
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Button -> Button -> Button
$cmin :: Button -> Button -> Button
max :: Button -> Button -> Button
$cmax :: Button -> Button -> Button
>= :: Button -> Button -> Bool
$c>= :: Button -> Button -> Bool
> :: Button -> Button -> Bool
$c> :: Button -> Button -> Bool
<= :: Button -> Button -> Bool
$c<= :: Button -> Button -> Bool
< :: Button -> Button -> Bool
$c< :: Button -> Button -> Bool
compare :: Button -> Button -> Ordering
$ccompare :: Button -> Button -> Ordering
Ord)

-- | Takes the label and the custom id of the button that is to be generated.
mkButton :: T.Text -> T.Text -> Button
mkButton :: Text -> Text -> Button
mkButton Text
label Text
customId = Text -> Bool -> ButtonStyle -> Maybe Text -> Maybe Emoji -> Button
Button Text
customId Bool
False ButtonStyle
ButtonStyleSecondary (forall a. a -> Maybe a
Just Text
label) forall a. Maybe a
Nothing

instance FromJSON Button where
  parseJSON :: Value -> Parser Button
parseJSON =
    forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject
      String
"Button"
      ( \Object
v -> do
          Int
t <- Object
v forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"type" :: Parser Int
          case Int
t of
            Int
2 -> do
              Bool
disabled <- Object
v forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"disabled" forall a. Parser (Maybe a) -> a -> Parser a
.!= Bool
False
              Maybe Text
label <- Object
v forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"label"
              Maybe Emoji
partialEmoji <- Object
v forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"emoji"
              Scientific
style <- Object
v forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"style" :: Parser Scientific
              case Scientific
style of
                Scientific
5 ->
                  Text -> Bool -> Maybe Text -> Maybe Emoji -> Button
ButtonUrl
                    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
v forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"url"
                    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
disabled
                    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Text
label
                    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Emoji
partialEmoji
                Scientific
_ ->
                  Text -> Bool -> ButtonStyle -> Maybe Text -> Maybe Emoji -> Button
Button
                    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
v forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"custom_id"
                    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
disabled
                    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. FromJSON a => Value -> Parser a
parseJSON (Scientific -> Value
Number Scientific
style)
                    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Text
label
                    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Emoji
partialEmoji
            Int
_ -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"expected button type, got a different component"
      )

instance ToJSON Button where
  toJSON :: Button -> Value
toJSON ButtonUrl {Bool
Maybe Text
Maybe Emoji
Text
buttonEmoji :: Maybe Emoji
buttonLabel :: Maybe Text
buttonDisabled :: Bool
buttonUrl :: Text
buttonUrl :: Button -> Text
buttonEmoji :: Button -> Maybe Emoji
buttonLabel :: Button -> Maybe Text
buttonDisabled :: Button -> Bool
..} =
    [Maybe Pair] -> Value
objectFromMaybes
      [ Key
"type" forall a. ToJSON a => Key -> a -> Maybe Pair
.== Scientific -> Value
Number Scientific
2,
        Key
"style" forall a. ToJSON a => Key -> a -> Maybe Pair
.== Scientific -> Value
Number Scientific
5,
        Key
"label" forall a. ToJSON a => Key -> Maybe a -> Maybe Pair
.=? Maybe Text
buttonLabel,
        Key
"disabled" forall a. ToJSON a => Key -> a -> Maybe Pair
.== Bool
buttonDisabled,
        Key
"url" forall a. ToJSON a => Key -> a -> Maybe Pair
.== Text
buttonUrl,
        Key
"emoji" forall a. ToJSON a => Key -> Maybe a -> Maybe Pair
.=? Maybe Emoji
buttonEmoji
      ]
  toJSON Button {Bool
Maybe Text
Maybe Emoji
Text
ButtonStyle
buttonEmoji :: Maybe Emoji
buttonLabel :: Maybe Text
buttonStyle :: ButtonStyle
buttonDisabled :: Bool
buttonCustomId :: Text
buttonEmoji :: Button -> Maybe Emoji
buttonLabel :: Button -> Maybe Text
buttonStyle :: Button -> ButtonStyle
buttonDisabled :: Button -> Bool
buttonCustomId :: Button -> Text
..} =
    [Maybe Pair] -> Value
objectFromMaybes
      [ Key
"type" forall a. ToJSON a => Key -> a -> Maybe Pair
.== Scientific -> Value
Number Scientific
2,
        Key
"style" forall a. ToJSON a => Key -> a -> Maybe Pair
.== ButtonStyle
buttonStyle,
        Key
"label" forall a. ToJSON a => Key -> Maybe a -> Maybe Pair
.=? Maybe Text
buttonLabel,
        Key
"disabled" forall a. ToJSON a => Key -> a -> Maybe Pair
.== Bool
buttonDisabled,
        Key
"custom_id" forall a. ToJSON a => Key -> a -> Maybe Pair
.== Text
buttonCustomId,
        Key
"emoji" forall a. ToJSON a => Key -> Maybe a -> Maybe Pair
.=? Maybe Emoji
buttonEmoji
      ]

-- | Buttton colors.
data ButtonStyle
  = -- | Blurple button
    ButtonStylePrimary
  | -- | Grey button
    ButtonStyleSecondary
  | -- | Green button
    ButtonStyleSuccess
  | -- | Red button
    ButtonStyleDanger
  deriving (Int -> ButtonStyle -> ShowS
[ButtonStyle] -> ShowS
ButtonStyle -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ButtonStyle] -> ShowS
$cshowList :: [ButtonStyle] -> ShowS
show :: ButtonStyle -> String
$cshow :: ButtonStyle -> String
showsPrec :: Int -> ButtonStyle -> ShowS
$cshowsPrec :: Int -> ButtonStyle -> ShowS
Show, ReadPrec [ButtonStyle]
ReadPrec ButtonStyle
Int -> ReadS ButtonStyle
ReadS [ButtonStyle]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [ButtonStyle]
$creadListPrec :: ReadPrec [ButtonStyle]
readPrec :: ReadPrec ButtonStyle
$creadPrec :: ReadPrec ButtonStyle
readList :: ReadS [ButtonStyle]
$creadList :: ReadS [ButtonStyle]
readsPrec :: Int -> ReadS ButtonStyle
$creadsPrec :: Int -> ReadS ButtonStyle
Read, ButtonStyle -> ButtonStyle -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ButtonStyle -> ButtonStyle -> Bool
$c/= :: ButtonStyle -> ButtonStyle -> Bool
== :: ButtonStyle -> ButtonStyle -> Bool
$c== :: ButtonStyle -> ButtonStyle -> Bool
Eq, Eq ButtonStyle
ButtonStyle -> ButtonStyle -> Bool
ButtonStyle -> ButtonStyle -> Ordering
ButtonStyle -> ButtonStyle -> ButtonStyle
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ButtonStyle -> ButtonStyle -> ButtonStyle
$cmin :: ButtonStyle -> ButtonStyle -> ButtonStyle
max :: ButtonStyle -> ButtonStyle -> ButtonStyle
$cmax :: ButtonStyle -> ButtonStyle -> ButtonStyle
>= :: ButtonStyle -> ButtonStyle -> Bool
$c>= :: ButtonStyle -> ButtonStyle -> Bool
> :: ButtonStyle -> ButtonStyle -> Bool
$c> :: ButtonStyle -> ButtonStyle -> Bool
<= :: ButtonStyle -> ButtonStyle -> Bool
$c<= :: ButtonStyle -> ButtonStyle -> Bool
< :: ButtonStyle -> ButtonStyle -> Bool
$c< :: ButtonStyle -> ButtonStyle -> Bool
compare :: ButtonStyle -> ButtonStyle -> Ordering
$ccompare :: ButtonStyle -> ButtonStyle -> Ordering
Ord)

instance FromJSON ButtonStyle where
  parseJSON :: Value -> Parser ButtonStyle
parseJSON =
    forall a. String -> (Scientific -> Parser a) -> Value -> Parser a
withScientific
      String
"ButtonStyle"
      ( \case
          Scientific
1 -> forall (m :: * -> *) a. Monad m => a -> m a
return ButtonStyle
ButtonStylePrimary
          Scientific
2 -> forall (m :: * -> *) a. Monad m => a -> m a
return ButtonStyle
ButtonStyleSecondary
          Scientific
3 -> forall (m :: * -> *) a. Monad m => a -> m a
return ButtonStyle
ButtonStyleSuccess
          Scientific
4 -> forall (m :: * -> *) a. Monad m => a -> m a
return ButtonStyle
ButtonStyleDanger
          Scientific
_ -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"unrecognised non-url button style"
      )

instance ToJSON ButtonStyle where
  toJSON :: ButtonStyle -> Value
toJSON ButtonStyle
ButtonStylePrimary = Scientific -> Value
Number Scientific
1
  toJSON ButtonStyle
ButtonStyleSecondary = Scientific -> Value
Number Scientific
2
  toJSON ButtonStyle
ButtonStyleSuccess = Scientific -> Value
Number Scientific
3
  toJSON ButtonStyle
ButtonStyleDanger = Scientific -> Value
Number Scientific
4

-- | Component type for a select menu.
--
-- Don't directly send select menus - they need to be within an action row.
data SelectMenu = SelectMenu
  { -- | Dev identifier
    SelectMenu -> Text
selectMenuCustomId :: T.Text,
    -- | Whether the select menu is disabled
    SelectMenu -> Bool
selectMenuDisabled :: Bool,
    -- | What options are in this select menu (up to 25)
    SelectMenu -> [SelectOption]
selectMenuOptions :: [SelectOption],
    -- | Placeholder text if nothing is selected
    SelectMenu -> Maybe Text
selectMenuPlaceholder :: Maybe T.Text,
    -- | Minimum number of values to select (def 1, min 0, max 25)
    SelectMenu -> Maybe Integer
selectMenuMinValues :: Maybe Integer,
    -- | Maximum number of values to select (def 1, max 25)
    SelectMenu -> Maybe Integer
selectMenuMaxValues :: Maybe Integer
  }
  deriving (Int -> SelectMenu -> ShowS
[SelectMenu] -> ShowS
SelectMenu -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SelectMenu] -> ShowS
$cshowList :: [SelectMenu] -> ShowS
show :: SelectMenu -> String
$cshow :: SelectMenu -> String
showsPrec :: Int -> SelectMenu -> ShowS
$cshowsPrec :: Int -> SelectMenu -> ShowS
Show, ReadPrec [SelectMenu]
ReadPrec SelectMenu
Int -> ReadS SelectMenu
ReadS [SelectMenu]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [SelectMenu]
$creadListPrec :: ReadPrec [SelectMenu]
readPrec :: ReadPrec SelectMenu
$creadPrec :: ReadPrec SelectMenu
readList :: ReadS [SelectMenu]
$creadList :: ReadS [SelectMenu]
readsPrec :: Int -> ReadS SelectMenu
$creadsPrec :: Int -> ReadS SelectMenu
Read, SelectMenu -> SelectMenu -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SelectMenu -> SelectMenu -> Bool
$c/= :: SelectMenu -> SelectMenu -> Bool
== :: SelectMenu -> SelectMenu -> Bool
$c== :: SelectMenu -> SelectMenu -> Bool
Eq, Eq SelectMenu
SelectMenu -> SelectMenu -> Bool
SelectMenu -> SelectMenu -> Ordering
SelectMenu -> SelectMenu -> SelectMenu
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: SelectMenu -> SelectMenu -> SelectMenu
$cmin :: SelectMenu -> SelectMenu -> SelectMenu
max :: SelectMenu -> SelectMenu -> SelectMenu
$cmax :: SelectMenu -> SelectMenu -> SelectMenu
>= :: SelectMenu -> SelectMenu -> Bool
$c>= :: SelectMenu -> SelectMenu -> Bool
> :: SelectMenu -> SelectMenu -> Bool
$c> :: SelectMenu -> SelectMenu -> Bool
<= :: SelectMenu -> SelectMenu -> Bool
$c<= :: SelectMenu -> SelectMenu -> Bool
< :: SelectMenu -> SelectMenu -> Bool
$c< :: SelectMenu -> SelectMenu -> Bool
compare :: SelectMenu -> SelectMenu -> Ordering
$ccompare :: SelectMenu -> SelectMenu -> Ordering
Ord)

-- | Takes the custom id and the options of the select menu that is to be
-- generated.
mkSelectMenu :: T.Text -> [SelectOption] -> SelectMenu
mkSelectMenu :: Text -> [SelectOption] -> SelectMenu
mkSelectMenu Text
customId [SelectOption]
sos = Text
-> Bool
-> [SelectOption]
-> Maybe Text
-> Maybe Integer
-> Maybe Integer
-> SelectMenu
SelectMenu Text
customId Bool
False [SelectOption]
sos forall a. Maybe a
Nothing forall a. Maybe a
Nothing forall a. Maybe a
Nothing

instance FromJSON SelectMenu where
  parseJSON :: Value -> Parser SelectMenu
parseJSON =
    forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject
      String
"SelectMenu"
      ( \Object
v ->
          do
            Int
t <- Object
v forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"type" :: Parser Int
            case Int
t of
              Int
3 ->
                Text
-> Bool
-> [SelectOption]
-> Maybe Text
-> Maybe Integer
-> Maybe Integer
-> SelectMenu
SelectMenu
                  forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
v forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"custom_id"
                  forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"disabled" forall a. Parser (Maybe a) -> a -> Parser a
.!= Bool
False
                  forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"options"
                  forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"placeholder"
                  forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"min_values"
                  forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"max_values"
              Int
_ -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"expected select menu type, got different component"
      )

instance ToJSON SelectMenu where
  toJSON :: SelectMenu -> Value
toJSON SelectMenu {Bool
[SelectOption]
Maybe Integer
Maybe Text
Text
selectMenuMaxValues :: Maybe Integer
selectMenuMinValues :: Maybe Integer
selectMenuPlaceholder :: Maybe Text
selectMenuOptions :: [SelectOption]
selectMenuDisabled :: Bool
selectMenuCustomId :: Text
selectMenuMaxValues :: SelectMenu -> Maybe Integer
selectMenuMinValues :: SelectMenu -> Maybe Integer
selectMenuPlaceholder :: SelectMenu -> Maybe Text
selectMenuOptions :: SelectMenu -> [SelectOption]
selectMenuDisabled :: SelectMenu -> Bool
selectMenuCustomId :: SelectMenu -> Text
..} =
    [Maybe Pair] -> Value
objectFromMaybes
      [ Key
"type" forall a. ToJSON a => Key -> a -> Maybe Pair
.== Scientific -> Value
Number Scientific
3,
        Key
"custom_id" forall a. ToJSON a => Key -> a -> Maybe Pair
.== Text
selectMenuCustomId,
        Key
"disabled" forall a. ToJSON a => Key -> a -> Maybe Pair
.== Bool
selectMenuDisabled,
        Key
"options" forall a. ToJSON a => Key -> a -> Maybe Pair
.== [SelectOption]
selectMenuOptions,
        Key
"placeholder" forall a. ToJSON a => Key -> Maybe a -> Maybe Pair
.=? Maybe Text
selectMenuPlaceholder,
        Key
"min_values" forall a. ToJSON a => Key -> Maybe a -> Maybe Pair
.=? Maybe Integer
selectMenuMinValues,
        Key
"max_values" forall a. ToJSON a => Key -> Maybe a -> Maybe Pair
.=? Maybe Integer
selectMenuMaxValues
      ]

-- | A single option in a select menu.
data SelectOption = SelectOption
  { -- | User facing option name
    SelectOption -> Text
selectOptionLabel :: T.Text,
    -- | Dev facing option value
    SelectOption -> Text
selectOptionValue :: T.Text,
    -- | additional description
    SelectOption -> Maybe Text
selectOptionDescription :: Maybe T.Text,
    -- | A partial emoji to show with the object (id, name, animated)
    SelectOption -> Maybe Emoji
selectOptionEmoji :: Maybe Emoji,
    -- | Use this value by default
    SelectOption -> Maybe Bool
selectOptionDefault :: Maybe Bool
  }
  deriving (Int -> SelectOption -> ShowS
[SelectOption] -> ShowS
SelectOption -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SelectOption] -> ShowS
$cshowList :: [SelectOption] -> ShowS
show :: SelectOption -> String
$cshow :: SelectOption -> String
showsPrec :: Int -> SelectOption -> ShowS
$cshowsPrec :: Int -> SelectOption -> ShowS
Show, ReadPrec [SelectOption]
ReadPrec SelectOption
Int -> ReadS SelectOption
ReadS [SelectOption]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [SelectOption]
$creadListPrec :: ReadPrec [SelectOption]
readPrec :: ReadPrec SelectOption
$creadPrec :: ReadPrec SelectOption
readList :: ReadS [SelectOption]
$creadList :: ReadS [SelectOption]
readsPrec :: Int -> ReadS SelectOption
$creadsPrec :: Int -> ReadS SelectOption
Read, SelectOption -> SelectOption -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SelectOption -> SelectOption -> Bool
$c/= :: SelectOption -> SelectOption -> Bool
== :: SelectOption -> SelectOption -> Bool
$c== :: SelectOption -> SelectOption -> Bool
Eq, Eq SelectOption
SelectOption -> SelectOption -> Bool
SelectOption -> SelectOption -> Ordering
SelectOption -> SelectOption -> SelectOption
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: SelectOption -> SelectOption -> SelectOption
$cmin :: SelectOption -> SelectOption -> SelectOption
max :: SelectOption -> SelectOption -> SelectOption
$cmax :: SelectOption -> SelectOption -> SelectOption
>= :: SelectOption -> SelectOption -> Bool
$c>= :: SelectOption -> SelectOption -> Bool
> :: SelectOption -> SelectOption -> Bool
$c> :: SelectOption -> SelectOption -> Bool
<= :: SelectOption -> SelectOption -> Bool
$c<= :: SelectOption -> SelectOption -> Bool
< :: SelectOption -> SelectOption -> Bool
$c< :: SelectOption -> SelectOption -> Bool
compare :: SelectOption -> SelectOption -> Ordering
$ccompare :: SelectOption -> SelectOption -> Ordering
Ord)

-- | Make a select option from the given label and value.
mkSelectOption :: T.Text -> T.Text -> SelectOption
mkSelectOption :: Text -> Text -> SelectOption
mkSelectOption Text
label Text
value = Text
-> Text -> Maybe Text -> Maybe Emoji -> Maybe Bool -> SelectOption
SelectOption Text
label Text
value forall a. Maybe a
Nothing forall a. Maybe a
Nothing forall a. Maybe a
Nothing

instance FromJSON SelectOption where
  parseJSON :: Value -> Parser SelectOption
parseJSON = forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"SelectOption" forall a b. (a -> b) -> a -> b
$ \Object
o ->
    Text
-> Text -> Maybe Text -> Maybe Emoji -> Maybe Bool -> SelectOption
SelectOption forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"label"
      forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"value"
      forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"description"
      forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"emoji"
      forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"default"

instance ToJSON SelectOption where
  toJSON :: SelectOption -> Value
toJSON SelectOption {Maybe Bool
Maybe Text
Maybe Emoji
Text
selectOptionDefault :: Maybe Bool
selectOptionEmoji :: Maybe Emoji
selectOptionDescription :: Maybe Text
selectOptionValue :: Text
selectOptionLabel :: Text
selectOptionDefault :: SelectOption -> Maybe Bool
selectOptionEmoji :: SelectOption -> Maybe Emoji
selectOptionDescription :: SelectOption -> Maybe Text
selectOptionValue :: SelectOption -> Text
selectOptionLabel :: SelectOption -> Text
..} =
    [Maybe Pair] -> Value
objectFromMaybes
      [ Key
"label" forall a. ToJSON a => Key -> a -> Maybe Pair
.== Text
selectOptionLabel,
        Key
"value" forall a. ToJSON a => Key -> a -> Maybe Pair
.== Text
selectOptionValue,
        Key
"description" forall a. ToJSON a => Key -> Maybe a -> Maybe Pair
.=? Maybe Text
selectOptionDescription,
        Key
"emoji" forall a. ToJSON a => Key -> Maybe a -> Maybe Pair
.=? Maybe Emoji
selectOptionEmoji,
        Key
"default" forall a. ToJSON a => Key -> Maybe a -> Maybe Pair
.=? Maybe Bool
selectOptionDefault
      ]

data TextInput = TextInput
  { -- | Dev identifier
    TextInput -> Text
textInputCustomId :: T.Text,
    -- | What style to use (short or paragraph)
    TextInput -> Bool
textInputIsParagraph :: Bool,
    -- | The label for this component
    TextInput -> Text
textInputLabel :: T.Text,
    -- | The minimum input length for a text input (0-4000)
    TextInput -> Maybe Integer
textInputMinLength :: Maybe Integer,
    -- | The maximum input length for a text input (1-4000)
    TextInput -> Maybe Integer
textInputMaxLength :: Maybe Integer,
    -- | Whether this component is required to be filled
    TextInput -> Bool
textInputRequired :: Bool,
    -- | The prefilled value for this component (max 4000)
    TextInput -> Text
textInputValue :: T.Text,
    -- | Placeholder text if empty (max 4000)
    TextInput -> Text
textInputPlaceholder :: T.Text
  }
  deriving (Int -> TextInput -> ShowS
[TextInput] -> ShowS
TextInput -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TextInput] -> ShowS
$cshowList :: [TextInput] -> ShowS
show :: TextInput -> String
$cshow :: TextInput -> String
showsPrec :: Int -> TextInput -> ShowS
$cshowsPrec :: Int -> TextInput -> ShowS
Show, ReadPrec [TextInput]
ReadPrec TextInput
Int -> ReadS TextInput
ReadS [TextInput]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [TextInput]
$creadListPrec :: ReadPrec [TextInput]
readPrec :: ReadPrec TextInput
$creadPrec :: ReadPrec TextInput
readList :: ReadS [TextInput]
$creadList :: ReadS [TextInput]
readsPrec :: Int -> ReadS TextInput
$creadsPrec :: Int -> ReadS TextInput
Read, TextInput -> TextInput -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TextInput -> TextInput -> Bool
$c/= :: TextInput -> TextInput -> Bool
== :: TextInput -> TextInput -> Bool
$c== :: TextInput -> TextInput -> Bool
Eq, Eq TextInput
TextInput -> TextInput -> Bool
TextInput -> TextInput -> Ordering
TextInput -> TextInput -> TextInput
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: TextInput -> TextInput -> TextInput
$cmin :: TextInput -> TextInput -> TextInput
max :: TextInput -> TextInput -> TextInput
$cmax :: TextInput -> TextInput -> TextInput
>= :: TextInput -> TextInput -> Bool
$c>= :: TextInput -> TextInput -> Bool
> :: TextInput -> TextInput -> Bool
$c> :: TextInput -> TextInput -> Bool
<= :: TextInput -> TextInput -> Bool
$c<= :: TextInput -> TextInput -> Bool
< :: TextInput -> TextInput -> Bool
$c< :: TextInput -> TextInput -> Bool
compare :: TextInput -> TextInput -> Ordering
$ccompare :: TextInput -> TextInput -> Ordering
Ord)

instance ToJSON TextInput where
  toJSON :: TextInput -> Value
toJSON TextInput {Bool
Maybe Integer
Text
textInputPlaceholder :: Text
textInputValue :: Text
textInputRequired :: Bool
textInputMaxLength :: Maybe Integer
textInputMinLength :: Maybe Integer
textInputLabel :: Text
textInputIsParagraph :: Bool
textInputCustomId :: Text
textInputPlaceholder :: TextInput -> Text
textInputValue :: TextInput -> Text
textInputRequired :: TextInput -> Bool
textInputMaxLength :: TextInput -> Maybe Integer
textInputMinLength :: TextInput -> Maybe Integer
textInputLabel :: TextInput -> Text
textInputIsParagraph :: TextInput -> Bool
textInputCustomId :: TextInput -> Text
..} =
    [Maybe Pair] -> Value
objectFromMaybes
      [ Key
"type" forall a. ToJSON a => Key -> a -> Maybe Pair
.== Scientific -> Value
Number Scientific
4,
        Key
"custom_id" forall a. ToJSON a => Key -> a -> Maybe Pair
.== Text
textInputCustomId,
        Key
"style" forall a. ToJSON a => Key -> a -> Maybe Pair
.== (Int
1 forall a. Num a => a -> a -> a
+ forall a. Enum a => a -> Int
fromEnum Bool
textInputIsParagraph),
        Key
"label" forall a. ToJSON a => Key -> a -> Maybe Pair
.== Text
textInputLabel,
        Key
"min_length" forall a. ToJSON a => Key -> Maybe a -> Maybe Pair
.=? Maybe Integer
textInputMinLength,
        Key
"max_length" forall a. ToJSON a => Key -> Maybe a -> Maybe Pair
.=? Maybe Integer
textInputMaxLength,
        Key
"required" forall a. ToJSON a => Key -> a -> Maybe Pair
.== Bool
textInputRequired,
        Key
"value" forall a. ToJSON a => Key -> a -> Maybe Pair
.== Text
textInputValue,
        Key
"placeholder" forall a. ToJSON a => Key -> a -> Maybe Pair
.== Text
textInputPlaceholder
      ]

instance FromJSON TextInput where
  parseJSON :: Value -> Parser TextInput
parseJSON = forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"TextInput" forall a b. (a -> b) -> a -> b
$ \Object
o -> do
    Int
t <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"type" :: Parser Int
    case Int
t of
      Int
4 ->
        Text
-> Bool
-> Text
-> Maybe Integer
-> Maybe Integer
-> Bool
-> Text
-> Text
-> TextInput
TextInput forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"custom_id"
          forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a. Eq a => a -> a -> Bool
== (Int
2 :: Int)) (Object
o forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"style" forall a. Parser (Maybe a) -> a -> Parser a
.!= Int
1)
          forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"label" forall a. Parser (Maybe a) -> a -> Parser a
.!= Text
""
          forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"min_length"
          forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"max_length"
          forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"required" forall a. Parser (Maybe a) -> a -> Parser a
.!= Bool
False
          forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"value" forall a. Parser (Maybe a) -> a -> Parser a
.!= Text
""
          forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"placeholder" forall a. Parser (Maybe a) -> a -> Parser a
.!= Text
""
      Int
_ -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"expected text input, found other type of component"

-- | Create a text input from an id and a label
mkTextInput :: T.Text -> T.Text -> TextInput
mkTextInput :: Text -> Text -> TextInput
mkTextInput Text
cid Text
label = Text
-> Bool
-> Text
-> Maybe Integer
-> Maybe Integer
-> Bool
-> Text
-> Text
-> TextInput
TextInput Text
cid Bool
False Text
label forall a. Maybe a
Nothing forall a. Maybe a
Nothing Bool
True Text
"" Text
""