Added on_raw_typing event
				
					
				
			This commit is contained in:
		@@ -24,6 +24,7 @@ DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 | 
			
		||||
from __future__ import annotations
 | 
			
		||||
 | 
			
		||||
import datetime
 | 
			
		||||
from typing import TYPE_CHECKING, Optional, Set, List
 | 
			
		||||
 | 
			
		||||
if TYPE_CHECKING:
 | 
			
		||||
@@ -34,7 +35,8 @@ if TYPE_CHECKING:
 | 
			
		||||
        MessageUpdateEvent,
 | 
			
		||||
        ReactionClearEvent,
 | 
			
		||||
        ReactionClearEmojiEvent,
 | 
			
		||||
        IntegrationDeleteEvent
 | 
			
		||||
        IntegrationDeleteEvent,
 | 
			
		||||
        TypingEvent
 | 
			
		||||
    )
 | 
			
		||||
    from .message import Message
 | 
			
		||||
    from .partial_emoji import PartialEmoji
 | 
			
		||||
@@ -49,6 +51,7 @@ __all__ = (
 | 
			
		||||
    'RawReactionClearEvent',
 | 
			
		||||
    'RawReactionClearEmojiEvent',
 | 
			
		||||
    'RawIntegrationDeleteEvent',
 | 
			
		||||
    'RawTypingEvent'
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -276,3 +279,36 @@ class RawIntegrationDeleteEvent(_RawReprMixin):
 | 
			
		||||
            self.application_id: Optional[int] = int(data['application_id'])
 | 
			
		||||
        except KeyError:
 | 
			
		||||
            self.application_id: Optional[int] = None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class RawTypingEvent(_RawReprMixin):
 | 
			
		||||
    """Represents the payload for a :func:`on_raw_typing` event.
 | 
			
		||||
 | 
			
		||||
    .. versionadded:: 2.0
 | 
			
		||||
 | 
			
		||||
    Attributes
 | 
			
		||||
    -----------
 | 
			
		||||
    channel_id: :class:`int`
 | 
			
		||||
        The channel ID where the typing originated from.
 | 
			
		||||
    user_id: :class:`int`
 | 
			
		||||
        The ID of the user that started typing.
 | 
			
		||||
    when: :class:`datetime.datetime`
 | 
			
		||||
        When the typing started as an aware datetime in UTC.
 | 
			
		||||
    guild_id: Optional[:class:`int`]
 | 
			
		||||
        The guild ID where the typing originated from, if applicable.
 | 
			
		||||
    member: Optional[:class:`Member`]
 | 
			
		||||
        The member who started typing. Only available if the member started typing in a guild.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    __slots__ = ("channel_id", "user_id", "when", "guild_id", "member")
 | 
			
		||||
 | 
			
		||||
    def __init__(self, data: TypingEvent) -> None:
 | 
			
		||||
        self.channel_id: int = int(data['channel_id'])
 | 
			
		||||
        self.user_id: int = int(data['user_id'])
 | 
			
		||||
        self.when: datetime.datetime = datetime.datetime.fromtimestamp(data.get('timestamp'), tz=datetime.timezone.utc)
 | 
			
		||||
        self.member: Optional[Member] = None
 | 
			
		||||
        
 | 
			
		||||
        try:
 | 
			
		||||
            self.guild_id: Optional[int] = int(data['guild_id'])
 | 
			
		||||
        except KeyError:
 | 
			
		||||
            self.guild_id: Optional[int] = None
 | 
			
		||||
@@ -1327,28 +1327,37 @@ class ConnectionState:
 | 
			
		||||
            asyncio.create_task(logging_coroutine(coro, info='Voice Protocol voice server update handler'))
 | 
			
		||||
 | 
			
		||||
    def parse_typing_start(self, data) -> None:
 | 
			
		||||
        raw = RawTypingEvent(data)
 | 
			
		||||
 | 
			
		||||
        member_data = data.get('member')
 | 
			
		||||
        if member_data:
 | 
			
		||||
            guild = self._get_guild(raw.guild_id)
 | 
			
		||||
            if guild is not None:
 | 
			
		||||
                raw.member = Member(data=member_data, guild=guild, state=self)
 | 
			
		||||
            else:
 | 
			
		||||
                raw.member = None
 | 
			
		||||
        else:
 | 
			
		||||
            raw.member = None
 | 
			
		||||
        self.dispatch('raw_typing', raw)
 | 
			
		||||
 | 
			
		||||
        channel, guild = self._get_guild_channel(data)
 | 
			
		||||
        if channel is not None:
 | 
			
		||||
            member = None
 | 
			
		||||
            user_id = utils._get_as_snowflake(data, 'user_id')
 | 
			
		||||
            if isinstance(channel, DMChannel):
 | 
			
		||||
                member = channel.recipient
 | 
			
		||||
            user = raw.member or self._get_typing_user(channel, raw.user_id)
 | 
			
		||||
 | 
			
		||||
            elif isinstance(channel, (Thread, TextChannel)) and guild is not None:
 | 
			
		||||
                # user_id won't be None
 | 
			
		||||
                member = guild.get_member(user_id)  # type: ignore
 | 
			
		||||
            if user is not None:
 | 
			
		||||
                self.dispatch('typing', channel, user, raw.when)
 | 
			
		||||
 | 
			
		||||
                if member is None:
 | 
			
		||||
                    member_data = data.get('member')
 | 
			
		||||
                    if member_data:
 | 
			
		||||
                        member = Member(data=member_data, state=self, guild=guild)
 | 
			
		||||
    def _get_typing_user(self, channel: Optional[MessageableChannel], user_id: int) -> Optional[Union[User, Member]]:
 | 
			
		||||
        if isinstance(channel, DMChannel):
 | 
			
		||||
            return channel.recipient
 | 
			
		||||
 | 
			
		||||
            elif isinstance(channel, GroupChannel):
 | 
			
		||||
                member = utils.find(lambda x: x.id == user_id, channel.recipients)
 | 
			
		||||
        elif isinstance(channel, (Thread, TextChannel)) and channel.guild is not None:
 | 
			
		||||
            return channel.guild.get_member(user_id)  # type: ignore
 | 
			
		||||
 | 
			
		||||
            if member is not None:
 | 
			
		||||
                timestamp = datetime.datetime.fromtimestamp(data.get('timestamp'), tz=datetime.timezone.utc)
 | 
			
		||||
                self.dispatch('typing', channel, member, timestamp)
 | 
			
		||||
        elif isinstance(channel, GroupChannel):
 | 
			
		||||
            return utils.find(lambda x: x.id == user_id, channel.recipients)
 | 
			
		||||
 | 
			
		||||
        return self.get_user(user_id)
 | 
			
		||||
 | 
			
		||||
    def _get_reaction_user(self, channel: MessageableChannel, user_id: int) -> Optional[Union[User, Member]]:
 | 
			
		||||
        if isinstance(channel, TextChannel):
 | 
			
		||||
 
 | 
			
		||||
@@ -85,3 +85,13 @@ class _IntegrationDeleteEventOptional(TypedDict, total=False):
 | 
			
		||||
class IntegrationDeleteEvent(_IntegrationDeleteEventOptional):
 | 
			
		||||
    id: Snowflake
 | 
			
		||||
    guild_id: Snowflake
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class _TypingEventOptional(TypedDict, total=False):
 | 
			
		||||
    guild_id: Snowflake
 | 
			
		||||
    member: Member
 | 
			
		||||
 | 
			
		||||
class TypingEvent(_TypingEventOptional):
 | 
			
		||||
    channel_id: Snowflake
 | 
			
		||||
    user_id: Snowflake
 | 
			
		||||
    timestamp: int
 | 
			
		||||
		Reference in New Issue
	
	Block a user