Skip to content

Add threads support#418

Open
Bilal2453 wants to merge 10 commits intoSinisterRectus:masterfrom
Bilal2453:threads-support
Open

Add threads support#418
Bilal2453 wants to merge 10 commits intoSinisterRectus:masterfrom
Bilal2453:threads-support

Conversation

@Bilal2453
Copy link
Copy Markdown
Contributor

@Bilal2453 Bilal2453 commented Oct 14, 2024

This should be everything we need to get Thread channels going on. Still some things to work out, mainly design related.
Here is an overview of the changes:

Added 2 new classes:

Hide details:
  • GuildThreadChannel: Represents a Thread channel, inherits from TextChannel.

  • ThreadMember: Wraps a Guild Member in a context of a specific Thread channel. This contains things like thread join time, etc.

Modified classes:

Show details:
  • Cache: the hash function used to get unique object keys is now exposed through Cache._hash, this allows us to prioritize using a specific field instead of data.id.

This is needed because Discord sends id in the ThreadMember data... but instead of that ID being the member ID, it is actually the thread's ID. Discordia will always use the field id as a hash when inserting into a cache, so we had to have a way to tell Discordia to use data._user_id instead of data.id.

  • SecondaryCache: added SecondaryCache:_delete(k), allowing us to delete an object by key, instead of being forced to use _remove for when we don't have the data, only the key.

This is needed to clear stale threads from cache when Discord sends THREAD_LIST_SYNC event, which only provides the ID of the thread to be removed.

  • Cache & SecondaryCache: allow passing a custom parent in :_insert.

A thread channel parent is the text channel it is created under, yet Discord will send the thread channels on GUILD_READY as guild.threads, this means threads needs to be cached in Guild and the text channels needs to hold a reference to this.

Therefor the thread channels cache is located and initialized at Guild._thread_channels, and each GuildChannel holds a SecondaryCache to that. A direct consequence of this is all thread channels will share the same parent instance (:_insert defaults to a single parent object provided at initialization). With this change it becomes possible to provide a different parent with each :_insert call.

New API calls:

Show details:
  • getThreadMember.
  • getThreadMembers.
  • addThreadMember.
  • removeThreadMember.
  • getCurrentThreadMember.
  • joinThread.
  • leaveThread.
  • startThreadWithMessage.
  • startThreadWithoutMessaeg.
  • listArchivedPublicThreads.
  • listArchivedPrivateThreads.
  • listJoinedArchivedPrivateThreads.

Those are supposed to be auto-generated... but we don't have the API generator available in the repo it seems? I vaguely remember a Discord docs scraper.

New resolvers

Show details:
  • Resolver.channelFlag: similar to how messageFlag is handled.

  • Resolver.isoTimestamp: utilize the Date class into timestamp inputs useful for getArchivedPublicThreads(..., before), which is an ISO timestamp input; accepts Date, Date.fromTable, Date.fromSeconds.

Also been thinking into integrating everything that accepts Time objects for duration as a resolver, we already make use of Time objects for Member.timeoutFor, and now Time is also used for things like GuildThreadChannel:setAutoArchiveDuration(duration).

New events:

Show details:
  • threadCreate: fired when a new thread channel is created.
  • threadUpdate: fired when a thread channel is updated.
  • threadDelete: fired when a thread channel is deleted and is in cache.
  • threadDeleteUncached: fired when a thread channel is deleted and is not in cache.
  • threadListSync: fired when the client gains/loses access to threads (e.x. gains permissions) and should sync cache.
  • threadMemberUpdate: when a thread member is updated (e.x. left/joined).
  • threadMembersUpdate: multiple thread members updates.

ThreadMember: add ThreadMember.user

ThreadMember: implement :remove and .threadId

GuildThreadChannel: add documentation

GuildThreadChannel: implement permission methods

ThreadMember: more documentation

GuildChannel: add setDefaultAutoArchiveDuration & some missing getters

Message & GuildChannel: add documentation
@Bilal2453 Bilal2453 marked this pull request as draft October 14, 2024 23:17
@Bilal2453
Copy link
Copy Markdown
Contributor Author

Bilal2453 commented Oct 15, 2024

I think I am mostly satisfied with this. I still need to do more testing before it becomes ready for merge, but should be good for a technical review.

One thing I am really not sure if I should keep are the permissions methods.

GuildThreadChannel:canManage()/ThreadMember:canUnarchive() etc. I honestly added them without much thought as I was looking into other libraries. But they don't really feel like they fit with Discordia's style, I feel like if we added them here they should also be added in TextChannel, with something like TextChannel:canSend().

Also to note, notice the naming scheme for GuildThreadChannel.isPrivate while the rest of getters are named like archived/pinned without the is, if I am not mistaken only methods should be prefixed with is and properties would simply have ed suffix. But I noticed the already existing GuildTextChannel.isNews, so I just followed what we already had. Those type of properties (ie isNews/isThread) also feel like they should be in Channel instead of the class directly? Like the new Channel.isThread.

@Bilal2453 Bilal2453 marked this pull request as ready for review October 15, 2024 17:51
@TFLTV
Copy link
Copy Markdown

TFLTV commented Jan 22, 2025

Do message events get emitted when something with a message happens in a thread?

@Bilal2453
Copy link
Copy Markdown
Contributor Author

Yes, that is correct 😆

When this PR gets merged, you will be able to receive messageCreate inside thread channels.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants