calamity 0.1.10 → 0.1.10.1
raw patch · 29 files changed
+528/−53 lines, 29 filesdep +colourdep +data-flagsdep ~df1PVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies added: colour, data-flags
Dependency ranges changed: df1
API changes (from Hackage documentation)
+ Calamity.Client.Client: runBotIO' :: forall r a. (Members '[Embed IO, Final IO, CacheEff, MetricEff] r, Typeable (SetupEff r)) => Token -> Maybe StatusUpdateData -> Maybe Intents -> Sem (SetupEff r) a -> Sem r (Maybe StartupError)
+ Calamity.Client.Types: InviteCreateEvt :: EventType
+ Calamity.Client.Types: InviteDeleteEvt :: EventType
+ Calamity.Commands.Parser: instance Calamity.Commands.Parser.Parser Calamity.Types.Model.Channel.Guild.GuildChannel r
+ Calamity.Commands.Parser: instance Calamity.Commands.Parser.Parser Calamity.Types.Model.Guild.Emoji.Emoji r
+ Calamity.Commands.Parser: instance Polysemy.Internal.Union.Member Calamity.Cache.Eff.CacheEff r => Calamity.Commands.Parser.Parser Calamity.Types.Model.Guild.Guild.Guild r
+ Calamity.Gateway.DispatchEvents: InviteCreate :: InviteCreateData -> DispatchData
+ Calamity.Gateway.DispatchEvents: InviteCreateData :: Snowflake Channel -> Text -> UnixTimestamp -> Maybe (Snowflake Guild) -> Maybe (Snowflake User) -> Int -> Int -> Maybe (Snowflake User) -> Maybe Integer -> Bool -> Integer -> InviteCreateData
+ Calamity.Gateway.DispatchEvents: InviteDelete :: InviteDeleteData -> DispatchData
+ Calamity.Gateway.DispatchEvents: InviteDeleteData :: Snowflake Channel -> Maybe (Snowflake Guild) -> Text -> InviteDeleteData
+ Calamity.Gateway.DispatchEvents: [$sel:channelID:InviteCreateData] :: InviteCreateData -> Snowflake Channel
+ Calamity.Gateway.DispatchEvents: [$sel:channelID:InviteDeleteData] :: InviteDeleteData -> Snowflake Channel
+ Calamity.Gateway.DispatchEvents: [$sel:code:InviteCreateData] :: InviteCreateData -> Text
+ Calamity.Gateway.DispatchEvents: [$sel:code:InviteDeleteData] :: InviteDeleteData -> Text
+ Calamity.Gateway.DispatchEvents: [$sel:createdAt:InviteCreateData] :: InviteCreateData -> UnixTimestamp
+ Calamity.Gateway.DispatchEvents: [$sel:guildID:InviteCreateData] :: InviteCreateData -> Maybe (Snowflake Guild)
+ Calamity.Gateway.DispatchEvents: [$sel:guildID:InviteDeleteData] :: InviteDeleteData -> Maybe (Snowflake Guild)
+ Calamity.Gateway.DispatchEvents: [$sel:inviter:InviteCreateData] :: InviteCreateData -> Maybe (Snowflake User)
+ Calamity.Gateway.DispatchEvents: [$sel:maxAge:InviteCreateData] :: InviteCreateData -> Int
+ Calamity.Gateway.DispatchEvents: [$sel:maxUses:InviteCreateData] :: InviteCreateData -> Int
+ Calamity.Gateway.DispatchEvents: [$sel:targetUser:InviteCreateData] :: InviteCreateData -> Maybe (Snowflake User)
+ Calamity.Gateway.DispatchEvents: [$sel:targetUserType:InviteCreateData] :: InviteCreateData -> Maybe Integer
+ Calamity.Gateway.DispatchEvents: [$sel:temporary:InviteCreateData] :: InviteCreateData -> Bool
+ Calamity.Gateway.DispatchEvents: [$sel:uses:InviteCreateData] :: InviteCreateData -> Integer
+ Calamity.Gateway.DispatchEvents: data InviteCreateData
+ Calamity.Gateway.DispatchEvents: data InviteDeleteData
+ Calamity.Gateway.DispatchEvents: instance Data.Aeson.Types.FromJSON.FromJSON Calamity.Gateway.DispatchEvents.InviteCreateData
+ Calamity.Gateway.DispatchEvents: instance Data.Aeson.Types.FromJSON.FromJSON Calamity.Gateway.DispatchEvents.InviteDeleteData
+ Calamity.Gateway.DispatchEvents: instance GHC.Generics.Generic Calamity.Gateway.DispatchEvents.InviteCreateData
+ Calamity.Gateway.DispatchEvents: instance GHC.Generics.Generic Calamity.Gateway.DispatchEvents.InviteDeleteData
+ Calamity.Gateway.DispatchEvents: instance GHC.Show.Show Calamity.Gateway.DispatchEvents.InviteCreateData
+ Calamity.Gateway.DispatchEvents: instance GHC.Show.Show Calamity.Gateway.DispatchEvents.InviteDeleteData
+ Calamity.Gateway.Intents: Intents :: Word32 -> Intents
+ Calamity.Gateway.Intents: instance Data.Aeson.Types.ToJSON.ToJSON Calamity.Gateway.Intents.Intents
+ Calamity.Gateway.Intents: instance Data.Flags.Base.BoundedFlags Calamity.Gateway.Intents.Intents
+ Calamity.Gateway.Intents: instance Data.Flags.Base.Flags Calamity.Gateway.Intents.Intents
+ Calamity.Gateway.Intents: instance GHC.Classes.Eq Calamity.Gateway.Intents.Intents
+ Calamity.Gateway.Intents: instance GHC.Show.Show Calamity.Gateway.Intents.Intents
+ Calamity.Gateway.Intents: intentDirectMessageReactions :: Intents
+ Calamity.Gateway.Intents: intentDirectMessageTyping :: Intents
+ Calamity.Gateway.Intents: intentDirectMessages :: Intents
+ Calamity.Gateway.Intents: intentGuildBans :: Intents
+ Calamity.Gateway.Intents: intentGuildEmojis :: Intents
+ Calamity.Gateway.Intents: intentGuildIntegrations :: Intents
+ Calamity.Gateway.Intents: intentGuildInvites :: Intents
+ Calamity.Gateway.Intents: intentGuildMembers :: Intents
+ Calamity.Gateway.Intents: intentGuildMessageReactions :: Intents
+ Calamity.Gateway.Intents: intentGuildMessageTyping :: Intents
+ Calamity.Gateway.Intents: intentGuildMessages :: Intents
+ Calamity.Gateway.Intents: intentGuildPresences :: Intents
+ Calamity.Gateway.Intents: intentGuildVoiceStates :: Intents
+ Calamity.Gateway.Intents: intentGuildWebhooks :: Intents
+ Calamity.Gateway.Intents: intentGuilds :: Intents
+ Calamity.Gateway.Intents: newtype Intents
+ Calamity.Gateway.Shard: [$sel:initialStatus:Shard] :: Shard -> Maybe StatusUpdateData
+ Calamity.Gateway.Shard: [$sel:intents:Shard] :: Shard -> Maybe Intents
+ Calamity.Gateway.Types: INVITE_CREATE :: DispatchType
+ Calamity.Gateway.Types: INVITE_DELETE :: DispatchType
+ Calamity.Gateway.Types: [$sel:initialStatus:Shard] :: Shard -> Maybe StatusUpdateData
+ Calamity.Gateway.Types: [$sel:intents:IdentifyData] :: IdentifyData -> Maybe Intents
+ Calamity.Gateway.Types: [$sel:intents:Shard] :: Shard -> Maybe Intents
+ Calamity.HTTP.Channel: [$sel:allowedMentions:CreateMessageOptions] :: CreateMessageOptions -> Maybe AllowedMentions
+ Calamity.HTTP.Channel: instance Data.Aeson.Types.ToJSON.ToJSON Calamity.HTTP.Channel.AllowedMentionType
+ Calamity.HTTP.Channel: instance Data.Aeson.Types.ToJSON.ToJSON Calamity.HTTP.Channel.AllowedMentions
+ Calamity.HTTP.Channel: instance Data.Default.Class.Default Calamity.HTTP.Channel.AllowedMentions
+ Calamity.HTTP.Channel: instance GHC.Generics.Generic Calamity.HTTP.Channel.AllowedMentionType
+ Calamity.HTTP.Channel: instance GHC.Generics.Generic Calamity.HTTP.Channel.AllowedMentions
+ Calamity.HTTP.Channel: instance GHC.Show.Show Calamity.HTTP.Channel.AllowedMentionType
+ Calamity.HTTP.Channel: instance GHC.Show.Show Calamity.HTTP.Channel.AllowedMentions
+ Calamity.Internal.IntColour: colourFromWord64 :: Word64 -> Colour Double
+ Calamity.Internal.IntColour: colourToWord64 :: Colour Double -> Word64
+ Calamity.Internal.IntColour: instance Data.Aeson.Types.FromJSON.FromJSON (Data.Colour.Internal.Colour GHC.Types.Double)
+ Calamity.Internal.IntColour: instance Data.Aeson.Types.ToJSON.ToJSON (Data.Colour.Internal.Colour GHC.Types.Double)
+ Calamity.Internal.Utils: instance (GHC.Show.Show a, GHC.Real.Fractional a) => TextShow.Classes.TextShow (Data.Colour.Internal.Colour a)
+ Calamity.Types.Model.Channel.Guild: instance Data.Generics.Product.Fields.HasField' "name" Calamity.Types.Model.Channel.Guild.GuildChannel Data.Text.Internal.Lazy.Text
+ Calamity.Types.Model.Channel.Guild: instance Data.Generics.Product.Fields.HasField' "permissionOverwrites" Calamity.Types.Model.Channel.Guild.GuildChannel (Calamity.Internal.SnowflakeMap.SnowflakeMap Calamity.Types.Model.Guild.Overwrite.Overwrite)
+ Calamity.Types.Model.Channel.Guild: instance Data.Generics.Product.Fields.HasField' "position" Calamity.Types.Model.Channel.Guild.GuildChannel GHC.Types.Int
+ Calamity.Types.Model.Guild.Permissions: Permissions :: Word64 -> Permissions
+ Calamity.Types.Model.Guild.Permissions: addReactions :: Permissions
+ Calamity.Types.Model.Guild.Permissions: administrator :: Permissions
+ Calamity.Types.Model.Guild.Permissions: attachFiles :: Permissions
+ Calamity.Types.Model.Guild.Permissions: banMembers :: Permissions
+ Calamity.Types.Model.Guild.Permissions: changeNickname :: Permissions
+ Calamity.Types.Model.Guild.Permissions: connect :: Permissions
+ Calamity.Types.Model.Guild.Permissions: createInstantInvite :: Permissions
+ Calamity.Types.Model.Guild.Permissions: deafenMembers :: Permissions
+ Calamity.Types.Model.Guild.Permissions: embedLinks :: Permissions
+ Calamity.Types.Model.Guild.Permissions: instance Data.Aeson.Types.FromJSON.FromJSON Calamity.Types.Model.Guild.Permissions.Permissions
+ Calamity.Types.Model.Guild.Permissions: instance Data.Aeson.Types.ToJSON.ToJSON Calamity.Types.Model.Guild.Permissions.Permissions
+ Calamity.Types.Model.Guild.Permissions: instance Data.Flags.Base.BoundedFlags Calamity.Types.Model.Guild.Permissions.Permissions
+ Calamity.Types.Model.Guild.Permissions: instance Data.Flags.Base.Flags Calamity.Types.Model.Guild.Permissions.Permissions
+ Calamity.Types.Model.Guild.Permissions: instance GHC.Classes.Eq Calamity.Types.Model.Guild.Permissions.Permissions
+ Calamity.Types.Model.Guild.Permissions: instance GHC.Show.Show Calamity.Types.Model.Guild.Permissions.Permissions
+ Calamity.Types.Model.Guild.Permissions: instance TextShow.Classes.TextShow Calamity.Types.Model.Guild.Permissions.Permissions
+ Calamity.Types.Model.Guild.Permissions: kickMembers :: Permissions
+ Calamity.Types.Model.Guild.Permissions: manageChannels :: Permissions
+ Calamity.Types.Model.Guild.Permissions: manageEmojis :: Permissions
+ Calamity.Types.Model.Guild.Permissions: manageGuild :: Permissions
+ Calamity.Types.Model.Guild.Permissions: manageMessages :: Permissions
+ Calamity.Types.Model.Guild.Permissions: manageNicknames :: Permissions
+ Calamity.Types.Model.Guild.Permissions: manageRoles :: Permissions
+ Calamity.Types.Model.Guild.Permissions: manageWebhooks :: Permissions
+ Calamity.Types.Model.Guild.Permissions: mentionEveryone :: Permissions
+ Calamity.Types.Model.Guild.Permissions: moveMembers :: Permissions
+ Calamity.Types.Model.Guild.Permissions: muteMembers :: Permissions
+ Calamity.Types.Model.Guild.Permissions: newtype Permissions
+ Calamity.Types.Model.Guild.Permissions: prioritySpeaker :: Permissions
+ Calamity.Types.Model.Guild.Permissions: readMessageHistory :: Permissions
+ Calamity.Types.Model.Guild.Permissions: sendMessages :: Permissions
+ Calamity.Types.Model.Guild.Permissions: sendTtsMessages :: Permissions
+ Calamity.Types.Model.Guild.Permissions: speak :: Permissions
+ Calamity.Types.Model.Guild.Permissions: stream :: Permissions
+ Calamity.Types.Model.Guild.Permissions: useExternalEmojis :: Permissions
+ Calamity.Types.Model.Guild.Permissions: useVad :: Permissions
+ Calamity.Types.Model.Guild.Permissions: viewAuditLog :: Permissions
+ Calamity.Types.Model.Guild.Permissions: viewChannel :: Permissions
+ Calamity.Types.Model.Guild.Permissions: viewGuildInsights :: Permissions
+ Calamity.Utils.Colour: blurple :: (Ord a, Floating a) => Colour a
+ Calamity.Utils.Colour: colourFromWord64 :: Word64 -> Colour Double
+ Calamity.Utils.Colour: colourToWord64 :: Colour Double -> Word64
+ Calamity.Utils.Colour: greyple :: (Ord a, Floating a) => Colour a
+ Calamity.Utils.Permissions: applyOverwrites :: GuildChannel -> Member -> Permissions -> Permissions
+ Calamity.Utils.Permissions: basePermissions :: Guild -> Member -> Permissions
+ Calamity.Utils.Permissions: class PermissionsIn a
+ Calamity.Utils.Permissions: class PermissionsIn' a
+ Calamity.Utils.Permissions: instance Calamity.Utils.Permissions.PermissionsIn (Calamity.Types.Model.Guild.Guild.Guild, Calamity.Types.Model.Channel.Guild.GuildChannel)
+ Calamity.Utils.Permissions: instance Calamity.Utils.Permissions.PermissionsIn Calamity.Types.Model.Guild.Guild.Guild
+ Calamity.Utils.Permissions: instance Calamity.Utils.Permissions.PermissionsIn' (Calamity.Types.Snowflake.Snowflake Calamity.Types.Model.Channel.Guild.GuildChannel)
+ Calamity.Utils.Permissions: instance Calamity.Utils.Permissions.PermissionsIn' (Calamity.Types.Snowflake.Snowflake Calamity.Types.Model.Guild.Guild.Guild)
+ Calamity.Utils.Permissions: instance Calamity.Utils.Permissions.PermissionsIn' Calamity.Types.Model.Channel.Guild.GuildChannel
+ Calamity.Utils.Permissions: instance Calamity.Utils.Permissions.PermissionsIn' Calamity.Types.Model.Guild.Guild.Guild
+ Calamity.Utils.Permissions: permissionsIn :: PermissionsIn a => a -> Member -> Permissions
+ Calamity.Utils.Permissions: permissionsIn' :: (PermissionsIn' a, BotC r) => a -> Member -> Sem r Permissions
- Calamity.Cache.Eff: delDM :: forall r_a9JU6. MemberWithError CacheEff r_a9JU6 => Snowflake DMChannel -> Sem r_a9JU6 ()
+ Calamity.Cache.Eff: delDM :: forall r_a9O0m. MemberWithError CacheEff r_a9O0m => Snowflake DMChannel -> Sem r_a9O0m ()
- Calamity.Cache.Eff: delGuild :: forall r_a9JTZ. MemberWithError CacheEff r_a9JTZ => Snowflake Guild -> Sem r_a9JTZ ()
+ Calamity.Cache.Eff: delGuild :: forall r_a9O0f. MemberWithError CacheEff r_a9O0f => Snowflake Guild -> Sem r_a9O0f ()
- Calamity.Cache.Eff: delMessage :: forall r_a9JUr. MemberWithError CacheEff r_a9JUr => Snowflake Message -> Sem r_a9JUr ()
+ Calamity.Cache.Eff: delMessage :: forall r_a9O0H. MemberWithError CacheEff r_a9O0H => Snowflake Message -> Sem r_a9O0H ()
- Calamity.Cache.Eff: delUnavailableGuild :: forall r_a9JUk. MemberWithError CacheEff r_a9JUk => Snowflake Guild -> Sem r_a9JUk ()
+ Calamity.Cache.Eff: delUnavailableGuild :: forall r_a9O0A. MemberWithError CacheEff r_a9O0A => Snowflake Guild -> Sem r_a9O0A ()
- Calamity.Cache.Eff: delUser :: forall r_a9JUd. MemberWithError CacheEff r_a9JUd => Snowflake User -> Sem r_a9JUd ()
+ Calamity.Cache.Eff: delUser :: forall r_a9O0t. MemberWithError CacheEff r_a9O0t => Snowflake User -> Sem r_a9O0t ()
- Calamity.Cache.Eff: getBotUser :: forall r_a9JTR. MemberWithError CacheEff r_a9JTR => Sem r_a9JTR (Maybe User)
+ Calamity.Cache.Eff: getBotUser :: forall r_a9O07. MemberWithError CacheEff r_a9O07 => Sem r_a9O07 (Maybe User)
- Calamity.Cache.Eff: getDM :: forall r_a9JU3. MemberWithError CacheEff r_a9JU3 => Snowflake DMChannel -> Sem r_a9JU3 (Maybe DMChannel)
+ Calamity.Cache.Eff: getDM :: forall r_a9O0j. MemberWithError CacheEff r_a9O0j => Snowflake DMChannel -> Sem r_a9O0j (Maybe DMChannel)
- Calamity.Cache.Eff: getDMs :: forall r_a9JU5. MemberWithError CacheEff r_a9JU5 => Sem r_a9JU5 [DMChannel]
+ Calamity.Cache.Eff: getDMs :: forall r_a9O0l. MemberWithError CacheEff r_a9O0l => Sem r_a9O0l [DMChannel]
- Calamity.Cache.Eff: getGuild :: forall r_a9JTU. MemberWithError CacheEff r_a9JTU => Snowflake Guild -> Sem r_a9JTU (Maybe Guild)
+ Calamity.Cache.Eff: getGuild :: forall r_a9O0a. MemberWithError CacheEff r_a9O0a => Snowflake Guild -> Sem r_a9O0a (Maybe Guild)
- Calamity.Cache.Eff: getGuildChannel :: forall r_a9JTW. MemberWithError CacheEff r_a9JTW => Snowflake GuildChannel -> Sem r_a9JTW (Maybe GuildChannel)
+ Calamity.Cache.Eff: getGuildChannel :: forall r_a9O0c. MemberWithError CacheEff r_a9O0c => Snowflake GuildChannel -> Sem r_a9O0c (Maybe GuildChannel)
- Calamity.Cache.Eff: getGuilds :: forall r_a9JTY. MemberWithError CacheEff r_a9JTY => Sem r_a9JTY [Guild]
+ Calamity.Cache.Eff: getGuilds :: forall r_a9O0e. MemberWithError CacheEff r_a9O0e => Sem r_a9O0e [Guild]
- Calamity.Cache.Eff: getMessage :: forall r_a9JUo. MemberWithError CacheEff r_a9JUo => Snowflake Message -> Sem r_a9JUo (Maybe Message)
+ Calamity.Cache.Eff: getMessage :: forall r_a9O0E. MemberWithError CacheEff r_a9O0E => Snowflake Message -> Sem r_a9O0E (Maybe Message)
- Calamity.Cache.Eff: getMessages :: forall r_a9JUq. MemberWithError CacheEff r_a9JUq => Sem r_a9JUq [Message]
+ Calamity.Cache.Eff: getMessages :: forall r_a9O0G. MemberWithError CacheEff r_a9O0G => Sem r_a9O0G [Message]
- Calamity.Cache.Eff: getUnavailableGuilds :: forall r_a9JUj. MemberWithError CacheEff r_a9JUj => Sem r_a9JUj [Snowflake Guild]
+ Calamity.Cache.Eff: getUnavailableGuilds :: forall r_a9O0z. MemberWithError CacheEff r_a9O0z => Sem r_a9O0z [Snowflake Guild]
- Calamity.Cache.Eff: getUser :: forall r_a9JUa. MemberWithError CacheEff r_a9JUa => Snowflake User -> Sem r_a9JUa (Maybe User)
+ Calamity.Cache.Eff: getUser :: forall r_a9O0q. MemberWithError CacheEff r_a9O0q => Snowflake User -> Sem r_a9O0q (Maybe User)
- Calamity.Cache.Eff: getUsers :: forall r_a9JUc. MemberWithError CacheEff r_a9JUc => Sem r_a9JUc [User]
+ Calamity.Cache.Eff: getUsers :: forall r_a9O0s. MemberWithError CacheEff r_a9O0s => Sem r_a9O0s [User]
- Calamity.Cache.Eff: isUnavailableGuild :: forall r_a9JUh. MemberWithError CacheEff r_a9JUh => Snowflake Guild -> Sem r_a9JUh Bool
+ Calamity.Cache.Eff: isUnavailableGuild :: forall r_a9O0x. MemberWithError CacheEff r_a9O0x => Snowflake Guild -> Sem r_a9O0x Bool
- Calamity.Cache.Eff: setBotUser :: forall r_a9JTP. MemberWithError CacheEff r_a9JTP => User -> Sem r_a9JTP ()
+ Calamity.Cache.Eff: setBotUser :: forall r_a9O05. MemberWithError CacheEff r_a9O05 => User -> Sem r_a9O05 ()
- Calamity.Cache.Eff: setDM :: forall r_a9JU1. MemberWithError CacheEff r_a9JU1 => DMChannel -> Sem r_a9JU1 ()
+ Calamity.Cache.Eff: setDM :: forall r_a9O0h. MemberWithError CacheEff r_a9O0h => DMChannel -> Sem r_a9O0h ()
- Calamity.Cache.Eff: setGuild :: forall r_a9JTS. MemberWithError CacheEff r_a9JTS => Guild -> Sem r_a9JTS ()
+ Calamity.Cache.Eff: setGuild :: forall r_a9O08. MemberWithError CacheEff r_a9O08 => Guild -> Sem r_a9O08 ()
- Calamity.Cache.Eff: setMessage :: forall r_a9JUm. MemberWithError CacheEff r_a9JUm => Message -> Sem r_a9JUm ()
+ Calamity.Cache.Eff: setMessage :: forall r_a9O0C. MemberWithError CacheEff r_a9O0C => Message -> Sem r_a9O0C ()
- Calamity.Cache.Eff: setUnavailableGuild :: forall r_a9JUf. MemberWithError CacheEff r_a9JUf => Snowflake Guild -> Sem r_a9JUf ()
+ Calamity.Cache.Eff: setUnavailableGuild :: forall r_a9O0v. MemberWithError CacheEff r_a9O0v => Snowflake Guild -> Sem r_a9O0v ()
- Calamity.Cache.Eff: setUser :: forall r_a9JU8. MemberWithError CacheEff r_a9JU8 => User -> Sem r_a9JU8 ()
+ Calamity.Cache.Eff: setUser :: forall r_a9O0o. MemberWithError CacheEff r_a9O0o => User -> Sem r_a9O0o ()
- Calamity.Client.ShardManager: shardBot :: BotC r => Sem r (Either StartupError ())
+ Calamity.Client.ShardManager: shardBot :: BotC r => Maybe StatusUpdateData -> Maybe Intents -> Sem r (Either StartupError ())
- Calamity.Commands.ParsePrefix: parsePrefix :: forall r_a6Fl4. MemberWithError ParsePrefix r_a6Fl4 => Message -> Sem r_a6Fl4 (Maybe (Text, Text))
+ Calamity.Commands.ParsePrefix: parsePrefix :: forall r_a7reh. MemberWithError ParsePrefix r_a7reh => Message -> Sem r_a7reh (Maybe (Text, Text))
- Calamity.Gateway.Shard: Shard :: Int -> Int -> Text -> InChan CalamityEvent -> OutChan ControlMessage -> IORef ShardState -> Text -> Shard
+ Calamity.Gateway.Shard: Shard :: Int -> Int -> Text -> InChan CalamityEvent -> OutChan ControlMessage -> IORef ShardState -> Text -> Maybe StatusUpdateData -> Maybe Intents -> Shard
- Calamity.Gateway.Shard: newShard :: Members '[LogEff, MetricEff, Embed IO, Final IO, Async] r => Text -> Int -> Int -> Token -> InChan CalamityEvent -> Sem r (InChan ControlMessage, Async (Maybe ()))
+ Calamity.Gateway.Shard: newShard :: Members '[LogEff, MetricEff, Embed IO, Final IO, Async] r => Text -> Int -> Int -> Token -> Maybe StatusUpdateData -> Maybe Intents -> InChan CalamityEvent -> Sem r (InChan ControlMessage, Async (Maybe ()))
- Calamity.Gateway.Types: IdentifyData :: Text -> IdentifyProps -> Bool -> Int -> (Int, Int) -> Maybe StatusUpdateData -> IdentifyData
+ Calamity.Gateway.Types: IdentifyData :: Text -> IdentifyProps -> Bool -> Int -> (Int, Int) -> Maybe StatusUpdateData -> Maybe Intents -> IdentifyData
- Calamity.Gateway.Types: Shard :: Int -> Int -> Text -> InChan CalamityEvent -> OutChan ControlMessage -> IORef ShardState -> Text -> Shard
+ Calamity.Gateway.Types: Shard :: Int -> Int -> Text -> InChan CalamityEvent -> OutChan ControlMessage -> IORef ShardState -> Text -> Maybe StatusUpdateData -> Maybe Intents -> Shard
- Calamity.HTTP.Channel: CreateMessageOptions :: Maybe Text -> Maybe Text -> Maybe Bool -> Maybe ByteString -> Maybe Embed -> CreateMessageOptions
+ Calamity.HTTP.Channel: CreateMessageOptions :: Maybe Text -> Maybe Text -> Maybe Bool -> Maybe ByteString -> Maybe Embed -> Maybe AllowedMentions -> CreateMessageOptions
- Calamity.HTTP.Guild: ModifyGuildRoleData :: Maybe Text -> Maybe Integer -> Maybe Integer -> Maybe Bool -> Maybe Bool -> ModifyGuildRoleData
+ Calamity.HTTP.Guild: ModifyGuildRoleData :: Maybe Text -> Maybe Permissions -> Maybe (Colour Double) -> Maybe Bool -> Maybe Bool -> ModifyGuildRoleData
- Calamity.HTTP.Guild: [$sel:color:ModifyGuildRoleData] :: ModifyGuildRoleData -> Maybe Integer
+ Calamity.HTTP.Guild: [$sel:color:ModifyGuildRoleData] :: ModifyGuildRoleData -> Maybe (Colour Double)
- Calamity.HTTP.Guild: [$sel:permissions:ModifyGuildRoleData] :: ModifyGuildRoleData -> Maybe Integer
+ Calamity.HTTP.Guild: [$sel:permissions:ModifyGuildRoleData] :: ModifyGuildRoleData -> Maybe Permissions
- Calamity.Internal.LocalWriter: llisten :: forall o_aC32 r_aCfd a_XC32. MemberWithError (LocalWriter o_aC32) r_aCfd => Sem r_aCfd a_XC32 -> Sem r_aCfd (o_aC32, a_XC32)
+ Calamity.Internal.LocalWriter: llisten :: forall o_aF4l r_aF5Z a_XF4l. MemberWithError (LocalWriter o_aF4l) r_aF5Z => Sem r_aF5Z a_XF4l -> Sem r_aF5Z (o_aF4l, a_XF4l)
- Calamity.Internal.LocalWriter: ltell :: forall o_aC2Y r_aCfb. MemberWithError (LocalWriter o_aC2Y) r_aCfb => o_aC2Y -> Sem r_aCfb ()
+ Calamity.Internal.LocalWriter: ltell :: forall o_aF4h r_aF5X. MemberWithError (LocalWriter o_aF4h) r_aF5X => o_aF4h -> Sem r_aF5X ()
- Calamity.Internal.RunIntoIO: intoIO :: forall p_aDF5 r_aDF7 r_aDKh. MemberWithError (IntoIO p_aDF5 r_aDF7) r_aDKh => (p_aDF5 -> Sem r_aDKh r_aDF7) -> Sem r_aDKh (p_aDF5 -> IO (Maybe r_aDF7))
+ Calamity.Internal.RunIntoIO: intoIO :: forall p_aG97 r_aG99 r_aGee. MemberWithError (IntoIO p_aG97 r_aG99) r_aGee => (p_aG97 -> Sem r_aGee r_aG99) -> Sem r_aGee (p_aG97 -> IO (Maybe r_aG99))
- Calamity.Metrics.Eff: addCounter :: forall r_aGh6. MemberWithError MetricEff r_aGh6 => Int -> Counter -> Sem r_aGh6 Int
+ Calamity.Metrics.Eff: addCounter :: forall r_aIVp. MemberWithError MetricEff r_aIVp => Int -> Counter -> Sem r_aIVp Int
- Calamity.Metrics.Eff: modifyGauge :: forall r_aGh9. MemberWithError MetricEff r_aGh9 => (Double -> Double) -> Gauge -> Sem r_aGh9 Double
+ Calamity.Metrics.Eff: modifyGauge :: forall r_aIVs. MemberWithError MetricEff r_aIVs => (Double -> Double) -> Gauge -> Sem r_aIVs Double
- Calamity.Metrics.Eff: observeHistogram :: forall r_aGhc. MemberWithError MetricEff r_aGhc => Double -> Histogram -> Sem r_aGhc HistogramSample
+ Calamity.Metrics.Eff: observeHistogram :: forall r_aIVv. MemberWithError MetricEff r_aIVv => Double -> Histogram -> Sem r_aIVv HistogramSample
- Calamity.Metrics.Eff: registerCounter :: forall r_aGgW. MemberWithError MetricEff r_aGgW => Text -> [(Text, Text)] -> Sem r_aGgW Counter
+ Calamity.Metrics.Eff: registerCounter :: forall r_aIVf. MemberWithError MetricEff r_aIVf => Text -> [(Text, Text)] -> Sem r_aIVf Counter
- Calamity.Metrics.Eff: registerGauge :: forall r_aGgZ. MemberWithError MetricEff r_aGgZ => Text -> [(Text, Text)] -> Sem r_aGgZ Gauge
+ Calamity.Metrics.Eff: registerGauge :: forall r_aIVi. MemberWithError MetricEff r_aIVi => Text -> [(Text, Text)] -> Sem r_aIVi Gauge
- Calamity.Metrics.Eff: registerHistogram :: forall r_aGh2. MemberWithError MetricEff r_aGh2 => Text -> [(Text, Text)] -> [Double] -> Sem r_aGh2 Histogram
+ Calamity.Metrics.Eff: registerHistogram :: forall r_aIVl. MemberWithError MetricEff r_aIVl => Text -> [(Text, Text)] -> [Double] -> Sem r_aIVl Histogram
- Calamity.Types.Model.Channel.Embed: Embed :: Maybe Text -> Maybe Text -> Maybe Text -> Maybe Text -> Maybe UTCTime -> Maybe Word64 -> Maybe EmbedFooter -> Maybe EmbedImage -> Maybe EmbedThumbnail -> Maybe EmbedVideo -> Maybe EmbedProvider -> Maybe EmbedAuthor -> [EmbedField] -> Embed
+ Calamity.Types.Model.Channel.Embed: Embed :: Maybe Text -> Maybe Text -> Maybe Text -> Maybe Text -> Maybe UTCTime -> Maybe (Colour Double) -> Maybe EmbedFooter -> Maybe EmbedImage -> Maybe EmbedThumbnail -> Maybe EmbedVideo -> Maybe EmbedProvider -> Maybe EmbedAuthor -> [EmbedField] -> Embed
- Calamity.Types.Model.Channel.Embed: [$sel:color:Embed] :: Embed -> Maybe Word64
+ Calamity.Types.Model.Channel.Embed: [$sel:color:Embed] :: Embed -> Maybe (Colour Double)
- Calamity.Types.Model.Channel.Guild.Category: Category :: Snowflake Category -> [Overwrite] -> Text -> Bool -> Int -> Snowflake Guild -> Category
+ Calamity.Types.Model.Channel.Guild.Category: Category :: Snowflake Category -> SnowflakeMap Overwrite -> Text -> Bool -> Int -> Snowflake Guild -> Category
- Calamity.Types.Model.Channel.Guild.Category: [$sel:permissionOverwrites:Category] :: Category -> [Overwrite]
+ Calamity.Types.Model.Channel.Guild.Category: [$sel:permissionOverwrites:Category] :: Category -> SnowflakeMap Overwrite
- Calamity.Types.Model.Channel.Guild.Text: TextChannel :: Snowflake TextChannel -> Snowflake Guild -> Int -> [Overwrite] -> Text -> Maybe Text -> Bool -> Maybe (Snowflake Message) -> Maybe UTCTime -> Maybe Int -> Maybe (Snowflake Category) -> TextChannel
+ Calamity.Types.Model.Channel.Guild.Text: TextChannel :: Snowflake TextChannel -> Snowflake Guild -> Int -> SnowflakeMap Overwrite -> Text -> Maybe Text -> Bool -> Maybe (Snowflake Message) -> Maybe UTCTime -> Maybe Int -> Maybe (Snowflake Category) -> TextChannel
- Calamity.Types.Model.Channel.Guild.Text: [$sel:permissionOverwrites:TextChannel] :: TextChannel -> [Overwrite]
+ Calamity.Types.Model.Channel.Guild.Text: [$sel:permissionOverwrites:TextChannel] :: TextChannel -> SnowflakeMap Overwrite
- Calamity.Types.Model.Channel.Guild.Voice: VoiceChannel :: Snowflake VoiceChannel -> Snowflake Guild -> Int -> [Overwrite] -> Text -> Int -> Int -> Maybe (Snowflake Category) -> VoiceChannel
+ Calamity.Types.Model.Channel.Guild.Voice: VoiceChannel :: Snowflake VoiceChannel -> Snowflake Guild -> Int -> SnowflakeMap Overwrite -> Text -> Int -> Int -> Maybe (Snowflake Category) -> VoiceChannel
- Calamity.Types.Model.Channel.Guild.Voice: [$sel:permissionOverwrites:VoiceChannel] :: VoiceChannel -> [Overwrite]
+ Calamity.Types.Model.Channel.Guild.Voice: [$sel:permissionOverwrites:VoiceChannel] :: VoiceChannel -> SnowflakeMap Overwrite
- Calamity.Types.Model.Guild.Overwrite: Overwrite :: Snowflake Overwrite -> Text -> Word64 -> Word64 -> Overwrite
+ Calamity.Types.Model.Guild.Overwrite: Overwrite :: Snowflake Overwrite -> Text -> Permissions -> Permissions -> Overwrite
- Calamity.Types.Model.Guild.Overwrite: [$sel:allow:Overwrite] :: Overwrite -> Word64
+ Calamity.Types.Model.Guild.Overwrite: [$sel:allow:Overwrite] :: Overwrite -> Permissions
- Calamity.Types.Model.Guild.Overwrite: [$sel:deny:Overwrite] :: Overwrite -> Word64
+ Calamity.Types.Model.Guild.Overwrite: [$sel:deny:Overwrite] :: Overwrite -> Permissions
- Calamity.Types.Model.Guild.Role: Role :: Snowflake Role -> Text -> Word64 -> Bool -> Int -> Word64 -> Bool -> Bool -> Role
+ Calamity.Types.Model.Guild.Role: Role :: Snowflake Role -> Text -> Colour Double -> Bool -> Int -> Permissions -> Bool -> Bool -> Role
- Calamity.Types.Model.Guild.Role: [$sel:color:Role] :: Role -> Word64
+ Calamity.Types.Model.Guild.Role: [$sel:color:Role] :: Role -> Colour Double
- Calamity.Types.Model.Guild.Role: [$sel:permissions:Role] :: Role -> Word64
+ Calamity.Types.Model.Guild.Role: [$sel:permissions:Role] :: Role -> Permissions
Files
- ChangeLog.md +15/−0
- calamity.cabal +11/−3
- src/Calamity.hs +5/−1
- src/Calamity/Client/Client.hs +30/−4
- src/Calamity/Client/ShardManager.hs +3/−3
- src/Calamity/Client/Types.hs +5/−1
- src/Calamity/Commands/Parser.hs +36/−2
- src/Calamity/Gateway.hs +2/−0
- src/Calamity/Gateway/DispatchEvents.hs +28/−0
- src/Calamity/Gateway/Intents.hs +46/−0
- src/Calamity/Gateway/Shard.hs +7/−3
- src/Calamity/Gateway/Types.hs +18/−10
- src/Calamity/HTTP/Channel.hs +26/−5
- src/Calamity/HTTP/Guild.hs +5/−2
- src/Calamity/Internal/IntColour.hs +29/−0
- src/Calamity/Internal/Utils.hs +4/−0
- src/Calamity/Types/Model/Channel/Embed.hs +4/−3
- src/Calamity/Types/Model/Channel/Guild.hs +36/−0
- src/Calamity/Types/Model/Channel/Guild/Category.hs +2/−1
- src/Calamity/Types/Model/Channel/Guild/Text.hs +2/−1
- src/Calamity/Types/Model/Channel/Guild/Voice.hs +2/−1
- src/Calamity/Types/Model/Guild.hs +3/−1
- src/Calamity/Types/Model/Guild/Guild.hs +0/−2
- src/Calamity/Types/Model/Guild/Overwrite.hs +5/−5
- src/Calamity/Types/Model/Guild/Permissions.hs +83/−0
- src/Calamity/Types/Model/Guild/Role.hs +8/−5
- src/Calamity/Utils.hs +7/−0
- src/Calamity/Utils/Colour.hs +18/−0
- src/Calamity/Utils/Permissions.hs +88/−0
ChangeLog.md view
@@ -1,6 +1,21 @@ # Changelog for Calamity +## 0.1.10.1++*2020-05-31*++* Add command parameter parsers for channel/guild/emoji+* Support allowed mentions+* Support invite events+* Support setting gateway intents+* Add `Calamity.Types.Model.Guild.Permission` and `Calamity.Utils.Permissions`+ and change permissions fields from `Word64` to `Permissions`+* Add `Calamity.Utils.Colour` and change color fields from `Word64` to+ `Data.Color.Color Double`+ ## 0.1.10.0++*2020-05-27* * Renamed `Calamity.Commands.Parser.KleeneConcat` to `Calamity.Commands.Parser.KleeneStarConcat` and added
calamity.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 386f342de92acd940a2fa9856b8efa38f04e137426a3c6100bcbeaadb5ac5e17+-- hash: f39d1fc0a8ea4e5b188911539c4b0bfdbc8887c9a631ff56d56547749cdc3cf8 name: calamity-version: 0.1.10+version: 0.1.10.1 synopsis: A library for writing discord bots description: Please see the README on GitHub at <https://github.com/nitros12/calamity#readme> category: Network, Web@@ -55,6 +55,7 @@ Calamity.Commands.Utils Calamity.Gateway Calamity.Gateway.DispatchEvents+ Calamity.Gateway.Intents Calamity.Gateway.Shard Calamity.Gateway.Types Calamity.HTTP@@ -75,6 +76,7 @@ Calamity.Internal.BoundedStore Calamity.Internal.ConstructorName Calamity.Internal.GenericCurry+ Calamity.Internal.IntColour Calamity.Internal.LocalWriter Calamity.Internal.RunIntoIO Calamity.Internal.SnowflakeMap@@ -107,6 +109,7 @@ Calamity.Types.Model.Guild.Invite Calamity.Types.Model.Guild.Member Calamity.Types.Model.Guild.Overwrite+ Calamity.Types.Model.Guild.Permissions Calamity.Types.Model.Guild.Role Calamity.Types.Model.Guild.UnavailableGuild Calamity.Types.Model.Presence@@ -122,6 +125,9 @@ Calamity.Types.Token Calamity.Types.UnixTimestamp Calamity.Types.Upgradeable+ Calamity.Utils+ Calamity.Utils.Colour+ Calamity.Utils.Permissions other-modules: Paths_calamity hs-source-dirs:@@ -133,12 +139,14 @@ , async >=2.2 && <3 , base >=4.12 && <5 , bytestring >=0.10 && <0.11+ , colour >=2.3.5 && <2.4 , concurrent-extra >=0.7 && <0.8 , containers >=0.6 && <0.7 , data-default-class >=0.1 && <0.2+ , data-flags >=0.0.3 && <0.1 , deepseq >=1.4.4.0 && <2 , deque >=0.4 && <0.5- , df1 >=0.3 && <0.4+ , df1 >=0.3 && <0.5 , di-polysemy >=0.1.3 && <0.2 , exceptions >=0.10 && <0.11 , fmt >=0.6 && <0.7
src/Calamity.hs view
@@ -1,8 +1,12 @@ module Calamity ( module Calamity.Client , module Calamity.HTTP- , module Calamity.Types ) where+ , module Calamity.Types+ , module Calamity.Utils+ , module Calamity.Gateway.Intents ) where import Calamity.Client+import Calamity.Gateway.Intents import Calamity.HTTP import Calamity.Types+import Calamity.Utils
src/Calamity/Client/Client.hs view
@@ -4,6 +4,7 @@ module Calamity.Client.Client ( react , runBotIO+ , runBotIO' , stopBot , sendPresence , events@@ -18,6 +19,7 @@ import Calamity.Client.Types import Calamity.Gateway.DispatchEvents import Calamity.Gateway.Types+import Calamity.Gateway.Intents import Calamity.HTTP.Internal.Ratelimit import Calamity.Internal.ConstructorName import Calamity.Internal.GenericCurry@@ -89,15 +91,31 @@ ehidCounter -- | Create a bot, run your setup action, and then loop until the bot closes.-runBotIO :: forall r a. (P.Members '[P.Embed IO, P.Final IO, CacheEff, MetricEff] r, Typeable (SetupEff r)) => Token -> P.Sem (SetupEff r) a -> P.Sem r (Maybe StartupError)-runBotIO token setup = do+runBotIO :: forall r a.+ (P.Members '[P.Embed IO, P.Final IO, CacheEff, MetricEff] r, Typeable (SetupEff r))+ => Token+ -> P.Sem (SetupEff r) a+ -> P.Sem r (Maybe StartupError)+runBotIO token setup = runBotIO' token Nothing Nothing setup++-- | Create a bot, run your setup action, and then loop until the bot closes.+--+-- This version allows you to specify the initial status and intents.+runBotIO' :: forall r a.+ (P.Members '[P.Embed IO, P.Final IO, CacheEff, MetricEff] r, Typeable (SetupEff r))+ => Token+ -> Maybe StatusUpdateData+ -> Maybe Intents+ -> P.Sem (SetupEff r) a+ -> P.Sem r (Maybe StartupError)+runBotIO' token status intents setup = do client <- P.embed $ newClient token handlers <- P.embed $ newTVarIO def P.asyncToIOFinal . P.runAtomicStateTVar handlers . P.runReader client . Di.runDiToStderrIO . Di.push "calamity" $ do void $ Di.push "calamity-setup" setup- r <- shardBot+ r <- shardBot status intents case r of- Left e -> pure (Just e)+ Left e -> pure (Just e) Right _ -> do Di.push "calamity-loop" clientLoop Di.push "calamity-stop" finishUp@@ -475,6 +493,12 @@ updateCache evt pure $ map (\f -> f guild role) (getEventHandlers @'GuildRoleDeleteEvt eh) +handleEvent' eh (InviteCreate d) = do+ pure $ map (\f -> f d) (getEventHandlers @'InviteCreateEvt eh)++handleEvent' eh (InviteDelete d) = do+ pure $ map (\f -> f d) (getEventHandlers @'InviteDeleteEvt eh)+ handleEvent' eh evt@(MessageCreate msg) = do updateCache evt pure $ map ($ msg) (getEventHandlers @'MessageCreateEvt eh)@@ -640,6 +664,8 @@ updateCache (TypingStart _) = pure () updateCache (ChannelPinsUpdate _) = pure () updateCache (WebhooksUpdate _) = pure ()+updateCache (InviteCreate _) = pure ()+updateCache (InviteDelete _) = pure () -- we don't handle voice state currently updateCache (VoiceStateUpdate _) = pure ()
src/Calamity/Client/ShardManager.hs view
@@ -26,8 +26,8 @@ mapLeft _ (Right b) = Right b -- | Connects the bot to the gateway over n shards-shardBot :: BotC r => Sem r (Either StartupError ())-shardBot = (mapLeft StartupError <$>) . P.runFail $ do+shardBot :: BotC r => Maybe StatusUpdateData -> Maybe Intents -> Sem r (Either StartupError ())+shardBot initialStatus intents = (mapLeft StartupError <$>) . P.runFail $ do numShardsVar <- P.asks numShards shardsVar <- P.asks shards @@ -46,7 +46,7 @@ info $ "Number of shards: " +| numShards' |+ "" shards <- for [0 .. numShards' - 1] $ \id ->- newShard host id numShards' token inc+ newShard host id numShards' token initialStatus intents inc P.embed . atomically $ writeTVar shardsVar shards
src/Calamity/Client/Types.hs view
@@ -16,7 +16,7 @@ , getCustomEventHandlers ) where import Calamity.Cache.Eff-import Calamity.Gateway.DispatchEvents ( CalamityEvent(..), ReadyData )+import Calamity.Gateway.DispatchEvents ( CalamityEvent(..), InviteCreateData, InviteDeleteData, ReadyData ) import Calamity.Gateway.Types ( ControlMessage ) import Calamity.HTTP.Internal.Types import Calamity.Internal.GenericCurry@@ -135,6 +135,8 @@ | GuildRoleCreateEvt | GuildRoleUpdateEvt | GuildRoleDeleteEvt+ | InviteCreateEvt+ | InviteDeleteEvt | MessageCreateEvt | MessageUpdateEvt | MessageDeleteEvt@@ -169,6 +171,8 @@ EHType 'GuildRoleCreateEvt m r = Guild -> Role -> m r EHType 'GuildRoleUpdateEvt m r = Guild -> Role -> Role -> m r EHType 'GuildRoleDeleteEvt m r = Guild -> Role -> m r+ EHType 'InviteCreateEvt m r = InviteCreateData -> m r+ EHType 'InviteDeleteEvt m r = InviteDeleteData -> m r EHType 'MessageCreateEvt m r = Message -> m r EHType 'MessageUpdateEvt m r = Message -> Message -> m r EHType 'MessageDeleteEvt m r = Message -> m r
src/Calamity/Commands/Parser.hs view
@@ -8,8 +8,8 @@ import Calamity.Cache.Eff import Calamity.Commands.Context-import Calamity.Types.Model.Channel ( Channel )-import Calamity.Types.Model.Guild ( Emoji, Member, Role )+import Calamity.Types.Model.Channel ( Channel, GuildChannel )+import Calamity.Types.Model.Guild ( Emoji, Guild, Member, Role ) import Calamity.Types.Model.User ( User ) import Calamity.Types.Snowflake @@ -198,6 +198,9 @@ Just r' -> pure r' _ -> parseError . errFancy offs . fancy . ErrorCustom $ SpannedError e offs offe +-- | Parser for members in the guild the command was invoked in, this only looks+-- in the cache. Use @'Snowflake' 'Member'@ and use+-- 'Calamity.Types.Upgradeable.upgrade' if you want to allow fetching from http. instance Parser Member r where parse = parseMP (parserName @Member) $ mapParserMaybeM (try (ping "@") <|> snowflake) "Couldn't find a Member with this id"@@ -205,10 +208,41 @@ ctx <- P.ask pure $ ctx ^? #guild . _Just . #members . ix mid) +-- | Parser for users, this only looks in the cache. Use @'Snowflake'+-- 'User'@ and use 'Calamity.Types.Upgradeable.upgrade' if you want to allow+-- fetching from http. instance P.Member CacheEff r => Parser User r where parse = parseMP (parserName @User @r) $ mapParserMaybeM (try (ping "@") <|> snowflake) "Couldn't find a User with this id" getUser++-- | Parser for channels in the guild the command was invoked in, this only+-- looks in the cache. Use @'Snowflake' 'Channel'@ and use+-- 'Calamity.Types.Upgradeable.upgrade' if you want to allow fetching from http.+instance Parser GuildChannel r where+ parse = parseMP (parserName @GuildChannel @r) $ mapParserMaybeM (try (ping "#") <|> snowflake)+ "Couldn't find a GuildChannel with this id"+ (\cid -> do+ ctx <- P.ask+ pure $ ctx ^? #guild . _Just . #channels . ix cid)++-- | Parser for guilds, this only looks in the cache. Use @'Snowflake' 'Guild'@+-- and use 'Calamity.Types.Upgradeable.upgrade' if you want to allow fetching+-- from http.+instance P.Member CacheEff r => Parser Guild r where+ parse = parseMP (parserName @Guild @r) $ mapParserMaybeM (try (ping "#") <|> snowflake)+ "Couldn't find a Guild with this id"+ getGuild++-- | Parser for emojis in the guild the command was invoked in, this only+-- looks in the cache. Use @'Snowflake' 'Emoji'@ and use+-- 'Calamity.Types.Upgradeable.upgrade' if you want to allow fetching from http.+instance Parser Emoji r where+ parse = parseMP (parserName @Emoji @r) $ mapParserMaybeM (try (ping "#") <|> snowflake)+ "Couldn't find an Emoji with this id"+ (\eid -> do+ ctx <- P.ask+ pure $ ctx ^? #guild . _Just . #emojis . ix eid) instance (Parser a r, Parser b r) => Parser (a, b) r where type ParserResult (a, b) = (ParserResult a, ParserResult b)
src/Calamity/Gateway.hs view
@@ -2,12 +2,14 @@ module Calamity.Gateway ( module Calamity.Gateway.Shard , module Calamity.Gateway.Types+ , module Calamity.Gateway.Intents -- * Gateway -- $gatewayDocs ) where import Calamity.Gateway.Shard import Calamity.Gateway.Types+import Calamity.Gateway.Intents -- $gatewayDocs --
src/Calamity/Gateway/DispatchEvents.hs view
@@ -57,6 +57,8 @@ | GuildRoleCreate GuildRoleData | GuildRoleUpdate GuildRoleData | GuildRoleDelete GuildRoleDeleteData+ | InviteCreate InviteCreateData+ | InviteDelete InviteDeleteData | MessageCreate Message | MessageUpdate UpdatedMessage | MessageDelete MessageDeleteData@@ -146,6 +148,32 @@ } deriving ( Show, Generic ) deriving FromJSON via CalamityJSON GuildRoleDeleteData++data InviteCreateData = InviteCreateData+ { channelID :: Snowflake Channel+ , code :: Text+ , createdAt :: UnixTimestamp+ , guildID :: Maybe (Snowflake Guild)+ , inviter :: Maybe (Snowflake User)+ , maxAge :: Int+ , maxUses :: Int+ , targetUser :: Maybe (Snowflake User)+ , targetUserType :: Maybe Integer+ , temporary :: Bool+ , uses :: Integer+ }+ deriving ( Show, Generic )+ deriving ( FromJSON ) via WithSpecialCases+ '["inviter" `ExtractField` "id", "targetUser" `ExtractField` "id"]+ InviteCreateData++data InviteDeleteData = InviteDeleteData+ { channelID :: Snowflake Channel+ , guildID :: Maybe (Snowflake Guild)+ , code :: Text+ }+ deriving ( Show, Generic )+ deriving ( FromJSON ) via CalamityJSON InviteDeleteData data MessageDeleteData = MessageDeleteData { id :: Snowflake Message
+ src/Calamity/Gateway/Intents.hs view
@@ -0,0 +1,46 @@+{-# LANGUAGE NoDeriveAnyClass #-}+{-# LANGUAGE TemplateHaskell #-}++-- | Discord gateway intents+module Calamity.Gateway.Intents+ ( Intents(..)+ , intentGuilds+ , intentGuildMembers+ , intentGuildBans+ , intentGuildEmojis+ , intentGuildIntegrations+ , intentGuildWebhooks+ , intentGuildInvites+ , intentGuildVoiceStates+ , intentGuildPresences+ , intentGuildMessages+ , intentGuildMessageReactions+ , intentGuildMessageTyping+ , intentDirectMessages+ , intentDirectMessageReactions+ , intentDirectMessageTyping ) where++import Data.Aeson ( ToJSON )+import Data.Bits+import Data.Flags ()+import Data.Flags.TH+import Data.Word++$(bitmaskWrapper "Intents" ''Word32 []+ [ ("intentGuilds", 1 `shiftL` 0)+ , ("intentGuildMembers", 1 `shiftL` 1)+ , ("intentGuildBans", 1 `shiftL` 2)+ , ("intentGuildEmojis", 1 `shiftL` 3)+ , ("intentGuildIntegrations", 1 `shiftL` 4)+ , ("intentGuildWebhooks", 1 `shiftL` 5)+ , ("intentGuildInvites", 1 `shiftL` 6)+ , ("intentGuildVoiceStates", 1 `shiftL` 7)+ , ("intentGuildPresences", 1 `shiftL` 8)+ , ("intentGuildMessages", 1 `shiftL` 9)+ , ("intentGuildMessageReactions", 1 `shiftL` 10)+ , ("intentGuildMessageTyping", 1 `shiftL` 11)+ , ("intentDirectMessages", 1 `shiftL` 12)+ , ("intentDirectMessageReactions", 1 `shiftL` 13)+ , ("intentDirectMessageTyping", 1 `shiftL` 14)])++deriving via Word32 instance ToJSON Intents
src/Calamity/Gateway/Shard.hs view
@@ -7,6 +7,7 @@ , newShard ) where import Calamity.Gateway.DispatchEvents+import Calamity.Gateway.Intents import Calamity.Gateway.Types import Calamity.Internal.Utils import Calamity.Metrics.Eff@@ -81,13 +82,15 @@ -> Int -> Int -> Token+ -> Maybe StatusUpdateData+ -> Maybe Intents -> UC.InChan CalamityEvent -> Sem r (UC.InChan ControlMessage, Async (Maybe ()))-newShard gateway id count token evtIn = do+newShard gateway id count token presence intents evtIn = do (cmdIn, stateVar) <- P.embed $ mdo (cmdIn, cmdOut) <- UC.newChan stateVar <- newIORef $ newShardState shard- let shard = Shard id count gateway evtIn cmdOut stateVar (rawToken token)+ let shard = Shard id count gateway evtIn cmdOut stateVar (rawToken token) presence intents pure (cmdIn, stateVar) let runShard = P.runAtomicStateIORef stateVar shardLoop@@ -218,7 +221,8 @@ , largeThreshold = 250 , shard = (shard ^. #shardID, shard ^. #shardCount)- , presence = Nothing+ , presence = shard ^. #initialStatus+ , intents = shard ^. #intents }) result <- P.resourceToIOFinal $ P.bracket (P.embed $ newTBMQueueIO 1)
src/Calamity/Gateway/Types.hs view
@@ -16,6 +16,7 @@ , ShardState(..) ) where import Calamity.Gateway.DispatchEvents+import Calamity.Gateway.Intents import Calamity.Internal.AesonThings import Calamity.Metrics.Eff import Calamity.Types.LogEff@@ -103,6 +104,8 @@ parseDispatchData GUILD_ROLE_CREATE data' = GuildRoleCreate <$> parseJSON data' parseDispatchData GUILD_ROLE_UPDATE data' = GuildRoleUpdate <$> parseJSON data' parseDispatchData GUILD_ROLE_DELETE data' = GuildRoleDelete <$> parseJSON data'+parseDispatchData INVITE_CREATE data' = InviteCreate <$> parseJSON data'+parseDispatchData INVITE_DELETE data' = InviteDelete <$> parseJSON data' parseDispatchData MESSAGE_CREATE data' = MessageCreate <$> parseJSON data' parseDispatchData MESSAGE_UPDATE data' = MessageUpdate <$> parseJSON data' parseDispatchData MESSAGE_DELETE data' = MessageDelete <$> parseJSON data'@@ -174,6 +177,8 @@ | GUILD_ROLE_CREATE | GUILD_ROLE_UPDATE | GUILD_ROLE_DELETE+ | INVITE_CREATE+ | INVITE_DELETE | MESSAGE_CREATE | MESSAGE_UPDATE | MESSAGE_DELETE@@ -197,6 +202,7 @@ , largeThreshold :: Int , shard :: (Int, Int) , presence :: Maybe StatusUpdateData+ , intents :: Maybe Intents } deriving ( Show, Generic ) deriving ToJSON via CalamityJSON IdentifyData@@ -226,8 +232,8 @@ deriving ( Show, Generic ) instance ToJSON RequestGuildMembersData where- toEncoding RequestGuildMembersData { guildID, query, limit } = pairs- ("guild_id" .= guildID <> "query" .= fromMaybe "" query <> "limit" .= fromMaybe 0 limit)+ toJSON RequestGuildMembersData { guildID, query, limit } =+ object ["guild_id" .= guildID, "query" .= fromMaybe "" query, "limit" .= fromMaybe 0 limit] data IdentifyProps = IdentifyProps { browser :: Text@@ -236,7 +242,7 @@ deriving ( Show, Generic ) instance ToJSON IdentifyProps where- toEncoding IdentifyProps { browser, device } = pairs ("$browser" .= browser <> "$device" .= device)+ toJSON IdentifyProps { browser, device } = object ["$browser" .= browser, "$device" .= device] data ControlMessage = RestartShard@@ -250,13 +256,15 @@ deriving ( Show ) data Shard = Shard- { shardID :: Int- , shardCount :: Int- , gateway :: Text- , evtIn :: InChan CalamityEvent- , cmdOut :: OutChan ControlMessage- , shardState :: IORef ShardState- , token :: Text+ { shardID :: Int+ , shardCount :: Int+ , gateway :: Text+ , evtIn :: InChan CalamityEvent+ , cmdOut :: OutChan ControlMessage+ , shardState :: IORef ShardState+ , token :: Text+ , initialStatus :: Maybe StatusUpdateData+ , intents :: Maybe Intents } deriving ( Generic )
src/Calamity/HTTP/Channel.hs view
@@ -33,13 +33,34 @@ import TextShow data CreateMessageOptions = CreateMessageOptions- { content :: Maybe Text- , nonce :: Maybe Text- , tts :: Maybe Bool- , file :: Maybe ByteString- , embed :: Maybe Embed+ { content :: Maybe Text+ , nonce :: Maybe Text+ , tts :: Maybe Bool+ , file :: Maybe ByteString+ , embed :: Maybe Embed+ , allowedMentions :: Maybe AllowedMentions } deriving ( Show, Generic, Default )++data AllowedMentionType+ = AllowedMentionRoles+ | AllowedMentionUsers+ | AllowedMentionEveryone+ deriving ( Show, Generic )++instance ToJSON AllowedMentionType where+ toJSON AllowedMentionRoles = String "roles"+ toJSON AllowedMentionUsers = String "users"+ toJSON AllowedMentionEveryone = String "everyone"++data AllowedMentions = AllowedMentions+ { parse :: [AllowedMentionType]+ , roles :: [Snowflake Role]+ , users :: [Snowflake User]+ }+ deriving ( Show, Generic, Default )+ deriving ( ToJSON ) via CalamityJSON AllowedMentions+ data CreateMessageJson = CreateMessageJson { content :: Maybe Text
src/Calamity/HTTP/Guild.hs view
@@ -15,6 +15,8 @@ import Calamity.HTTP.Internal.Request import Calamity.HTTP.Internal.Route import Calamity.Internal.AesonThings+import Calamity.Internal.IntColour ()+import Calamity.Internal.Utils () import Calamity.Types.Model.Channel import Calamity.Types.Model.Guild import Calamity.Types.Model.User@@ -25,6 +27,7 @@ import Control.Lens hiding ( (.=) ) import Data.Aeson+import Data.Colour ( Colour ) import Data.Default.Class import Data.Maybe import Data.Text ( Text )@@ -121,8 +124,8 @@ data ModifyGuildRoleData = ModifyGuildRoleData { name :: Maybe Text- , permissions :: Maybe Integer- , color :: Maybe Integer+ , permissions :: Maybe Permissions+ , color :: Maybe (Colour Double) , hoist :: Maybe Bool , mentionable :: Maybe Bool }
+ src/Calamity/Internal/IntColour.hs view
@@ -0,0 +1,29 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}++-- | An orphan instnace to parse @'Data.Colour' 'Double'@ as a word64+module Calamity.Internal.IntColour+ ( colourToWord64+ , colourFromWord64 ) where++import Data.Aeson+import Data.Bits+import Data.Colour+import Data.Colour.SRGB ( RGB(RGB), sRGB24, toSRGB24 )+import Data.Word ( Word64 )++colourToWord64 :: Colour Double -> Word64+colourToWord64 c = let RGB r g b = toSRGB24 c+ i = (fromIntegral r `shiftL` 16) .|. (fromIntegral g `shiftL` 8) .|. fromIntegral b+ in i++colourFromWord64 :: Word64 -> Colour Double+colourFromWord64 i = let r = (i `shiftR` 16) .&. 0xff+ g = (i `shiftR` 8) .&. 0xff+ b = i .&. 0xff+ in sRGB24 (fromIntegral r) (fromIntegral g) (fromIntegral b)++instance ToJSON (Colour Double) where+ toJSON = toJSON . colourToWord64++instance FromJSON (Colour Double) where+ parseJSON v = colourFromWord64 <$> parseJSON v
src/Calamity/Internal/Utils.hs view
@@ -35,6 +35,7 @@ import qualified Polysemy as P import TextShow+import Data.Colour (Colour) whenJust :: Applicative m => Maybe a -> (a -> m ()) -> m () whenJust = flip $ maybe (pure ())@@ -99,6 +100,9 @@ showb = fromString . show instance (Show k, Show v) => TextShow (M.Map k v) where+ showb = fromString . show++instance (Show a, Fractional a) => TextShow (Colour a) where showb = fromString . show instance Default (M.Map k v) where
src/Calamity/Types/Model/Channel/Embed.hs view
@@ -10,11 +10,13 @@ , EmbedField(..) ) where import Calamity.Internal.AesonThings+import Calamity.Internal.IntColour () import Calamity.Internal.Utils () import Control.Lens import Data.Aeson+import Data.Colour ( Colour ) import Data.Default.Class import Data.Generics.Labels () import Data.Semigroup@@ -33,7 +35,7 @@ , description :: Maybe Text , url :: Maybe Text , timestamp :: Maybe UTCTime- , color :: Maybe Word64+ , color :: Maybe (Colour Double) , footer :: Maybe EmbedFooter , image :: Maybe EmbedImage , thumbnail :: Maybe EmbedThumbnail@@ -44,8 +46,7 @@ } deriving ( Eq, Show, Generic, Default ) deriving ( TextShow ) via TSG.FromGeneric Embed- deriving ( FromJSON ) via WithSpecialCases '[IfNoneThen "fields" DefaultToEmptyArray]- Embed+ deriving ( FromJSON ) via WithSpecialCases '[IfNoneThen "fields" DefaultToEmptyArray] Embed deriving ( ToJSON ) via CalamityJSON Embed instance Semigroup Embed where
src/Calamity/Types/Model/Channel/Guild.hs view
@@ -5,18 +5,21 @@ , module Calamity.Types.Model.Channel.Guild.Text , module Calamity.Types.Model.Channel.Guild.Voice ) where +import Calamity.Internal.SnowflakeMap ( SnowflakeMap ) import {-# SOURCE #-} Calamity.Types.Model.Channel import Calamity.Types.Model.Channel.ChannelType import Calamity.Types.Model.Channel.Guild.Category import Calamity.Types.Model.Channel.Guild.Text import Calamity.Types.Model.Channel.Guild.Voice import {-# SOURCE #-} Calamity.Types.Model.Guild.Guild+import Calamity.Types.Model.Guild.Overwrite import Calamity.Types.Snowflake import Control.Lens import Data.Aeson import Data.Generics.Product.Fields+import Data.Text.Lazy ( Text ) import GHC.Generics @@ -52,3 +55,36 @@ getID (GuildTextChannel a) = coerceSnowflake $ a ^. field' @"guildID" getID (GuildVoiceChannel a) = coerceSnowflake $ a ^. field' @"guildID" getID (GuildCategory a) = coerceSnowflake $ a ^. field' @"guildID"++instance {-# OVERLAPS #-}HasField' "name" GuildChannel Text where+ field' = lens get set+ where+ get (GuildTextChannel (TextChannel { name })) = name+ get (GuildVoiceChannel (VoiceChannel { name })) = name+ get (GuildCategory (Category { name })) = name++ set (GuildTextChannel t) v = GuildTextChannel (t { name = v })+ set (GuildVoiceChannel t) v = GuildVoiceChannel (t { name = v })+ set (GuildCategory t) v = GuildCategory (t { name = v })++instance {-# OVERLAPS #-}HasField' "permissionOverwrites" GuildChannel (SnowflakeMap Overwrite) where+ field' = lens get set+ where+ get (GuildTextChannel (TextChannel { permissionOverwrites })) = permissionOverwrites+ get (GuildVoiceChannel (VoiceChannel { permissionOverwrites })) = permissionOverwrites+ get (GuildCategory (Category { permissionOverwrites })) = permissionOverwrites++ set (GuildTextChannel t) v = GuildTextChannel (t { permissionOverwrites = v })+ set (GuildVoiceChannel t) v = GuildVoiceChannel (t { permissionOverwrites = v })+ set (GuildCategory t) v = GuildCategory (t { permissionOverwrites = v })++instance {-# OVERLAPS #-}HasField' "position" GuildChannel Int where+ field' = lens get set+ where+ get (GuildTextChannel (TextChannel { position })) = position+ get (GuildVoiceChannel (VoiceChannel { position })) = position+ get (GuildCategory (Category { position })) = position++ set (GuildTextChannel t) v = GuildTextChannel (t { position = v })+ set (GuildVoiceChannel t) v = GuildVoiceChannel (t { position = v })+ set (GuildCategory t) v = GuildCategory (t { position = v })
src/Calamity/Types/Model/Channel/Guild/Category.hs view
@@ -2,6 +2,7 @@ ( Category(..) ) where import Calamity.Internal.AesonThings+import Calamity.Internal.SnowflakeMap ( SnowflakeMap ) import Calamity.Internal.Utils () import {-# SOURCE #-} Calamity.Types.Model.Channel import {-# SOURCE #-} Calamity.Types.Model.Guild.Guild@@ -18,7 +19,7 @@ data Category = Category { id :: Snowflake Category- , permissionOverwrites :: [Overwrite]+ , permissionOverwrites :: SnowflakeMap Overwrite , name :: Text , nsfw :: Bool , position :: Int
src/Calamity/Types/Model/Channel/Guild/Text.hs view
@@ -3,6 +3,7 @@ ( TextChannel(..) ) where import Calamity.Internal.AesonThings+import Calamity.Internal.SnowflakeMap ( SnowflakeMap ) import Calamity.Internal.Utils () import {-# SOURCE #-} Calamity.Types.Model.Channel import {-# SOURCE #-} Calamity.Types.Model.Channel.Guild.Category@@ -24,7 +25,7 @@ { id :: Snowflake TextChannel , guildID :: Snowflake Guild , position :: Int- , permissionOverwrites :: [Overwrite]+ , permissionOverwrites :: SnowflakeMap Overwrite , name :: Text , topic :: Maybe Text , nsfw :: Bool
src/Calamity/Types/Model/Channel/Guild/Voice.hs view
@@ -3,6 +3,7 @@ ( VoiceChannel(..) ) where import Calamity.Internal.AesonThings+import Calamity.Internal.SnowflakeMap ( SnowflakeMap ) import Calamity.Internal.Utils () import {-# SOURCE #-} Calamity.Types.Model.Channel import {-# SOURCE #-} Calamity.Types.Model.Channel.Guild.Category@@ -22,7 +23,7 @@ { id :: Snowflake VoiceChannel , guildID :: Snowflake Guild , position :: Int- , permissionOverwrites :: [Overwrite]+ , permissionOverwrites :: SnowflakeMap Overwrite , name :: Text , bitrate :: Int , userLimit :: Int
src/Calamity/Types/Model/Guild.hs view
@@ -8,7 +8,8 @@ , module Calamity.Types.Model.Guild.Overwrite , module Calamity.Types.Model.Guild.Invite , module Calamity.Types.Model.Guild.Role- , module Calamity.Types.Model.Guild.UnavailableGuild ) where+ , module Calamity.Types.Model.Guild.UnavailableGuild+ , module Calamity.Types.Model.Guild.Permissions ) where import Calamity.Types.Model.Guild.AuditLog import Calamity.Types.Model.Guild.Ban@@ -19,3 +20,4 @@ import Calamity.Types.Model.Guild.Overwrite import Calamity.Types.Model.Guild.Role import Calamity.Types.Model.Guild.UnavailableGuild+import Calamity.Types.Model.Guild.Permissions
src/Calamity/Types/Model/Guild/Guild.hs view
@@ -74,8 +74,6 @@ parseJSON = withObject "Guild" $ \v -> do id <- v .: "id" - -- TODO: clean this up- members' <- do members' <- v .: "members" SM.fromList <$> traverse (\m -> parseJSON $ Object (m <> "guild_id" .= id)) members'
src/Calamity/Types/Model/Guild/Overwrite.hs view
@@ -3,22 +3,22 @@ ( Overwrite(..) ) where import Calamity.Internal.AesonThings+import Calamity.Types.Model.Guild.Permissions import Calamity.Types.Snowflake import Data.Aeson-import Data.Text.Lazy ( Text )-import Data.Word+import Data.Text.Lazy ( Text ) import GHC.Generics import TextShow-import qualified TextShow.Generic as TSG+import qualified TextShow.Generic as TSG data Overwrite = Overwrite { id :: Snowflake Overwrite , type_ :: Text- , allow :: Word64- , deny :: Word64+ , allow :: Permissions+ , deny :: Permissions } deriving ( Eq, Show, Generic ) deriving ( TextShow ) via TSG.FromGeneric Overwrite
+ src/Calamity/Types/Model/Guild/Permissions.hs view
@@ -0,0 +1,83 @@+{-# LANGUAGE NoDeriveAnyClass #-}+{-# LANGUAGE TemplateHaskell #-}++-- | Guild permissions+module Calamity.Types.Model.Guild.Permissions+ ( Permissions(..)+ , createInstantInvite+ , kickMembers+ , banMembers+ , administrator+ , manageChannels+ , manageGuild+ , addReactions+ , viewAuditLog+ , prioritySpeaker+ , stream+ , viewChannel+ , sendMessages+ , sendTtsMessages+ , manageMessages+ , embedLinks+ , attachFiles+ , readMessageHistory+ , mentionEveryone+ , useExternalEmojis+ , viewGuildInsights+ , connect+ , speak+ , muteMembers+ , deafenMembers+ , moveMembers+ , useVad+ , changeNickname+ , manageNicknames+ , manageRoles+ , manageWebhooks+ , manageEmojis ) where++import Data.Aeson ( FromJSON, ToJSON )+import Data.Flags ()+import Data.Flags.TH+import Data.Word++import TextShow++$(bitmaskWrapper "Permissions" ''Word64 []+ [ ("createInstantInvite", 0x00000001)+ , ("kickMembers", 0x00000002)+ , ("banMembers", 0x00000004)+ , ("administrator", 0x00000008)+ , ("manageChannels", 0x00000010)+ , ("manageGuild", 0x00000020)+ , ("addReactions", 0x00000040)+ , ("viewAuditLog", 0x00000080)+ , ("prioritySpeaker", 0x00000100)+ , ("stream", 0x00000200)+ , ("viewChannel", 0x00000400)+ , ("sendMessages", 0x00000800)+ , ("sendTtsMessages", 0x00001000)+ , ("manageMessages", 0x00002000)+ , ("embedLinks", 0x00004000)+ , ("attachFiles", 0x00008000)+ , ("readMessageHistory", 0x00010000)+ , ("mentionEveryone", 0x00020000)+ , ("useExternalEmojis", 0x00040000)+ , ("viewGuildInsights", 0x00080000)+ , ("connect", 0x00100000)+ , ("speak", 0x00200000)+ , ("muteMembers", 0x00400000)+ , ("deafenMembers", 0x00800000)+ , ("moveMembers", 0x01000000)+ , ("useVad", 0x02000000)+ , ("changeNickname", 0x04000000)+ , ("manageNicknames", 0x08000000)+ , ("manageRoles", 0x10000000)+ , ("manageWebhooks", 0x20000000)+ , ("manageEmojis", 0x4000000)])++deriving via Word64 instance ToJSON Permissions++deriving via Word64 instance FromJSON Permissions++deriving via FromStringShow Permissions instance TextShow Permissions
src/Calamity/Types/Model/Guild/Role.hs view
@@ -3,24 +3,27 @@ ( Role(..) ) where import Calamity.Internal.AesonThings+import Calamity.Internal.IntColour ()+import Calamity.Internal.Utils ()+import Calamity.Types.Model.Guild.Permissions import Calamity.Types.Snowflake import Data.Aeson-import Data.Text.Lazy ( Text )-import Data.Word+import Data.Colour+import Data.Text.Lazy ( Text ) import GHC.Generics import TextShow-import qualified TextShow.Generic as TSG+import qualified TextShow.Generic as TSG data Role = Role { id :: Snowflake Role , name :: Text- , color :: Word64+ , color :: Colour Double , hoist :: Bool , position :: Int- , permissions :: Word64+ , permissions :: Permissions , managed :: Bool , mentionable :: Bool }
+ src/Calamity/Utils.hs view
@@ -0,0 +1,7 @@+-- | Useful things+module Calamity.Utils+ ( module Calamity.Utils.Permissions+ , module Calamity.Utils.Colour ) where++import Calamity.Utils.Colour+import Calamity.Utils.Permissions
+ src/Calamity/Utils/Colour.hs view
@@ -0,0 +1,18 @@+-- | Discord colour utilities+module Calamity.Utils.Colour+ ( colourToWord64+ , colourFromWord64+ -- * Useful colours+ , blurple+ , greyple ) where++import Calamity.Internal.IntColour++import Data.Colour+import Data.Colour.SRGB ( sRGB24 )++blurple :: (Ord a, Floating a) => Colour a+blurple = sRGB24 0x72 0x89 0xda++greyple :: (Ord a, Floating a) => Colour a+greyple = sRGB24 0x99 0xaa 0xb5
+ src/Calamity/Utils/Permissions.hs view
@@ -0,0 +1,88 @@+-- | Permission utilities+module Calamity.Utils.Permissions+ ( PermissionsIn(..)+ , PermissionsIn'(..)+ , basePermissions+ , applyOverwrites ) where++import Calamity.Client.Types+import Calamity.Types.Model.Channel.Guild+import Calamity.Types.Model.Guild.Guild+import Calamity.Types.Model.Guild.Member+import Calamity.Types.Model.Guild.Overwrite+import Calamity.Types.Model.Guild.Permissions+import Calamity.Types.Snowflake+import Calamity.Types.Upgradeable++import Control.Lens++import Data.Flags+import qualified Data.Vector.Unboxed as V++import qualified Polysemy as P++basePermissions :: Guild -> Member -> Permissions+basePermissions g m+ | (g ^. #ownerID == getID m) = allFlags+ | otherwise = let everyoneRole = g ^. #roles . at (coerceSnowflake $ getID @Guild g)+ permsEveryone = maybe noFlags (^. #permissions) everyoneRole+ rolePerms = g ^.. #roles . foldMap ix (V.toList $ m ^. #roles) . #permissions+ perms = foldl andFlags noFlags (permsEveryone:rolePerms)+ in if perms .<=. administrator+ then allFlags+ else perms++applyOverwrites :: GuildChannel -> Member -> Permissions -> Permissions+applyOverwrites c m p+ | p .<=. administrator = allFlags+ | otherwise =+ let everyoneOverwrite = c ^. #permissionOverwrites . at (coerceSnowflake $ getID @Guild c)+ everyoneAllow = maybe noFlags (^. #allow) everyoneOverwrite+ everyoneDeny = maybe noFlags (^. #deny) everyoneOverwrite+ p' = p .-. everyoneDeny .+. everyoneAllow+ roleOverwrites = c ^.. #permissionOverwrites . foldMap ix+ (map (coerceSnowflake @_ @Overwrite) . V.toList $ m ^. #roles)+ roleAllow = foldl andFlags noFlags (roleOverwrites ^.. traverse . #allow)+ roleDeny = foldl andFlags noFlags (roleOverwrites ^.. traverse . #deny)+ p'' = p' .-. roleDeny .+. roleAllow+ memberOverwrite = c ^. #permissionOverwrites . at (coerceSnowflake @_ @Overwrite $ getID @Member m)+ memberAllow = maybe noFlags (^. #allow) memberOverwrite+ memberDeny = maybe noFlags (^. #deny) memberOverwrite+ p''' = p'' .-. memberDeny .+. memberAllow+ in p'''++class PermissionsIn a where+ permissionsIn :: a -> Member -> Permissions++instance PermissionsIn (Guild, GuildChannel) where+ permissionsIn (g, c) m = applyOverwrites c m $ basePermissions g m++instance PermissionsIn Guild where+ permissionsIn g m = basePermissions g m++class PermissionsIn' a where+ permissionsIn' :: BotC r => a -> Member -> P.Sem r Permissions++instance PermissionsIn' GuildChannel where+ permissionsIn' c m = do+ g <- upgrade (getID @Guild c)+ case g of+ Just g' -> pure $ permissionsIn (g', c) m+ Nothing -> pure noFlags++instance PermissionsIn' Guild where+ permissionsIn' g m = pure $ permissionsIn g m++instance PermissionsIn' (Snowflake GuildChannel) where+ permissionsIn' cid m = do+ c <- upgrade cid+ case c of+ Just c' -> permissionsIn' c' m+ Nothing -> pure noFlags++instance PermissionsIn' (Snowflake Guild) where+ permissionsIn' gid m = do+ g <- upgrade gid+ case g of+ Just g' -> permissionsIn' g' m+ Nothing -> pure noFlags