PycordViews 1.2.5__tar.gz → 1.2.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. {pycordviews-1.2.5 → pycordviews-1.2.6}/PKG-INFO +1 -1
  2. {pycordviews-1.2.5 → pycordviews-1.2.6}/PycordViews.egg-info/PKG-INFO +1 -1
  3. {pycordviews-1.2.5 → pycordviews-1.2.6}/PycordViews.egg-info/SOURCES.txt +8 -0
  4. {pycordviews-1.2.5 → pycordviews-1.2.6}/PycordViews.egg-info/top_level.txt +1 -0
  5. pycordviews-1.2.6/pycordViews/kit/__init__.py +2 -0
  6. pycordviews-1.2.6/pycordViews/kit/confirm.py +69 -0
  7. pycordviews-1.2.6/pycordViews/kit/poll.py +147 -0
  8. {pycordviews-1.2.5 → pycordviews-1.2.6}/pycordViews/pagination/__init__.py +1 -0
  9. pycordviews-1.2.6/pycordViews/pagination/page.py +25 -0
  10. {pycordviews-1.2.5 → pycordviews-1.2.6}/pycordViews/pagination/pagination_view.py +24 -16
  11. {pycordviews-1.2.5 → pycordviews-1.2.6}/pycordViews/views/easy_modified_view.py +37 -11
  12. {pycordviews-1.2.5 → pycordviews-1.2.6}/setup.py +2 -2
  13. {pycordviews-1.2.5 → pycordviews-1.2.6}/LICENSE +0 -0
  14. {pycordviews-1.2.5 → pycordviews-1.2.6}/PycordViews.egg-info/dependency_links.txt +0 -0
  15. {pycordviews-1.2.5 → pycordviews-1.2.6}/PycordViews.egg-info/requires.txt +0 -0
  16. {pycordviews-1.2.5 → pycordviews-1.2.6}/README.md +0 -0
  17. {pycordviews-1.2.5 → pycordviews-1.2.6}/pycordViews/__init__.py +0 -0
  18. {pycordviews-1.2.5 → pycordviews-1.2.6}/pycordViews/menu/__init__.py +0 -0
  19. {pycordviews-1.2.5 → pycordviews-1.2.6}/pycordViews/menu/errors.py +0 -0
  20. {pycordviews-1.2.5 → pycordviews-1.2.6}/pycordViews/menu/menu.py +0 -0
  21. {pycordviews-1.2.5 → pycordviews-1.2.6}/pycordViews/menu/selectMenu.py +0 -0
  22. {pycordviews-1.2.5 → pycordviews-1.2.6}/pycordViews/multibot/__init__.py +0 -0
  23. {pycordviews-1.2.5 → pycordviews-1.2.6}/pycordViews/multibot/bot.py +0 -0
  24. {pycordviews-1.2.5 → pycordviews-1.2.6}/pycordViews/multibot/errors.py +0 -0
  25. {pycordviews-1.2.5 → pycordviews-1.2.6}/pycordViews/multibot/multibot.py +0 -0
  26. {pycordviews-1.2.5 → pycordviews-1.2.6}/pycordViews/multibot/process.py +0 -0
  27. {pycordviews-1.2.5 → pycordviews-1.2.6}/pycordViews/pagination/errors.py +0 -0
  28. {pycordviews-1.2.5 → pycordviews-1.2.6}/pycordViews/views/__init__.py +0 -0
  29. {pycordviews-1.2.5 → pycordviews-1.2.6}/pycordViews/views/errors.py +0 -0
  30. {pycordviews-1.2.5 → pycordviews-1.2.6}/pyproject.toml +0 -0
  31. {pycordviews-1.2.5 → pycordviews-1.2.6}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PycordViews
3
- Version: 1.2.5
3
+ Version: 1.2.6
4
4
  Summary: Views and multibot for py-cord library
5
5
  Home-page: https://github.com/BOXERRMD/Py-cord_Views
6
6
  Author: Chronos (alias BOXERRMD)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PycordViews
3
- Version: 1.2.5
3
+ Version: 1.2.6
4
4
  Summary: Views and multibot for py-cord library
5
5
  Home-page: https://github.com/BOXERRMD/Py-cord_Views
6
6
  Author: Chronos (alias BOXERRMD)
@@ -8,6 +8,9 @@ PycordViews.egg-info/dependency_links.txt
8
8
  PycordViews.egg-info/requires.txt
9
9
  PycordViews.egg-info/top_level.txt
10
10
  pycordViews/__init__.py
11
+ pycordViews/kit/__init__.py
12
+ pycordViews/kit/confirm.py
13
+ pycordViews/kit/poll.py
11
14
  pycordViews/menu/__init__.py
12
15
  pycordViews/menu/errors.py
13
16
  pycordViews/menu/menu.py
@@ -19,10 +22,14 @@ pycordViews/multibot/multibot.py
19
22
  pycordViews/multibot/process.py
20
23
  pycordViews/pagination/__init__.py
21
24
  pycordViews/pagination/errors.py
25
+ pycordViews/pagination/page.py
22
26
  pycordViews/pagination/pagination_view.py
23
27
  pycordViews/views/__init__.py
24
28
  pycordViews/views/easy_modified_view.py
25
29
  pycordViews/views/errors.py
30
+ pycordViews/kit/__init__.py
31
+ pycordViews/kit/confirm.py
32
+ pycordViews/kit/poll.py
26
33
  pycordViews/menu/__init__.py
27
34
  pycordViews/menu/errors.py
28
35
  pycordViews/menu/menu.py
@@ -34,6 +41,7 @@ pycordViews/multibot/multibot.py
34
41
  pycordViews/multibot/process.py
35
42
  pycordViews/pagination/__init__.py
36
43
  pycordViews/pagination/errors.py
44
+ pycordViews/pagination/page.py
37
45
  pycordViews/pagination/pagination_view.py
38
46
  pycordViews/views/__init__.py
39
47
  pycordViews/views/easy_modified_view.py
@@ -1,4 +1,5 @@
1
1
  pycordViews
2
+ pycordViews/kit
2
3
  pycordViews/menu
3
4
  pycordViews/multibot
4
5
  pycordViews/pagination
@@ -0,0 +1,2 @@
1
+ from .poll import Poll
2
+ from .confirm import Confirm
@@ -0,0 +1,69 @@
1
+ from typing import Optional
2
+ from ..views.easy_modified_view import EasyModifiedViews
3
+ from discord import Interaction, ButtonStyle, Bot
4
+ from discord.ui import Button
5
+ from asyncio import wait_for, Future, get_event_loop, TimeoutError
6
+
7
+
8
+ class Confirm:
9
+
10
+ def __init__(self, timeout: Optional[float] = None, disable_on_click: bool = False):
11
+ """
12
+ Init a Confirm class instance kit.
13
+ :param timeout: Time before end the view
14
+ """
15
+ self.__timeout: float = timeout
16
+ self.__disable_on_click: bool = disable_on_click
17
+ self.__view: EasyModifiedViews = EasyModifiedViews(disabled_on_timeout=True, timeout=timeout, call_on_timeout=self._on_timeout)
18
+ self.__button_confirm: Button = Button(label='Confirm', emoji='✅', style=ButtonStyle.green, custom_id='Confirm_confirm')
19
+ self.__button_denied: Button = Button(label='Denied', emoji='❌', style=ButtonStyle.gray, custom_id='Confirm_denied')
20
+ self.__view.add_items(self.__button_confirm, self.__button_denied)
21
+ self.__view.set_callable(self.__button_confirm.custom_id, _callable=self._confirm)
22
+ self.__view.set_callable(self.__button_denied.custom_id, _callable=self._denied)
23
+
24
+ self.__future: Future = get_event_loop().create_future()
25
+
26
+ async def _confirm(self, button: Button, interaction: Interaction):
27
+ """
28
+ Base asynchronous _confirm function called when button is pressed
29
+ """
30
+ if not self.__future.done():
31
+ self.__future.set_result(True)
32
+ if self.__disable_on_click:
33
+ await self.__view.disable_items('Confirm_confirm', 'Confirm_denied')
34
+ await interaction.response.defer()
35
+
36
+ async def _denied(self, button: Button, interaction: Interaction):
37
+ """
38
+ Base asynchronous _denied function called when button is pressed
39
+ """
40
+ if not self.__future.done():
41
+ self.__future.set_result(False)
42
+ if self.__disable_on_click:
43
+ await self.__view.disable_items('Confirm_confirm', 'Confirm_denied')
44
+ await interaction.response.defer()
45
+
46
+ async def wait_for_response(self) -> Optional[bool]:
47
+ """
48
+ Wait and return the result of current button pressed.
49
+ :return: True if it is confirmed, False else. If timeout is reached, return None
50
+ """
51
+ try:
52
+ return await wait_for(self.__future, timeout=self.__timeout)
53
+
54
+ except TimeoutError:
55
+ return None
56
+
57
+ async def _on_timeout(self, ctx):
58
+ """
59
+ Called when the timeout is reached to end the Future
60
+ """
61
+ if not self.__future.done():
62
+ self.__future.set_result(None)
63
+
64
+ @property
65
+ def get_view(self) -> EasyModifiedViews:
66
+ """
67
+ Get the current view
68
+ """
69
+ return self.__view
@@ -0,0 +1,147 @@
1
+ from ..views.easy_modified_view import EasyModifiedViews
2
+ from ..views.errors import CoroutineError
3
+ from discord.ui.button import Button, ButtonStyle
4
+ from discord import Emoji, PartialEmoji, Embed, Color
5
+ from typing import Optional, Callable, Union
6
+ from asyncio import iscoroutinefunction
7
+
8
+
9
+ class Poll:
10
+
11
+ def __init__(self, timeout: Optional[float] = None, unique_vote: bool = True):
12
+ """
13
+ Class instance to make poll with buttons
14
+ :param timeout: Time before end the view
15
+ :param unique_vote: Set True to make vote unchangeable
16
+ """
17
+ self.yes_count: int = 0
18
+ self.no_count: int = 0
19
+ self.__unique_vote: bool = unique_vote
20
+ self.__view = EasyModifiedViews(disabled_on_timeout=True, timeout=timeout)
21
+ self.__button_yes = Button(label='Yes', emoji='✅', custom_id='Poll_yes', style=ButtonStyle.green)
22
+ self.__button_no = Button(label='No', emoji='❌', custom_id='Poll_no', style=ButtonStyle.gray)
23
+ self.__view.add_items(self.__button_yes, self.__button_no)
24
+ self.__view.set_callable('Poll_yes', _callable=self.yes)
25
+ self.__view.set_callable('Poll_no', _callable=self.no)
26
+ self.__view.call_on_timeout(self._result) # asynchrone fonction quand la view est arrivé à son timeout
27
+ self.__clicked_members: list[int] = []
28
+
29
+ def add_answer_button(self, label: str,
30
+ custom_id: str,
31
+ emoji: Optional[Union[str, Emoji, PartialEmoji]] = None,
32
+ style: ButtonStyle = ButtonStyle.secondary,
33
+ row: Optional[int] = None,
34
+ _callable: Optional[Callable] = None) -> Button:
35
+ """
36
+ Create a new answer button and add it in the view.
37
+ :param label: Button label
38
+ :param custom_id: Button ID
39
+ :param emoji: Button emoji
40
+ :param style: Button style
41
+ :param row: Button row
42
+ :param _callable: Asynchronous function linked to the button interaction. It's called when the button is pressed
43
+ """
44
+
45
+ if not iscoroutinefunction(_callable):
46
+ raise CoroutineError(_callable)
47
+
48
+ b = Button(label=label, emoji=emoji, style=style, row=row, custom_id=custom_id)
49
+ self.__view.add_items(b)
50
+ self.__view.set_callable(custom_id, _callable=_callable)
51
+
52
+ return b
53
+
54
+
55
+ def set_yes_button(self, label: Optional[str] = None,
56
+ emoji: Optional[Union[str, Emoji, PartialEmoji]] = None,
57
+ style: Optional[ButtonStyle] = None,
58
+ row: Optional[int] = None,
59
+ _callable: Optional[Callable] = None):
60
+ """
61
+ Set yes button parameters (he didn't change dynamically if the view was sent before)
62
+ :param label: Button label
63
+ :param emoji: Button emoji
64
+ :param style: Button style
65
+ :param row: Button row
66
+ :param _callable: Asynchronous function linked to the button interaction. It's called when the button is pressed
67
+ """
68
+ self.__button_yes.emoji = emoji if emoji is not None else self.__button_yes.emoji
69
+ self.__button_yes.style = style if style is not None else self.__button_yes.style
70
+ self.__button_yes.label = label if label is not None else self.__button_yes.label
71
+ self.__button_yes.row = row if row is not None else self.__button_yes.row
72
+
73
+ if not iscoroutinefunction(_callable):
74
+ raise CoroutineError(_callable)
75
+
76
+ if _callable is not None:
77
+ self.__view.set_callable(self.__button_yes.custom_id, _callable=_callable)
78
+
79
+ def set_no_button(self, label: Optional[str] = None,
80
+ emoji: Optional[Union[str, Emoji, PartialEmoji]] = None,
81
+ style: Optional[ButtonStyle] = None,
82
+ row: Optional[int] = None,
83
+ _callable: Optional[Callable] = None):
84
+ """
85
+ Set no button parameters (he didn't change dynamically if the view was sent before)
86
+ :param label: Button label
87
+ :param emoji: Button emoji
88
+ :param row: Button row
89
+ :param style: Button style
90
+ :param callable: Asynchronous function linked to the button interaction. It's called when the button is pressed
91
+ """
92
+ self.__button_no.emoji = emoji if emoji is not None else self.__button_no.emoji
93
+ self.__button_no.style = style if style is not None else self.__button_no.style
94
+ self.__button_no.label = label if label is not None else self.__button_no.label
95
+ self.__button_no.row = row if row is not None else self.__button_no.row
96
+
97
+ if not iscoroutinefunction(_callable):
98
+ raise CoroutineError(_callable)
99
+
100
+ if _callable is not None:
101
+ self.__view.set_callable(self.__button_no.custom_id, _callable=_callable)
102
+
103
+ async def yes(self, button, interaction):
104
+ """
105
+ Base asynchronous function when "yes" button is pressed.
106
+ Increment “yes_count” attribute when pressed and respond with an ephemeral message.
107
+ This function can be changed.
108
+ """
109
+ if self.__unique_vote and interaction.user.id in self.__clicked_members:
110
+ await interaction.response.send_message(f"You have already voted !", ephemeral=True)
111
+ return
112
+ self.yes_count += 1
113
+ self.__clicked_members.append(interaction.user.id)
114
+ await interaction.response.send_message(f"You have selected : {button.label}", ephemeral=True)
115
+
116
+ async def no(self, button, interaction):
117
+ """
118
+ Base asynchronous function when "no" button is pressed.
119
+ Increment “yes_count” attribute when pressed and respond with an ephemeral message.
120
+ This function can be changed.
121
+ """
122
+ if self.__unique_vote and interaction.user.id in self.__clicked_members:
123
+ await interaction.response.send_message(f"You have already voted !", ephemeral=True)
124
+ return
125
+ self.yes_count += 1
126
+ self.__clicked_members.append(interaction.user.id)
127
+ await interaction.response.send_message(f"You have selected : {button.label}", ephemeral=True)
128
+
129
+ async def _result(self, ctx):
130
+ """
131
+ Asynchronous base function called when timeout is reached.
132
+ :param ctx: Actual command context
133
+ """
134
+ embed = Embed(title="Poll ended !",
135
+ description=f"## Results :\n"
136
+ f" `-` {self.__button_yes.emoji.name} {self.__button_yes.label} -> `{self.yes_count}`\n"
137
+ f" `-` {self.__button_no.emoji.name} {self.__button_no.label} -> `{self.no_count}`",
138
+ color=Color.gold())
139
+
140
+ await self.__view.message.reply(embed=embed)
141
+
142
+ @property
143
+ def get_view(self) -> EasyModifiedViews:
144
+ """
145
+ Get the current view
146
+ """
147
+ return self.__view
@@ -1,2 +1,3 @@
1
1
  from .pagination_view import Pagination
2
2
  from .errors import PageNumberNotFound
3
+ from .page import Page
@@ -0,0 +1,25 @@
1
+ from __future__ import annotations
2
+ from typing import Optional, Callable
3
+ from discord import File, Embed
4
+ from immutableType import callable_, NoneType
5
+ from ..views import EasyModifiedViews
6
+
7
+ class Page:
8
+
9
+ @callable_(is_class=True, kwargs_types={'view': [NoneType, EasyModifiedViews], 'content': [NoneType, str], 'embed': [NoneType, Embed], 'embeds': [list], 'file': [NoneType, File], 'files': [list]})
10
+ def __init__(self, view: EasyModifiedViews, content: Optional[str] = None, embed: Optional[Embed] = None, embeds: list[Embed] = [], file: Optional[File] = None, files: Optional[list[File]] = []):
11
+ """
12
+ Init Page instance from Pagination class
13
+ """
14
+ self.__view: EasyModifiedViews = view if view is not None else EasyModifiedViews()
15
+ self.content: Optional[str] = content
16
+ self.embeds: list[Embed] = embeds if embed is None else embeds + [embed]
17
+ self.files: list[File] = files if file is None else files + [file]
18
+
19
+ @property
20
+ def get_page_view(self) -> EasyModifiedViews:
21
+ """
22
+ Get the current page view
23
+ """
24
+ return self.__view
25
+
@@ -1,9 +1,10 @@
1
1
  from ..views.easy_modified_view import EasyModifiedViews
2
- from discord import ButtonStyle, Interaction, TextChannel, Member, ApplicationContext
2
+ from discord import ButtonStyle, Interaction, TextChannel, Member, ApplicationContext, File, Embed
3
3
  from discord.ui import Button
4
4
  from .errors import PageNumberNotFound
5
+ from .page import Page
5
6
 
6
- from typing import Union, Any
7
+ from typing import Union, Any, Optional
7
8
 
8
9
 
9
10
  class Pagination:
@@ -28,17 +29,17 @@ class Pagination:
28
29
  self.__view.add_items(Button(label='⏭', row=0, custom_id='forward+', style=ButtonStyle.blurple))
29
30
  self.__view.set_callable('back+', 'back', 'forward', 'forward+', _callable=self.__turn_page)
30
31
 
31
- self.__pages: list[tuple[tuple, dict]] = []
32
+ self.__pages: list[Page] = []
32
33
  self.__current_page: int = 0
33
34
 
34
- def add_page(self, *args, **kwargs) -> "Pagination":
35
+ def add_page(self, content: Optional[str] = None, embed: Optional[Embed] = None, embeds: list[Embed] = [], file: Optional[File] = None, files: Optional[list[File]] = [], view: Optional[EasyModifiedViews] = None) -> "Pagination":
35
36
  """
36
37
  Adds a page (in a list) as if this function directly sent the message
37
38
  Pages are just modified and not reset ! Don't forget to disable embeds or content if the page don't need this.
38
39
 
39
40
  add_page(content="my message", embeds=[embed1, embed2], ...)
40
41
  """
41
- self.__pages.append((args, kwargs))
42
+ self.__pages.append(Page(content=content, embed=embed, embeds=embeds, file=file, files=files, view=view))
42
43
  self.__view.get_ui('counter').label = f"{self.__current_page+1}/{len(self.__pages)}"
43
44
  return self
44
45
 
@@ -86,13 +87,15 @@ class Pagination:
86
87
 
87
88
  self.__view.get_ui('counter').label = f"{self.__current_page + 1}/{len(self.__pages)}"
88
89
 
89
- await interaction.message.edit(
90
+ c = self.__pages[self.__current_page]
90
91
 
91
- *self.__pages[self.__current_page][0],
92
+ await interaction.message.edit(
92
93
 
93
- view=self.get_view,
94
+ content=c.content,
95
+ embeds=c.embeds,
96
+ files=c.files,
94
97
 
95
- **self.__pages[self.__current_page][1]
98
+ view=self.__view.copy() + self.__pages[self.__current_page].get_page_view,
96
99
 
97
100
  )
98
101
 
@@ -104,23 +107,28 @@ class Pagination:
104
107
  Send pagination without introduction message.
105
108
  :param target: The member or channel to send the pagination
106
109
  """
107
- return await self.__view.send(ctx=target, *self.__pages[0][0], **self.__pages[0][1], view=self.get_view)
110
+ first_page = self.__pages[0]
111
+ return await self.__view.send(target=target, content=first_page.content, embeds=first_page.embeds, files=first_page.files, view=self.__view.copy() + first_page.get_page_view)
108
112
 
109
113
  async def respond(self, ctx: ApplicationContext) -> Any:
110
114
  """
111
115
  Respond to the command call
116
+ :param ctx: ApplicationContext to respond
112
117
  """
113
- return await self.__view.respond(ctx=ctx, *self.__pages[0][0], **self.__pages[0][1], view=self.get_view)
118
+ first_page = self.__pages[0]
119
+ return await self.__view.respond(ctx=ctx, content=first_page.content, embeds=first_page.embeds, files=first_page.files, view=self.__view.copy() + first_page.get_page_view)
114
120
 
115
- @property
116
- def get_view(self) -> EasyModifiedViews:
121
+ def get_page(self, page_number: int) -> Page:
117
122
  """
118
- Get the view of pagination
123
+ Get the page
119
124
  """
120
- return self.__view
125
+ if 0 <= page_number <= len(self.__pages):
126
+ return self.__pages[page_number]
127
+ else:
128
+ raise PageNumberNotFound(page_number)
121
129
 
122
130
  @property
123
- def get_page(self) -> int:
131
+ def get_current_showed_page(self) -> int:
124
132
  """
125
133
  Get the number of showed page
126
134
  (start to 0)
@@ -2,8 +2,8 @@ from __future__ import annotations
2
2
  from discord import Interaction, ApplicationContext, Message, Member
3
3
  from discord.abc import GuildChannel
4
4
  from discord.ui import View, Item
5
- from typing import Union, Callable, TYPE_CHECKING, Optional, Any
6
- from asyncio import iscoroutinefunction, create_task, get_event_loop, Future
5
+ from typing import Union, Callable, TYPE_CHECKING, Optional
6
+ from asyncio import iscoroutinefunction, create_task
7
7
 
8
8
  from .errors import CustomIDNotFound, CoroutineError
9
9
 
@@ -56,14 +56,17 @@ class EasyModifiedViews(View):
56
56
  self.__ctx = await target.send(*args, **kwargs)
57
57
 
58
58
  def add_items(self,
59
- *items: Union[Item, SelectMenu, Pagination, Poll, Confirm]) -> "EasyModifiedViews":
59
+ *items: Union[EasyModifiedViews, Confirm, Pagination, Poll, SelectMenu, Item]) -> EasyModifiedViews:
60
60
  """
61
61
  Add all items in the View.
62
62
  """
63
63
 
64
64
  for ui in items:
65
65
 
66
- if type(ui).__name__ in ('SelectMenu', 'Pagination', 'Confirm', 'Poll'):
66
+ if ui is None: # si l'ui n'est pas setup
67
+ continue
68
+
69
+ if type(ui).__name__ in ('SelectMenu', 'Pagination', 'Confirm', 'Poll', 'EasyModifiedViews'):
67
70
  for item in ui.get_view.items:
68
71
  self.add_items(item)
69
72
  self.set_callable(item.custom_id, _callable=ui.get_callable(item.custom_id))
@@ -286,13 +289,6 @@ class EasyModifiedViews(View):
286
289
  elif self.__ctx:
287
290
  await self.__ctx.edit(view=self)
288
291
 
289
- @property
290
- def get_uis(self) -> list[Item]:
291
- """
292
- Get all uis in the view
293
- """
294
- return [i['ui'] for i in self.__callback.values()]
295
-
296
292
  def get_ui(self, custom_id: str) -> Item:
297
293
  """
298
294
  Get an ui in the view
@@ -301,9 +297,39 @@ class EasyModifiedViews(View):
301
297
  self.__check_custom_id(custom_id)
302
298
  return self.__callback[custom_id]['ui']
303
299
 
300
+ def copy(self) -> EasyModifiedViews:
301
+ """
302
+ Return an exact copy of the view. All mutable object in the view is a new object
303
+ """
304
+ e = EasyModifiedViews(timeout=self.__timeout, disabled_on_timeout=self.__disabled_on_timeout).add_items(*self.items)
305
+ for i in self.items:
306
+ e.set_callable(i.custom_id, _callable=self.get_callable(i.custom_id))
307
+
308
+ return e
309
+
304
310
  def __str__(self):
305
311
  return str(self.__callback)
306
312
 
307
313
  @property
308
314
  def items(self) -> tuple[Item]:
309
315
  return tuple([i['ui'] for i in self.__callback.values()])
316
+
317
+ @property
318
+ def get_view(self) -> EasyModifiedViews:
319
+ """
320
+ Get The current view. Don't use in your code
321
+ """
322
+ return self
323
+
324
+ def __add__(self, _view: Union[EasyModifiedViews, Confirm, Pagination, Poll, SelectMenu, Item]) -> EasyModifiedViews:
325
+ """
326
+ Add all items to _view from the current EasyModifiedViews instance
327
+ """
328
+ self.add_items(_view)
329
+ return self
330
+
331
+ def __iadd__(self, _view) -> EasyModifiedViews:
332
+ """
333
+ Add all items to _view from the current EasyModifiedViews instance
334
+ """
335
+ return self.__add__(_view)
@@ -5,7 +5,7 @@ with open("README.md", encoding='utf-8') as file:
5
5
 
6
6
  setup(
7
7
  name="PycordViews",
8
- version="1.2.5",
8
+ version="1.2.6",
9
9
  url="https://github.com/BOXERRMD/Py-cord_Views",
10
10
  author="Chronos (alias BOXERRMD)",
11
11
  author_email="vagabonwalybi@gmail.com",
@@ -27,6 +27,6 @@ setup(
27
27
  install_requires=[
28
28
  "immutable-Python-type"
29
29
  ],
30
- packages=['pycordViews', 'pycordViews/pagination', 'pycordViews/views', 'pycordViews/menu', 'pycordViews/multibot'],
30
+ packages=['pycordViews', 'pycordViews/pagination', 'pycordViews/views', 'pycordViews/menu', 'pycordViews/multibot', 'pycordViews/kit'],
31
31
  python_requires='>=3.9'
32
32
  )
File without changes
File without changes
File without changes
File without changes