calamity 0.6.0.0 → 0.7.0.0
raw patch · 23 files changed
+408/−86 lines, 23 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Calamity.Client.Types: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.IORef.IORef GHC.Num.Integer.Integer, b GHC.Types.~ GHC.IORef.IORef GHC.Num.Integer.Integer) => Optics.Label.LabelOptic "ehidCounter" k Calamity.Client.Types.Client Calamity.Client.Types.Client a b
- Calamity.Gateway.DispatchEvents: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Num.Integer.Integer, b GHC.Types.~ GHC.Num.Integer.Integer) => Optics.Label.LabelOptic "v" k Calamity.Gateway.DispatchEvents.ReadyData Calamity.Gateway.DispatchEvents.ReadyData a b
- Calamity.HTTP.Channel: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe GHC.Num.Integer.Integer, b GHC.Types.~ GHC.Maybe.Maybe GHC.Num.Integer.Integer) => Optics.Label.LabelOptic "limit" k Calamity.HTTP.Channel.GetReactionsOptions Calamity.HTTP.Channel.GetReactionsOptions a b
- Calamity.HTTP.Channel: instance (k GHC.Types.~ Optics.Internal.Optic.Types.An_Iso, a GHC.Types.~ GHC.Num.Integer.Integer, b GHC.Types.~ GHC.Num.Integer.Integer) => Optics.Label.LabelOptic "limit" k Calamity.HTTP.Channel.ChannelMessagesLimit Calamity.HTTP.Channel.ChannelMessagesLimit a b
- Calamity.HTTP.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe GHC.Num.Integer.Integer, b GHC.Types.~ GHC.Maybe.Maybe GHC.Num.Integer.Integer) => Optics.Label.LabelOptic "afkTimeout" k Calamity.HTTP.Guild.ModifyGuildData Calamity.HTTP.Guild.ModifyGuildData a b
- Calamity.HTTP.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe GHC.Num.Integer.Integer, b GHC.Types.~ GHC.Maybe.Maybe GHC.Num.Integer.Integer) => Optics.Label.LabelOptic "bitrate" k Calamity.HTTP.Guild.ChannelCreateData Calamity.HTTP.Guild.ChannelCreateData a b
- Calamity.HTTP.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe GHC.Num.Integer.Integer, b GHC.Types.~ GHC.Maybe.Maybe GHC.Num.Integer.Integer) => Optics.Label.LabelOptic "defaultMessageNotifications" k Calamity.HTTP.Guild.ModifyGuildData Calamity.HTTP.Guild.ModifyGuildData a b
- Calamity.HTTP.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe GHC.Num.Integer.Integer, b GHC.Types.~ GHC.Maybe.Maybe GHC.Num.Integer.Integer) => Optics.Label.LabelOptic "deleteMessageDays" k Calamity.HTTP.Guild.CreateGuildBanData Calamity.HTTP.Guild.CreateGuildBanData a b
- Calamity.HTTP.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe GHC.Num.Integer.Integer, b GHC.Types.~ GHC.Maybe.Maybe GHC.Num.Integer.Integer) => Optics.Label.LabelOptic "explicitContentFilter" k Calamity.HTTP.Guild.ModifyGuildData Calamity.HTTP.Guild.ModifyGuildData a b
- Calamity.HTTP.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe GHC.Num.Integer.Integer, b GHC.Types.~ GHC.Maybe.Maybe GHC.Num.Integer.Integer) => Optics.Label.LabelOptic "limit" k Calamity.HTTP.Guild.ListMembersOptions Calamity.HTTP.Guild.ListMembersOptions a b
- Calamity.HTTP.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe GHC.Num.Integer.Integer, b GHC.Types.~ GHC.Maybe.Maybe GHC.Num.Integer.Integer) => Optics.Label.LabelOptic "position" k Calamity.HTTP.Guild.ChannelCreateData Calamity.HTTP.Guild.ChannelCreateData a b
- Calamity.HTTP.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe GHC.Num.Integer.Integer, b GHC.Types.~ GHC.Maybe.Maybe GHC.Num.Integer.Integer) => Optics.Label.LabelOptic "position" k Calamity.HTTP.Guild.ChannelPosition Calamity.HTTP.Guild.ChannelPosition a b
- Calamity.HTTP.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe GHC.Num.Integer.Integer, b GHC.Types.~ GHC.Maybe.Maybe GHC.Num.Integer.Integer) => Optics.Label.LabelOptic "position" k Calamity.HTTP.Guild.ModifyGuildRolePositionsData Calamity.HTTP.Guild.ModifyGuildRolePositionsData a b
- Calamity.HTTP.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe GHC.Num.Integer.Integer, b GHC.Types.~ GHC.Maybe.Maybe GHC.Num.Integer.Integer) => Optics.Label.LabelOptic "rateLimitPerUser" k Calamity.HTTP.Guild.ChannelCreateData Calamity.HTTP.Guild.ChannelCreateData a b
- Calamity.HTTP.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe GHC.Num.Integer.Integer, b GHC.Types.~ GHC.Maybe.Maybe GHC.Num.Integer.Integer) => Optics.Label.LabelOptic "userLimit" k Calamity.HTTP.Guild.ChannelCreateData Calamity.HTTP.Guild.ChannelCreateData a b
- Calamity.HTTP.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe GHC.Num.Integer.Integer, b GHC.Types.~ GHC.Maybe.Maybe GHC.Num.Integer.Integer) => Optics.Label.LabelOptic "verificationLevel" k Calamity.HTTP.Guild.ModifyGuildData Calamity.HTTP.Guild.ModifyGuildData a b
- Calamity.HTTP.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Num.Integer.Integer, b GHC.Types.~ GHC.Num.Integer.Integer) => Optics.Label.LabelOptic "defaultMessageNotifications" k Calamity.HTTP.Guild.CreateGuildData Calamity.HTTP.Guild.CreateGuildData a b
- Calamity.HTTP.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Num.Integer.Integer, b GHC.Types.~ GHC.Num.Integer.Integer) => Optics.Label.LabelOptic "explicitContentFilter" k Calamity.HTTP.Guild.CreateGuildData Calamity.HTTP.Guild.CreateGuildData a b
- Calamity.HTTP.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Num.Integer.Integer, b GHC.Types.~ GHC.Num.Integer.Integer) => Optics.Label.LabelOptic "verificationLevel" k Calamity.HTTP.Guild.CreateGuildData Calamity.HTTP.Guild.CreateGuildData a b
- Calamity.HTTP.Internal.Request: type Result a;
- Calamity.HTTP.Internal.Route: type ConsRes a reqs;
- Calamity.HTTP.User: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe GHC.Num.Integer.Integer, b GHC.Types.~ GHC.Maybe.Maybe GHC.Num.Integer.Integer) => Optics.Label.LabelOptic "limit" k Calamity.HTTP.User.GetCurrentUserGuildsOptions Calamity.HTTP.User.GetCurrentUserGuildsOptions a b
- Calamity.Types.Model.Channel.Reaction: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Num.Integer.Integer, b GHC.Types.~ GHC.Num.Integer.Integer) => Optics.Label.LabelOptic "count" k Calamity.Types.Model.Channel.Reaction.Reaction Calamity.Types.Model.Channel.Reaction.Reaction a b
- Calamity.Types.Model.Channel.Webhook: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Num.Integer.Integer, b GHC.Types.~ GHC.Num.Integer.Integer) => Optics.Label.LabelOptic "type_" k Calamity.Types.Model.Channel.Webhook.Webhook Calamity.Types.Model.Channel.Webhook.Webhook a b
- Calamity.Types.Model.Guild.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe Data.Text.Internal.Text, b GHC.Types.~ GHC.Maybe.Maybe Data.Text.Internal.Text) => Optics.Label.LabelOptic "icon" k Calamity.Types.Model.Guild.Guild.Guild Calamity.Types.Model.Guild.Guild.Guild a b
- Calamity.Types.Model.Guild.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe Data.Text.Internal.Text, b GHC.Types.~ GHC.Maybe.Maybe Data.Text.Internal.Text) => Optics.Label.LabelOptic "icon" k Calamity.Types.Model.Guild.Guild.UpdatedGuild Calamity.Types.Model.Guild.Guild.UpdatedGuild a b
- Calamity.Types.Model.Guild.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe Data.Text.Internal.Text, b GHC.Types.~ GHC.Maybe.Maybe Data.Text.Internal.Text) => Optics.Label.LabelOptic "splash" k Calamity.Types.Model.Guild.Guild.Guild Calamity.Types.Model.Guild.Guild.Guild a b
- Calamity.Types.Model.Guild.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe Data.Text.Internal.Text, b GHC.Types.~ GHC.Maybe.Maybe Data.Text.Internal.Text) => Optics.Label.LabelOptic "splash" k Calamity.Types.Model.Guild.Guild.UpdatedGuild Calamity.Types.Model.Guild.Guild.UpdatedGuild a b
- Calamity.Types.Model.Guild.Member: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe Data.Text.Internal.Text, b GHC.Types.~ GHC.Maybe.Maybe Data.Text.Internal.Text) => Optics.Label.LabelOptic "avatar" k Calamity.Types.Model.Guild.Member.Member Calamity.Types.Model.Guild.Member.Member a b
- Calamity.Types.Model.User: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe Data.Text.Internal.Text, b GHC.Types.~ GHC.Maybe.Maybe Data.Text.Internal.Text) => Optics.Label.LabelOptic "avatar" k Calamity.Types.Model.User.User Calamity.Types.Model.User.User a b
+ Calamity.Client.Types: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.IORef.IORef GHC.Integer.Type.Integer, b GHC.Types.~ GHC.IORef.IORef GHC.Integer.Type.Integer) => Optics.Label.LabelOptic "ehidCounter" k Calamity.Client.Types.Client Calamity.Client.Types.Client a b
+ Calamity.Gateway.DispatchEvents: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Integer.Type.Integer, b GHC.Types.~ GHC.Integer.Type.Integer) => Optics.Label.LabelOptic "v" k Calamity.Gateway.DispatchEvents.ReadyData Calamity.Gateway.DispatchEvents.ReadyData a b
+ Calamity.HTTP.Channel: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe GHC.Integer.Type.Integer, b GHC.Types.~ GHC.Maybe.Maybe GHC.Integer.Type.Integer) => Optics.Label.LabelOptic "limit" k Calamity.HTTP.Channel.GetReactionsOptions Calamity.HTTP.Channel.GetReactionsOptions a b
+ Calamity.HTTP.Channel: instance (k GHC.Types.~ Optics.Internal.Optic.Types.An_Iso, a GHC.Types.~ GHC.Integer.Type.Integer, b GHC.Types.~ GHC.Integer.Type.Integer) => Optics.Label.LabelOptic "limit" k Calamity.HTTP.Channel.ChannelMessagesLimit Calamity.HTTP.Channel.ChannelMessagesLimit a b
+ Calamity.HTTP.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Integer.Type.Integer, b GHC.Types.~ GHC.Integer.Type.Integer) => Optics.Label.LabelOptic "defaultMessageNotifications" k Calamity.HTTP.Guild.CreateGuildData Calamity.HTTP.Guild.CreateGuildData a b
+ Calamity.HTTP.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Integer.Type.Integer, b GHC.Types.~ GHC.Integer.Type.Integer) => Optics.Label.LabelOptic "explicitContentFilter" k Calamity.HTTP.Guild.CreateGuildData Calamity.HTTP.Guild.CreateGuildData a b
+ Calamity.HTTP.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Integer.Type.Integer, b GHC.Types.~ GHC.Integer.Type.Integer) => Optics.Label.LabelOptic "verificationLevel" k Calamity.HTTP.Guild.CreateGuildData Calamity.HTTP.Guild.CreateGuildData a b
+ Calamity.HTTP.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe GHC.Integer.Type.Integer, b GHC.Types.~ GHC.Maybe.Maybe GHC.Integer.Type.Integer) => Optics.Label.LabelOptic "afkTimeout" k Calamity.HTTP.Guild.ModifyGuildData Calamity.HTTP.Guild.ModifyGuildData a b
+ Calamity.HTTP.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe GHC.Integer.Type.Integer, b GHC.Types.~ GHC.Maybe.Maybe GHC.Integer.Type.Integer) => Optics.Label.LabelOptic "bitrate" k Calamity.HTTP.Guild.ChannelCreateData Calamity.HTTP.Guild.ChannelCreateData a b
+ Calamity.HTTP.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe GHC.Integer.Type.Integer, b GHC.Types.~ GHC.Maybe.Maybe GHC.Integer.Type.Integer) => Optics.Label.LabelOptic "defaultMessageNotifications" k Calamity.HTTP.Guild.ModifyGuildData Calamity.HTTP.Guild.ModifyGuildData a b
+ Calamity.HTTP.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe GHC.Integer.Type.Integer, b GHC.Types.~ GHC.Maybe.Maybe GHC.Integer.Type.Integer) => Optics.Label.LabelOptic "deleteMessageDays" k Calamity.HTTP.Guild.CreateGuildBanData Calamity.HTTP.Guild.CreateGuildBanData a b
+ Calamity.HTTP.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe GHC.Integer.Type.Integer, b GHC.Types.~ GHC.Maybe.Maybe GHC.Integer.Type.Integer) => Optics.Label.LabelOptic "explicitContentFilter" k Calamity.HTTP.Guild.ModifyGuildData Calamity.HTTP.Guild.ModifyGuildData a b
+ Calamity.HTTP.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe GHC.Integer.Type.Integer, b GHC.Types.~ GHC.Maybe.Maybe GHC.Integer.Type.Integer) => Optics.Label.LabelOptic "limit" k Calamity.HTTP.Guild.ListMembersOptions Calamity.HTTP.Guild.ListMembersOptions a b
+ Calamity.HTTP.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe GHC.Integer.Type.Integer, b GHC.Types.~ GHC.Maybe.Maybe GHC.Integer.Type.Integer) => Optics.Label.LabelOptic "position" k Calamity.HTTP.Guild.ChannelCreateData Calamity.HTTP.Guild.ChannelCreateData a b
+ Calamity.HTTP.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe GHC.Integer.Type.Integer, b GHC.Types.~ GHC.Maybe.Maybe GHC.Integer.Type.Integer) => Optics.Label.LabelOptic "position" k Calamity.HTTP.Guild.ChannelPosition Calamity.HTTP.Guild.ChannelPosition a b
+ Calamity.HTTP.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe GHC.Integer.Type.Integer, b GHC.Types.~ GHC.Maybe.Maybe GHC.Integer.Type.Integer) => Optics.Label.LabelOptic "position" k Calamity.HTTP.Guild.ModifyGuildRolePositionsData Calamity.HTTP.Guild.ModifyGuildRolePositionsData a b
+ Calamity.HTTP.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe GHC.Integer.Type.Integer, b GHC.Types.~ GHC.Maybe.Maybe GHC.Integer.Type.Integer) => Optics.Label.LabelOptic "rateLimitPerUser" k Calamity.HTTP.Guild.ChannelCreateData Calamity.HTTP.Guild.ChannelCreateData a b
+ Calamity.HTTP.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe GHC.Integer.Type.Integer, b GHC.Types.~ GHC.Maybe.Maybe GHC.Integer.Type.Integer) => Optics.Label.LabelOptic "userLimit" k Calamity.HTTP.Guild.ChannelCreateData Calamity.HTTP.Guild.ChannelCreateData a b
+ Calamity.HTTP.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe GHC.Integer.Type.Integer, b GHC.Types.~ GHC.Maybe.Maybe GHC.Integer.Type.Integer) => Optics.Label.LabelOptic "verificationLevel" k Calamity.HTTP.Guild.ModifyGuildData Calamity.HTTP.Guild.ModifyGuildData a b
+ Calamity.HTTP.Internal.Request: type family Result a;
+ Calamity.HTTP.Internal.Route: type family ConsRes a reqs;
+ Calamity.HTTP.User: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe GHC.Integer.Type.Integer, b GHC.Types.~ GHC.Maybe.Maybe GHC.Integer.Type.Integer) => Optics.Label.LabelOptic "limit" k Calamity.HTTP.User.GetCurrentUserGuildsOptions Calamity.HTTP.User.GetCurrentUserGuildsOptions a b
+ Calamity.Internal.Updateable: type family Updated a;
+ Calamity.Types.CDNAsset: assetURL :: CDNAsset a => a -> Url 'Https
+ Calamity.Types.CDNAsset: class CDNAsset a
+ Calamity.Types.CDNAsset: fetchAsset :: (CDNAsset a, Member (Embed IO) r) => a -> Sem r (Either HttpException ByteString)
+ Calamity.Types.CDNAsset: fetchAsset' :: (CDNAsset a, MonadHttp m) => a -> m ByteString
+ Calamity.Types.Model.Avatar: Avatar :: Maybe Text -> Snowflake User -> Int -> Avatar
+ Calamity.Types.Model.Avatar: MemberAvatar :: Text -> Snowflake Guild -> Snowflake User -> MemberAvatar
+ Calamity.Types.Model.Avatar: [$sel:discrim:Avatar] :: Avatar -> Int
+ Calamity.Types.Model.Avatar: [$sel:guildID:MemberAvatar] :: MemberAvatar -> Snowflake Guild
+ Calamity.Types.Model.Avatar: [$sel:hash:Avatar] :: Avatar -> Maybe Text
+ Calamity.Types.Model.Avatar: [$sel:hash:MemberAvatar] :: MemberAvatar -> Text
+ Calamity.Types.Model.Avatar: [$sel:userID:Avatar] :: Avatar -> Snowflake User
+ Calamity.Types.Model.Avatar: [$sel:userID:MemberAvatar] :: MemberAvatar -> Snowflake User
+ Calamity.Types.Model.Avatar: data Avatar
+ Calamity.Types.Model.Avatar: data MemberAvatar
+ Calamity.Types.Model.Avatar: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ Calamity.Types.Snowflake.Snowflake Calamity.Types.Model.Guild.Guild.Guild, b GHC.Types.~ Calamity.Types.Snowflake.Snowflake Calamity.Types.Model.Guild.Guild.Guild) => Optics.Label.LabelOptic "guildID" k Calamity.Types.Model.Avatar.MemberAvatar Calamity.Types.Model.Avatar.MemberAvatar a b
+ Calamity.Types.Model.Avatar: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ Calamity.Types.Snowflake.Snowflake Calamity.Types.Model.User.User, b GHC.Types.~ Calamity.Types.Snowflake.Snowflake Calamity.Types.Model.User.User) => Optics.Label.LabelOptic "userID" k Calamity.Types.Model.Avatar.Avatar Calamity.Types.Model.Avatar.Avatar a b
+ Calamity.Types.Model.Avatar: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ Calamity.Types.Snowflake.Snowflake Calamity.Types.Model.User.User, b GHC.Types.~ Calamity.Types.Snowflake.Snowflake Calamity.Types.Model.User.User) => Optics.Label.LabelOptic "userID" k Calamity.Types.Model.Avatar.MemberAvatar Calamity.Types.Model.Avatar.MemberAvatar a b
+ Calamity.Types.Model.Avatar: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ Data.Text.Internal.Text, b GHC.Types.~ Data.Text.Internal.Text) => Optics.Label.LabelOptic "hash" k Calamity.Types.Model.Avatar.MemberAvatar Calamity.Types.Model.Avatar.MemberAvatar a b
+ Calamity.Types.Model.Avatar: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe Data.Text.Internal.Text, b GHC.Types.~ GHC.Maybe.Maybe Data.Text.Internal.Text) => Optics.Label.LabelOptic "hash" k Calamity.Types.Model.Avatar.Avatar Calamity.Types.Model.Avatar.Avatar a b
+ Calamity.Types.Model.Avatar: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Types.Int, b GHC.Types.~ GHC.Types.Int) => Optics.Label.LabelOptic "discrim" k Calamity.Types.Model.Avatar.Avatar Calamity.Types.Model.Avatar.Avatar a b
+ Calamity.Types.Model.Avatar: instance Calamity.Types.CDNAsset.CDNAsset Calamity.Types.Model.Avatar.Avatar
+ Calamity.Types.Model.Avatar: instance Calamity.Types.CDNAsset.CDNAsset Calamity.Types.Model.Avatar.MemberAvatar
+ Calamity.Types.Model.Avatar: instance GHC.Classes.Eq Calamity.Types.Model.Avatar.Avatar
+ Calamity.Types.Model.Avatar: instance GHC.Classes.Eq Calamity.Types.Model.Avatar.MemberAvatar
+ Calamity.Types.Model.Avatar: instance GHC.Show.Show Calamity.Types.Model.Avatar.Avatar
+ Calamity.Types.Model.Avatar: instance GHC.Show.Show Calamity.Types.Model.Avatar.MemberAvatar
+ Calamity.Types.Model.Avatar: instance TextShow.Classes.TextShow Calamity.Types.Model.Avatar.Avatar
+ Calamity.Types.Model.Avatar: instance TextShow.Classes.TextShow Calamity.Types.Model.Avatar.MemberAvatar
+ Calamity.Types.Model.Channel.Reaction: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Integer.Type.Integer, b GHC.Types.~ GHC.Integer.Type.Integer) => Optics.Label.LabelOptic "count" k Calamity.Types.Model.Channel.Reaction.Reaction Calamity.Types.Model.Channel.Reaction.Reaction a b
+ Calamity.Types.Model.Channel.Webhook: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Integer.Type.Integer, b GHC.Types.~ GHC.Integer.Type.Integer) => Optics.Label.LabelOptic "type_" k Calamity.Types.Model.Channel.Webhook.Webhook Calamity.Types.Model.Channel.Webhook.Webhook a b
+ Calamity.Types.Model.Guild: GuildBanner :: Snowflake Guild -> Text -> GuildBanner
+ Calamity.Types.Model.Guild: GuildDiscoverySplash :: Snowflake Guild -> Text -> GuildDiscoverySplash
+ Calamity.Types.Model.Guild: GuildIcon :: Snowflake Guild -> Text -> GuildIcon
+ Calamity.Types.Model.Guild: GuildSplash :: Snowflake Guild -> Text -> GuildSplash
+ Calamity.Types.Model.Guild: [$sel:banner:Guild] :: Guild -> Maybe GuildBanner
+ Calamity.Types.Model.Guild: [$sel:discoverySplash:Guild] :: Guild -> Maybe GuildSplash
+ Calamity.Types.Model.Guild: [$sel:guildID:GuildBanner] :: GuildBanner -> Snowflake Guild
+ Calamity.Types.Model.Guild: [$sel:guildID:GuildDiscoverySplash] :: GuildDiscoverySplash -> Snowflake Guild
+ Calamity.Types.Model.Guild: [$sel:guildID:GuildIcon] :: GuildIcon -> Snowflake Guild
+ Calamity.Types.Model.Guild: [$sel:guildID:GuildSplash] :: GuildSplash -> Snowflake Guild
+ Calamity.Types.Model.Guild: [$sel:hash:GuildBanner] :: GuildBanner -> Text
+ Calamity.Types.Model.Guild: [$sel:hash:GuildDiscoverySplash] :: GuildDiscoverySplash -> Text
+ Calamity.Types.Model.Guild: [$sel:hash:GuildIcon] :: GuildIcon -> Text
+ Calamity.Types.Model.Guild: [$sel:hash:GuildSplash] :: GuildSplash -> Text
+ Calamity.Types.Model.Guild: data GuildBanner
+ Calamity.Types.Model.Guild: data GuildDiscoverySplash
+ Calamity.Types.Model.Guild: data GuildIcon
+ Calamity.Types.Model.Guild: data GuildSplash
+ Calamity.Types.Model.Guild.Emoji: instance Calamity.Types.CDNAsset.CDNAsset Calamity.Types.Model.Guild.Emoji.Emoji
+ Calamity.Types.Model.Guild.Guild: GuildBanner :: Snowflake Guild -> Text -> GuildBanner
+ Calamity.Types.Model.Guild.Guild: GuildDiscoverySplash :: Snowflake Guild -> Text -> GuildDiscoverySplash
+ Calamity.Types.Model.Guild.Guild: GuildIcon :: Snowflake Guild -> Text -> GuildIcon
+ Calamity.Types.Model.Guild.Guild: GuildSplash :: Snowflake Guild -> Text -> GuildSplash
+ Calamity.Types.Model.Guild.Guild: [$sel:banner:Guild] :: Guild -> Maybe GuildBanner
+ Calamity.Types.Model.Guild.Guild: [$sel:banner:UpdatedGuild] :: UpdatedGuild -> Maybe GuildBanner
+ Calamity.Types.Model.Guild.Guild: [$sel:discoverySplash:Guild] :: Guild -> Maybe GuildSplash
+ Calamity.Types.Model.Guild.Guild: [$sel:discoverySplash:UpdatedGuild] :: UpdatedGuild -> Maybe GuildSplash
+ Calamity.Types.Model.Guild.Guild: [$sel:guildID:GuildBanner] :: GuildBanner -> Snowflake Guild
+ Calamity.Types.Model.Guild.Guild: [$sel:guildID:GuildDiscoverySplash] :: GuildDiscoverySplash -> Snowflake Guild
+ Calamity.Types.Model.Guild.Guild: [$sel:guildID:GuildIcon] :: GuildIcon -> Snowflake Guild
+ Calamity.Types.Model.Guild.Guild: [$sel:guildID:GuildSplash] :: GuildSplash -> Snowflake Guild
+ Calamity.Types.Model.Guild.Guild: [$sel:hash:GuildBanner] :: GuildBanner -> Text
+ Calamity.Types.Model.Guild.Guild: [$sel:hash:GuildDiscoverySplash] :: GuildDiscoverySplash -> Text
+ Calamity.Types.Model.Guild.Guild: [$sel:hash:GuildIcon] :: GuildIcon -> Text
+ Calamity.Types.Model.Guild.Guild: [$sel:hash:GuildSplash] :: GuildSplash -> Text
+ Calamity.Types.Model.Guild.Guild: data GuildBanner
+ Calamity.Types.Model.Guild.Guild: data GuildDiscoverySplash
+ Calamity.Types.Model.Guild.Guild: data GuildIcon
+ Calamity.Types.Model.Guild.Guild: data GuildSplash
+ Calamity.Types.Model.Guild.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ Calamity.Types.Snowflake.Snowflake Calamity.Types.Model.Guild.Guild.Guild, b GHC.Types.~ Calamity.Types.Snowflake.Snowflake Calamity.Types.Model.Guild.Guild.Guild) => Optics.Label.LabelOptic "guildID" k Calamity.Types.Model.Guild.Guild.GuildIcon Calamity.Types.Model.Guild.Guild.GuildIcon a b
+ Calamity.Types.Model.Guild.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ Data.Text.Internal.Text, b GHC.Types.~ Data.Text.Internal.Text) => Optics.Label.LabelOptic "hash" k Calamity.Types.Model.Guild.Guild.GuildIcon Calamity.Types.Model.Guild.Guild.GuildIcon a b
+ Calamity.Types.Model.Guild.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe Calamity.Types.Model.Guild.Guild.GuildBanner, b GHC.Types.~ GHC.Maybe.Maybe Calamity.Types.Model.Guild.Guild.GuildBanner) => Optics.Label.LabelOptic "banner" k Calamity.Types.Model.Guild.Guild.Guild Calamity.Types.Model.Guild.Guild.Guild a b
+ Calamity.Types.Model.Guild.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe Calamity.Types.Model.Guild.Guild.GuildBanner, b GHC.Types.~ GHC.Maybe.Maybe Calamity.Types.Model.Guild.Guild.GuildBanner) => Optics.Label.LabelOptic "banner" k Calamity.Types.Model.Guild.Guild.UpdatedGuild Calamity.Types.Model.Guild.Guild.UpdatedGuild a b
+ Calamity.Types.Model.Guild.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe Calamity.Types.Model.Guild.Guild.GuildIcon, b GHC.Types.~ GHC.Maybe.Maybe Calamity.Types.Model.Guild.Guild.GuildIcon) => Optics.Label.LabelOptic "icon" k Calamity.Types.Model.Guild.Guild.Guild Calamity.Types.Model.Guild.Guild.Guild a b
+ Calamity.Types.Model.Guild.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe Calamity.Types.Model.Guild.Guild.GuildIcon, b GHC.Types.~ GHC.Maybe.Maybe Calamity.Types.Model.Guild.Guild.GuildIcon) => Optics.Label.LabelOptic "icon" k Calamity.Types.Model.Guild.Guild.UpdatedGuild Calamity.Types.Model.Guild.Guild.UpdatedGuild a b
+ Calamity.Types.Model.Guild.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe Calamity.Types.Model.Guild.Guild.GuildSplash, b GHC.Types.~ GHC.Maybe.Maybe Calamity.Types.Model.Guild.Guild.GuildSplash) => Optics.Label.LabelOptic "discoverySplash" k Calamity.Types.Model.Guild.Guild.Guild Calamity.Types.Model.Guild.Guild.Guild a b
+ Calamity.Types.Model.Guild.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe Calamity.Types.Model.Guild.Guild.GuildSplash, b GHC.Types.~ GHC.Maybe.Maybe Calamity.Types.Model.Guild.Guild.GuildSplash) => Optics.Label.LabelOptic "discoverySplash" k Calamity.Types.Model.Guild.Guild.UpdatedGuild Calamity.Types.Model.Guild.Guild.UpdatedGuild a b
+ Calamity.Types.Model.Guild.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe Calamity.Types.Model.Guild.Guild.GuildSplash, b GHC.Types.~ GHC.Maybe.Maybe Calamity.Types.Model.Guild.Guild.GuildSplash) => Optics.Label.LabelOptic "splash" k Calamity.Types.Model.Guild.Guild.Guild Calamity.Types.Model.Guild.Guild.Guild a b
+ Calamity.Types.Model.Guild.Guild: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe Calamity.Types.Model.Guild.Guild.GuildSplash, b GHC.Types.~ GHC.Maybe.Maybe Calamity.Types.Model.Guild.Guild.GuildSplash) => Optics.Label.LabelOptic "splash" k Calamity.Types.Model.Guild.Guild.UpdatedGuild Calamity.Types.Model.Guild.Guild.UpdatedGuild a b
+ Calamity.Types.Model.Guild.Guild: instance Calamity.Types.CDNAsset.CDNAsset Calamity.Types.Model.Guild.Guild.GuildBanner
+ Calamity.Types.Model.Guild.Guild: instance Calamity.Types.CDNAsset.CDNAsset Calamity.Types.Model.Guild.Guild.GuildDiscoverySplash
+ Calamity.Types.Model.Guild.Guild: instance Calamity.Types.CDNAsset.CDNAsset Calamity.Types.Model.Guild.Guild.GuildIcon
+ Calamity.Types.Model.Guild.Guild: instance Calamity.Types.CDNAsset.CDNAsset Calamity.Types.Model.Guild.Guild.GuildSplash
+ Calamity.Types.Model.Guild.Guild: instance GHC.Classes.Eq Calamity.Types.Model.Guild.Guild.GuildBanner
+ Calamity.Types.Model.Guild.Guild: instance GHC.Classes.Eq Calamity.Types.Model.Guild.Guild.GuildDiscoverySplash
+ Calamity.Types.Model.Guild.Guild: instance GHC.Classes.Eq Calamity.Types.Model.Guild.Guild.GuildIcon
+ Calamity.Types.Model.Guild.Guild: instance GHC.Classes.Eq Calamity.Types.Model.Guild.Guild.GuildSplash
+ Calamity.Types.Model.Guild.Guild: instance GHC.Show.Show Calamity.Types.Model.Guild.Guild.GuildBanner
+ Calamity.Types.Model.Guild.Guild: instance GHC.Show.Show Calamity.Types.Model.Guild.Guild.GuildDiscoverySplash
+ Calamity.Types.Model.Guild.Guild: instance GHC.Show.Show Calamity.Types.Model.Guild.Guild.GuildIcon
+ Calamity.Types.Model.Guild.Guild: instance GHC.Show.Show Calamity.Types.Model.Guild.Guild.GuildSplash
+ Calamity.Types.Model.Guild.Guild: instance TextShow.Classes.TextShow Calamity.Types.Model.Guild.Guild.GuildIcon
+ Calamity.Types.Model.Guild.Member: [$sel:accentColour:Member] :: Member -> Maybe (Colour Double)
+ Calamity.Types.Model.Guild.Member: [$sel:banner:Member] :: Member -> Maybe UserBanner
+ Calamity.Types.Model.Guild.Member: [$sel:locale:Member] :: Member -> Maybe Text
+ Calamity.Types.Model.Guild.Member: [$sel:memberAvatar:Member] :: Member -> Maybe Text
+ Calamity.Types.Model.Guild.Member: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ Calamity.Types.Model.Avatar.Avatar, b GHC.Types.~ Calamity.Types.Model.Avatar.Avatar) => Optics.Label.LabelOptic "avatar" k Calamity.Types.Model.Guild.Member.Member Calamity.Types.Model.Guild.Member.Member a b
+ Calamity.Types.Model.Guild.Member: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe (Data.Colour.Internal.Colour GHC.Types.Double), b GHC.Types.~ GHC.Maybe.Maybe (Data.Colour.Internal.Colour GHC.Types.Double)) => Optics.Label.LabelOptic "accentColour" k Calamity.Types.Model.Guild.Member.Member Calamity.Types.Model.Guild.Member.Member a b
+ Calamity.Types.Model.Guild.Member: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe Calamity.Types.Model.User.UserBanner, b GHC.Types.~ GHC.Maybe.Maybe Calamity.Types.Model.User.UserBanner) => Optics.Label.LabelOptic "banner" k Calamity.Types.Model.Guild.Member.Member Calamity.Types.Model.Guild.Member.Member a b
+ Calamity.Types.Model.Guild.Member: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe Data.Text.Internal.Text, b GHC.Types.~ GHC.Maybe.Maybe Data.Text.Internal.Text) => Optics.Label.LabelOptic "locale" k Calamity.Types.Model.Guild.Member.Member Calamity.Types.Model.Guild.Member.Member a b
+ Calamity.Types.Model.Guild.Member: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe Data.Text.Internal.Text, b GHC.Types.~ GHC.Maybe.Maybe Data.Text.Internal.Text) => Optics.Label.LabelOptic "memberAvatar" k Calamity.Types.Model.Guild.Member.Member Calamity.Types.Model.Guild.Member.Member a b
+ Calamity.Types.Model.Guild.Role: RoleIcon :: Snowflake Role -> Text -> RoleIcon
+ Calamity.Types.Model.Guild.Role: [$sel:emoji:Role] :: Role -> Maybe RawEmoji
+ Calamity.Types.Model.Guild.Role: [$sel:hash:RoleIcon] :: RoleIcon -> Text
+ Calamity.Types.Model.Guild.Role: [$sel:icon:Role] :: Role -> Maybe RoleIcon
+ Calamity.Types.Model.Guild.Role: [$sel:roleID:RoleIcon] :: RoleIcon -> Snowflake Role
+ Calamity.Types.Model.Guild.Role: data RoleIcon
+ Calamity.Types.Model.Guild.Role: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe Calamity.Types.Model.Guild.Emoji.RawEmoji, b GHC.Types.~ GHC.Maybe.Maybe Calamity.Types.Model.Guild.Emoji.RawEmoji) => Optics.Label.LabelOptic "emoji" k Calamity.Types.Model.Guild.Role.Role Calamity.Types.Model.Guild.Role.Role a b
+ Calamity.Types.Model.Guild.Role: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe Calamity.Types.Model.Guild.Role.RoleIcon, b GHC.Types.~ GHC.Maybe.Maybe Calamity.Types.Model.Guild.Role.RoleIcon) => Optics.Label.LabelOptic "icon" k Calamity.Types.Model.Guild.Role.Role Calamity.Types.Model.Guild.Role.Role a b
+ Calamity.Types.Model.Guild.Role: instance Calamity.Types.CDNAsset.CDNAsset Calamity.Types.Model.Guild.Role.RoleIcon
+ Calamity.Types.Model.Guild.Role: instance GHC.Classes.Eq Calamity.Types.Model.Guild.Role.RoleIcon
+ Calamity.Types.Model.Guild.Role: instance GHC.Show.Show Calamity.Types.Model.Guild.Role.RoleIcon
+ Calamity.Types.Model.User: UserBanner :: Snowflake User -> Text -> UserBanner
+ Calamity.Types.Model.User: [$sel:accentColour:User] :: User -> Maybe (Colour Double)
+ Calamity.Types.Model.User: [$sel:banner:User] :: User -> Maybe UserBanner
+ Calamity.Types.Model.User: [$sel:hash:UserBanner] :: UserBanner -> Text
+ Calamity.Types.Model.User: [$sel:locale:User] :: User -> Maybe Text
+ Calamity.Types.Model.User: [$sel:userID:UserBanner] :: UserBanner -> Snowflake User
+ Calamity.Types.Model.User: data UserBanner
+ Calamity.Types.Model.User: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ Calamity.Types.Model.Avatar.Avatar, b GHC.Types.~ Calamity.Types.Model.Avatar.Avatar) => Optics.Label.LabelOptic "avatar" k Calamity.Types.Model.User.User Calamity.Types.Model.User.User a b
+ Calamity.Types.Model.User: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe (Data.Colour.Internal.Colour GHC.Types.Double), b GHC.Types.~ GHC.Maybe.Maybe (Data.Colour.Internal.Colour GHC.Types.Double)) => Optics.Label.LabelOptic "accentColour" k Calamity.Types.Model.User.User Calamity.Types.Model.User.User a b
+ Calamity.Types.Model.User: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe Calamity.Types.Model.User.UserBanner, b GHC.Types.~ GHC.Maybe.Maybe Calamity.Types.Model.User.UserBanner) => Optics.Label.LabelOptic "banner" k Calamity.Types.Model.User.User Calamity.Types.Model.User.User a b
+ Calamity.Types.Model.User: instance (k GHC.Types.~ Optics.Internal.Optic.Types.A_Lens, a GHC.Types.~ GHC.Maybe.Maybe Data.Text.Internal.Text, b GHC.Types.~ GHC.Maybe.Maybe Data.Text.Internal.Text) => Optics.Label.LabelOptic "locale" k Calamity.Types.Model.User.User Calamity.Types.Model.User.User a b
+ Calamity.Types.Model.User: instance Calamity.Types.CDNAsset.CDNAsset Calamity.Types.Model.User.UserBanner
+ Calamity.Types.Model.User: instance GHC.Classes.Eq Calamity.Types.Model.User.UserBanner
+ Calamity.Types.Model.User: instance GHC.Show.Show Calamity.Types.Model.User.UserBanner
+ Calamity.Types.Snowflake: instance Web.Internal.HttpApiData.ToHttpApiData (Calamity.Types.Snowflake.Snowflake t)
+ Calamity.Utils.CDNUrl: assetHashFile :: Text -> Text
+ Calamity.Utils.CDNUrl: cdnURL :: Url 'Https
+ Calamity.Utils.CDNUrl: isGIFAsset :: Text -> Bool
- Calamity.Cache.Eff: delDM :: forall r_a4nGS. Member CacheEff r_a4nGS => Snowflake DMChannel -> Sem r_a4nGS ()
+ Calamity.Cache.Eff: delDM :: forall r_a4OLa. MemberWithError CacheEff r_a4OLa => Snowflake DMChannel -> Sem r_a4OLa ()
- Calamity.Cache.Eff: delGuild :: forall r_a4nGL. Member CacheEff r_a4nGL => Snowflake Guild -> Sem r_a4nGL ()
+ Calamity.Cache.Eff: delGuild :: forall r_a4OL3. MemberWithError CacheEff r_a4OL3 => Snowflake Guild -> Sem r_a4OL3 ()
- Calamity.Cache.Eff: delMessage :: forall r_a4nHd. Member CacheEff r_a4nHd => Snowflake Message -> Sem r_a4nHd ()
+ Calamity.Cache.Eff: delMessage :: forall r_a4OLv. MemberWithError CacheEff r_a4OLv => Snowflake Message -> Sem r_a4OLv ()
- Calamity.Cache.Eff: delUnavailableGuild :: forall r_a4nH6. Member CacheEff r_a4nH6 => Snowflake Guild -> Sem r_a4nH6 ()
+ Calamity.Cache.Eff: delUnavailableGuild :: forall r_a4OLo. MemberWithError CacheEff r_a4OLo => Snowflake Guild -> Sem r_a4OLo ()
- Calamity.Cache.Eff: delUser :: forall r_a4nGZ. Member CacheEff r_a4nGZ => Snowflake User -> Sem r_a4nGZ ()
+ Calamity.Cache.Eff: delUser :: forall r_a4OLh. MemberWithError CacheEff r_a4OLh => Snowflake User -> Sem r_a4OLh ()
- Calamity.Cache.Eff: getBotUser :: forall r_a4nGD. Member CacheEff r_a4nGD => Sem r_a4nGD (Maybe User)
+ Calamity.Cache.Eff: getBotUser :: forall r_a4OKV. MemberWithError CacheEff r_a4OKV => Sem r_a4OKV (Maybe User)
- Calamity.Cache.Eff: getDM :: forall r_a4nGP. Member CacheEff r_a4nGP => Snowflake DMChannel -> Sem r_a4nGP (Maybe DMChannel)
+ Calamity.Cache.Eff: getDM :: forall r_a4OL7. MemberWithError CacheEff r_a4OL7 => Snowflake DMChannel -> Sem r_a4OL7 (Maybe DMChannel)
- Calamity.Cache.Eff: getDMs :: forall r_a4nGR. Member CacheEff r_a4nGR => Sem r_a4nGR [DMChannel]
+ Calamity.Cache.Eff: getDMs :: forall r_a4OL9. MemberWithError CacheEff r_a4OL9 => Sem r_a4OL9 [DMChannel]
- Calamity.Cache.Eff: getGuild :: forall r_a4nGG. Member CacheEff r_a4nGG => Snowflake Guild -> Sem r_a4nGG (Maybe Guild)
+ Calamity.Cache.Eff: getGuild :: forall r_a4OKY. MemberWithError CacheEff r_a4OKY => Snowflake Guild -> Sem r_a4OKY (Maybe Guild)
- Calamity.Cache.Eff: getGuildChannel :: forall r_a4nGI. Member CacheEff r_a4nGI => Snowflake GuildChannel -> Sem r_a4nGI (Maybe GuildChannel)
+ Calamity.Cache.Eff: getGuildChannel :: forall r_a4OL0. MemberWithError CacheEff r_a4OL0 => Snowflake GuildChannel -> Sem r_a4OL0 (Maybe GuildChannel)
- Calamity.Cache.Eff: getGuilds :: forall r_a4nGK. Member CacheEff r_a4nGK => Sem r_a4nGK [Guild]
+ Calamity.Cache.Eff: getGuilds :: forall r_a4OL2. MemberWithError CacheEff r_a4OL2 => Sem r_a4OL2 [Guild]
- Calamity.Cache.Eff: getMessage :: forall r_a4nHa. Member CacheEff r_a4nHa => Snowflake Message -> Sem r_a4nHa (Maybe Message)
+ Calamity.Cache.Eff: getMessage :: forall r_a4OLs. MemberWithError CacheEff r_a4OLs => Snowflake Message -> Sem r_a4OLs (Maybe Message)
- Calamity.Cache.Eff: getMessages :: forall r_a4nHc. Member CacheEff r_a4nHc => Sem r_a4nHc [Message]
+ Calamity.Cache.Eff: getMessages :: forall r_a4OLu. MemberWithError CacheEff r_a4OLu => Sem r_a4OLu [Message]
- Calamity.Cache.Eff: getUnavailableGuilds :: forall r_a4nH5. Member CacheEff r_a4nH5 => Sem r_a4nH5 [Snowflake Guild]
+ Calamity.Cache.Eff: getUnavailableGuilds :: forall r_a4OLn. MemberWithError CacheEff r_a4OLn => Sem r_a4OLn [Snowflake Guild]
- Calamity.Cache.Eff: getUser :: forall r_a4nGW. Member CacheEff r_a4nGW => Snowflake User -> Sem r_a4nGW (Maybe User)
+ Calamity.Cache.Eff: getUser :: forall r_a4OLe. MemberWithError CacheEff r_a4OLe => Snowflake User -> Sem r_a4OLe (Maybe User)
- Calamity.Cache.Eff: getUsers :: forall r_a4nGY. Member CacheEff r_a4nGY => Sem r_a4nGY [User]
+ Calamity.Cache.Eff: getUsers :: forall r_a4OLg. MemberWithError CacheEff r_a4OLg => Sem r_a4OLg [User]
- Calamity.Cache.Eff: isUnavailableGuild :: forall r_a4nH3. Member CacheEff r_a4nH3 => Snowflake Guild -> Sem r_a4nH3 Bool
+ Calamity.Cache.Eff: isUnavailableGuild :: forall r_a4OLl. MemberWithError CacheEff r_a4OLl => Snowflake Guild -> Sem r_a4OLl Bool
- Calamity.Cache.Eff: setBotUser :: forall r_a4nGB. Member CacheEff r_a4nGB => User -> Sem r_a4nGB ()
+ Calamity.Cache.Eff: setBotUser :: forall r_a4OKT. MemberWithError CacheEff r_a4OKT => User -> Sem r_a4OKT ()
- Calamity.Cache.Eff: setDM :: forall r_a4nGN. Member CacheEff r_a4nGN => DMChannel -> Sem r_a4nGN ()
+ Calamity.Cache.Eff: setDM :: forall r_a4OL5. MemberWithError CacheEff r_a4OL5 => DMChannel -> Sem r_a4OL5 ()
- Calamity.Cache.Eff: setGuild :: forall r_a4nGE. Member CacheEff r_a4nGE => Guild -> Sem r_a4nGE ()
+ Calamity.Cache.Eff: setGuild :: forall r_a4OKW. MemberWithError CacheEff r_a4OKW => Guild -> Sem r_a4OKW ()
- Calamity.Cache.Eff: setMessage :: forall r_a4nH8. Member CacheEff r_a4nH8 => Message -> Sem r_a4nH8 ()
+ Calamity.Cache.Eff: setMessage :: forall r_a4OLq. MemberWithError CacheEff r_a4OLq => Message -> Sem r_a4OLq ()
- Calamity.Cache.Eff: setUnavailableGuild :: forall r_a4nH1. Member CacheEff r_a4nH1 => Snowflake Guild -> Sem r_a4nH1 ()
+ Calamity.Cache.Eff: setUnavailableGuild :: forall r_a4OLj. MemberWithError CacheEff r_a4OLj => Snowflake Guild -> Sem r_a4OLj ()
- Calamity.Cache.Eff: setUser :: forall r_a4nGU. Member CacheEff r_a4nGU => User -> Sem r_a4nGU ()
+ Calamity.Cache.Eff: setUser :: forall r_a4OLc. MemberWithError CacheEff r_a4OLc => User -> Sem r_a4OLc ()
- Calamity.HTTP.Internal.Ratelimit: getRatelimitState :: forall r_a4D5I. Member RatelimitEff r_a4D5I => Sem r_a4D5I RateLimitState
+ Calamity.HTTP.Internal.Ratelimit: getRatelimitState :: forall r_a3GC4. MemberWithError RatelimitEff r_a3GC4 => Sem r_a3GC4 RateLimitState
- Calamity.Interactions.Eff: getInteraction :: forall r_a3xkB. Member InteractionEff r_a3xkB => Sem r_a3xkB Interaction
+ Calamity.Interactions.Eff: getInteraction :: forall r_a3vaO. MemberWithError InteractionEff r_a3vaO => Sem r_a3vaO Interaction
- Calamity.Interactions.View: endView :: forall ret_a6juM inp_a6juN sendResp_a6juO r_a6jIO. Member (ViewEff ret_a6juM inp_a6juN sendResp_a6juO) r_a6jIO => ret_a6juM -> Sem r_a6jIO ()
+ Calamity.Interactions.View: endView :: forall ret_a6wrR inp_a6wrS sendResp_a6wrT r_a6wFZ. MemberWithError (ViewEff ret_a6wrR inp_a6wrS sendResp_a6wrT) r_a6wFZ => ret_a6wrR -> Sem r_a6wFZ ()
- Calamity.Interactions.View: getSendResponse :: forall ret_a6juU inp_a6juV sendResp_a6juW r_a6jIT. Member (ViewEff ret_a6juU inp_a6juV sendResp_a6juW) r_a6jIT => Sem r_a6jIT sendResp_a6juW
+ Calamity.Interactions.View: getSendResponse :: forall ret_a6wrZ inp_a6ws0 sendResp_a6ws1 r_a6wG4. MemberWithError (ViewEff ret_a6wrZ inp_a6ws0 sendResp_a6ws1) r_a6wG4 => Sem r_a6wG4 sendResp_a6ws1
- Calamity.Interactions.View: replaceView :: forall ret_a6juS inp_a6juQ sendResp_a6juT r_a6jIQ. Member (ViewEff ret_a6juS inp_a6juQ sendResp_a6juT) r_a6jIQ => View inp_a6juQ -> ([Component] -> Sem r_a6jIQ ()) -> Sem r_a6jIQ ()
+ Calamity.Interactions.View: replaceView :: forall ret_a6wrX inp_a6wrV sendResp_a6wrY r_a6wG1. MemberWithError (ViewEff ret_a6wrX inp_a6wrV sendResp_a6wrY) r_a6wG1 => View inp_a6wrV -> ([Component] -> Sem r_a6wG1 ()) -> Sem r_a6wG1 ()
- Calamity.Internal.LocalWriter: llisten :: forall o_atyq r_atzQ a_X0. Member (LocalWriter o_atyq) r_atzQ => Sem r_atzQ a_X0 -> Sem r_atzQ (o_atyq, a_X0)
+ Calamity.Internal.LocalWriter: llisten :: forall o_ausF r_auub a_XusF. MemberWithError (LocalWriter o_ausF) r_auub => Sem r_auub a_XusF -> Sem r_auub (o_ausF, a_XusF)
- Calamity.Internal.LocalWriter: ltell :: forall o_atym r_atzO. Member (LocalWriter o_atym) r_atzO => o_atym -> Sem r_atzO ()
+ Calamity.Internal.LocalWriter: ltell :: forall o_ausB r_auu9. MemberWithError (LocalWriter o_ausB) r_auu9 => o_ausB -> Sem r_auu9 ()
- Calamity.Metrics.Eff: addCounter :: forall r_auWq. Member MetricEff r_auWq => Int -> Counter -> Sem r_auWq Int
+ Calamity.Metrics.Eff: addCounter :: forall r_axhf. MemberWithError MetricEff r_axhf => Int -> Counter -> Sem r_axhf Int
- Calamity.Metrics.Eff: modifyGauge :: forall r_auWt. Member MetricEff r_auWt => (Double -> Double) -> Gauge -> Sem r_auWt Double
+ Calamity.Metrics.Eff: modifyGauge :: forall r_axhi. MemberWithError MetricEff r_axhi => (Double -> Double) -> Gauge -> Sem r_axhi Double
- Calamity.Metrics.Eff: observeHistogram :: forall r_auWw. Member MetricEff r_auWw => Double -> Histogram -> Sem r_auWw HistogramSample
+ Calamity.Metrics.Eff: observeHistogram :: forall r_axhl. MemberWithError MetricEff r_axhl => Double -> Histogram -> Sem r_axhl HistogramSample
- Calamity.Metrics.Eff: registerCounter :: forall r_auWg. Member MetricEff r_auWg => Text -> [(Text, Text)] -> Sem r_auWg Counter
+ Calamity.Metrics.Eff: registerCounter :: forall r_axh5. MemberWithError MetricEff r_axh5 => Text -> [(Text, Text)] -> Sem r_axh5 Counter
- Calamity.Metrics.Eff: registerGauge :: forall r_auWj. Member MetricEff r_auWj => Text -> [(Text, Text)] -> Sem r_auWj Gauge
+ Calamity.Metrics.Eff: registerGauge :: forall r_axh8. MemberWithError MetricEff r_axh8 => Text -> [(Text, Text)] -> Sem r_axh8 Gauge
- Calamity.Metrics.Eff: registerHistogram :: forall r_auWm. Member MetricEff r_auWm => Text -> [(Text, Text)] -> [Double] -> Sem r_auWm Histogram
+ Calamity.Metrics.Eff: registerHistogram :: forall r_axhb. MemberWithError MetricEff r_axhb => Text -> [(Text, Text)] -> [Double] -> Sem r_axhb Histogram
- Calamity.Types.Model.Guild: Guild :: Snowflake Guild -> Text -> Maybe Text -> Maybe Text -> Maybe Bool -> Snowflake User -> Word64 -> Maybe (Snowflake GuildChannel) -> Int -> Bool -> Maybe (Snowflake GuildChannel) -> Int -> Int -> Int -> SnowflakeMap Role -> SnowflakeMap Emoji -> [Text] -> Int -> Maybe (Snowflake User) -> Bool -> Maybe (Snowflake GuildChannel) -> Maybe (Snowflake GuildChannel) -> Maybe UTCTime -> Bool -> Bool -> Int -> [VoiceState] -> SnowflakeMap Member -> SnowflakeMap GuildChannel -> HashMap (Snowflake User) Presence -> Text -> Guild
+ Calamity.Types.Model.Guild: Guild :: Snowflake Guild -> Text -> Maybe GuildIcon -> Maybe GuildSplash -> Maybe GuildSplash -> Maybe GuildBanner -> Maybe Bool -> Snowflake User -> Word64 -> Maybe (Snowflake GuildChannel) -> Int -> Bool -> Maybe (Snowflake GuildChannel) -> Int -> Int -> Int -> SnowflakeMap Role -> SnowflakeMap Emoji -> [Text] -> Int -> Maybe (Snowflake User) -> Bool -> Maybe (Snowflake GuildChannel) -> Maybe (Snowflake GuildChannel) -> Maybe UTCTime -> Bool -> Bool -> Int -> [VoiceState] -> SnowflakeMap Member -> SnowflakeMap GuildChannel -> HashMap (Snowflake User) Presence -> Text -> Guild
- Calamity.Types.Model.Guild: [$sel:icon:Guild] :: Guild -> Maybe Text
+ Calamity.Types.Model.Guild: [$sel:icon:Guild] :: Guild -> Maybe GuildIcon
- Calamity.Types.Model.Guild: [$sel:splash:Guild] :: Guild -> Maybe Text
+ Calamity.Types.Model.Guild: [$sel:splash:Guild] :: Guild -> Maybe GuildSplash
- Calamity.Types.Model.Guild.Guild: Guild :: Snowflake Guild -> Text -> Maybe Text -> Maybe Text -> Maybe Bool -> Snowflake User -> Word64 -> Maybe (Snowflake GuildChannel) -> Int -> Bool -> Maybe (Snowflake GuildChannel) -> Int -> Int -> Int -> SnowflakeMap Role -> SnowflakeMap Emoji -> [Text] -> Int -> Maybe (Snowflake User) -> Bool -> Maybe (Snowflake GuildChannel) -> Maybe (Snowflake GuildChannel) -> Maybe UTCTime -> Bool -> Bool -> Int -> [VoiceState] -> SnowflakeMap Member -> SnowflakeMap GuildChannel -> HashMap (Snowflake User) Presence -> Text -> Guild
+ Calamity.Types.Model.Guild.Guild: Guild :: Snowflake Guild -> Text -> Maybe GuildIcon -> Maybe GuildSplash -> Maybe GuildSplash -> Maybe GuildBanner -> Maybe Bool -> Snowflake User -> Word64 -> Maybe (Snowflake GuildChannel) -> Int -> Bool -> Maybe (Snowflake GuildChannel) -> Int -> Int -> Int -> SnowflakeMap Role -> SnowflakeMap Emoji -> [Text] -> Int -> Maybe (Snowflake User) -> Bool -> Maybe (Snowflake GuildChannel) -> Maybe (Snowflake GuildChannel) -> Maybe UTCTime -> Bool -> Bool -> Int -> [VoiceState] -> SnowflakeMap Member -> SnowflakeMap GuildChannel -> HashMap (Snowflake User) Presence -> Text -> Guild
- Calamity.Types.Model.Guild.Guild: UpdatedGuild :: Snowflake Guild -> Text -> Maybe Text -> Maybe Text -> Maybe Bool -> Snowflake User -> Maybe Word64 -> Maybe (Snowflake GuildChannel) -> Int -> Maybe Bool -> Maybe (Snowflake GuildChannel) -> Int -> Int -> Int -> SnowflakeMap Role -> SnowflakeMap Emoji -> [Text] -> Int -> Maybe (Snowflake User) -> Maybe Bool -> Maybe (Snowflake GuildChannel) -> Maybe (Snowflake GuildChannel) -> Text -> UpdatedGuild
+ Calamity.Types.Model.Guild.Guild: UpdatedGuild :: Snowflake Guild -> Text -> Maybe GuildIcon -> Maybe GuildSplash -> Maybe GuildSplash -> Maybe GuildBanner -> Maybe Bool -> Snowflake User -> Maybe Word64 -> Maybe (Snowflake GuildChannel) -> Int -> Maybe Bool -> Maybe (Snowflake GuildChannel) -> Int -> Int -> Int -> SnowflakeMap Role -> SnowflakeMap Emoji -> [Text] -> Int -> Maybe (Snowflake User) -> Maybe Bool -> Maybe (Snowflake GuildChannel) -> Maybe (Snowflake GuildChannel) -> Text -> UpdatedGuild
- Calamity.Types.Model.Guild.Guild: [$sel:icon:Guild] :: Guild -> Maybe Text
+ Calamity.Types.Model.Guild.Guild: [$sel:icon:Guild] :: Guild -> Maybe GuildIcon
- Calamity.Types.Model.Guild.Guild: [$sel:icon:UpdatedGuild] :: UpdatedGuild -> Maybe Text
+ Calamity.Types.Model.Guild.Guild: [$sel:icon:UpdatedGuild] :: UpdatedGuild -> Maybe GuildIcon
- Calamity.Types.Model.Guild.Guild: [$sel:splash:Guild] :: Guild -> Maybe Text
+ Calamity.Types.Model.Guild.Guild: [$sel:splash:Guild] :: Guild -> Maybe GuildSplash
- Calamity.Types.Model.Guild.Guild: [$sel:splash:UpdatedGuild] :: UpdatedGuild -> Maybe Text
+ Calamity.Types.Model.Guild.Guild: [$sel:splash:UpdatedGuild] :: UpdatedGuild -> Maybe GuildSplash
- Calamity.Types.Model.Guild.Member: Member :: Snowflake User -> Text -> Text -> Maybe Bool -> Maybe Text -> Maybe Bool -> Maybe Bool -> Maybe Text -> Maybe Word64 -> Maybe Word64 -> Maybe Text -> Vector (Snowflake Role) -> UTCTime -> Bool -> Bool -> Member
+ Calamity.Types.Model.Guild.Member: Member :: Snowflake User -> Text -> Text -> Maybe Bool -> Avatar -> Maybe Text -> Maybe Bool -> Maybe UserBanner -> Maybe (Colour Double) -> Maybe Text -> Maybe Bool -> Maybe Text -> Maybe Word64 -> Maybe Word64 -> Maybe Text -> Vector (Snowflake Role) -> UTCTime -> Bool -> Bool -> Member
- Calamity.Types.Model.Guild.Member: [$sel:avatar:Member] :: Member -> Maybe Text
+ Calamity.Types.Model.Guild.Member: [$sel:avatar:Member] :: Member -> Avatar
- Calamity.Types.Model.Guild.Role: Role :: Snowflake Role -> Text -> Colour Double -> Bool -> Int -> Permissions -> Bool -> Bool -> Role
+ Calamity.Types.Model.Guild.Role: Role :: Snowflake Role -> Text -> Colour Double -> Bool -> Maybe RoleIcon -> Maybe RawEmoji -> Int -> Permissions -> Bool -> Bool -> Role
- Calamity.Types.Model.User: User :: Snowflake User -> Text -> Text -> Maybe Bool -> Maybe Text -> Maybe Bool -> Maybe Bool -> Maybe Text -> Maybe Word64 -> Maybe Word64 -> User
+ Calamity.Types.Model.User: User :: Snowflake User -> Text -> Text -> Maybe Bool -> Avatar -> Maybe Bool -> Maybe UserBanner -> Maybe (Colour Double) -> Maybe Text -> Maybe Bool -> Maybe Text -> Maybe Word64 -> Maybe Word64 -> User
- Calamity.Types.Model.User: [$sel:avatar:User] :: User -> Maybe Text
+ Calamity.Types.Model.User: [$sel:avatar:User] :: User -> Avatar
- Calamity.Types.TokenEff: getBotToken :: forall r_a4D2c. Member TokenEff r_a4D2c => Sem r_a4D2c Token
+ Calamity.Types.TokenEff: getBotToken :: forall r_a1zEh. MemberWithError TokenEff r_a1zEh => Sem r_a1zEh Token
Files
- Calamity/Client/Client.hs +6/−6
- Calamity/Client/ShardManager.hs +2/−1
- Calamity/Gateway/Shard.hs +9/−9
- Calamity/HTTP/Channel.hs +1/−1
- Calamity/HTTP/Interaction.hs +5/−5
- Calamity/HTTP/Internal/Ratelimit.hs +6/−6
- Calamity/HTTP/Webhook.hs +1/−1
- Calamity/Internal/Updateable.hs +3/−1
- Calamity/Types.hs +35/−25
- Calamity/Types/CDNAsset.hs +30/−0
- Calamity/Types/Model.hs +4/−0
- Calamity/Types/Model/Avatar.hs +47/−0
- Calamity/Types/Model/Guild/Emoji.hs +8/−0
- Calamity/Types/Model/Guild/Emoji.hs-boot +13/−0
- Calamity/Types/Model/Guild/Guild.hs +84/−16
- Calamity/Types/Model/Guild/Member.hs +23/−4
- Calamity/Types/Model/Guild/Role.hs +29/−4
- Calamity/Types/Model/User.hs +39/−5
- Calamity/Types/Model/User.hs-boot +8/−0
- Calamity/Types/Snowflake.hs +2/−0
- Calamity/Utils/CDNUrl.hs +22/−0
- ChangeLog.md +26/−0
- calamity.cabal +5/−2
Calamity/Client/Client.hs view
@@ -406,11 +406,11 @@ r <- P.errorToIOFinal . P.fromExceptionSem @SomeException $ P.raise m case r of Right _ -> pure ()- Left e -> debug [fmt|got exception: {e:s}|]+ Left e -> debug . T.pack $ "got exception: " <> show e handleEvent :: BotC r => Int -> DispatchData -> P.Sem r () handleEvent shardID data' = do- debug [fmt|"handling an event: {ctorName data'}"|]+ debug . T.pack $ "handling an event: " <> ctorName data' eventHandlers <- P.atomicGet actions <- P.runFail $ do evtCounter <- registerCounter "events_received" [("type", T.pack $ ctorName data'), ("shard", showt shardID)]@@ -427,7 +427,7 @@ (time, _) <- timeA . catchAllLogging $ P.embed action void $ observeHistogram time eventHandleHisto -- pattern match failures are usually stuff like events for uncached guilds, etc- Left err -> debug [fmt|Failed handling actions for event: {err:s}|]+ Left err -> debug . T.pack $ "Failed handling actions for event: " <> show err handleEvent' :: BotC r =>@@ -711,10 +711,10 @@ updateGuild guildID (#roles %~ SM.insert role) updateCache (GuildRoleDelete GuildRoleDeleteData {guildID, roleID}) = updateGuild guildID (#roles %~ sans roleID)-updateCache (MessageCreate !msg !_ !_) =+updateCache (MessageCreate !msg !user !_) = do setMessage msg--- I think it's for the best not to cache things here, instead the end user--- can just cache manually which users and members they want+ whenJust user $ \u ->+ setUser u updateCache (MessageUpdate msg !_ !_) = updateMessage (getID msg) (update msg) updateCache (MessageDelete MessageDeleteData {id}) = delMessage id
Calamity/Client/ShardManager.hs view
@@ -8,6 +8,7 @@ import Control.Concurrent.MVar import Control.Concurrent.STM import Control.Monad+import qualified Data.Text as T import Data.Traversable import Optics import Polysemy (Sem)@@ -38,7 +39,7 @@ let host = gateway ^. #url P.embed $ putMVar numShardsVar numShards' - info [fmt|Number of shards: {numShards'}|]+ info . T.pack $ "Number of shards: " <> show numShards' shards <- for [0 .. numShards' - 1] $ \id -> newShard host id numShards' token initialStatus intents inc
Calamity/Gateway/Shard.hs view
@@ -123,7 +123,7 @@ -- We have to do this all ourself I think? -- TODO: see if this isn't needed- let logExc e = debug [fmt|runWebsocket raised with {e:s}|]+ let logExc e = debug $ "runWebsocket raised with " <> (T.pack . show $ e) logExc' <- bindSemToIO logExc let handler e = do void $ logExc' e@@ -186,7 +186,7 @@ case wsConn' of Just wsConn -> do let encodedData = A.encode data'- debug [fmt|sending {data':s} encoded to {encodedData:s} to gateway|]+ debug . T.pack $ "sending " <> show data' <> " encoded to " <> show encodedData <> " to gateway" P.embed . sendTextData wsConn $ encodedData Nothing -> debug "tried to send to closed WS" @@ -237,7 +237,7 @@ case msg of Left (c, reason) -> do- whenJust reason (\r -> error [fmt|Shard closed with reason: {r}|])+ whenJust reason (\r -> error . T.pack $ "Shard closed with reason: " <> show r) P.embed . atomically $ writeTBMQueue outqueue (Control c) Right msg' -> do -- debug [fmt|Got msg: {msg'}|]@@ -246,7 +246,7 @@ Right a -> P.embed . atomically $ tryWriteTBMQueue' outqueue (Discord a) Left e -> do- error [fmt|Failed to decode {e}: {msg'}|]+ error . T.pack $ "Failed to decode " <> e <> ": "<> show msg' pure True when r inner outerloop :: ShardC r => Sem r ()@@ -254,7 +254,7 @@ shard :: Shard <- P.atomicGets (^. #shardS) let host = shard ^. #gateway let host' = fromMaybe host $ T.stripPrefix "wss://" host- info [fmt|starting up shard {shardID shard} of {shardCount shard}|]+ info . T.pack $ "starting up shard " <> show (shardID shard) <> " of " <> show (shardCount shard) innerLoopVal <- runWebsocket host' "/?v=9&encoding=json" innerloop @@ -284,7 +284,7 @@ case (seqNum', sessionID') of (Just n, Just s) -> do- debug [fmt|Resuming shard (sessionID: {s}, seq: {n})|]+ debug $ "Resuming shard (sessionID: " <> s <> ", seq: " <> T.pack (show n) sendToWs ( Resume ResumeData@@ -362,14 +362,14 @@ P.embed $ threadDelay (15 * 1000 * 1000) P.throw ShardFlowRestart Hello interval -> do- info [fmt|Received hello, beginning to heartbeat at an interval of {interval}ms|]+ info . T.pack $ "Received hello, beginning to heartbeat at an interval of " <> show interval <> "ms" startHeartBeatLoop interval HeartBeatAck -> do debug "Received heartbeat ack" P.atomicModify' (#hbResponse .~ True) handleMsg (Control msg) = case msg of SendPresence data' -> do- debug [fmt|Sending presence: ({data':s})|]+ debug . T.pack $ "Sending presence: (" <> show data' <> ")" sendToWs $ StatusUpdate data' RestartShard -> P.throw ShardFlowRestart ShutDownShard -> P.throw ShardFlowShutDown@@ -395,7 +395,7 @@ sendHeartBeat :: ShardC r => Sem r () sendHeartBeat = do sn <- P.atomicGets (^. #seqNum)- debug [fmt|Sending heartbeat (seq: {sn:s})|]+ debug . T.pack $ "Sending heartbeat (seq: " <> show sn <> ")" sendToWs $ HeartBeat sn P.atomicModify' (#hbResponse .~ False)
Calamity/HTTP/Channel.hs view
@@ -418,7 +418,7 @@ & buildRoute action (CreateMessage _ cm) = \u o -> do let filePart CreateMessageAttachment {filename, content} n =- (partLBS @IO [fmt|files[{n}]|] content)+ (partLBS @IO (T.pack $ "files[" <> show n <> "]") content) { partFilename = Just (T.unpack filename) , partContentType = Just (defaultMimeLookup filename) }
Calamity/HTTP/Interaction.hs view
@@ -324,7 +324,7 @@ in postWith' (ReqBodyJson jsonBody) action (CreateResponseMessage _ _ cm) = \u o -> do let filePart CreateMessageAttachment {filename, content} n =- (partLBS @IO [fmt|files[{n}]|] content)+ (partLBS @IO (T.pack $ "files[" <> show n <> "]") content) { partFilename = Just (T.unpack filename) , partContentType = Just (defaultMimeLookup filename) }@@ -354,7 +354,7 @@ postWith' body u o action (CreateResponseUpdate _ _ cm) = \u o -> do let filePart CreateMessageAttachment {filename, content} n =- (partLBS @IO [fmt|files[{n}]|] content)+ (partLBS @IO (T.pack $ "files[" <> show n <> "]") content) { partFilename = Just (T.unpack filename) , partContentType = Just (defaultMimeLookup filename) }@@ -399,7 +399,7 @@ action (GetOriginalInteractionResponse _ _) = getWith action (EditOriginalInteractionResponse _ _ cm) = \u o -> do let filePart CreateMessageAttachment {filename, content} n =- (partLBS @IO [fmt|files[{n}]|] content)+ (partLBS @IO (T.pack $ "files[" <> show n <> "]") content) { partFilename = Just (T.unpack filename) , partContentType = Just (defaultMimeLookup filename) }@@ -430,7 +430,7 @@ action (DeleteOriginalInteractionResponse _ _) = deleteWith action (CreateFollowupMessage _ _ cm) = \u o -> do let filePart CreateMessageAttachment {filename, content} n =- (partLBS @IO [fmt|files[{n}]|] content)+ (partLBS @IO (T.pack $ "files[" <> show n <> "]") content) { partFilename = Just (T.unpack filename) , partContentType = Just (defaultMimeLookup filename) }@@ -456,7 +456,7 @@ action GetFollowupMessage {} = getWith action (EditFollowupMessage _ _ _ cm) = \u o -> do let filePart CreateMessageAttachment {filename, content} n =- (partLBS @IO [fmt|files[{n}]|] content)+ (partLBS @IO (T.pack $ "files[" <> show n <> "]") content) { partFilename = Just (T.unpack filename) , partContentType = Just (defaultMimeLookup filename) }
Calamity/HTTP/Internal/Ratelimit.hs view
@@ -210,7 +210,7 @@ if | statusIsSuccessful status -> do let resp = responseBody r'- debug [fmt|Got good response from discord: {status:s}|]+ debug $ "Got good response from discord: " <> (T.pack . show $ status) now <- P.embed getCurrentTime let rlHeaders = buildBucketState now r' pure $ Good resp rlHeaders@@ -224,13 +224,13 @@ pure $ ServerError (statusCode status) | statusIsClientError status -> do let err = responseBody r'- error [fmt|Something went wrong: {err:s}, response: {r':s}|]+ error . T.pack $ ("Something went wrong: " <> show err <> ", response: " <> show r') pure $ ClientError (statusCode status) err | otherwise -> do- debug [fmt|Got server error from discord: {statusCode status}|]+ debug . T.pack $ "Got server error from discord: " <> (show . statusCode $ status) pure $ ServerError (statusCode status) Left e -> do- error [fmt|Something went wrong with the http client: {e}|]+ error . T.pack $ "Something went wrong with the http client: " <> e pure . InternalResponseError $ T.pack e -- | Parse a ratelimit header returning when it unlocks@@ -286,7 +286,7 @@ res <- action case res of Retry r | numRetries > maxRetries -> do- debug [fmt|Request failed after {maxRetries} retries|]+ debug . T.pack $ "Request failed after " <> show maxRetries <> " retries" pure $ Left r Retry _ -> retryInner (numRetries + 1)@@ -344,7 +344,7 @@ Nothing -> pure () pure $ RGood v Ratelimited unlockWhen False (Just (bs, bk)) -> do- debug [fmt|429 ratelimited on route, retrying at {unlockWhen:s}|]+ debug . T.pack $ "429 ratelimited on route, retrying at " <> show unlockWhen P.embed . atomically $ do case rl of
Calamity/HTTP/Webhook.hs view
@@ -183,7 +183,7 @@ action (DeleteWebhookToken _ _) = deleteWith action (ExecuteWebhook _ _ wh) = \u o -> do let filePart CreateMessageAttachment {filename, content} n =- (partLBS @IO [fmt|files[{n}]|] content)+ (partLBS @IO (T.pack $ "files[" <> show n <> "]") content) { partFilename = Just (T.unpack filename) , partContentType = Just (defaultMimeLookup filename) }
Calamity/Internal/Updateable.hs view
@@ -110,6 +110,8 @@ & setF @"name" n & setF @"icon" n & setF @"splash" n+ & setF @"discoverySplash" n+ & setF @"banner" n & setF @"owner" n & setF @"ownerID" n & mergeF @"permissions" n@@ -135,7 +137,7 @@ & setF @"username" n & setF @"discriminator" n & mergeF' @"bot" n- & mergeF' @"avatar" n+ & setF @"avatar" n & mergeF' @"mfaEnabled" n & mergeF' @"verified" n & mergeF' @"email" n
Calamity/Types.hs view
@@ -1,28 +1,38 @@ -- | All user facing types-module Calamity.Types- ( module Calamity.Types.Model- , module Calamity.Types.Partial- , module Calamity.Types.Snowflake- , module Calamity.Types.Token- , module Calamity.Types.Tellable- , module Calamity.Types.Upgradeable- -- * Types- -- $typesDocs- ) where+module Calamity.Types (+ module Calamity.Types.Model,+ module Calamity.Types.Partial,+ module Calamity.Types.Snowflake,+ module Calamity.Types.Token,+ module Calamity.Types.Tellable,+ module Calamity.Types.Upgradeable,+ module Calamity.Types.CDNAsset,+ module Calamity.Types.TokenEff,+ module Calamity.Types.LogEff, -import Calamity.Types.Model-import Calamity.Types.Partial-import Calamity.Types.Snowflake-import Calamity.Types.Token-import Calamity.Types.Tellable-import Calamity.Types.Upgradeable+ -- * Types+ -- $typesDocs+) where --- $typesDocs------ This module collects all discord models, and other useful types together.------ The 'Tellable' class allows you to construct and send--- messages to things to you can send messages to in a neat way.------ The 'Upgradeable' class allows you to upgrade a snowflake to the full value--- it refers to.+import Calamity.Types.CDNAsset+import Calamity.Types.LogEff+import Calamity.Types.Model+import Calamity.Types.Partial+import Calamity.Types.Snowflake+import Calamity.Types.Tellable+import Calamity.Types.Token+import Calamity.Types.TokenEff+import Calamity.Types.Upgradeable++{- $typesDocs++ This module collects all discord models, and other useful types together.++ The 'Tellable' class allows you to construct and send+ messages to things to you can send messages to in a neat way.++ The 'Upgradeable' class allows you to upgrade a snowflake to the full value+ it refers to.++ The 'CDNAsset' class allows you to fetch assets from the discord CDN.+-}
+ Calamity/Types/CDNAsset.hs view
@@ -0,0 +1,30 @@+-- | Things that can be fetched from the discord CDN+module Calamity.Types.CDNAsset (+ CDNAsset (..),+ fetchAsset,+ fetchAsset',+) where++import qualified Control.Exception.Safe as Ex+import Data.ByteString.Lazy (LazyByteString)+import qualified Network.HTTP.Req as Req+import qualified Polysemy as P++-- | Retrieve the asset from the CDN, like 'fetchAsset' but gives you more control+fetchAsset' :: (CDNAsset a, Req.MonadHttp m) => a -> m LazyByteString+fetchAsset' a = Req.responseBody <$> Req.req Req.GET (assetURL a) Req.NoReqBody Req.lbsResponse mempty++-- | Retrieve the asset from the CDN+fetchAsset :: (CDNAsset a, P.Member (P.Embed IO) r) => a -> P.Sem r (Either Req.HttpException LazyByteString)+fetchAsset a = P.embed $ Ex.catch (Right <$> r) (\(e :: Req.HttpException) -> pure $ Left e)+ where+ r = Req.runReq reqConfig $ fetchAsset' a++reqConfig :: Req.HttpConfig+reqConfig =+ Req.defaultHttpConfig+ { Req.httpConfigCheckResponse = \_ _ _ -> Nothing+ }++class CDNAsset a where+ assetURL :: a -> Req.Url 'Req.Https
Calamity/Types/Model.hs view
@@ -5,10 +5,14 @@ module Calamity.Types.Model.Presence, module Calamity.Types.Model.User, module Calamity.Types.Model.Voice,+ module Calamity.Types.Model.Avatar,+ module Calamity.Types.Model.Interaction, ) where +import Calamity.Types.Model.Avatar import Calamity.Types.Model.Channel import Calamity.Types.Model.Guild+import Calamity.Types.Model.Interaction import Calamity.Types.Model.Presence import Calamity.Types.Model.User import Calamity.Types.Model.Voice
+ Calamity/Types/Model/Avatar.hs view
@@ -0,0 +1,47 @@+{-# LANGUAGE TemplateHaskell #-}++module Calamity.Types.Model.Avatar (+ Avatar (..),+ MemberAvatar (..),+) where++import Calamity.Types.CDNAsset (CDNAsset (..))+import {-# SOURCE #-} Calamity.Types.Model.Guild.Guild+import {-# SOURCE #-} Calamity.Types.Model.User+import Calamity.Types.Snowflake (Snowflake, fromSnowflake)+import Calamity.Utils.CDNUrl (assetHashFile, cdnURL)+import qualified Data.Text as T+import Network.HTTP.Req ((/:), (/~))+import Optics (makeFieldLabelsNoPrefix)+import TextShow (showt)+import TextShow.TH (deriveTextShow)++data Avatar = Avatar+ { hash :: Maybe T.Text+ , userID :: Snowflake User+ , discrim :: Int+ }+ deriving (Show, Eq)++instance CDNAsset Avatar where+ assetURL Avatar {hash = Just h, userID} =+ cdnURL /: "avatars" /~ fromSnowflake userID /: assetHashFile h+ assetURL Avatar {discrim} =+ cdnURL /: "embed" /: "avatars" /: (showt (discrim `mod` 5) <> ".png")++-- | A member's custom guild avatar+data MemberAvatar = MemberAvatar+ { hash :: T.Text+ , guildID :: Snowflake Guild+ , userID :: Snowflake User+ }+ deriving (Show, Eq)++instance CDNAsset MemberAvatar where+ assetURL MemberAvatar {hash, guildID, userID} =+ cdnURL /: "guilds" /~ guildID /: "users" /~ userID /: "avatars" /: assetHashFile hash++$(deriveTextShow ''Avatar)+$(makeFieldLabelsNoPrefix ''Avatar)+$(deriveTextShow ''MemberAvatar)+$(makeFieldLabelsNoPrefix ''MemberAvatar)
Calamity/Types/Model/Guild/Emoji.hs view
@@ -14,14 +14,18 @@ CalamityToJSON' (..), (.=), )+import Calamity.Types.CDNAsset (CDNAsset (..)) import Calamity.Types.Model.Guild.Role import Calamity.Types.Model.User import Calamity.Types.Snowflake+import Calamity.Utils.CDNUrl (cdnURL) import Data.Aeson ((.!=), (.:), (.:?)) import qualified Data.Aeson as Aeson import qualified Data.Text as T import Data.Vector.Unboxing (Vector)+import Network.HTTP.Req ((/:)) import Optics.TH+import TextShow (showt) import qualified TextShow data Emoji = Emoji@@ -47,6 +51,10 @@ <*> v .:? "require_colons" .!= False <*> v .:? "managed" .!= False <*> v .:? "animated" .!= False++instance CDNAsset Emoji where+ assetURL Emoji {id, animated} =+ cdnURL /: "emojis" /: (showt id <> if animated then ".gif" else ".png") emojiAsRawEmoji :: Emoji -> RawEmoji emojiAsRawEmoji Emoji {id, name, animated} = CustomEmoji $ PartialEmoji id name animated
+ Calamity/Types/Model/Guild/Emoji.hs-boot view
@@ -0,0 +1,13 @@+-- | Discord Emojis+module Calamity.Types.Model.Guild.Emoji+ ( RawEmoji+ ) where++import Data.Aeson++data RawEmoji++instance Show RawEmoji+instance Eq RawEmoji++instance FromJSON RawEmoji
Calamity/Types/Model/Guild/Guild.hs view
@@ -3,6 +3,10 @@ -- | Discord Guilds module Calamity.Types.Model.Guild.Guild ( Guild (..),+ GuildIcon (..),+ GuildSplash (..),+ GuildDiscoverySplash (..),+ GuildBanner (..), Partial (PartialGuild), UpdatedGuild (..), ) where@@ -10,6 +14,7 @@ import Calamity.Internal.SnowflakeMap (SnowflakeMap) import qualified Calamity.Internal.SnowflakeMap as SM import Calamity.Internal.Utils (CalamityToJSON (..), CalamityToJSON' (..), (.=))+import Calamity.Types.CDNAsset (CDNAsset (..)) import Calamity.Types.Model.Channel import Calamity.Types.Model.Guild.Emoji import Calamity.Types.Model.Guild.Member@@ -18,24 +23,68 @@ import Calamity.Types.Model.User import Calamity.Types.Model.Voice.VoiceState import Calamity.Types.Snowflake+import Calamity.Utils.CDNUrl (assetHashFile, cdnURL) import Data.Aeson ((.!=), (.:), (.:?)) import qualified Data.Aeson as Aeson import qualified Data.Aeson.Types as Aeson import Data.HashMap.Strict (HashMap) import qualified Data.HashMap.Strict as LH import Data.Maybe-import Data.Text (Text)+import qualified Data.Text as T import Data.Time import Data.Word+import Network.HTTP.Req ((/:), (/~)) import Optics import qualified TextShow import TextShow.TH (deriveTextShow) +data GuildIcon = GuildIcon+ { guildID :: Snowflake Guild+ , hash :: T.Text+ }+ deriving (Show, Eq)++instance CDNAsset GuildIcon where+ assetURL GuildIcon {hash, guildID} =+ cdnURL /: "icons" /~ guildID /: assetHashFile hash++data GuildSplash = GuildSplash+ { guildID :: Snowflake Guild+ , hash :: T.Text+ }+ deriving (Show, Eq)++instance CDNAsset GuildSplash where+ assetURL GuildSplash {hash, guildID} =+ cdnURL /: "splashes" /~ guildID /: assetHashFile hash++data GuildDiscoverySplash = GuildDiscoverySplash+ { guildID :: Snowflake Guild+ , hash :: T.Text+ }+ deriving (Show, Eq)++instance CDNAsset GuildDiscoverySplash where+ assetURL GuildDiscoverySplash {hash, guildID} =+ cdnURL /: "discovery-splashes" /~ guildID /: assetHashFile hash++data GuildBanner = GuildBanner+ { guildID :: Snowflake Guild+ , hash :: T.Text+ }+ deriving (Show, Eq)++instance CDNAsset GuildBanner where+ assetURL GuildBanner {hash, guildID} =+ cdnURL /: "banners" /~ guildID /: assetHashFile hash+ data Guild = Guild { id :: Snowflake Guild- , name :: Text- , icon :: Maybe Text- , splash :: Maybe Text+ , name :: T.Text+ , icon :: Maybe GuildIcon+ , splash :: Maybe GuildSplash+ , discoverySplash :: Maybe GuildSplash+ , banner :: Maybe GuildBanner , owner :: Maybe Bool , ownerID :: Snowflake User , permissions :: Word64@@ -48,7 +97,7 @@ , explicitContentFilter :: Int , roles :: SnowflakeMap Role , emojis :: SnowflakeMap Emoji- , features :: [Text]+ , features :: [T.Text] , mfaLevel :: Int , applicationID :: Maybe (Snowflake User) , widgetEnabled :: Bool@@ -63,7 +112,7 @@ , members :: SnowflakeMap Member , channels :: SnowflakeMap GuildChannel , presences :: HashMap (Snowflake User) Presence- , preferredLocale :: Text+ , preferredLocale :: T.Text } deriving (Eq, Show) deriving (TextShow.TextShow) via TextShow.FromStringShow Guild@@ -93,10 +142,17 @@ ) $ presences' + icon <- (GuildIcon id <$>) <$> v .:? "icon"+ splash <- (GuildSplash id <$>) <$> v .:? "splash"+ discoverySplash <- (GuildSplash id <$>) <$> v .:? "discovery_splash"+ banner <- (GuildBanner id <$>) <$> v .:? "banner"+ Guild id <$> v .: "name"- <*> v .: "icon"- <*> v .:? "splash"+ <*> pure icon+ <*> pure splash+ <*> pure discoverySplash+ <*> pure banner <*> v .:? "owner" <*> v .: "owner_id" <*> v .:? "permissions" .!= 0@@ -127,7 +183,7 @@ data instance Partial Guild = PartialGuild { id :: Snowflake Guild- , name :: Text+ , name :: T.Text } deriving (Eq, Show) deriving (HasID Guild) via HasIDField "id" (Partial Guild)@@ -147,9 +203,11 @@ data UpdatedGuild = UpdatedGuild { id :: Snowflake Guild- , name :: Text- , icon :: Maybe Text- , splash :: Maybe Text+ , name :: T.Text+ , icon :: Maybe GuildIcon+ , splash :: Maybe GuildSplash+ , discoverySplash :: Maybe GuildSplash+ , banner :: Maybe GuildBanner , owner :: Maybe Bool , ownerID :: Snowflake User , permissions :: Maybe Word64@@ -162,13 +220,13 @@ , explicitContentFilter :: Int , roles :: SnowflakeMap Role , emojis :: SnowflakeMap Emoji- , features :: [Text]+ , features :: [T.Text] , mfaLevel :: Int , applicationID :: Maybe (Snowflake User) , widgetEnabled :: Maybe Bool , widgetChannelID :: Maybe (Snowflake GuildChannel) , systemChannelID :: Maybe (Snowflake GuildChannel)- , preferredLocale :: Text+ , preferredLocale :: T.Text } deriving (Eq, Show) deriving (TextShow.TextShow) via TextShow.FromStringShow UpdatedGuild@@ -176,11 +234,19 @@ instance Aeson.FromJSON UpdatedGuild where parseJSON = Aeson.withObject "Guild" $ \v -> do+ id <- v .: "id"+ icon <- (GuildIcon id <$>) <$> v .:? "icon"+ splash <- (GuildSplash id <$>) <$> v .:? "splash"+ discoverySplash <- (GuildSplash id <$>) <$> v .:? "discovery_splash"+ banner <- (GuildBanner id <$>) <$> v .:? "banner"+ UpdatedGuild <$> v .: "id" <*> v .: "name"- <*> v .:? "icon"- <*> v .:? "splash"+ <*> pure icon+ <*> pure splash+ <*> pure discoverySplash+ <*> pure banner <*> v .:? "owner" <*> v .: "owner_id" <*> v .:? "permissions"@@ -201,8 +267,10 @@ <*> v .:? "system_channel_id" <*> v .: "preferred_locale" +$(deriveTextShow ''GuildIcon) $(deriveTextShow 'PartialGuild) $(makeFieldLabelsNoPrefix ''Guild)+$(makeFieldLabelsNoPrefix ''GuildIcon) $(makeFieldLabelsNoPrefix 'PartialGuild) $(makeFieldLabelsNoPrefix ''UpdatedGuild)
Calamity/Types/Model/Guild/Member.hs view
@@ -3,13 +3,17 @@ -- | Guild Members module Calamity.Types.Model.Guild.Member (Member (..)) where +import Calamity.Internal.IntColour import Calamity.Internal.Utils (AesonVector (unAesonVector))+import Calamity.Types.Model.Avatar (Avatar (..)) import Calamity.Types.Model.Guild.Role import Calamity.Types.Model.User import Calamity.Types.Snowflake-import Data.Aeson ((.:), (.:?), (.!=))+import Data.Aeson ((.!=), (.:), (.:?)) import qualified Data.Aeson as Aeson+import Data.Colour (Colour) import Data.Text (Text)+import Data.Text.Read (decimal) import Data.Time import Data.Vector.Unboxing (Vector) import qualified Data.Vector.Unboxing as V@@ -22,8 +26,12 @@ , username :: Text , discriminator :: Text , bot :: Maybe Bool- , avatar :: Maybe Text+ , avatar :: Avatar+ , memberAvatar :: Maybe Text , mfaEnabled :: Maybe Bool+ , banner :: Maybe UserBanner+ , accentColour :: Maybe (Colour Double)+ , locale :: Maybe Text , verified :: Maybe Bool , email :: Maybe Text , flags :: Maybe Word64@@ -42,14 +50,25 @@ instance Aeson.FromJSON Member where parseJSON = Aeson.withObject "Member" $ \v -> do u :: Aeson.Object <- v .: "user"-+ uid <- u .: "id"+ avatarHash <- u .:? "avatar"+ discrim <- u .: "discriminator"+ discrim' <- case decimal discrim of+ Right (n, _) -> pure n+ Left e -> fail e+ let avatar = Avatar avatarHash uid discrim'+ banner <- (UserBanner uid <$>) <$> v .:? "banner" Member- <$> u .: "id"+ <$> pure uid <*> u .: "username" <*> u .: "discriminator" <*> v .:? "bot"+ <*> pure avatar <*> v .:? "avatar" <*> v .:? "mfa_enabled"+ <*> pure banner+ <*> (fmap fromIntColour <$> v .:? "accent_color")+ <*> v .:? "locale" <*> v .:? "verified" <*> v .:? "email" <*> v .:? "flags"
Calamity/Types/Model/Guild/Role.hs view
@@ -1,24 +1,44 @@ {-# LANGUAGE TemplateHaskell #-} -- | Guild roles-module Calamity.Types.Model.Guild.Role (Role (..)) where+module Calamity.Types.Model.Guild.Role (+ Role (..),+ RoleIcon (..),+) where import Calamity.Internal.IntColour import Calamity.Internal.Utils+import Calamity.Types.CDNAsset (CDNAsset (..))+import {-# SOURCE #-} Calamity.Types.Model.Guild.Emoji import Calamity.Types.Model.Guild.Permissions import Calamity.Types.Snowflake-import Data.Aeson ((.:))+import Calamity.Utils.CDNUrl (assetHashFile, cdnURL)+import Data.Aeson ((.:), (.:?)) import qualified Data.Aeson as Aeson import Data.Colour import Data.Text (Text)+import qualified Data.Text as T+import Network.HTTP.Req ((/:), (/~)) import Optics.TH import qualified TextShow +data RoleIcon = RoleIcon+ { roleID :: Snowflake Role+ , hash :: T.Text+ }+ deriving (Show, Eq)++instance CDNAsset RoleIcon where+ assetURL RoleIcon {hash, roleID} =+ cdnURL /: "icons" /~ roleID /: assetHashFile hash+ data Role = Role { id :: Snowflake Role , name :: Text , color :: Colour Double , hoist :: Bool+ , icon :: Maybe RoleIcon+ , emoji :: Maybe RawEmoji , position :: Int , permissions :: Permissions , managed :: Bool@@ -41,12 +61,17 @@ ] instance Aeson.FromJSON Role where- parseJSON = Aeson.withObject "Role" $ \v ->+ parseJSON = Aeson.withObject "Role" $ \v -> do+ id <- v .: "id"+ icon <- (RoleIcon id <$>) <$> v .: "icon"+ Role- <$> v .: "id"+ <$> pure id <*> v .: "name" <*> (fromIntColour <$> v .: "color") <*> v .: "hoist"+ <*> pure icon+ <*> v .:? "unicode_emoji" <*> v .: "position" <*> v .: "permissions" <*> v .: "managed"
Calamity/Types/Model/User.hs view
@@ -3,45 +3,80 @@ -- | A User module Calamity.Types.Model.User ( User (..),+ UserBanner (..), Partial (PartialUser), StatusType (..), ) where +import Calamity.Internal.IntColour+import Calamity.Types.CDNAsset (CDNAsset (..))+import Calamity.Types.Model.Avatar import {-# SOURCE #-} Calamity.Types.Model.Guild.Member import Calamity.Types.Partial import Calamity.Types.Snowflake+import Calamity.Utils.CDNUrl (assetHashFile, cdnURL) import Data.Aeson ((.:), (.:?)) import qualified Data.Aeson as Aeson+import Data.Colour (Colour) import Data.Text (Text)+import qualified Data.Text as T+import Data.Text.Read (decimal) import Data.Word+import Network.HTTP.Req ((/:), (/~)) import Optics.TH+import qualified TextShow import TextShow.TH +data UserBanner = UserBanner+ { userID :: Snowflake User+ , hash :: T.Text+ }+ deriving (Show, Eq)++instance CDNAsset UserBanner where+ assetURL UserBanner {hash, userID} =+ cdnURL /: "banners" /~ userID /: assetHashFile hash+ data User = User { id :: Snowflake User , username :: Text , discriminator :: Text , bot :: Maybe Bool- , avatar :: Maybe Text+ , avatar :: Avatar , mfaEnabled :: Maybe Bool+ , banner :: Maybe UserBanner+ , accentColour :: Maybe (Colour Double)+ , locale :: Maybe Text , verified :: Maybe Bool , email :: Maybe Text , flags :: Maybe Word64 , premiumType :: Maybe Word64 } deriving (Show, Eq)+ deriving (TextShow.TextShow) via TextShow.FromStringShow User deriving (HasID User) via HasIDField "id" User deriving (HasID Member) via HasIDFieldCoerce' "id" User instance Aeson.FromJSON User where- parseJSON = Aeson.withObject "User" $ \v ->+ parseJSON = Aeson.withObject "User" $ \v -> do+ uid <- v .: "id"+ avatarHash <- v .:? "avatar"+ discrim <- v .: "discriminator"+ discrim' <- case decimal discrim of+ Right (n, _) -> pure n+ Left e -> fail e+ let avatar = Avatar avatarHash uid discrim'+ banner <- (UserBanner uid <$>) <$> v .:? "banner" User- <$> v .: "id"+ <$> pure uid <*> v .: "username" <*> v .: "discriminator" <*> v .:? "bot"- <*> v .:? "avatar"+ <*> pure avatar <*> v .:? "mfa_enabled"+ <*> pure banner+ <*> (fmap fromIntColour <$> v .:? "accent_color")+ <*> v .:? "locale" <*> v .:? "verified" <*> v .:? "email" <*> v .:? "flags"@@ -83,7 +118,6 @@ Offline -> "offline" Invisible -> "invisible" -$(deriveTextShow ''User) $(deriveTextShow 'PartialUser) $(deriveTextShow ''StatusType) $(makeFieldLabelsNoPrefix ''User)
+ Calamity/Types/Model/User.hs-boot view
@@ -0,0 +1,8 @@+-- | Users+module Calamity.Types.Model.User+ ( User ) where++data User++instance Show User+instance Eq User
Calamity/Types/Snowflake.hs view
@@ -19,6 +19,7 @@ import Data.Word import GHC.Records (HasField (getField)) import TextShow+import Web.HttpApiData (ToHttpApiData) -- Thanks sbrg -- https://github.com/saevarb/haskord/blob/d1bb07bcc4f3dbc29f2dfd3351ff9f16fc100c07/haskord-lib/src/Haskord/Types/Common.hs#L78@@ -28,6 +29,7 @@ deriving (Eq, Ord, Data) deriving newtype (Show, TextShow, FromJSONKey) deriving newtype (ToJSONKey, U.Unboxable)+ deriving newtype (ToHttpApiData) -- I'm pretty sure that Word64's hash just being 'fromIntegral' is a bad idea when -- attempting to use it in a hashmap, so swizzle the bits a bit to give a good
+ Calamity/Utils/CDNUrl.hs view
@@ -0,0 +1,22 @@+-- | CDN url stuff+module Calamity.Utils.CDNUrl (+ cdnURL,+ assetHashFile,+ isGIFAsset,+) where++import qualified Data.Text as T+import qualified Network.HTTP.Req as Req++-- | The CDN URL+cdnURL :: Req.Url 'Req.Https+cdnURL = Req.https "cdn.discordapp.com"++-- | Test if an asset hash is animated+isGIFAsset :: T.Text -> Bool+isGIFAsset = T.isPrefixOf "a_"++-- | Generate \'hash.ext\' for an asset hash. @ext@ will be \'gif\' for animated+-- assets, \'png\' otherwise.+assetHashFile :: T.Text -> T.Text+assetHashFile h = if isGIFAsset h then h <> ".gif" else h <> ".png"
ChangeLog.md view
@@ -1,5 +1,31 @@ # Changelog for Calamity +## 0.7.0.0+++ Added the `CDNAsset` typeclass for resolving CDN asset links and fetching+ them.++ Added the module `Calamity.Types.Model.Avatar` with the types `Avatar` and+ `MemberAvatar`++ Changed the `avatar` field of `User` and `Member` to be `Avatar` (the default+ avatar will be fetched if the user does not have one set).++ Added the field `banner` to `User` and `Member` with type `Maybe UserBanner`.++ Added the field `accentColour` to `User` and `Member` with type `Maybe (Colour Double)`.++ Added the field `locale` to `User` and `Member` with type `Maybe Text`.++ Added the field `Member.memberAvatar` with type `Text`. (discord limitation,+ the guild id is needed to construct the member's guild avatar url, but discord+ doesn't attach the guild id to the member...)++ Added the type `RoleIcon` to `Calamity.Types.Model.Guild.Role`.++ Added the field `Role.icon` with type `RoleIcon`.++ Added the field `Role.emoji` with type `RawEmoji`.++ Added the types `GuildIcon`, `GuildSplash`, `GuildDiscoverySplash`,+ `GuildBanner` to `Calamity.Types.Model.Guild.Guild`.++ Changed the type of `Guild.icon` to `Maybe GuildIcon`.++ Changed the type of `Guild.splash` to `Maybe GuildSplash`.++ Added the field `Guild.discoverySplash` with type `Maybe+ GuildDiscoverySplash`.++ Added the field `Guild.banner` with type `Maybe GuildBanner`.++ ## 0.6.0.0 + Updated the events `GuildMemberAddEvt`, `GuildMemberRemoveEvt`, and
calamity.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack name: calamity-version: 0.6.0.0+version: 0.7.0.0 synopsis: A library for writing discord bots in haskell description: Please see the README on GitHub at <https://github.com/simmsb/calamity#readme> category: Network, Web@@ -18,7 +18,7 @@ license-file: LICENSE build-type: Simple tested-with:- GHC == 8.10.7, GHC == 9.2.2+ GHC == 8.10.7, GHC == 9.2.4 extra-source-files: README.md ChangeLog.md@@ -84,6 +84,7 @@ Calamity.Types Calamity.Types.LogEff Calamity.Types.Model+ Calamity.Types.Model.Avatar Calamity.Types.Model.Channel Calamity.Types.Model.Channel.Attachment Calamity.Types.Model.Channel.ChannelType@@ -118,6 +119,7 @@ Calamity.Types.Model.Voice Calamity.Types.Model.Voice.VoiceRegion Calamity.Types.Model.Voice.VoiceState+ Calamity.Types.CDNAsset Calamity.Types.Partial Calamity.Types.Snowflake Calamity.Types.Tellable@@ -125,6 +127,7 @@ Calamity.Types.TokenEff Calamity.Types.Upgradeable Calamity.Utils+ Calamity.Utils.CDNUrl Calamity.Utils.Colour Calamity.Utils.Message Calamity.Utils.Permissions