diff --git a/gui/resources/images/hysteria2_nl_li.png b/gui/resources/images/hysteria2_nl_li.png new file mode 100644 index 0000000..c2c88cb Binary files /dev/null and b/gui/resources/images/hysteria2_nl_li.png differ diff --git a/gui/resources/images/hysteria2_us_ny.png b/gui/resources/images/hysteria2_us_ny.png new file mode 100644 index 0000000..ab1ed7a Binary files /dev/null and b/gui/resources/images/hysteria2_us_ny.png differ diff --git a/gui/resources/images/hysteria2_us_wa.png b/gui/resources/images/hysteria2_us_wa.png new file mode 100644 index 0000000..ad604ce Binary files /dev/null and b/gui/resources/images/hysteria2_us_wa.png differ diff --git a/gui/resources/images/vless_nl_li.png b/gui/resources/images/vless_nl_li.png new file mode 100644 index 0000000..b6c0976 Binary files /dev/null and b/gui/resources/images/vless_nl_li.png differ diff --git a/gui/resources/images/vless_us_ny.png b/gui/resources/images/vless_us_ny.png new file mode 100644 index 0000000..e3e806d Binary files /dev/null and b/gui/resources/images/vless_us_ny.png differ diff --git a/gui/resources/images/vless_us_wa.png b/gui/resources/images/vless_us_wa.png new file mode 100644 index 0000000..0d15484 Binary files /dev/null and b/gui/resources/images/vless_us_wa.png differ diff --git a/gui/v2/actions/profile_operations.py b/gui/v2/actions/profile_operations.py index 85ab208..06f1b70 100755 --- a/gui/v2/actions/profile_operations.py +++ b/gui/v2/actions/profile_operations.py @@ -103,6 +103,10 @@ def _consume_ticket(profile: BaseProfile, request: dict[str, Any], ticket: int | def _prepare_subscription(profile: BaseProfile, request: dict[str, Any]) -> MenuResult | None: """Prepare billing once before activation while retaining recovery data across prompts.""" + + print(f"request is entering: {request}") + print(f"request type is {type(request)}") + if request.get("subscription_attached"): return None ticket = request.get("use_ticket") @@ -167,6 +171,9 @@ def _enable_error(error: Exception, profile: BaseProfile, request: dict[str, Any def _enable(request: dict[str, Any], emit: MenuCallback, max_resolution: str | None) -> MenuResult: """Own readiness, billing, activation and recovery as one connect task.""" + + print(f"request enters _enable. {request}") + synced = synchronize(current_connection()) if request.pop("sync_before_enable", False) else None if synced is not None: emit({**synced, "busy": True}) @@ -191,15 +198,20 @@ def _enable(request: dict[str, Any], emit: MenuCallback, max_resolution: str | N except Exception as e: print(f"Skipping billing resume check") - preparation = _prepare_subscription(profile, request) - if preparation is not None: - return preparation + print(f"checking preparation") + # preparation = _prepare_subscription(profile, request) + # if preparation is not None: + # return preparation + + print("entering observers") ignored = {"ignore_endpoint_verification": EndpointVerificationError, "ignore_profile_state_conflict": ProfileStateConflictError} observer = ProfileObserver() observer.subscribe("enabled", partial(_profile_event, emit, True)) observer.subscribe("disabled", partial(_profile_event, emit, False)) + + print("doing the enable") try: ProfileController.enable(profile, ignore=tuple(error for flag, error in ignored.items() if request.get(flag)), profile_observer=observer, application_version_observer=application_version_observer, @@ -207,6 +219,7 @@ def _enable(request: dict[str, Any], emit: MenuCallback, max_resolution: str | N max_resolution=max_resolution) except Exception as error: return _enable_error(error, profile, request) + print("returning success..") return {"status": "success", "request": dict(request), "refresh": True} @@ -290,6 +303,9 @@ def _update() -> MenuResult: def execute_menu_task(request: dict[str, Any], emit: MenuCallback, max_resolution: str | None) -> MenuResult: """Dispatch background operations independently of Qt and normalize their failure results.""" + + print(f"request is in execute_menu_task as {request}") + handlers = {"enable": partial(_enable, request, emit, max_resolution), "disable": partial(_disable, request), "disable_all": lambda: _disable_profiles([_require_profile(profile_id) for profile_id in request["connected_ids"]]), "delete": partial(_delete, request), "create": partial(_navigate, request, emit), diff --git a/gui/v2/actions/ticket_actions.py b/gui/v2/actions/ticket_actions.py index 2cb577e..6d9612e 100644 --- a/gui/v2/actions/ticket_actions.py +++ b/gui/v2/actions/ticket_actions.py @@ -3,7 +3,9 @@ from core.controllers.tickets.TicketPayController import initiate_payment from core.services.subscriptions.subscriptions_by_protocol import start_billing_state from core.services.payment_phase.payment_state import OverallPaymentCycle, TicketPaymentData from core.models.enum_models import PaymentType, PaymentCategory -from core.controllers.tickets.UseTicketController import get_unused_tickets +# from core.controllers.tickets.UseTicketController import get_unused_tickets +from core.services.prepare_tickets.ticket_tracker import get_all_unused_tickets + from core.models.Result import Result, ResultError # from core.controllers.ProfileController import ProfileController from core.errors.logger import logger @@ -67,9 +69,9 @@ def fetch_ticket_invoice(invoice_ui_caller: Callable, timer_resume_caller: Calla def get_ticket_data() -> Result: - """This is running in the background ALREADY. Get a list of unused tickets from core""" + """This is running in the background ALREADY. Get & format a list of unused tickets from core""" - ticket_results = get_unused_tickets() + ticket_results = get_all_unused_tickets() valid = ticket_results.get('valid') if not valid: @@ -81,7 +83,7 @@ def get_ticket_data() -> Result: raw_tickets = ticket_results.get('data') print(f"raw_tickets is {raw_tickets}") if not raw_tickets: - Result(valid=True, data=raw_tickets, message="No tickets available.") + Result(valid=False, error_type=ResultError.NO_TICKET, message="No tickets available. Would you like to get some?") formatted_data = [(f"Ticket #{t}", t) for t in raw_tickets] print(f"formatted_data is {formatted_data}") diff --git a/gui/v2/ui/pages/menu_page.py b/gui/v2/ui/pages/menu_page.py index 8341ad2..011e9ab 100755 --- a/gui/v2/ui/pages/menu_page.py +++ b/gui/v2/ui/pages/menu_page.py @@ -515,6 +515,7 @@ class MenuPage(Page): and not self.connection_manager.is_profile_connected(self.reverse_id)) def connect(self): + print(f"hit connect to enable profile. self.reverse_id is {self.reverse_id}") self._set_task_busy(True) self.update_status.update_status("Attempting to connect...") self.worker = enable_profile({"id": self.reverse_id}, self.handle_task_result) diff --git a/gui/v2/ui/pages/ticket_or_billing_choice_page.py b/gui/v2/ui/pages/ticket_or_billing_choice_page.py index 2310115..4f1b55e 100755 --- a/gui/v2/ui/pages/ticket_or_billing_choice_page.py +++ b/gui/v2/ui/pages/ticket_or_billing_choice_page.py @@ -25,6 +25,8 @@ from PyQt6 import QtCore class TicketOrBillingChoicePage(Page): def __init__(self, page_stack, main_window=None, parent=None): super().__init__("TicketOrBilling", page_stack, main_window, parent) + + print("loading TicketOrBillingChoicePage") self.update_status = main_window self.title.setText("Pick a Ticket or Use Billing") @@ -64,6 +66,7 @@ class TicketOrBillingChoicePage(Page): def get_tickets(self): """Gets tickets in the background""" + print("doing get_tickets in background") take_action( action=get_ticket_data, ui_caller=self.populate @@ -72,14 +75,13 @@ class TicketOrBillingChoicePage(Page): @mainthread def populate(self, result: Result): """Callback to Populate tickets.""" + print(f"populate recieved {result}") self.ticket_list.clear() message = result.message if not result.valid: - self.status_label.setText("Error reading tickets") - if message: - self.show_a_popup(message) # this is an error + self.handle_error(result) return data = result.data @@ -94,6 +96,17 @@ class TicketOrBillingChoicePage(Page): item.setData(QtCore.Qt.ItemDataRole.UserRole, ticket_id) self.ticket_list.addItem(item) + + def handle_error(result: Result): + self.status_label.setText("Error") + + if message: + self.show_a_popup(message) # this is an error + + if result.error_type == ResultError.NAVIGATE_TO: + self.custom_window.navigator.navigate(result.navigate_to) + + def on_use_ticket(self): # 1. Get the visual item the user clicked on item = self.ticket_list.currentItem()