-
-
Notifications
You must be signed in to change notification settings - Fork 239
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
🚧 Initial Discord message components v2 implementation #1294
base: master
Are you sure you want to change the base?
Conversation
P neat implementation ❤️ Good job! |
The v2 contract was an excellent idea, and something I'd like to see in other parts of the library. It would certainly cut down on a lost of instances of checking against hardcoded types like this. |
* @return int | ||
*/ | ||
public function getFlags(): int | ||
{ | ||
return $this->flags; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the property might be not set yet
* @return int | |
*/ | |
public function getFlags(): int | |
{ | |
return $this->flags; | |
* @return ?int | |
*/ | |
public function getFlags(): ?int | |
{ | |
return $this->flags; |
@@ -181,6 +181,7 @@ class Message extends Part | |||
public const FLAG_LOADING = (1 << 7); | |||
public const FLAG_FAILED_TO_MENTION_SOME_ROLES_IN_THREAD = (1 << 8); | |||
public const FLAG_SUPPRESS_NOTIFICATIONS = (1 << 12); | |||
public const FLAG_V2_COMPONENTS = (1 << 15); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The official name is IS_COMPONENTS_V2
public const FLAG_V2_COMPONENTS = (1 << 15); | |
public const FLAG_IS_V2_COMPONENTS = (1 << 15); |
please also adjust the referencing code
if (isset($this->components) && count($this->components) >= 10) { | ||
throw new \OverflowException('You can only add 10 components to a v2 message'); | ||
} | ||
} elseif (! ($component instanceof Components\ActionRow || $component instanceof Components\SelectMenu)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please import directly, so it is easy to update/refactor in future (or alias as seen in functions.php)
use Discord\Builders\Components\ActionRow;
use Discord\Builders\Components\SelectMenu;
} elseif (! ($component instanceof Components\ActionRow || $component instanceof Components\SelectMenu)) { | |
} elseif (! ($component instanceof ActionRow || $component instanceof SelectMenu)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please also adjust the class implements Components\xx
to have the namespace imported per my previous suggestion
'width' => $this->width ?? null, | ||
'height' => $this->height ?? null, | ||
'content_type' => $this->content_type ?? null, | ||
'loading_state' => $this->loading_state ?? null, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'loading_state' => $this->loading_state ?? null, | |
'loading_state' => $this->loading_state, |
loading_state
will be always set since isResolved()
returns true
public function setUrl(string $url): self | ||
{ | ||
$this->url = $url; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implement validation of $url
like in Embed::ensureValidUrl()
* @param string $url URL of the media item. | ||
* | ||
* @return $this | ||
*/ | ||
public function setMedia(string $url): self | ||
{ | ||
$this->media = ['url' => $url]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The spec actually expects the media to contain UnfurledMediaItem, even though only the url
for now that will be taken, that is what you can deal with inside jsonSerialize()
Needs to change on the getter too
For example
* @param string $url URL of the media item. | |
* | |
* @return $this | |
*/ | |
public function setMedia(string $url): self | |
{ | |
$this->media = ['url' => $url]; | |
* @param UnfurledMediaItem|string $url URL of the media item. | |
* | |
* @return $this | |
*/ | |
public function setMedia(UnfurledMediaItem|string $url): self | |
{ | |
if (is_string($url)) { | |
$url = UnfurledMediaItem::new($url); | |
} | |
$this->media = $url; |
with this we can anticipate more changes in future
/** | ||
* Set the spacing size to small. | ||
* | ||
* @return $this | ||
*/ | ||
public function setSpacingSmall(): self | ||
{ | ||
return $this->setSpacing(self::SPACING_SMALL); | ||
} | ||
|
||
/** | ||
* Set the spacing size to large. | ||
* | ||
* @return $this | ||
*/ | ||
public function setSpacingLarge(): self | ||
{ | ||
return $this->setSpacing(self::SPACING_LARGE); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/** | |
* Set the spacing size to small. | |
* | |
* @return $this | |
*/ | |
public function setSpacingSmall(): self | |
{ | |
return $this->setSpacing(self::SPACING_SMALL); | |
} | |
/** | |
* Set the spacing size to large. | |
* | |
* @return $this | |
*/ | |
public function setSpacingLarge(): self | |
{ | |
return $this->setSpacing(self::SPACING_LARGE); | |
} |
Don't think this is necessary when there is a setSpacing()
already, we don't want the code to get huge when there is another type of spacing in future
public function addComponent(Component $component): self | ||
{ | ||
if (! ($component instanceof TextDisplay)) { | ||
throw new \InvalidArgumentException('Section can only contain TextDisplay components. Use setAccessory() for Thumbnail or Button.'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
throw new \InvalidArgumentException('Section can only contain TextDisplay components. Use setAccessory() for Thumbnail or Button.'); | |
throw new \InvalidArgumentException('Section can only contain TextDisplay components.'); |
You are not checking wether the $component
is a Thumbnail
or Button
here so it's better not to explicitly say that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On a second though, the spec is telling us to not hardcode this, so we should not validate this yet
throw new \InvalidArgumentException('Section can only contain TextDisplay components. Use setAccessory() for Thumbnail or Button.'); | |
trigger_error('Section may only contain TextDisplay components.', E_USER_NOTICE); |
public function setAccessory(Thumbnail|Button $component): self | ||
{ | ||
$this->accessory = $component; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The spec is telling us to not hard code the supported components yet (anyway leave the phpdoc as is)
public function setAccessory(Thumbnail|Button $component): self | |
{ | |
$this->accessory = $component; | |
public function setAccessory(Component $component): self | |
{ | |
if (! ($component instanceof Thumbnail || $component instanceof Button)) { | |
trigger_error('Accessory may only contain Thumbnail or Button component.', E_USER_NOTICE); | |
} | |
$this->accessory = $component; |
*/ | ||
public function setDescription(?string $description): self | ||
{ | ||
if ($description !== null && strlen($description) > 1024) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if ($description !== null && strlen($description) > 1024) { | |
if ($description !== null && poly_strlen($description) > 1024) { |
multibyte
if (count($this->components) >= 10) { | ||
throw new \OverflowException('You can only have 10 components per container.'); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
might want to validate the component type that can be added here or perhaps strict type them
According to the spec, using the components v2 may disable content and embeds, it would be good to warn the users in the MessageBuilder to avoid confusion Also seems this PR has not supported webhooks yet |
🚧 Work in progress.
Completely blind & untested. Should be able to try it later today.
Edit: everything appears to be functional.