Skip to content
Snippets Groups Projects

Display a data waiting message only if any tracked account is present

Merged Jakub Ziebinski requested to merge jziebinski/fix-no-account-message into develop
@@ -19,6 +19,7 @@ if TYPE_CHECKING:
from textual.widget import Widget
from clive.__private.ui.app import Clive
from clive.__private.ui.types import ActiveBindingsMap
@@ -47,27 +48,35 @@ class CliveScreen(Screen[ScreenResultType], CliveWidget):
"""Provides the ability to control the binding order in the footer."""
return self._sort_bindings(super().active_bindings)
@staticmethod
def prevent_action_when_no_accounts_node_data(func: Callable[P, None]) -> Callable[P, None]:
@wraps(func)
def wrapper(*args: P.args, **kwargs: P.kwargs) -> None:
app_ = get_clive().app_instance()
if (
not app_.world.profile.accounts.is_tracked_accounts_node_data_available
or not app_.world.profile.accounts.is_tracked_accounts_alarms_data_available
):
logger.debug(f"action {func.__name__} prevented because no node or alarms data is available yet")
app_.notify("Waiting for data...", severity="warning")
return
func(*args, **kwargs)
return wrapper
@classmethod
def prevent_action_when_no_accounts_node_data(
cls, message: str = "Waiting for data..."
) -> Callable[[Callable[P, None]], Callable[P, None]]:
def can_run_condition(app: Clive) -> bool:
accounts = app.world.profile.accounts
return (
accounts.is_tracked_accounts_node_data_available and accounts.is_tracked_accounts_alarms_data_available
)
return cls._create_prevent_decorator(can_run_condition, message)
@classmethod
def prevent_action_when_no_working_account(
cls, message: str = "Cannot perform this action without working account"
) -> Callable[[Callable[P, None]], Callable[P, None]]:
return cls._create_prevent_decorator(lambda app: app.world.profile.accounts.has_working_account, message)
@classmethod
def prevent_action_when_no_tracked_accounts(
cls, message: str = "Cannot perform this action without tracked accounts"
) -> Callable[[Callable[P, None]], Callable[P, None]]:
return cls._create_prevent_decorator(lambda app: app.world.profile.accounts.has_tracked_accounts, message)
@staticmethod
def try_again_after_unlock(func: Callable[P, Awaitable[None]]) -> Callable[P, Awaitable[None]]:
@wraps(func)
async def wrapper(*args: P.args, **kwargs: P.kwargs) -> None:
app_ = get_clive().app_instance()
app = get_clive().app_instance()
try:
await func(*args, **kwargs)
@@ -76,16 +85,35 @@ class CliveScreen(Screen[ScreenResultType], CliveWidget):
async def _on_unlock_result(*, unlocked: bool) -> None:
if not unlocked:
app_.notify("Aborted. UNLOCKED mode was required for this action.", severity="warning")
app.notify("Aborted. UNLOCKED mode was required for this action.", severity="warning")
return
await func(*args, **kwargs)
app_.notify("This action requires Clive to be in UNLOCKED mode. Please unlock...")
await app_.push_screen(Unlock(unlock_result_callback=_on_unlock_result))
app.notify("This action requires Clive to be in UNLOCKED mode. Please unlock...")
await app.push_screen(Unlock(unlock_result_callback=_on_unlock_result))
return wrapper
@classmethod
def _create_prevent_decorator(
cls, can_run_condition: Callable[[Clive], bool], message: str
) -> Callable[[Callable[P, None]], Callable[P, None]]:
def decorator(func: Callable[P, None]) -> Callable[P, None]:
@wraps(func)
def wrapper(*args: P.args, **kwargs: P.kwargs) -> None:
app = get_clive().app_instance()
if not can_run_condition(app):
logger.debug(f"Preventing action: {func.__name__} with message of: {message}")
app.notify(message, severity="warning")
return
func(*args, **kwargs)
return wrapper
return decorator
@on(ScreenSuspend)
def _post_suspended(self) -> None:
"""
Loading