rewrite: Initial statistics UI.
This commit is contained in:
176
src/modules/statistics/ui/goals.py
Normal file
176
src/modules/statistics/ui/goals.py
Normal file
@@ -0,0 +1,176 @@
|
||||
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
|
||||
Reference in New Issue
Block a user