Improved Status Updates with Notification system for payment prompts

This commit is contained in:
SimplifiedPrivacy 2026-10-20 18:28:38 -04:00
parent ea12aecf05
commit 707935f80f
5 changed files with 52 additions and 14 deletions

View file

@ -23,6 +23,7 @@ from core.controllers.ProfileController import ProfileController
from core.Errors import UnknownConnectionTypeError
from core.errors.logger import logger as core_logger
from core.models.Result import Result, ResultError
from core.observers.Notifications import Notifications, EventType
core_logger.propagate = False
@ -161,8 +162,12 @@ class CustomWindow(QMainWindow):
self.sync_button = bottom['sync_button']
self.page_stack.raise_()
# class based notification system:
self.observers = setup_observers(self.update_status)
# New EventBus-style notification system:
self.notfication_trigger()
self.update_image()
self.set_scroll_speed(7)
@ -753,6 +758,11 @@ class CustomWindow(QMainWindow):
self.status_label.setStyleSheet(
f"color: rgb(0, 255, 255); font-size: {font_size}px;")
@mainthread
def notfication_trigger(self):
Notifications.subscribe(EventType.STATUS_UPDATE, self.update_status)
@mainthread # wrapper of ThreadSafetyTool
def update_status(self, text, clear=False):
"""

View file

@ -14,7 +14,7 @@ from core.errors.translate_error import translate_error, get_ignored_exceptions
from core.services.payment_phase.payment_state import OverallPaymentCycle
# gui
from gui.v2.actions.payment_actions import wipe_expired_subscription
# from gui.v2.actions.payment_actions import wipe_expired_subscription
from gui.v2.actions.ticket_actions import dispatch_ticketing
from gui.v2.infrastructure.action_registry import register_action
from gui.v2.infrastructure.take_plumbing_action import take_action

View file

@ -11,6 +11,7 @@ from core.models.enum_models import PaymentType, PaymentCategory
from core.models.Result import Result, ResultError
from core.errors.logger import logger
from core.utils.type_checker import type_checker
from core.observers.Notifications import Notifications, EventType
# gui
@ -55,18 +56,25 @@ def reset_individual_billing_cycle() -> Result:
return _wipe_and_navigate()
@register_action(ResultError.EXPIRED_SUB)
def wipe_expired_subscription(profile_id: int) -> Result:
"""Call core to wipe a subscription, then navigate to the billing page"""
logger.info(f"Wiping the subscription for {profile_id}")
# @register_action(ResultError.EXPIRED_SUB)
# def wipe_expired_subscription(profile_id: int) -> Result:
# """Call core to wipe a subscription, then navigate to the billing page"""
# logger.info(f"Wiping the subscription for {profile_id}")
wiped_result = wipe_subscription(profile_id)
if wiped_result.valid:
logger.info("Successfully wiped")
# also clear the whole billing cycle, so it's ready for an individual purchase,
return _wipe_and_navigate(profile_id)
else:
return wiped_result
# wiped_result = wipe_subscription(profile_id)
# if wiped_result.valid:
# logger.info("Successfully wiped")
# payment_cycle = OverallPaymentCycle()
# payment_cycle.wipe_billing_cycle()
# # also clear the whole billing cycle, so it's ready for an individual purchase,
# return _wipe_and_navigate(profile_id)
# else:
# return wiped_result
@type_checker
@ -108,6 +116,9 @@ def gui_starts_invoice(invoice_ui_caller: Callable, timer_resume_caller: Callabl
else:
return return_pre_existing_invoice(billing_code=billing_code, connection_observer=connection_observer)
notification = "Fetching Invoice.."
Notifications.emit(EventType.STATUS_UPDATE, notification)
take_action(
action=create_new_invoice,
ui_caller=invoice_ui_caller,
@ -149,6 +160,9 @@ def start_polling(billing_code: str, profile_id: int, ui_caller: Callable) -> st
# update the global singleton:
payment_cycle.already_polling = True
notification = "Checking if Paid.."
Notifications.emit(EventType.STATUS_UPDATE, notification)
# setup the timer with the callback:
# it doesn't return result here. It calls the view_callback function.
check_paid_timer = CheckPaidTimer(
@ -166,7 +180,7 @@ def start_polling(billing_code: str, profile_id: int, ui_caller: Callable) -> st
def stop_current() -> Result:
wiped_result = wipe_billing_cycle()
logger.info("Stopping current!")
logger.info("Stopping current billing cycle!")
# if not wiped_result.valid:
# return wiped_result
@ -176,6 +190,8 @@ def stop_current() -> Result:
# if not new_cycle_result.valid:
# return new_cycle_result
notification = "Stopped Checking if Paid"
Notifications.emit(EventType.STATUS_UPDATE, notification)
return Result(valid=True, error_type=ResultError.NAVIGATE_TO, navigate_to="menu")
@ -194,6 +210,8 @@ def stop_payment_timer() -> Result:
if wiped_result.valid:
content_to_display = "Stopped! You can resume a different profile's invoice now"
notification = "Stopped Checking if Paid"
Notifications.emit(EventType.STATUS_UPDATE, notification)
return Result(valid=True, message=content_to_display)
else:
error_msg = "Unable to stop the payment timer and wipe the profile inside stop_payment_timer. But didn't get an actual error."

View file

@ -145,9 +145,15 @@ class MenuPage(Page):
self.refresh_menu_buttons()
def trigger_action_button_visuals(self, desired_status: bool):
"""Backend uses direct Notifications to trigger the action button status, without a profile_id"""
if desired_status:
self.action_button.setEnabled(True)
self.action_button.setVisible(True)
def update_action_button_visuals(self, triggered_profile_id: Optional[int] = None):
"""Syncs the button art and enabled state with the current external truth."""
"""Syncs the button art with enabled state with the current external truth."""
# Which profile is selected:
profile_id = getattr(self.update_status, 'current_profile_id', None)
@ -818,6 +824,7 @@ class MenuPage(Page):
Notifications.subscribe(EventType.SESSION_PROFILE_DISABLE, self.turn_off_session_visuals)
Notifications.subscribe(EventType.SYSTEM_ENABLE, self.turn_on_system_visuals)
Notifications.subscribe(EventType.SYSTEM_DISABLE, self.turn_off_system_visuals)
Notifications.subscribe(EventType.RESUME_ACTIONS, self.trigger_action_button_visuals)
take_action(
action=evaluate_state_on_startup,

View file

@ -5,6 +5,7 @@ from core.models.pydantic_models.ServerReply import SubscriptionInvoice
from core.models.invoice.TicketInvoice import TicketInvoice
from core.models.enum_models import Currency
from core.models.Result import Result
from core.observers.Notifications import Notifications, EventType
# GUI
from gui.v2.actions.payment_actions import (
@ -233,6 +234,8 @@ class PaymentDetailsPage(Page):
def background_fetch_mode(self):
"""Continue checking if paid, but navigate back to the menu page"""
if self.polling:
notification = "Checking if Paid in Background.."
Notifications.emit(EventType.STATUS_UPDATE, notification)
self.custom_window.navigator.navigate("menu")
else:
message = "It was not polling to begin with."