Update timetable to include scroller

This commit is contained in:
nex 2022-11-06 21:35:14 +00:00
parent 5543ba2a3e
commit f8900af678
2 changed files with 85 additions and 19 deletions

View file

@ -1,12 +1,12 @@
import asyncio
import sys
from typing import Optional, Union, Dict
from typing import Optional, Union, Dict, Callable
import discord
from discord.ext import commands, tasks
import json
from pathlib import Path
from utils import console
from utils import console, TimeTableDaySwitcherView
from datetime import time, datetime, timedelta
@ -42,6 +42,27 @@ class TimeTableCog(commands.Cog):
if date.timestamp() <= end_date.timestamp() and date.timestamp() >= start_date.timestamp():
return {"name": name, "start": start_date, "end": end_date}
def format_timetable_message(self, date: datetime) -> str:
"""Pre-formats the timetable or error message."""
if _break := self.are_on_break(date):
return f"No lessons on {discord.utils.format_dt(date, 'D')} - On break {_break['name']!r}."
lessons = self.timetable.get(date.strftime("%A").lower(), [])
if not lessons:
return f"No lessons on {discord.utils.format_dt(date, 'D')}."
blocks = [f"```\nTimetable for {date.strftime('%A')} ({date.strftime('%d/%m/%Y')}):\n```"]
for lesson in lessons:
start_datetime = date.replace(hour=lesson["start"][0], minute=lesson["start"][1])
end_datetime = date.replace(hour=lesson["end"][0], minute=lesson["end"][1])
text = (
f"{discord.utils.format_dt(start_datetime, 't')} to {discord.utils.format_dt(end_datetime, 't')}"
f":\n> Lesson Name: {lesson['name']!r}\n"
f"> Tutor: **{lesson['tutor']}**\n> Room: `{lesson['room']}`"
)
blocks.append(text)
return "\n\n".join(blocks)
def current_lesson(self, date: datetime = None) -> Optional[dict]:
date = date or datetime.now()
lessons = self.timetable.get(date.strftime("%A").lower(), [])
@ -106,7 +127,7 @@ class TimeTableCog(commands.Cog):
async def update_timetable_message(
self,
message: Union[discord.Message, discord.ApplicationContext],
message: Union[discord.Message, discord.ApplicationContext, discord.InteractionMessage],
date: datetime = None,
*,
no_prefix: bool = False,
@ -213,21 +234,9 @@ class TimeTableCog(commands.Cog):
else:
date = datetime.now()
lessons = self.timetable.get(date.strftime("%A").lower(), [])
if not lessons:
return await ctx.respond(f"No lessons on {discord.utils.format_dt(date, 'D')}.")
blocks = [f"```\nTimetable for {date.strftime('%A')}:\n```"]
for lesson in lessons:
start_datetime = date.replace(hour=lesson["start"][0], minute=lesson["start"][1])
end_datetime = date.replace(hour=lesson["end"][0], minute=lesson["end"][1])
text = (
f"{discord.utils.format_dt(start_datetime, 't')} to {discord.utils.format_dt(end_datetime, 't')}"
f":\n> Lesson Name: {lesson['name']!r}\n"
f"> Tutor: **{lesson['tutor']}**\n> Room: `{lesson['room']}`"
)
blocks.append(text)
await ctx.respond("\n\n".join(blocks))
text = self.format_timetable_message(date)
view = TimeTableDaySwitcherView(ctx.author, self, date)
await ctx.respond(text, view=view)
def setup(bot):

View file

@ -1,13 +1,18 @@
import secrets
from datetime import datetime, timedelta
import discord
import typing
import re
import orm
from discord.ui import View
from utils import send_verification_code, get_or_none, Student, VerifyCode, console, TOKEN_LENGTH, BannedStudentID
if typing.TYPE_CHECKING:
from cogs.timetable import TimeTableCog
class VerifyView(discord.ui.View):
class VerifyView(View):
def __init__(self, ctx: discord.ApplicationContext):
self.ctx = ctx
super().__init__(timeout=300, disable_on_timeout=True)
@ -141,3 +146,55 @@ class VerifyView(discord.ui.View):
ephemeral=True,
delete_after=60,
)
class TimeTableDaySwitcherView(View):
def __init__(self, user: discord.User, instance: "TimeTableCog", date: datetime):
super().__init__(disable_on_timeout=True)
self.user = user
self.cog = instance
self.current_date = date
self.update_buttons()
def mod_date(self, by: int):
self.current_date += timedelta(days=by)
self.update_buttons()
def update_buttons(self):
def _format(d: datetime) -> str:
return d.strftime("(%A) %d/%m/%Y")
day_before = self.current_date + timedelta(days=-1)
day_after = self.current_date + timedelta(days=1)
self.get_item("day_before").label = _format(day_before)
self.get_item("day_after").label = _format(day_after)
self.get_item("custom_day").label = _format(self.current_date)
async def interaction_check(self, interaction: discord.Interaction) -> bool:
return interaction.user == self.user
@discord.ui.button(
custom_id="day_before",
emoji="\N{leftwards black arrow}"
)
async def day_before(self, _, interaction: discord.Interaction):
self.mod_date(-1)
await interaction.response.edit_message(self.cog.format_timetable_message(self.current_date), view=self)
@discord.ui.button(
custom_id="custom_day",
emoji="\N{tear-off calendar}",
disabled=True,
style=discord.ButtonStyle.primary
)
async def current_day(self, _, __):
...
@discord.ui.button(
custom_id="day_after",
emoji="\N{leftwards black arrow}"
)
async def day_before(self, _, interaction: discord.Interaction):
self.mod_date(-1)
await interaction.response.edit_message(self.cog.format_timetable_message(self.current_date), view=self)