Source code for bacommon.docui.routes.classicstore

# Released under the MIT License. See LICENSE for details.
#
"""Routes for the classic store and inventory doc-ui domains.

The store and inventory are two domains served by a single set of
pages (the inventory is essentially the store filtered to owned things
plus player-profiles), so they share one route family. Each has its
own local-actions.
"""

from __future__ import annotations  # Docs-generation hack.

from enum import Enum
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,
    DocUIState,
    PressSound,
    family_members,
)


[docs] class PurchaseMethod(Enum): """How to purchase something.""" TOKENS = 't' TICKETS = 'k' PURPLE_TICKETS = 'p' GOLD_PASS = 'g'
[docs] class StoreRoute(DocUIRoute): """Family class for classic store/inventory routes."""
[docs] @override @classmethod def get_route_types(cls) -> tuple[type[DocUIRoute], ...]: return family_members(AnyStoreRoute)
[docs] @ioprepped @dataclass class Root(StoreRoute, path='/'): """The main store/inventory listing.""" #: Draw bounds and other debug bits. debug: bool = False #: Set on the page's own refresh button. One-time-use; the server #: does not carry it into further links. is_refresh: bool = False #: (Inventory) the client is showing its locally-spliced legacy #: profiles; omit cloud profile rows. legacy_profiles: bool = False #: (Inventory) render only the profiles section (the in-game #: profile browser). profiles_only: bool = False #: Legacy purchase ids required to unlock something; when provided, #: only items providing those are shown. unlockreqs: list[str] | None = None
[docs] @ioprepped @dataclass class Purchase(StoreRoute, path='/p'): """Purchase options for a single item.""" purchase_id: str debug: bool = False
[docs] @ioprepped @dataclass class PurchaseConfirm(StoreRoute, path='/pc', method=dui2.RequestMethod.POST): """Actually purchase an item.""" purchase_id: str purchase_method: PurchaseMethod debug: bool = False
[docs] @ioprepped @dataclass class ProfileDraft(DocUIState, state_id='classic.profile_draft'): """The profile editor's working profile. Page state for the editor and its save: what the user has composed so far. A request with no draft at all (the first visit) gets one built from the stored profile, or fresh defaults when creating; an empty name or character means the same for that field. """ color: tuple[float, float, float] highlight: tuple[float, float, float] name: str = '' character: str = ''
[docs] @ioprepped @dataclass class ProfileEdit(StoreRoute, path='/profile'): """(Inventory) the cloud player-profile editor. The draft being composed rides along as :class:`ProfileDraft` page state; the route itself only says which stored profile (if any) is being edited. """ #: Stored profile being edited, or None when creating one. profile_name: str | None = ( None )
[docs] @override @classmethod def get_window_layout(cls) -> dui2.WindowLayout: # The editor's controls go in the column; the pane beside them # shows the character being composed. return dui2.WindowLayout.VIEWER
[docs] @ioprepped @dataclass class ProfileSave( StoreRoute, path='/profile/save', method=dui2.RequestMethod.POST ): """(Inventory) save the editor's draft (its :class:`ProfileDraft`).""" #: See :attr:`ProfileEdit.profile_name`. profile_name: str | None = ( None )
[docs] @ioprepped @dataclass class ProfileDelete( StoreRoute, path='/profile/delete', method=dui2.RequestMethod.POST ): """(Inventory) delete a stored profile.""" profile_name: str
# All routes in the family. AnyStoreRoute = ( Root | Purchase | PurchaseConfirm | ProfileEdit | ProfileSave | ProfileDelete )
[docs] class StoreLocalAction(DocUILocalActionBase): """Family class for classic store local-actions."""
[docs] @override @classmethod def get_action_types(cls) -> tuple[type[DocUILocalActionBase], ...]: return family_members(AnyStoreLocalAction)
[docs] @ioprepped @dataclass class GetTokens(StoreLocalAction, name='get_tokens'): """Show the get-tokens window."""
[docs] @ioprepped @dataclass class RestorePurchases(StoreLocalAction, name='restore_purchases'): """Kick off a platform purchase-restore."""
# All store local-actions. AnyStoreLocalAction = GetTokens | RestorePurchases
[docs] class InventoryLocalAction(DocUILocalActionBase): """Family class for classic inventory local-actions."""
[docs] @override @classmethod def get_action_types(cls) -> tuple[type[DocUILocalActionBase], ...]: return family_members(AnyInventoryLocalAction)
[docs] @ioprepped @dataclass class NewProfile(InventoryLocalAction, name='new_profile'): """Open the (legacy) profile editor on a new profile."""
[docs] @override @classmethod def get_press_sound(cls) -> PressSound: return PressSound.SWISH
[docs] @ioprepped @dataclass class EditProfile(InventoryLocalAction, name='edit_profile'): """Open the (legacy) profile editor on an existing profile."""
[docs] @override @classmethod def get_press_sound(cls) -> PressSound: return PressSound.SWISH
profile: str
[docs] @ioprepped @dataclass class SpawnBot(InventoryLocalAction, name='spawn_bot'): """Spawn a character in the main-menu background.""" #: Internal appearance name of the character. name: str
[docs] @ioprepped @dataclass class ShowLegacyProfiles(InventoryLocalAction, name='show_legacy_profiles'): """Switch the inventory to the client's legacy profiles."""
[docs] @ioprepped @dataclass class ShowCloudProfiles(InventoryLocalAction, name='show_cloud_profiles'): """Switch the inventory to cloud profiles."""
# All inventory local-actions. AnyInventoryLocalAction = ( NewProfile | EditProfile | SpawnBot | ShowLegacyProfiles | ShowCloudProfiles ) # 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