-
-
Notifications
You must be signed in to change notification settings - Fork 482
feat: FileUpload in Modal #2938
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
Open
plun1331
wants to merge
27
commits into
master
Choose a base branch
from
feat/model3
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+359
−14
Open
Changes from 23 commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
d8e1eef
fix(state): ensure _messages is not None before updating message list
plun1331 9d3b32b
chore: update changelog
plun1331 f32b688
feat: FileUpload in Modals
plun1331 9af88cf
Merge remote-tracking branch 'origin/master' into feat/model3
plun1331 b025df5
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] 590a7a2
changelog & docs
plun1331 9c42603
ahh! nobody look! my shitty debug code!
plun1331 498c28b
add fileupload to __all__
plun1331 033f684
more changelog!!
plun1331 14665b6
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] 7ba0276
docs n enums n stuff
plun1331 a00d79e
Merge remote-tracking branch 'origin/feat/model3' into feat/model3
plun1331 a903005
oh god more debug code
plun1331 6e36204
that aint right
plun1331 7a66cb7
that *still* aint right
plun1331 7bff68a
Apply suggestion from @Soheab
plun1331 b356c75
suggested review changes
plun1331 4478fcb
Merge remote-tracking branch 'origin/feat/model3' into feat/model3
plun1331 9a08c32
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] a7fa66a
suggested review changes
plun1331 b9283b6
Merge remote-tracking branch 'origin/feat/model3' into feat/model3
plun1331 cfc2e5e
they can go in more than messages
plun1331 0b55aba
this is becoming a very large example
plun1331 99417f9
Update examples/modal_dialogs.py
plun1331 c0af721
Update discord/types/components.py (thanks copilot)
plun1331 46030b3
Apply suggestions from code review
plun1331 f3df97f
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,188 @@ | ||
from __future__ import annotations | ||
|
||
import os | ||
from typing import TYPE_CHECKING | ||
|
||
from ..components import FileUpload as FileUploadComponent | ||
from ..enums import ComponentType | ||
from ..message import Attachment | ||
|
||
__all__ = ("FileUpload",) | ||
|
||
if TYPE_CHECKING: | ||
from ..interactions import Interaction | ||
from ..types.components import FileUploadComponent as FileUploadComponentPayload | ||
|
||
|
||
class FileUpload: | ||
"""Represents a UI file upload field. | ||
|
||
.. versionadded:: 2.7 | ||
|
||
Parameters | ||
---------- | ||
label: :class:`str` | ||
The label for the file upload field. | ||
Must be 45 characters or fewer. | ||
custom_id: Optional[:class:`str`] | ||
The ID of the input text field that gets received during an interaction. | ||
description: Optional[:class:`str`] | ||
The description for the file upload field. | ||
Must be 100 characters or fewer. | ||
min_values: Optional[:class:`int`] | ||
The minimum number of files that must be uploaded. | ||
Defaults to 0 and must be between 0 and 10, inclusive. | ||
max_values: Optional[:class:`int`] | ||
The maximum number of files that can be uploaded. | ||
Must be between 1 and 10, inclusive. | ||
required: Optional[:class:`bool`] | ||
Whether the file upload field is required or not. Defaults to ``True``. | ||
row: Optional[:class:`int`] | ||
The relative row this file upload field belongs to. A modal dialog can only have 5 | ||
rows. By default, items are arranged automatically into those 5 rows. If you'd | ||
like to control the relative positioning of the row then passing an index is advised. | ||
For example, row=1 will show up before row=2. Defaults to ``None``, which is automatic | ||
ordering. The row number must be between 0 and 4 (i.e. zero indexed). | ||
""" | ||
|
||
__item_repr_attributes__: tuple[str, ...] = ( | ||
"label", | ||
"required", | ||
"min_values", | ||
"max_values", | ||
"custom_id", | ||
"id", | ||
"description", | ||
) | ||
|
||
def __init__( | ||
self, | ||
*, | ||
label: str, | ||
custom_id: str | None = None, | ||
min_values: int | None = None, | ||
max_values: int | None = None, | ||
required: bool | None = True, | ||
row: int | None = None, | ||
id: int | None = None, | ||
description: str | None = None, | ||
): | ||
super().__init__() | ||
if len(str(label)) > 45: | ||
raise ValueError("label must be 45 characters or fewer") | ||
if description and len(description) > 100: | ||
raise ValueError("description must be 100 characters or fewer") | ||
if min_values and (min_values < 0 or min_values > 10): | ||
raise ValueError("min_values must be between 0 and 10") | ||
if max_values and (max_values < 1 or max_values > 10): | ||
raise ValueError("max_length must be between 1 and 10") | ||
if custom_id is not None and not isinstance(custom_id, str): | ||
raise TypeError( | ||
f"expected custom_id to be str, not {custom_id.__class__.__name__}" | ||
) | ||
custom_id = os.urandom(16).hex() if custom_id is None else custom_id | ||
self.label: str = str(label) | ||
self.description: str | None = description | ||
|
||
self._underlying: FileUploadComponent = FileUploadComponent._raw_construct( | ||
type=ComponentType.file_upload, | ||
custom_id=custom_id, | ||
min_values=min_values, | ||
max_values=max_values, | ||
required=required, | ||
id=id, | ||
) | ||
self._attachments: list[Attachment] | None = None | ||
self.row = row | ||
self._rendered_row: int | None = None | ||
|
||
def __repr__(self) -> str: | ||
attrs = " ".join( | ||
f"{key}={getattr(self, key)!r}" for key in self.__item_repr_attributes__ | ||
) | ||
return f"<{self.__class__.__name__} {attrs}>" | ||
|
||
@property | ||
def type(self) -> ComponentType: | ||
return self._underlying.type | ||
|
||
@property | ||
def id(self) -> int | None: | ||
"""The file upload's ID. If not provided by the user, it is set sequentially by Discord.""" | ||
return self._underlying.id | ||
|
||
@property | ||
def custom_id(self) -> str: | ||
"""The ID of the file upload field that gets received during an interaction.""" | ||
return self._underlying.custom_id | ||
|
||
@custom_id.setter | ||
def custom_id(self, value: str): | ||
if not isinstance(value, str): | ||
raise TypeError( | ||
f"custom_id must be None or str not {value.__class__.__name__}" | ||
) | ||
self._underlying.custom_id = value | ||
|
||
@property | ||
def min_values(self) -> int | None: | ||
"""The minimum number of files that must be uploaded. Defaults to 0.""" | ||
return self._underlying.min_values | ||
|
||
@min_values.setter | ||
def min_values(self, value: int | None): | ||
if value and not isinstance(value, int): | ||
raise TypeError(f"min_values must be None or int not {value.__class__.__name__}") # type: ignore | ||
if value and (value < 0 or value > 10): | ||
raise ValueError("min_values must be between 0 and 10") | ||
self._underlying.min_values = value | ||
|
||
@property | ||
def max_values(self) -> int | None: | ||
"""The maximum number of files that can be uploaded.""" | ||
return self._underlying.max_values | ||
|
||
@max_values.setter | ||
def max_values(self, value: int | None): | ||
if value and not isinstance(value, int): | ||
raise TypeError(f"max_values must be None or int not {value.__class__.__name__}") # type: ignore | ||
if value and (value < 1 or value > 10): | ||
raise ValueError("max_values must be between 1 and 10") | ||
self._underlying.max_values = value | ||
|
||
@property | ||
def required(self) -> bool | None: | ||
"""Whether the input file upload is required or not. Defaults to ``True``.""" | ||
return self._underlying.required | ||
|
||
@required.setter | ||
def required(self, value: bool | None): | ||
if not isinstance(value, bool): | ||
raise TypeError(f"required must be bool not {value.__class__.__name__}") # type: ignore | ||
self._underlying.required = bool(value) | ||
|
||
@property | ||
def values(self) -> list[Attachment] | None: | ||
"""The files that were uploaded to the field.""" | ||
return self._attachments | ||
|
||
@property | ||
def width(self) -> int: | ||
return 5 | ||
|
||
def to_component_dict(self) -> FileUploadComponentPayload: | ||
return self._underlying.to_dict() | ||
|
||
def refresh_from_modal(self, interaction: Interaction, data: dict) -> None: | ||
values = data.get("values", []) | ||
self._attachments = [ | ||
Attachment( | ||
state=interaction._state, | ||
data=interaction.data["resolved"]["attachments"][attachment_id], | ||
) | ||
for attachment_id in values | ||
] | ||
|
||
@staticmethod | ||
def uses_label() -> bool: | ||
return True |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.