Source code for bauiv1lib.chestui

# Released under the MIT License. See LICENSE for details.
#
"""The doc-ui based chest window."""

from __future__ import annotations  # Docs-generation hack.

import weakref
from typing import override, assert_never, TYPE_CHECKING

import bacommon.docui.routes.classicchest

from bauiv1lib.docui import TypedDocUIController

import bauiv1 as bui

if TYPE_CHECKING:
    import bacommon.docui.v2
    from bacommon.docui import DocUIResponse

    from bauiv1lib.docui import DocUILocalAction, DocUIWindow

#: Config key for whether to remind about opening chests early.
HIGHLIGHT_TOKEN_PURCHASES_CONFIG_KEY = 'Highlight Potential Token Purchases'


[docs] class ChestUIController( TypedDocUIController[ bacommon.docui.routes.classicchest.AnyChestRoute, bacommon.docui.routes.classicchest.AnyChestLocalAction, ] ): """DocUI setup for a chest slot.""" def __init__(self) -> None: super().__init__() # Held while an ad is up: showing one can resize our app window # (system toolbars coming and going), and a recreated window # would cancel the ad flow. self._recreate_suppress: bui.MainWindowAutoRecreateSuppress | None = ( None )
[docs] @override @classmethod def get_route_type( cls, ) -> type[bacommon.docui.routes.classicchest.ChestRoute]: return bacommon.docui.routes.classicchest.ChestRoute
[docs] @override @classmethod def get_local_action_type( cls, ) -> type[bacommon.docui.routes.classicchest.ChestLocalAction]: return bacommon.docui.routes.classicchest.ChestLocalAction
[docs] @override def fulfill_route( self, route: bacommon.docui.routes.classicchest.AnyChestRoute ) -> DocUIResponse: return self.fulfill_request_cloud(route, 'classicchest')
[docs] @override def fulfill_unrouted_request( self, request: bacommon.docui.v2.Request, error: str ) -> DocUIResponse: # Something newer than us from the server; let it handle it. return self.fulfill_request_cloud(request, 'classicchest')
[docs] @override def run_local_action( self, action: bacommon.docui.routes.classicchest.AnyChestLocalAction, context: DocUILocalAction, ) -> None: match action: case bacommon.docui.routes.classicchest.WatchAd(): self._watch_ad(action.slot, context.window) case bacommon.docui.routes.classicchest.StopReminding(): bui.app.config[HIGHLIGHT_TOKEN_PURCHASES_CONFIG_KEY] = False bui.app.config.apply_and_commit() self.replace( context.window, slot_route(action.slot).request(), is_refresh=True, ) case bacommon.docui.routes.classicchest.GetTokens(): # pylint: disable=cyclic-import from bauiv1lib.gettokens import show_get_tokens_prompt show_get_tokens_prompt( origin_widget=bui.existing(context.widget) ) case _: assert_never(action)
def _watch_ad(self, slot: int, window: DocUIWindow) -> None: plus = bui.app.plus assert plus is not None self._recreate_suppress = bui.MainWindowAutoRecreateSuppress() weakwin = weakref.ref(window) plus.ads.show_ad_2( 'reduce_chest_wait', on_completion_call=bui.WeakCallPartial( self._ad_complete, slot, weakwin ), ) def _ad_complete( self, slot: int, weakwin: weakref.ref[DocUIWindow], actually_showed: bool, ) -> None: self._recreate_suppress = None window = weakwin() if window is None or not actually_showed: return self.replace( window, bacommon.docui.routes.classicchest.AdWatched(slot=slot).request(), )
[docs] def slot_route(slot: int) -> bacommon.docui.routes.classicchest.Root: """The root route for a chest slot, with what only we can know.""" plus = bui.app.plus return bacommon.docui.routes.classicchest.Root( slot=slot, ad_ready=plus is not None and plus.ads.have_incentivized_ad(), open_me=bool( bui.app.config.resolve(HIGHLIGHT_TOKEN_PURCHASES_CONFIG_KEY) ), )
[docs] def show_chest_window( slot: int, origin_widget: bui.Widget | None = None ) -> None: """Pop up a chest slot's window wherever we are in the nav stack.""" from bauiv1lib.docui import DocUIWindow bui.app.ui_v1.auxiliary_window_activate( win_type=DocUIWindow, win_create_call=bui.CallStrict( ChestUIController().create_window, slot_route(slot), origin_widget=origin_widget, uiopenstateid=f'classicchest{slot}', ), # Distinct per slot, so pressing another slot's chest switches # to it rather than just closing this one. win_extra_type_id=( f'{ChestUIController.get_window_extra_type_id()}:{slot}' ), )
# 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