Source code for bacommon.docui.routes.classicinbox
# Released under the MIT License. See LICENSE for details.
#
"""Routes for the classic inbox doc-ui domain.
The inbox lists an account's messages (rewards, notices, tournament
results) as cards; responding to one -- claiming a reward, accepting or
declining -- posts back and gets the updated list in return.
"""
from __future__ import annotations # Docs-generation hack.
from dataclasses import dataclass
from typing import Annotated, override
from efro.dataclassio import ioprepped, IOAttrs
import bacommon.docui.v2 as dui2
from bacommon.docui.routes import (
DocUIRoute,
DocUILocalActionBase,
PressSound,
family_members,
)
[docs]
class InboxRoute(DocUIRoute):
"""Family class for classic inbox routes."""
[docs]
@override
@classmethod
def get_route_types(cls) -> tuple[type[DocUIRoute], ...]:
return family_members(AnyInboxRoute)
[docs]
@override
@classmethod
def get_window_layout(cls) -> dui2.WindowLayout:
# A narrow column of message cards, like the classic inbox.
return dui2.WindowLayout.SMALL_TALL
[docs]
@ioprepped
@dataclass
class Root(InboxRoute, path='/'):
"""The inbox: every message, newest first."""
#: Draw bounds and other debug bits.
debug: bool = False
[docs]
@ioprepped
@dataclass
class Respond(InboxRoute, path='/', method=dui2.RequestMethod.POST):
"""Respond to one message (claim it, accept or decline it, etc.).
Answered with the updated inbox, with any effects of the response
(reward animations, sounds) attached. Shares the inbox's own path so
the client treats the answer as the same page updated (holding its
scroll position) rather than a new one.
"""
#: The message.
entry_id: str
#: Whether this is the message's positive response (claim, accept,
#: ok) as opposed to its negative one (decline).
positive: bool = True
# All inbox routes.
AnyInboxRoute = Root | Respond
[docs]
class InboxLocalAction(DocUILocalActionBase):
"""Family class for classic inbox local-actions."""
[docs]
@override
@classmethod
def get_action_types(cls) -> tuple[type[DocUILocalActionBase], ...]:
return family_members(AnyInboxLocalAction)
[docs]
@ioprepped
@dataclass
class OpenUrl(InboxLocalAction, name='open_url'):
"""Open a url in the platform's browser."""
url: str
[docs]
@ioprepped
@dataclass
class TourneyScores(InboxLocalAction, name='tourney_scores'):
"""Show a tournament's final standings."""
tournament_id: str
[docs]
@override
@classmethod
def get_press_sound(cls) -> PressSound:
return PressSound.SWISH
# All inbox local-actions.
AnyInboxLocalAction = OpenUrl | TourneyScores
# Docs-generation hack; import some stuff that we likely only forward-declared
# in our actual source code so that docs tools can find it.
from typing import (Coroutine, Any, Literal, Callable,
Generator, Awaitable, Sequence, Self, TypeIs)
import asyncio
from concurrent.futures import Future
from pathlib import Path
from enum import Enum