pycord icon indicating copy to clipboard operation
pycord copied to clipboard

feat: components v2 & `View` improvements

Open NeloBlivion opened this issue 11 months ago • 29 comments

Summary

Soon


  • Edit by Lala: Temporary reference: https://github.com/Lulalaby/discord-api-docs/blob/comp_v2/docs/interactions/Message_Components.md#v2-components

  • Yet another edit by Lala: Official PR for the docs is available now at https://github.com/discord/discord-api-docs/pull/7487

Information

  • [ ] This PR fixes an issue.
  • [x] This PR adds something new (e.g. new method or parameters).
  • [ ] This PR is a breaking change (e.g. methods or parameters removed/renamed).
  • [ ] This PR is not a code change (e.g. documentation, README, typehinting, examples, ...).

Checklist

  • [x] I have searched the open pull requests for duplicates.
  • [ ] If code changes were made then they have been tested.
    • [ ] I have updated the documentation to reflect the changes.
  • [ ] If type: ignore comments were used, a comment is also left explaining why.
  • [ ] I have updated the changelog to include these changes.

Reference:

message-components-v2-text-display message-components-v2-container message-components-v2-file message-components-v2-media-gallery message-components-v2-section message-components-v2-separator

NeloBlivion avatar Feb 06 '25 04:02 NeloBlivion

note to self, https://github.com/discord/discord-api-docs/pull/7368 would be appropriate here too (webhooks may make full use of the new V2 components and link buttons, but not the existing interactive components)

NeloBlivion avatar Feb 18 '25 23:02 NeloBlivion

yeah agreed. we should get that in as well. i originally included that in my discord-docs, but since it was kinda separate, i removed it again since advaith made a separate pr

Lulalaby avatar Feb 18 '25 23:02 Lulalaby

todo: changelog, example pls test within whatever limits you can https://discord.com/channels/881207955029110855/881735314987708456/1344584270601261067 if you get any errors apart from maze then ping me there

NeloBlivion avatar Feb 27 '25 16:02 NeloBlivion

Sometimes when parsing a received components the code crashes here saying no attribute custom_id: https://github.com/Pycord-Development/pycord/blob/8fdf18ec0b7d47d395194470b21621ebc6b6d971/discord/ui/view.py#L464

Paillat-dev avatar Feb 28 '25 23:02 Paillat-dev

Sometimes when parsing a received components the code crashes here saying no attribute custom_id:

https://github.com/Pycord-Development/pycord/blob/8fdf18ec0b7d47d395194470b21621ebc6b6d971/discord/ui/view.py#L464

that's odd, is_dispatchable should mean it has a custom id

plun1331 avatar Mar 01 '25 04:03 plun1331

Yeah I thought the same

Paillat-dev avatar Mar 01 '25 12:03 Paillat-dev

Experiment flag has been lifted; this PR can now be freely tested by any user. You may have to force canary API; this can be done by running the below line in your main bot file.

discord.Route.API_BASE_URL = "https://canary.discord.com/api/v10"

NeloBlivion avatar Apr 18 '25 18:04 NeloBlivion

Additionally, examples in the example/ui directory should be something to consider.

JustaSqu1d avatar Apr 22 '25 19:04 JustaSqu1d

Additionally, examples in the example/ui directory should be something to consider.

This could be done in a separate PR to not delay this PR.

Icebluewolf avatar Apr 23 '25 13:04 Icebluewolf

When using a decorator in a container, should the items appear above or below items set in __init__

NeloBlivion avatar Apr 23 '25 17:04 NeloBlivion

Can row not be used? But I would say below when not specified.

Icebluewolf avatar Apr 23 '25 17:04 Icebluewolf

Is there a way to add your own ActionRow?

RealBongoChongo avatar Apr 30 '25 02:04 RealBongoChongo

The button limit was not increased correctly, this could most likely be fixed by allowing manual ActionRow creation and not bother fixing the weights system as of now (as suggested by RealBongoChongo). The 26th button is what causes the error.

Code ```py v = discord.ui.View() for i in range(33): v.add_item(discord.ui.Button(label=str(i))) ```
Traceback ``` Traceback (most recent call last): File "site-packages\discord\commands\core.py", line 138, in wrapped ret = await coro(arg) ^^^^^^^^^^^^^^^ File "site-packages\discord\commands\core.py", line 1082, in _invoke await self.callback(ctx, **kwargs) File "PycordTesting\components_v2.py", line 24, in components_v2 v.add_item(discord.ui.Button(label=str(i))) File "site-packages\discord\ui\view.py", line 341, in add_item self.__weights.add_item(item) File "site-packages\discord\ui\view.py", line 145, in add_item index = self.find_open_space(item) ^^^^^^^^^^^^^^^^^^^^^^^^^^ File "site-packages\discord\ui\view.py", line 131, in find_open_space raise ValueError("could not find open space for item") ValueError: could not find open space for item ```

Icebluewolf avatar Apr 30 '25 04:04 Icebluewolf

Implementing ui.ActionRow alongside weights is not ideal and not a goal for 2.7; this will be added in v3.

NeloBlivion avatar Apr 30 '25 05:04 NeloBlivion

Not copilot being almost completely worthless on this mildly large PR

plun1331 avatar May 01 '25 06:05 plun1331

hi, I am just trying out this addition with the default bot example, and I am recieving a 404 error. Is this an known or unknown problem? -> moved to Pycord Discord

DTheIcyDragon avatar May 01 '25 12:05 DTheIcyDragon

@DTheIcyDragon Heyy, would you mind asking in the discord server https://discord.gg/pycord as this issue is not related to this pull request specifically ?

Paillat-dev avatar May 01 '25 12:05 Paillat-dev

Would it be possible to not include timeout handling in views without an interactive component. I dont think there is any reason to save the view in the cache when there are no interactive components. This would also save a lot of memory in active bots that send a lot of containers in place of embeds where the current behavior saves the view for 3 minutes.

Icebluewolf avatar May 03 '25 16:05 Icebluewolf

I've now started to implement this PR in the Beta version of my bot, and I have a question: Is it possible to add an item to a container via decorator? Or is self.container.add_item(callback) the only way?

iqnite avatar May 06 '25 19:05 iqnite

Is it possible to add an item to a container via decorator?

@button and @select work when subclassing container, same usage as in views

NeloBlivion avatar May 06 '25 19:05 NeloBlivion

Would it be possible to not include timeout handling in views without an interactive component

This has been added through the new View.is_dispatchable() function - non-dispatchable views will no longer automatically call store_view when being sent

NeloBlivion avatar May 11 '25 19:05 NeloBlivion

Kinda hefty but since this is already a large pr on Views i added some other conveniences

  • New command, view and modal attributes on Interaction
  • New events on_view_error and on_modal_error

Will go through full review comments and suggestions this weekend.

NeloBlivion avatar May 16 '25 22:05 NeloBlivion

~~View.disable_all_items() does not disable section accessories. Is this intentional?~~

EDIT: MB I was using an older version.

iqnite avatar May 19 '25 07:05 iqnite

self.disable_all_item() returns error AttributeError: 'MediaGallery' object has no attribute 'disable_all_items' Screenshot 2025-05-20 111646

crashi-c avatar May 20 '25 09:05 crashi-c

Task exception was never retrieved future: <Task finished name='discord-ui-view-timeout-a2d765a0e561bfb23f667ef91f67f8ad' coro=<MyView.on_timeout() done, defined at C:\Users\0000\Desktop\0000\main.py:64> exception=AttributeError("'NoneType' object has no attribute 'edit'")> Traceback (most recent call last): File "C:\Users\0000\Desktop\0000\main.py", line 66, in on_timeout await self.message.edit(view=self) AttributeError: 'NoneType' object has no attribute 'edit'

It looks like there's a problem with editing messages. image

lIlIlIIlIIlIIlI avatar May 25 '25 13:05 lIlIlIIlIIlIIlI

Task exception was never retrieved future: <Task finished name='discord-ui-view-timeout-a2d765a0e561bfb23f667ef91f67f8ad' coro=<MyView.on_timeout() done, defined at C:\Users\0000\Desktop\0000\main.py:64> exception=AttributeError("'NoneType' object has no attribute 'edit'")> Traceback (most recent call last): File "C:\Users\0000\Desktop\0000\main.py", line 66, in on_timeout await self.message.edit(view=self) AttributeError: 'NoneType' object has no attribute 'edit'

It looks like there's a problem with editing messages. image

This is not new. It also happens in the stable version. I've complained about it several times, but they haven't fixed it yet.

iqnite avatar May 25 '25 15:05 iqnite

This is not new. It also happens in the stable version. I've complained about it several times, but they haven't fixed it yet.

@iqnite Please create a new issue with the necessary information, we'll look into it.

Dorukyum avatar May 25 '25 18:05 Dorukyum

https://github.com/discord/discord-api-spec/commit/2a2605c2df77df198aef8fc78e298a3652cbd746

we have attachment_id on the UnfurledMedia object now

Lulalaby avatar Jun 10 '25 21:06 Lulalaby

and the file display component has two more fields: size in bytes and name ref https://github.com/discord/discord-api-docs/pull/7609

Lulalaby avatar Jun 10 '25 23:06 Lulalaby

@NeloBlivion I think something broke with your recent pushes:

if payload["content"] or payload["embeds"]

in ``discord/webhooks/_async.py`

Is causing:

KeyError: 'content'
  File "discord/commands/core.py", line 138, in wrapped
    ret = await coro(arg)
  File "discord/commands/core.py", line 1078, in _invoke
    await self.callback(self.cog, ctx, **kwargs)
  File "src/extensions/chatcop/cogs/admin/__init__.py", line 260, in view
    await ctx.respond(view=view, ephemeral=True, allowed_mentions=discord.AllowedMentions.none())
  File "discord/ext/bridge/context.py", line 92, in respond
    return await self._respond(*args, **kwargs)
  File "discord/ext/bridge/context.py", line 145, in _respond
    return await self._get_super("respond")(*args, **kwargs)
  File "discord/interactions.py", line 694, in respond
    return await self.followup.send(*args, **kwargs)
  File "discord/webhook/async_.py", line 1822, in send
    params = handle_message_parameters(
  File "discord/webhook/async_.py", line 673, in handle_message_parameters
    if payload["content"] or payload["embeds"]:

Paillat-dev avatar Jul 02 '25 18:07 Paillat-dev