diff --git a/src/Discord/Builders/ChannelBuilder.php b/src/Discord/Builders/ChannelBuilder.php index 40438a2e8..fb5fcadfb 100644 --- a/src/Discord/Builders/ChannelBuilder.php +++ b/src/Discord/Builders/ChannelBuilder.php @@ -14,8 +14,21 @@ namespace Discord\Builders; use Discord\Http\Exceptions\RequestFailedException; +use Discord\Parts\Channel\AnnouncementThread; use Discord\Parts\Channel\Channel; +use Discord\Parts\Channel\DM; +use Discord\Parts\Channel\GroupDM; +use Discord\Parts\Channel\GuildAnnouncement; +use Discord\Parts\Channel\GuildCategory; +use Discord\Parts\Channel\GuildDirectory; +use Discord\Parts\Channel\GuildForum; +use Discord\Parts\Channel\GuildMedia; +use Discord\Parts\Channel\GuildStageVoice; +use Discord\Parts\Channel\GuildText; +use Discord\Parts\Channel\GuildVoice; use Discord\Parts\Channel\Overwrite; +use Discord\Parts\Channel\PrivateThread; +use Discord\Parts\Channel\PublicThread; use Discord\Parts\Guild\Emoji; use Discord\Voice\Region; use JsonSerializable; @@ -31,6 +44,22 @@ */ class ChannelBuilder extends Builder implements JsonSerializable { + public const TYPES = [ + Channel::TYPE_GUILD_TEXT => GuildText::class, // A text channel within a server + Channel::TYPE_DM => DM::class, // A direct message between users + Channel::TYPE_GUILD_VOICE => GuildVoice::class, // A voice channel within a server + Channel::TYPE_GROUP_DM => GroupDM::class, // A direct message between multiple users + Channel::TYPE_GUILD_CATEGORY => GuildCategory::class, // An organizational category that contains up to 50 channels + Channel::TYPE_GUILD_ANNOUNCEMENT => GuildAnnouncement::class, // A channel that users can follow and crosspost into their own server (formerly news channels) + Channel::TYPE_ANNOUNCEMENT_THREAD => AnnouncementThread::class, // A temporary sub-channel within a GUILD_ANNOUNCEMENT channel + Channel::TYPE_PUBLIC_THREAD => PublicThread::class, // A temporary sub-channel within a GUILD_TEXT or GUILD_FORUM channel + Channel::TYPE_PRIVATE_THREAD => PrivateThread::class, // A temporary sub-channel within a GUILD_TEXT channel that is only viewable by those invited and those with the MANAGE_THREADS permission + Channel::TYPE_GUILD_STAGE_VOICE => GuildStageVoice::class, // A voice channel for hosting events with an audience + Channel::TYPE_GUILD_DIRECTORY => GuildDirectory::class, // The channel in a hub containing the listed servers + Channel::TYPE_GUILD_FORUM => GuildForum::class, // Channel that can only contain threads + Channel::TYPE_GUILD_MEDIA => GuildMedia::class, // Channel that can only contain threads, similar to GUILD_FORUM channels + ]; + protected string $name; protected ?int $type; protected ?string $topic; // Text, Announcement, Forum, Media diff --git a/src/Discord/Parts/Channel/AnnouncementThread.php b/src/Discord/Parts/Channel/AnnouncementThread.php new file mode 100644 index 000000000..b905a40af --- /dev/null +++ b/src/Discord/Parts/Channel/AnnouncementThread.php @@ -0,0 +1,20 @@ + + * + * This file is subject to the MIT license that is bundled + * with this source code in the LICENSE.md file. + */ + +namespace Discord\Parts\Channel; + +use Discord\Parts\Thread\Thread; + +class AnnouncementThread extends Thread +{ +} diff --git a/src/Discord/Parts/Channel/DM.php b/src/Discord/Parts/Channel/DM.php new file mode 100644 index 000000000..04105bfe7 --- /dev/null +++ b/src/Discord/Parts/Channel/DM.php @@ -0,0 +1,18 @@ + + * + * This file is subject to the MIT license that is bundled + * with this source code in the LICENSE.md file. + */ + +namespace Discord\Parts\Channel; + +class DM extends Channel +{ +} diff --git a/src/Discord/Parts/Channel/GroupDM.php b/src/Discord/Parts/Channel/GroupDM.php new file mode 100644 index 000000000..30cb962a1 --- /dev/null +++ b/src/Discord/Parts/Channel/GroupDM.php @@ -0,0 +1,18 @@ + + * + * This file is subject to the MIT license that is bundled + * with this source code in the LICENSE.md file. + */ + +namespace Discord\Parts\Channel; + +class GroupDM extends Channel +{ +} diff --git a/src/Discord/Parts/Channel/GuildAnnouncement.php b/src/Discord/Parts/Channel/GuildAnnouncement.php new file mode 100644 index 000000000..602e00571 --- /dev/null +++ b/src/Discord/Parts/Channel/GuildAnnouncement.php @@ -0,0 +1,18 @@ + + * + * This file is subject to the MIT license that is bundled + * with this source code in the LICENSE.md file. + */ + +namespace Discord\Parts\Channel; + +class GuildAnnouncement extends Channel +{ +} diff --git a/src/Discord/Parts/Channel/GuildCategory.php b/src/Discord/Parts/Channel/GuildCategory.php new file mode 100644 index 000000000..997b65030 --- /dev/null +++ b/src/Discord/Parts/Channel/GuildCategory.php @@ -0,0 +1,18 @@ + + * + * This file is subject to the MIT license that is bundled + * with this source code in the LICENSE.md file. + */ + +namespace Discord\Parts\Channel; + +class GuildCategory extends Channel +{ +} diff --git a/src/Discord/Parts/Channel/GuildDirectory.php b/src/Discord/Parts/Channel/GuildDirectory.php new file mode 100644 index 000000000..f6560f2fa --- /dev/null +++ b/src/Discord/Parts/Channel/GuildDirectory.php @@ -0,0 +1,18 @@ + + * + * This file is subject to the MIT license that is bundled + * with this source code in the LICENSE.md file. + */ + +namespace Discord\Parts\Channel; + +class GuildDirectory extends Channel +{ +} diff --git a/src/Discord/Parts/Channel/GuildForum.php b/src/Discord/Parts/Channel/GuildForum.php new file mode 100644 index 000000000..a0c4444ba --- /dev/null +++ b/src/Discord/Parts/Channel/GuildForum.php @@ -0,0 +1,18 @@ + + * + * This file is subject to the MIT license that is bundled + * with this source code in the LICENSE.md file. + */ + +namespace Discord\Parts\Channel; + +class GuildForum extends Channel +{ +} diff --git a/src/Discord/Parts/Channel/GuildMedia.php b/src/Discord/Parts/Channel/GuildMedia.php new file mode 100644 index 000000000..13201ec37 --- /dev/null +++ b/src/Discord/Parts/Channel/GuildMedia.php @@ -0,0 +1,18 @@ + + * + * This file is subject to the MIT license that is bundled + * with this source code in the LICENSE.md file. + */ + +namespace Discord\Parts\Channel; + +class GuildMedia extends Channel +{ +} diff --git a/src/Discord/Parts/Channel/GuildStageVoice.php b/src/Discord/Parts/Channel/GuildStageVoice.php new file mode 100644 index 000000000..33e30ac59 --- /dev/null +++ b/src/Discord/Parts/Channel/GuildStageVoice.php @@ -0,0 +1,18 @@ + + * + * This file is subject to the MIT license that is bundled + * with this source code in the LICENSE.md file. + */ + +namespace Discord\Parts\Channel; + +class GuildStageVoice extends Channel +{ +} diff --git a/src/Discord/Parts/Channel/GuildText.php b/src/Discord/Parts/Channel/GuildText.php new file mode 100644 index 000000000..03d1c3cb8 --- /dev/null +++ b/src/Discord/Parts/Channel/GuildText.php @@ -0,0 +1,18 @@ + + * + * This file is subject to the MIT license that is bundled + * with this source code in the LICENSE.md file. + */ + +namespace Discord\Parts\Channel; + +class GuildText extends Channel +{ +} diff --git a/src/Discord/Parts/Channel/GuildVoice.php b/src/Discord/Parts/Channel/GuildVoice.php new file mode 100644 index 000000000..d63c608c4 --- /dev/null +++ b/src/Discord/Parts/Channel/GuildVoice.php @@ -0,0 +1,18 @@ + + * + * This file is subject to the MIT license that is bundled + * with this source code in the LICENSE.md file. + */ + +namespace Discord\Parts\Channel; + +class GuildVoice extends Channel +{ +} diff --git a/src/Discord/Parts/Channel/Message.php b/src/Discord/Parts/Channel/Message.php index 223455e0f..d61324717 100644 --- a/src/Discord/Parts/Channel/Message.php +++ b/src/Discord/Parts/Channel/Message.php @@ -471,9 +471,10 @@ protected function getChannelAttribute(): Part return $channel; } - return $this->factory->part(Channel::class, [ + return $this->factory->part(DM::class, [ 'id' => $this->channel_id, 'type' => Channel::TYPE_DM, + 'recipients' => [$this->author], ], true); } diff --git a/src/Discord/Parts/Channel/PrivateThread.php b/src/Discord/Parts/Channel/PrivateThread.php new file mode 100644 index 000000000..186f30f0c --- /dev/null +++ b/src/Discord/Parts/Channel/PrivateThread.php @@ -0,0 +1,20 @@ + + * + * This file is subject to the MIT license that is bundled + * with this source code in the LICENSE.md file. + */ + +namespace Discord\Parts\Channel; + +use Discord\Parts\Thread\Thread; + +class PrivateThread extends Thread +{ +} diff --git a/src/Discord/Parts/Channel/PublicThread.php b/src/Discord/Parts/Channel/PublicThread.php new file mode 100644 index 000000000..9caca6542 --- /dev/null +++ b/src/Discord/Parts/Channel/PublicThread.php @@ -0,0 +1,20 @@ + + * + * This file is subject to the MIT license that is bundled + * with this source code in the LICENSE.md file. + */ + +namespace Discord\Parts\Channel; + +use Discord\Parts\Thread\Thread; + +class PublicThread extends Thread +{ +} diff --git a/src/Discord/Parts/Guild/Guild.php b/src/Discord/Parts/Guild/Guild.php index 93af26978..25f6a7177 100644 --- a/src/Discord/Parts/Guild/Guild.php +++ b/src/Discord/Parts/Guild/Guild.php @@ -1631,6 +1631,7 @@ public function save(?string $reason = null): PromiseInterface return reject(new NoPermissionsException("You do not have permission to save changes to the guild {$this->id}.")); } } + return $this->discord->guilds->save($this, $reason); } diff --git a/src/Discord/Parts/Interactions/Request/Resolved.php b/src/Discord/Parts/Interactions/Request/Resolved.php index c0833364b..d7965b3c8 100644 --- a/src/Discord/Parts/Interactions/Request/Resolved.php +++ b/src/Discord/Parts/Interactions/Request/Resolved.php @@ -13,6 +13,7 @@ namespace Discord\Parts\Interactions\Request; +use Discord\Builders\ChannelBuilder; use Discord\Helpers\Collection; use Discord\Helpers\ExCollectionInterface; use Discord\Parts\Channel\Attachment; @@ -186,11 +187,7 @@ protected function getChannelsAttribute(): ExCollectionInterface } if (! isset($channelPart)) { - if (in_array($channel->type, [Channel::TYPE_ANNOUNCEMENT_THREAD, Channel::TYPE_PRIVATE_THREAD, Channel::TYPE_PUBLIC_THREAD])) { - $channelPart = $this->factory->part(Thread::class, (array) $channel + ['guild_id' => $this->guild_id], true); - } else { - $channelPart = $this->factory->part(Channel::class, (array) $channel + ['guild_id' => $this->guild_id], true); - } + $channelPart = $this->factory->part(ChannelBuilder::TYPES[$channel->type] ?? Channel::class, (array) $channel + ['guild_id' => $this->guild_id], true); } $collection->pushItem($channelPart); diff --git a/src/Discord/Parts/PartTrait.php b/src/Discord/Parts/PartTrait.php index 7feada1ee..f7f2991b5 100644 --- a/src/Discord/Parts/PartTrait.php +++ b/src/Discord/Parts/PartTrait.php @@ -50,7 +50,7 @@ protected function afterConstruct(): void * * @param string|null $reason The reason for the audit log, if supported. * - * @throws \Exception If the part does not support saving. + * @throws \Exception If the part does not support saving. * @throws NoPermissionsException Missing permission. * * @return PromiseInterface Resolves with the saved part. diff --git a/src/Discord/WebSockets/Events/ChannelCreate.php b/src/Discord/WebSockets/Events/ChannelCreate.php index a704fb53f..6c07de0ba 100644 --- a/src/Discord/WebSockets/Events/ChannelCreate.php +++ b/src/Discord/WebSockets/Events/ChannelCreate.php @@ -13,6 +13,7 @@ namespace Discord\WebSockets\Events; +use Discord\Builders\ChannelBuilder; use Discord\Parts\Channel\Channel; use Discord\WebSockets\Event; use Discord\Parts\Guild\Guild; @@ -30,7 +31,7 @@ class ChannelCreate extends Event public function handle($data) { /** @var Channel */ - $channelPart = $this->factory->part(Channel::class, (array) $data, true); + $channelPart = $this->factory->part(ChannelBuilder::TYPES[$data->type] ?? Channel::class, (array) $data, true); if ($channelPart->is_private) { $this->discord->private_channels->set($data->id, $channelPart); diff --git a/src/Discord/WebSockets/Events/ChannelDelete.php b/src/Discord/WebSockets/Events/ChannelDelete.php index a86aa208d..6bd7d3ccd 100644 --- a/src/Discord/WebSockets/Events/ChannelDelete.php +++ b/src/Discord/WebSockets/Events/ChannelDelete.php @@ -13,6 +13,7 @@ namespace Discord\WebSockets\Events; +use Discord\Builders\ChannelBuilder; use Discord\Parts\Channel\Channel; use Discord\WebSockets\Event; @@ -39,6 +40,6 @@ public function handle($data) } } - return $channelPart ?? $this->factory->part(Channel::class, (array) $data); + return $channelPart ?? $this->factory->part(ChannelBuilder::TYPES[$data->type] ?? Channel::class, (array) $data); } } diff --git a/src/Discord/WebSockets/Events/ChannelUpdate.php b/src/Discord/WebSockets/Events/ChannelUpdate.php index d38cfb9b2..af7c08c1b 100644 --- a/src/Discord/WebSockets/Events/ChannelUpdate.php +++ b/src/Discord/WebSockets/Events/ChannelUpdate.php @@ -13,6 +13,7 @@ namespace Discord\WebSockets\Events; +use Discord\Builders\ChannelBuilder; use Discord\Parts\Channel\Channel; use Discord\WebSockets\Event; @@ -31,7 +32,7 @@ public function handle($data) $oldChannel = $repository = null; /** @var Channel */ - $channelPart = $this->factory->part(Channel::class, (array) $data, true); + $channelPart = $this->factory->part(ChannelBuilder::TYPES[$data->type] ?? Channel::class, (array) $data, true); if ($channelPart->is_private) { /** @var ?Channel */ diff --git a/src/Discord/WebSockets/Events/MessageCreate.php b/src/Discord/WebSockets/Events/MessageCreate.php index dd668b0b0..490bec8e9 100644 --- a/src/Discord/WebSockets/Events/MessageCreate.php +++ b/src/Discord/WebSockets/Events/MessageCreate.php @@ -37,16 +37,12 @@ public function handle($data) /** @var Message */ $messagePart = $this->factory->part(Message::class, (array) $data, true); - if ($messagePart->is_private) { - /** @var Channel */ - $channel = $this->factory->part(Channel::class, [ - 'id' => $data->channel_id, - 'type' => Channel::TYPE_DM, - 'last_message_id' => $data->id, - 'recipients' => [$data->author], - ], true); - - $this->discord->private_channels->set($data->channel_id, $channel); + $channel = $messagePart->channel; + if ($channel->type === Channel::TYPE_DM || $channel->type === Channel::TYPE_GROUP_DM) { + $channel->last_message_id = $data->id; + $this->discord->private_channels->set($channel->id, $channel); + } else { + unset($channel); // Force reload below } /** @var ?Guild */ diff --git a/src/Discord/WebSockets/Events/ThreadCreate.php b/src/Discord/WebSockets/Events/ThreadCreate.php index e34e04cea..1ec463ec3 100644 --- a/src/Discord/WebSockets/Events/ThreadCreate.php +++ b/src/Discord/WebSockets/Events/ThreadCreate.php @@ -13,6 +13,7 @@ namespace Discord\WebSockets\Events; +use Discord\Builders\ChannelBuilder; use Discord\Parts\Channel\Channel; use Discord\Parts\Channel\Message; use Discord\Parts\Guild\Guild; @@ -32,7 +33,7 @@ class ThreadCreate extends Event public function handle($data) { /** @var Thread */ - $threadPart = $this->factory->part(Thread::class, (array) $data, true); + $threadPart = $this->factory->part(ChannelBuilder::TYPES[$data->type] ?? Thread::class, (array) $data, true); /** @var ?Guild */ if ($guild = yield $this->discord->guilds->cacheGet($data->guild_id)) { diff --git a/src/Discord/WebSockets/Events/ThreadDelete.php b/src/Discord/WebSockets/Events/ThreadDelete.php index d156cbea1..9d8464b61 100644 --- a/src/Discord/WebSockets/Events/ThreadDelete.php +++ b/src/Discord/WebSockets/Events/ThreadDelete.php @@ -13,8 +13,10 @@ namespace Discord\WebSockets\Events; +use Discord\Builders\ChannelBuilder; use Discord\Parts\Channel\Channel; use Discord\Parts\Guild\Guild; +use Discord\Parts\Thread\Thread; use Discord\WebSockets\Event; /** @@ -36,6 +38,6 @@ public function handle($data) } } - return $threadPart ?? $data; + return $threadPart ?? $threadPart = $this->factory->part(ChannelBuilder::TYPES[$data->type] ?? Thread::class, (array) $data, true); } } diff --git a/src/Discord/WebSockets/Events/ThreadListSync.php b/src/Discord/WebSockets/Events/ThreadListSync.php index 92594f841..7d9344313 100644 --- a/src/Discord/WebSockets/Events/ThreadListSync.php +++ b/src/Discord/WebSockets/Events/ThreadListSync.php @@ -13,6 +13,7 @@ namespace Discord\WebSockets\Events; +use Discord\Builders\ChannelBuilder; use Discord\Helpers\Collection; use Discord\Parts\Channel\Channel; use Discord\Parts\Guild\Guild; @@ -38,8 +39,9 @@ public function handle($data) } foreach ($data->threads as $thread) { + /** @var Thread $thread */ /** @var Thread */ - $threadPart = $this->factory->part(Thread::class, (array) $thread, true); + $threadPart = $this->factory->part(ChannelBuilder::TYPES[$thread->type ?? Thread::class], (array) $thread, true); /** @var ?Channel */ if ($channel = $channels[$thread->parent_id] ?? null) { /** @var ?Thread */ diff --git a/src/Discord/WebSockets/Events/ThreadUpdate.php b/src/Discord/WebSockets/Events/ThreadUpdate.php index 25780e117..462f8ccf9 100644 --- a/src/Discord/WebSockets/Events/ThreadUpdate.php +++ b/src/Discord/WebSockets/Events/ThreadUpdate.php @@ -13,6 +13,7 @@ namespace Discord\WebSockets\Events; +use Discord\Builders\ChannelBuilder; use Discord\Parts\Channel\Channel; use Discord\Parts\Guild\Guild; use Discord\Parts\Thread\Thread; @@ -46,7 +47,7 @@ public function handle($data) if ($threadPart === null) { /** @var Thread */ - $threadPart = $this->factory->part(Thread::class, (array) $data, true); + $threadPart = $this->factory->part(ChannelBuilder::TYPES[$data->type] ?? Thread::class, (array) $data, true); } if (isset($parent)) {