Files
croccybot/src/modules/statistics/ui/goals.py

177 lines
5.2 KiB
Python

from typing import Optional
from enum import Enum
import asyncio
import discord
from discord.ui.button import button, Button, ButtonStyle
from discord.ui.select import select, Select, SelectOption
from utils.lib import MessageArgs
from .. import babel
from .base import StatsUI
from gui.cards import WeeklyStatsCard, MonthlyStatsCard, WeeklyGoalCard, MonthlyGoalCard
_p = babel._p
class SessionType(Enum):
Voice = 0
Text = 1
Anki = 2
class GoalBaseUI(StatsUI):
"""
switcher row, local|global
voice, text, anki
Prev, Select, Next, Edit Goals
"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.__rendered = {} # (offset, type) |-> (goal_card, stats_card)
self._offset: int = 0
self._stat_type: Optional[SessionType] = None
@property
def _key(self):
return (self._offset, self._stat_type)
@property
def _rendered(self):
return self.__rendered.get(self._key, None) is not None
async def lazy_rerun_using(self, interaction: discord.Interaction):
if self._rendered:
await interaction.response.defer()
waiting = None
else:
await interaction.response.defer(thinking=True)
waiting = interaction
await self.run(waiting_interaction=waiting)
@button(label='VOICE_PLACEHOLDER')
async def voice_pressed(self, press: discord.Interaction, pressed: Button):
self._stat_type = SessionType.Voice
await self.lazy_rerun_using(press)
@button(label='TEXT_PLACEHOLDER')
async def text_pressed(self, press: discord.Interaction, pressed: Button):
self._stat_type = SessionType.Text
await self.lazy_rerun_using(press)
@button(label='ANKI_PLACEHOLDER')
async def anki_pressed(self, press: discord.Interaction, pressed: Button):
self._stat_type = SessionType.Anki
await self.lazy_rerun_using(press)
@button(label="PREV_PLACEHOLDER")
async def prev_pressed(self, press: discord.Interaction, pressed: Button):
self._offset -= 1
await self.lazy_rerun_using(press)
@button(label="NEXT_PLACEHOLDER")
async def next_pressed(self, press: discord.Interaction, pressed: Button):
self._offset += 1
await self.lazy_rerun_using(press)
@button(label="SELECT_PLACEHOLDER")
async def next_pressed(self, press: discord.Interaction, pressed: Button):
# TODO: Date selection
...
@button(label="EDIT_PLACEHOLDER")
async def edit_pressed(self, press: discord.Interaction, pressed: Button):
# TODO: Goal editing
...
class MonthlyUI(StatsUI):
_ui_name = _p('ui:MonthlyUI|name', 'Monthly')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._rendered = False
self._stats_card: Optional[MonthlyStatsCard] = None
self._goals_card: Optional[MonthlyGoalCard] = None
async def redraw(self):
self._layout = [
(*self._switcher_buttons, self.toggle_pressed)
]
await super().redraw()
async def make_message(self) -> MessageArgs:
if not self._rendered:
await self._render()
stats_file = self._stats_card.as_file('monthly_stats.png')
goals_file = self._goals_card.as_file('monthly_goals.png')
return MessageArgs(files=[goals_file, stats_file])
async def _render(self):
await asyncio.gather(self._render_goals(), self._render_stats())
self._rendered = True
async def _render_stats(self):
args = await MonthlyStatsCard.sample_args(None)
card = MonthlyStatsCard(**args)
await card.render()
self._stats_card = card
return card
async def _render_goals(self):
args = await MonthlyGoalCard.sample_args(None)
card = WeeklyGoalCard(**args)
await card.render()
self._goals_card = card
return card
class WeeklyUI(StatsUI):
_ui_name = _p('ui:WeeklyUI|name', 'Weekly')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._rendered = False
self._stats_card: Optional[WeeklyStatsCard] = None
self._goals_card: Optional[WeeklyGoalCard] = None
async def redraw(self):
self._layout = [
[*self._switcher_buttons]
]
if self.guild:
self._layout[0].append(self.toggle_pressed)
await super().redraw()
async def _render(self):
await asyncio.gather(self._render_goals(), self._render_stats())
self._rendered = True
async def make_message(self) -> MessageArgs:
if not self._rendered:
await self._render()
stats_file = self._stats_card.as_file('weekly_stats.png')
goals_file = self._goals_card.as_file('weekly_goals.png')
return MessageArgs(files=[goals_file, stats_file])
async def _render_stats(self):
args = await WeeklyStatsCard.sample_args(None)
card = WeeklyStatsCard(**args)
await card.render()
self._stats_card = card
return card
async def _render_goals(self):
args = await WeeklyGoalCard.sample_args(None)
card = WeeklyGoalCard(**args)
await card.render()
self._goals_card = card
return card