calamity-0.8.0.0: Calamity/Types/Model/Presence/Activity.hs
{-# LANGUAGE TemplateHaskell #-}
-- | User activities
module Calamity.Types.Model.Presence.Activity (
Activity (..),
activity,
ActivityType (..),
ActivityTimestamps (..),
ActivityParty (..),
ActivityAssets (..),
ActivitySecrets (..),
) where
import Calamity.Internal.UnixTimestamp
import Calamity.Internal.Utils
import Calamity.Types.Snowflake
import Data.Aeson ((.:), (.:?))
import Data.Aeson qualified as Aeson
import Data.Scientific
import Data.Text (Text)
import Data.Time (UTCTime)
import Data.Word
import Optics.TH
import TextShow qualified
import TextShow.TH
data ActivityType
= Game
| Streaming
| Listening
| Custom
| Other Int
deriving (Eq, Show)
instance Aeson.ToJSON ActivityType where
toJSON Game = Aeson.Number 0
toJSON Streaming = Aeson.Number 1
toJSON Listening = Aeson.Number 2
toJSON Custom = Aeson.Number 4
toJSON (Other n) = Aeson.Number $ fromIntegral n
instance Aeson.FromJSON ActivityType where
parseJSON = Aeson.withScientific "ActivityType" $ \n -> case toBoundedInteger @Int n of
Just v -> case v of
0 -> pure Game
1 -> pure Streaming
2 -> pure Listening
4 -> pure Custom
n -> pure $ Other n
Nothing -> fail $ "Invalid ActivityType: " <> show n
data Activity = Activity
{ name :: Text
, type_ :: ActivityType
, url :: Maybe Text
, timestamps :: Maybe ActivityTimestamps
, applicationID :: Maybe (Snowflake ())
, details :: Maybe Text
, state :: Maybe Text
, party :: Maybe ActivityParty
, assets :: Maybe ActivityAssets
, secrets :: Maybe ActivitySecrets
, instance_ :: Maybe Bool
, flags :: Maybe Word64
}
deriving (Eq, Show)
deriving (Aeson.ToJSON) via CalamityToJSON Activity
instance CalamityToJSON' Activity where
toPairs Activity {..} =
[ "name" .= name
, "type" .= type_
, "url" .?= url
, "timestamps" .?= timestamps
, "application_id" .?= applicationID
, "details" .?= details
, "state" .?= state
, "party" .?= party
, "assets" .?= assets
, "secrets" .?= secrets
, "instance" .?= instance_
, "flags" .?= flags
]
instance Aeson.FromJSON Activity where
parseJSON = Aeson.withObject "Activity" $ \v ->
Activity
<$> v .: "name"
<*> v .: "type"
<*> v .:? "url"
<*> v .:? "timestamps"
<*> v .:? "application_id"
<*> v .:? "details"
<*> v .:? "state"
<*> v .:? "party"
<*> v .:? "assets"
<*> v .:? "secrets"
<*> v .:? "instance"
<*> v .:? "flags"
-- | Make an 'Activity' with all optional fields set to Nothing
activity :: Text -> ActivityType -> Activity
activity !name !type_ =
Activity
{ name = name
, type_ = type_
, url = Nothing
, timestamps = Nothing
, applicationID = Nothing
, details = Nothing
, state = Nothing
, party = Nothing
, assets = Nothing
, secrets = Nothing
, instance_ = Nothing
, flags = Nothing
}
data ActivityTimestamps = ActivityTimestamps
{ start :: Maybe UTCTime
, end :: Maybe UTCTime
}
deriving (Eq, Show)
deriving (TextShow.TextShow) via TextShow.FromStringShow ActivityTimestamps
deriving (Aeson.ToJSON) via CalamityToJSON ActivityTimestamps
instance CalamityToJSON' ActivityTimestamps where
toPairs ActivityTimestamps {..} =
[ "start" .?= fmap UnixTimestamp start
, "end" .?= fmap UnixTimestamp end
]
instance Aeson.FromJSON ActivityTimestamps where
parseJSON = Aeson.withObject "ActivityTimestamps" $ \v ->
ActivityTimestamps
<$> (fmap unUnixTimestamp <$> v .:? "start")
<*> (fmap unUnixTimestamp <$> v .:? "end")
data ActivityParty = ActivityParty
{ id :: Maybe Text
, size :: Maybe (Int, Int)
}
deriving (Eq, Show)
deriving (Aeson.ToJSON) via CalamityToJSON ActivityParty
instance CalamityToJSON' ActivityParty where
toPairs ActivityParty {..} =
[ "id" .?= id
, "size" .?= size
]
instance Aeson.FromJSON ActivityParty where
parseJSON = Aeson.withObject "ActivityParty" $ \v ->
ActivityParty
<$> v .:? "id"
<*> v .:? "size"
data ActivityAssets = ActivityAssets
{ largeImage :: Maybe Text
, largeText :: Maybe Text
, smallImage :: Maybe Text
, smallText :: Maybe Text
}
deriving (Eq, Show)
deriving (Aeson.ToJSON) via CalamityToJSON ActivityAssets
instance CalamityToJSON' ActivityAssets where
toPairs ActivityAssets {..} =
[ "large_image" .?= largeImage
, "large_text" .?= largeText
, "small_image" .?= smallImage
, "small_text" .?= smallText
]
instance Aeson.FromJSON ActivityAssets where
parseJSON = Aeson.withObject "ActivityAssets" $ \v ->
ActivityAssets
<$> v .:? "large_image"
<*> v .:? "large_text"
<*> v .:? "small_image"
<*> v .:? "small_text"
data ActivitySecrets = ActivitySecrets
{ join :: Maybe Text
, spectate :: Maybe Text
, match :: Maybe Text
}
deriving (Eq, Show)
deriving (Aeson.ToJSON) via CalamityToJSON ActivitySecrets
instance CalamityToJSON' ActivitySecrets where
toPairs ActivitySecrets {..} =
[ "join" .?= join
, "spectate" .?= spectate
, "match" .?= match
]
instance Aeson.FromJSON ActivitySecrets where
parseJSON = Aeson.withObject "ActivitySecrets" $ \v ->
ActivitySecrets
<$> v .:? "join"
<*> v .:? "spectate"
<*> v .:? "match"
$(deriveTextShow ''ActivityType)
$(deriveTextShow ''ActivityParty)
$(deriveTextShow ''ActivityAssets)
$(deriveTextShow ''ActivitySecrets)
$(deriveTextShow ''Activity)
$(makeFieldLabelsNoPrefix ''Activity)
$(makeFieldLabelsNoPrefix ''ActivityTimestamps)
$(makeFieldLabelsNoPrefix ''ActivityParty)
$(makeFieldLabelsNoPrefix ''ActivityAssets)
$(makeFieldLabelsNoPrefix ''ActivitySecrets)