Skip to content

Instantly share code, notes, and snippets.

@Kwieeciol
Last active February 22, 2022 17:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Kwieeciol/6df0ab2cd5426ed69fe6efc8f1728f93 to your computer and use it in GitHub Desktop.
Save Kwieeciol/6df0ab2cd5426ed69fe6efc8f1728f93 to your computer and use it in GitHub Desktop.
import discord # type: ignore
from typing import ClassVar, Optional
from itertools import cycle
import asyncio
from async_timeout import timeout
class LoadingBar:
SLEEP_TIME: ClassVar[int] = 1
def __init__(self, channel: discord.TextChannel) -> None:
SELF.MESSAGES: ClassVar[cycle] = cycle(
["Loading |", "Loading. /", "Loading.. --", "Loading... \\"]
)
self.channel: discord.TextChannel = channel
self.message: Optional[discord.Message] = None
self._running: bool = False
self._task: Optional[asyncio.Task] = None
def start(self) -> asyncio.Task:
if self.message is not None:
raise Exception("Loading bar already started")
self._task = task = asyncio.create_task(self.run())
return task
async def run(self) -> None:
self._running = True
self.message = message = await self.channel.send(next(self.MESSAGES))
while self._running:
await message.edit(content=next(self.MESSAGES))
await asyncio.sleep(self.SLEEP_TIME)
async def stop(self) -> None:
if self.message is None or self._task is None:
raise Exception("Loading bar not started")
self._running = False
async with timeout(self.SLEEP_TIME + 1):
await self._task
await self.message.delete()
async def __aenter__(self) -> "LoadingBar":
self.start()
return self
async def __aexit__(self, exc_type, exc_value, traceback) -> None:
await self.stop()
# Usage
@bot.command()
async def load(ctx):
message = await ctx.send("Initializing loading bar...")
async with LoadingBar(ctx.channel) as bar:
# do something here, the loading bar is started "in the background"
await message.edit(content="Loading bar started, deleting in 5 seconds...")
await asyncio.sleep(5)
# the loading bar is deleted here
@Kwieeciol
Copy link
Author

You can also use the loading bar your way, so:

@bot.command()
async def load(ctx):
    await ctx.send("Starting loading bar...")
    bar =  LoadingBar(ctx.channel)
    bar.start()

    # do something while the loading bar is "in the background"

    # stoping the loading bar
    await bar.stop()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment