An optional component handler for hikari, inspired by discord.py's views.

Overview

hikari-miru

An optional component handler for hikari, inspired by discord.py's views.

Installation

pip install git+https://github.com/HyperGH/hikari-miru.git

Usage

None: if event.is_bot or not event.content: return if event.content.startswith("hm.buttons"): view = MyView(bot, timeout=60) # Create a new view message = await event.message.respond("Rock Paper Scissors!", components=view.build()) view.start(message) # Start listening for interactions await view.wait() # Wait until the view times out or gets stopped await event.message.respond("Thank you for playing!") bot.run()">
import hikari
import hikari_miru as miru


class MyView(miru.View):

    @miru.button(label="Rock", emoji="🪨", style=hikari.ButtonStyle.PRIMARY)
    async def rock_button(self, button: miru.Button, interaction: hikari.ComponentInteraction):
        await interaction.create_initial_response(hikari.ResponseType.MESSAGE_CREATE, content=f"Paper!")

    @miru.button(label="Paper", emoji="📜", style=hikari.ButtonStyle.PRIMARY)
    async def paper_button(self, button: miru.Button, interaction: hikari.ComponentInteraction):
        await interaction.create_initial_response(hikari.ResponseType.MESSAGE_CREATE, content=f"Scissors!")

    @miru.button(label="Scissors", emoji="✂️", style=hikari.ButtonStyle.PRIMARY)
    async def scissors_button(self, button: miru.Button, interaction: hikari.ComponentInteraction):
        await interaction.create_initial_response(hikari.ResponseType.MESSAGE_CREATE, content=f"Rock!")

    @miru.button(emoji="⏹️", style=hikari.ButtonStyle.DANGER, row=2)
    async def stop_button(self, button: miru.Button, interaction: hikari.ComponentInteraction):
        await interaction.create_initial_response(hikari.ResponseType.DEFERRED_MESSAGE_UPDATE)
        self.stop() # Stop listening for interactions


bot = hikari.GatewayBot(token="...")


@bot.listen()
async def buttons(event: hikari.GuildMessageCreateEvent) -> None:

    if event.is_bot or not event.content:
        return

    if event.content.startswith("hm.buttons"):
        view = MyView(bot, timeout=60)  # Create a new view
        message = await event.message.respond("Rock Paper Scissors!", components=view.build())
        view.start(message)  # Start listening for interactions
        await view.wait() # Wait until the view times out or gets stopped
        await event.message.respond("Thank you for playing!")

bot.run()

Issues and support

For general usage help or questions, ping Hyper#0001 in the hikari discord, if you have found a bug or have a feature request, feel free to open an issue!

Contributing

If you wish to contribute, be sure to first enable the formatting pre-commit hook via git config core.hooksPath .githooks, then make your changes.

Comments
  • Components break in hikari 2.0.0.dev110

    Components break in hikari 2.0.0.dev110

    Steps to reproduce

    1. Upgrade to hikari 2.0.0.dev110
    2. Send a message with any components
    3. Try to use said components
    4. Observe the components failing

    Expected result

    The bot should've responded to the component interaction.

    Actual result

    The bot didn't respond to any component interactions.

    System information

    hikari-miru - package information
    ----------------------------------
    Miru version: 1.1.1
    Install path: /root/venv/lib/python3.10/site-packages/miru
    Hikari version: 2.0.0.dev110
    Install path: /root/venv/lib/python3.10/site-packages/hikari
    Python: CPython 3.10.5 (GCC 12.1.0)
    System: Linux x86_64 (solar) - 5.18.16-arch1-1
    

    Further information

    No response

    Checklist

    • [X] I have made sure to remove ANY sensitive information (bot token, passwords, credentials, personal details, etc.).
    • [X] I have searched the issue tracker and have made sure it's not a duplicate. If it is a follow up of another issue, I have specified it.
    bug 
    opened by piotr25691 6
  • Allow customization of item and context classes

    Allow customization of item and context classes

    Wake up babe new pr just dropped

    import miru
    
    
    
    class MyButton(miru.Button):
        ...
    
    class MyContext(miru.Context):
        ...
    
    class MyView(miru.View):
        @miru.button(cls=MyButton, context_cls=MyContext, label="label")
        async def foo(self, button: MyButton, context: MyContext):
            ...
        
        @miru.button(label="label")
        async def bar(self, button: MyButton, context: MyContext):
            ...
    
    view = MyView()
    
    enhancement 
    opened by thesadru 4
  • Persistant components between bot restarts

    Persistant components between bot restarts

    Summary

    Miru should replace the current component persistence system to one thats easier to work with/possibly more efficient. I believe a side effect of my implementation will also allow custom timeout responses for buttons.

    Why is this needed?

    I think it is good if bots can still respond to a button after a restart.

    Ideal implementation

    # Internal
    class ComponentInfo:
        """Info used to distinguish miru components from each other."""
        ....
    
    # External
    # The user is expected to implement these functions if they want to use persistence between restarts.
    
    # Called when a component is created
    @miru.persistence.save_component
    async def save(nonce: str, component: miru.ComponentInfo) -> None:
        """Save a ComponentInfo object"""
        ...
    
    # Called when a component nonce is received that isn't in the cachce
    @miru.persistence.load_component
    async def load(nonce: str) -> miru.ComponentInfo | None:
        """Load a ComponentInfo object. Return `None` if the object doesn't exist."""
        ...
    
    # Called when 
    @miru.persistence.delete_component
    async def load(nonce: str) -> None:
        """Delete a component with a specific nonce."""
        ...
    

    The internals will need to be reworked is have "registry/cache" with all the components. The nonce will be used to run the correct callback. This is similar to how crescent works so I can vouch for the system.

    Checklist

    • [X] I have searched the issue tracker and have made sure it's not a duplicate. If it is a follow up of another issue, I have specified it.
    enhancement 
    opened by Lunarmagpie 3
  • Change autodefer to auto_defer

    Change autodefer to auto_defer

    This is more of a suggestion, but it might make consistency between different handlers and libs for Hikari more consistent if these references were changed.

    opened by GoogleGenius 1
  • link buttons cannot be added

    link buttons cannot be added

    When I try to add link buttons with the following code, an error is raised and it doesn't work.

    view = miru.View()
    view.add_item(miru.Button(label="View Online", url=str(ctx.options.user.display_avatar_url)))
    return await ctx.respond(e, components=view.build())
    

    The issue lies in https://github.com/HyperGH/hikari-miru/blob/main/miru/button.py#L127 and causes a following error:

    Traceback (most recent call last):
      File "C:\Users\User\PycharmProjects\h\iodine\lib\site-packages\lightbulb\app.py", line 994, in handle_message_create_for_prefix_commands
        await self.process_prefix_commands(context)
      File "C:\Users\User\PycharmProjects\h\iodine\lib\site-packages\lightbulb\app.py", line 966, in process_prefix_commands
        await context.invoke()
      File "C:\Users\User\PycharmProjects\h\iodine\lib\site-packages\lightbulb\context\base.py", line 292, in invoke
        await self.command.invoke(self)
      File "C:\Users\User\PycharmProjects\h\iodine\lib\site-packages\lightbulb\commands\prefix.py", line 112, in invoke
        await self(context)
      File "C:\Users\User\PycharmProjects\h\iodine\lib\site-packages\lightbulb\commands\base.py", line 435, in __call__
        return await self.callback(context)
      File "D:\Coding\Iodine\cogs\tools.py", line 41, in avatar
        view.add_item(miru.Button(label="View Online", url=str(ctx.options.user.display_avatar_url)))
      File "C:\Users\User\PycharmProjects\h\iodine\lib\site-packages\miru\button.py", line 109, in __init__
        self.style = hikari.ButtonStyle.LINK
      File "C:\Users\User\PycharmProjects\h\iodine\lib\site-packages\miru\button.py", line 128, in style
        raise ValueError("A link button cannot have it's style changed. Remove the url first.")
    ValueError: A link button cannot have it's style changed. Remove the url first.
    
    bug 
    opened by piotr25691 1
  • Fix typing issues in miru

    Fix typing issues in miru

    Some internal changes had to be made to make miru type-safe

    Changes

    • make items generic (item.view can now be given attributes)
    • make @button and @select be typed to return the same function that was given
      • A possible alternative is returning the actual type, happy to hear your opinions on this one!
    • added all missing typing.Any and None annotations where they were forgotten
    opened by thesadru 1
  • Add readme files to subdirectories

    Add readme files to subdirectories

    Summary

    Add readme files to most important subdirectories with short explainers detailing what can be found in the directory & directing users to helpful resources.

    Why is this needed?

    Because it is fancy.

    Ideal implementation

    Sit down and write them.

    Checklist

    • [X] I have searched the issue tracker and have made sure it's not a duplicate. If it is a follow up of another issue, I have specified it.
    enhancement 
    opened by HyperGH 0
  • Fix a few bugs and inconsistencies

    Fix a few bugs and inconsistencies

    See changelog.

    • no longer use explicit submodules unless they're exported
    • no longer use pass where it's not needed
    • ignore when 3rd party libraries are missing stubs
    • for the sake of user experience assume the class is initialized when annotating
    • make the colorama dependency optional (gawd the dependency management is funky)
    • allow for unloading miru and stopping all views
    enhancement 
    opened by thesadru 0
  • Add colorama to requirements

    Add colorama to requirements

    I install hikari-miru and did python3 -m miru and it said no package named colorama, after installing, it worked fine but it didn't install with hikari-miru, so I suggest adding it as a requirement

    bug 
    opened by VG08 0
  • Add exercises to documentation

    Add exercises to documentation

    Summary

    Add short exercises to documentation to facilitate learning the different features of the library.

    Why is this needed?

    It helps people learn the library a lot quicker if there are potentially quick example problems to solve.

    Ideal implementation

    To be decided.

    Checklist

    • [X] I have searched the issue tracker and have made sure it's not a duplicate. If it is a follow up of another issue, I have specified it.
    enhancement 
    opened by HyperGH 0
Releases(v2.0.1)
  • v2.0.1(Dec 6, 2022)

  • v2.0.0(Dec 5, 2022)

    • BREAKING: View.start() is now asynchronous and needs to be awaited.

    • BREAKING: View.start_listener() has been removed. Use View.start() instead.

    • Added support for modals via miru.Modal.

    • Added support for text input fields via miru.TextInput.

    • Added RawComponentContext, RawModalContext, ViewContext, and ModalContext that inherit from Context.

    • Added miru.InteractionResponse, an object representing responses sent out by the application to interactions.

    • Context.respond() and Context.edit_response() now return an InteractionResponse object.

    • Added Context.bot and Context.author as aliases for Context.app and Context.user respectively.

    • Added overloads to Context.defer() to allow use of different deffered response-types.

    • Added miru.abc.ViewItem and miru.abc.ModalItem that inherit from miru.abc.Item.

    • Views now expect items of type ViewItem and provide ViewContext.

    • Button and Select are now subclasses of ViewItem.

    • Added miru.abc.ItemHandler. View and Modal are subclasses of this object.

    • Added miru.abc.ItemHandler.last_context to access the last received context & interaction by the item handler.

    • miru.abc.ItemHandler now implements Sequence[hikari.api.MessageActionRowBuilder], and thus can be treated as a sequence of action rows. This means that calling .build() on item handlers is no longer required.

    • Removed miru.Interaction.

    • Added View.from_message() classmethod to allow creation of views from message components.

    • Added View.wait_for_input() to wait for any component interaction relating to the view.

    • Added timeout parameter to ItemHandler.wait().

    • Added View.get_context() and Modal.get_context() for custom context support.

    • Added two new event types ModalInteractionCreateEvent and ComponentInteractionCreateEvent.

    • These listeners include the corresponding raw context with the event object, along with every field from hikari.InteractionCreateEvent.

    • ItemHandler.add_item(), ItemHandler.remove_item(), and ItemHandler.clear_items() now return the ItemHandler object to allow for method chaining.

    • Added responded kwarg to NavigatorView to have the ability to send navigators on acknowledged interactions.

    • Added start_at kwarg to NavigatorView to define what the first page should be.

    • Added a “Jump to page” modal to built-in ext.nav.IndicatorButton when pressed.

    • Allow passing datetime.timedelta to ItemHandler.timeout upon instantiation.

    • Add delete_after to Context.respond() as a kwarg, and as a method to InteractionResponse.

    • Added miru.ext.nav.utils.Paginator to help pagination of long strings.

    • View.start() now accepts awaitables that return hikari.Message, thus allowing it to function with custom objects that support this behaviour.

    • Fixed selectoption is_default fields being ignored.

    • Deprecate miru.load and miru.unload in favor of miru.install and miru.uninstall.

    Source code(tar.gz)
    Source code(zip)
This is a batch script created to WEB-DL.

widevine-L3-WEB-DL-Script This is a batch script created to WEB-DL. Works well with .mpd files , for m3u8 please use n_m3u8 program (not included in t

Paranjay Singh 312 Dec 31, 2022
Visualization of COVID-19 Omicron wave data in Seoul, Osaka, Tokyo, Hong Kong and Shanghai. 首尔、大阪、东京、香港、上海由新冠病毒 Omicron 变异株引起的本轮疫情数据可视化分析。

COVID-19 in East Asian Megacities This repository holds original Python code for processing and visualization COVID-19 data in East Asian megacities a

STONE 10 May 18, 2022
A simple single-color identicon generator

Identicons What are identicons? Setup: git clone https://github.com/vjdad4m/identicons.git cd identicons pip3 install -r requirements.txt chmod +x

Adam Vajda 1 Oct 31, 2021
A web-based chat application that enables multiple users to interact with one another

A web-based chat application that enables multiple users to interact with one another, in the same chat room or different ones according to their choosing.

3 Apr 22, 2022
A custom advent of code I am completing

advent-of-code-custom A custom advent of code I am doing in python. The link to the problems I am solving is here: https://github.com/seldoncode/Adven

Rocio PV 2 Dec 11, 2021
Python project setup, updater, and launcher

Launcher Python project setup, updater, and launcher Purpose: Increase project productivity and provide features easily. Once installed as a git submo

DAAV, LLC 1 Jan 07, 2022
Python implementation of the ASFLIP advection method

This is a python implementation of the ASFLIP advection method . We would like to hear from you if you appreciate this work.

Raymond Yun Fei 133 Nov 13, 2022
A(Sync) Interface for internal Audible API written in pure Python.

Audible Audible is a Python low-level interface to communicate with the non-publicly Audible API. It enables Python developers to create there own Aud

mkb79 192 Jan 03, 2023
Tutor plugin for integration of Open edX with a Richie course catalog

Richie plugin for Tutor This is a plugin to integrate Richie, the learning portal CMS, with Open edX. The integration takes the form of a Tutor plugin

Overhang.IO 2 Sep 08, 2022
A Classroom Engagement Platform

Project Introduction This is project introduction Setup Setting up Postgres This is the most tricky part when setting up the application. You will nee

Santosh Kumar Patro 1 Nov 18, 2021
Created a Python Keylogger script.

Python Script Simple Keylogger Script WHAT IS IT? Created a Python Keylogger script. HOW IT WORKS Once the script has been executed, it will automatic

AC 0 Dec 12, 2021
Package pyVHR is a comprehensive framework for studying methods of pulse rate estimation relying on remote photoplethysmography (rPPG)

Package pyVHR (short for Python framework for Virtual Heart Rate) is a comprehensive framework for studying methods of pulse rate estimation relying on remote photoplethysmography (rPPG)

PHUSE Lab 261 Jan 03, 2023
SysCFG R/W Utility written in Swift

MagicCFG SysCFG R/W Utility written in Swift MagicCFG is one of our first, successful applications that we launched last year. The app makes it possib

Jan Fabel 82 Aug 08, 2022
Notebooks for computing approximations to the prime counting function using Riemann's formula.

Notebooks for computing approximations to the prime counting function using Riemann's formula.

Tom White 2 Aug 02, 2022
Covid 19 status. Flask application. CovidAPI. Heroku.

Covid 19 In this project we see total count of people who got this virus and total death. How does it works Written in Python. Web app, Flask. package

AmirHossein Mohammadi 12 Jan 16, 2022
Platform Tree for Xiaomi Redmi Note 7/7S (lavender)

The Xiaomi Redmi Note 7 (codenamed "lavender") is a mid-range smartphone from Xiaomi announced in January 2019. Device specifications Device Xiaomi Re

MUHAMAD KHOIRON 2 Dec 20, 2021
Python screenshot library, replacement for the Pillow ImageGrab module on Linux.

tldr: Use Pillow The pyscreenshot module is obsolete in most cases. It was created because PIL ImageGrab module worked on Windows only, but now Linux

455 Dec 24, 2022
Check a discord message and give it a percentage of scamminess

scamChecker Check a discord message and give it a percentage of scamminess Run the bot, and run the command !scamCheck and it will return a percentage

3 Sep 22, 2022
E5 自动续期

请选择跳转 新版本系统 (2021-2-9采用): 以后更新都在AutoApi,采用v0.0版本号覆盖式更新 AutoApi : 最新版 保留1到2个稳定的简易版,防止萌新大范围报错 AutoApi'X' : 稳定版1 ( 即本版AutpApiP ) AutoApiP ( 即v5.0,稳定版 ) —

95 Feb 15, 2021
Jannik Ramrath 1 Feb 05, 2022