forked from Support/sp-hydra-veil-gui
update: fixes to v2 version
This commit is contained in:
parent
9f714b9f7b
commit
50da80e7d1
26 changed files with 125 additions and 7 deletions
|
|
@ -9,7 +9,7 @@ from PyQt6.QtWidgets import (
|
||||||
)
|
)
|
||||||
from PyQt6.QtGui import QPixmap, QFont, QFontDatabase
|
from PyQt6.QtGui import QPixmap, QFont, QFontDatabase
|
||||||
from PyQt6 import QtGui
|
from PyQt6 import QtGui
|
||||||
from PyQt6.QtCore import Qt, QTimer
|
from PyQt6.QtCore import Qt, QTimer, QEvent
|
||||||
|
|
||||||
from core.Constants import Constants
|
from core.Constants import Constants
|
||||||
from core.controllers.ConfigurationController import ConfigurationController
|
from core.controllers.ConfigurationController import ConfigurationController
|
||||||
|
|
@ -151,6 +151,7 @@ class CustomWindow(QMainWindow):
|
||||||
|
|
||||||
self.toggle_button.clicked.connect(self.toggle_mode)
|
self.toggle_button.clicked.connect(self.toggle_mode)
|
||||||
self.sync_button.clicked.connect(self.sync)
|
self.sync_button.clicked.connect(self.sync)
|
||||||
|
QApplication.instance().installEventFilter(self)
|
||||||
|
|
||||||
self.create_toggle(self.is_tor_mode)
|
self.create_toggle(self.is_tor_mode)
|
||||||
self.animation_timer = QTimer()
|
self.animation_timer = QTimer()
|
||||||
|
|
@ -422,10 +423,15 @@ class CustomWindow(QMainWindow):
|
||||||
self.off_label = QLabel("OFF", self.toggle_button)
|
self.off_label = QLabel("OFF", self.toggle_button)
|
||||||
self.off_label.setGeometry(25, 4, 40, 14)
|
self.off_label.setGeometry(25, 4, 40, 14)
|
||||||
|
|
||||||
|
for widget in (self.toggle_bg, self.toggle_handle, self.on_label, self.off_label):
|
||||||
|
widget.setAttribute(Qt.WidgetAttribute.WA_TransparentForMouseEvents)
|
||||||
|
|
||||||
self._update_toggle_colors(colors)
|
self._update_toggle_colors(colors)
|
||||||
if is_tor_mode:
|
if is_tor_mode:
|
||||||
self.set_tor_icon()
|
self.set_tor_icon()
|
||||||
|
|
||||||
|
self.raise_bottom_controls()
|
||||||
|
|
||||||
def _get_toggle_colors(self, is_tor_mode):
|
def _get_toggle_colors(self, is_tor_mode):
|
||||||
return {
|
return {
|
||||||
'bg': "#00a8ff" if is_tor_mode else "#2c3e50",
|
'bg': "#00a8ff" if is_tor_mode else "#2c3e50",
|
||||||
|
|
@ -459,20 +465,62 @@ class CustomWindow(QMainWindow):
|
||||||
|
|
||||||
def set_toggle_state(self, is_tor_mode):
|
def set_toggle_state(self, is_tor_mode):
|
||||||
self.is_tor_mode = is_tor_mode
|
self.is_tor_mode = is_tor_mode
|
||||||
|
self.toggle_button.setChecked(is_tor_mode)
|
||||||
handle_x = 30 if is_tor_mode else 3
|
handle_x = 30 if is_tor_mode else 3
|
||||||
self.toggle_handle.setGeometry(handle_x, 3, 16, 16)
|
self.toggle_handle.setGeometry(handle_x, 3, 16, 16)
|
||||||
self._update_toggle_colors(self._get_toggle_colors(is_tor_mode))
|
self._update_toggle_colors(self._get_toggle_colors(is_tor_mode))
|
||||||
self.set_tor_icon()
|
self.set_tor_icon()
|
||||||
|
|
||||||
def toggle_mode(self):
|
def toggle_mode(self, *_args):
|
||||||
|
if self.is_animating and not self.animation_timer.isActive():
|
||||||
|
self.is_animating = False
|
||||||
|
|
||||||
if not self.is_animating:
|
if not self.is_animating:
|
||||||
|
target_is_tor = not self.is_tor_mode
|
||||||
|
new_connection = 'tor' if target_is_tor else 'system'
|
||||||
|
core_logger.info(f"Tor toggle clicked; switching connection mode to '{new_connection}'")
|
||||||
|
self.update_status(f"Tor toggle clicked: switching to {new_connection}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
ConfigurationController.set_connection(new_connection)
|
||||||
|
except Exception as error:
|
||||||
|
core_logger.exception(
|
||||||
|
f"Tor toggle failed while switching connection mode to '{new_connection}'")
|
||||||
|
self.update_status(f"Tor toggle failed: {error}")
|
||||||
|
self.set_toggle_state(self.is_tor_mode)
|
||||||
|
return
|
||||||
|
|
||||||
|
self.set_toggle_state(target_is_tor)
|
||||||
self.is_animating = True
|
self.is_animating = True
|
||||||
self.animation_step = 0
|
self.animation_step = 0
|
||||||
self.animation_timer.start(16)
|
self.animation_timer.start(16)
|
||||||
self.is_tor_mode = not self.is_tor_mode
|
return
|
||||||
new_connection = 'tor' if self.is_tor_mode else 'system'
|
|
||||||
ConfigurationController.set_connection(new_connection)
|
core_logger.info("Tor toggle clicked while animation was still running")
|
||||||
core_logger.info(f"User toggled connection mode to '{new_connection}'")
|
self.update_status("Tor toggle clicked: still switching")
|
||||||
|
|
||||||
|
def raise_bottom_controls(self):
|
||||||
|
for widget in (self.status_label, self.tor_text, self.toggle_button, self.tor_icon, self.sync_button):
|
||||||
|
widget.raise_()
|
||||||
|
|
||||||
|
def eventFilter(self, source, event):
|
||||||
|
if event.type() == QEvent.Type.MouseButtonPress and event.button() == Qt.MouseButton.LeftButton:
|
||||||
|
if self._is_toggle_event(event):
|
||||||
|
self.toggle_mode()
|
||||||
|
return True
|
||||||
|
return super().eventFilter(source, event)
|
||||||
|
|
||||||
|
def _is_toggle_event(self, event):
|
||||||
|
if not hasattr(self, 'toggle_button') or not self.toggle_button.isVisible():
|
||||||
|
return False
|
||||||
|
if hasattr(event, 'globalPosition'):
|
||||||
|
global_pos = event.globalPosition().toPoint()
|
||||||
|
else:
|
||||||
|
global_pos = event.globalPos()
|
||||||
|
for widget in (self.tor_text, self.toggle_button, self.tor_icon):
|
||||||
|
if widget.isVisible() and widget.rect().contains(widget.mapFromGlobal(global_pos)):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def animate_toggle(self):
|
def animate_toggle(self):
|
||||||
TOTAL_STEPS = 5
|
TOTAL_STEPS = 5
|
||||||
|
|
@ -699,6 +747,8 @@ class CustomWindow(QMainWindow):
|
||||||
self.toggle_button.setGeometry(540, 541, 50, 22)
|
self.toggle_button.setGeometry(540, 541, 50, 22)
|
||||||
self.tor_icon.setGeometry(600, 537, 25, 25)
|
self.tor_icon.setGeometry(600, 537, 25, 25)
|
||||||
|
|
||||||
|
self.raise_bottom_controls()
|
||||||
|
|
||||||
if current_page != previous_page:
|
if current_page != previous_page:
|
||||||
self.page_history.append(current_page)
|
self.page_history.append(current_page)
|
||||||
|
|
||||||
|
|
|
||||||
BIN
gui/v2/__pycache__/__init__.cpython-312.pyc
Normal file → Executable file
BIN
gui/v2/__pycache__/__init__.cpython-312.pyc
Normal file → Executable file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -26,6 +26,7 @@ def location_candidates(profile, preferred=None):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
for source in sources:
|
for source in sources:
|
||||||
|
add(getattr(source, 'id', None))
|
||||||
add(getattr(source, 'country_name', None))
|
add(getattr(source, 'country_name', None))
|
||||||
add(getattr(source, 'name', None))
|
add(getattr(source, 'name', None))
|
||||||
add(getattr(source, 'code', None))
|
add(getattr(source, 'code', None))
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -17,6 +17,7 @@ def create_bottom_section(parent, btn_path, client_version, is_sync_urgent):
|
||||||
|
|
||||||
tor_text = QLabel("Billing & Browsers", parent)
|
tor_text = QLabel("Billing & Browsers", parent)
|
||||||
tor_text.setGeometry(532, 541, 150, 20)
|
tor_text.setGeometry(532, 541, 150, 20)
|
||||||
|
tor_text.setCursor(Qt.CursorShape.PointingHandCursor)
|
||||||
tor_text.setStyleSheet("""
|
tor_text.setStyleSheet("""
|
||||||
QLabel {
|
QLabel {
|
||||||
color: cyan;
|
color: cyan;
|
||||||
|
|
@ -28,9 +29,11 @@ def create_bottom_section(parent, btn_path, client_version, is_sync_urgent):
|
||||||
toggle_button = QPushButton(parent)
|
toggle_button = QPushButton(parent)
|
||||||
toggle_button.setGeometry(670, 541, 50, 22)
|
toggle_button.setGeometry(670, 541, 50, 22)
|
||||||
toggle_button.setCheckable(True)
|
toggle_button.setCheckable(True)
|
||||||
|
toggle_button.setCursor(Qt.CursorShape.PointingHandCursor)
|
||||||
|
|
||||||
tor_icon = QLabel(parent)
|
tor_icon = QLabel(parent)
|
||||||
tor_icon.setGeometry(730, 537, 25, 25)
|
tor_icon.setGeometry(730, 537, 25, 25)
|
||||||
|
tor_icon.setCursor(Qt.CursorShape.PointingHandCursor)
|
||||||
|
|
||||||
sync_button = QPushButton(parent)
|
sync_button = QPushButton(parent)
|
||||||
sync_button.setGeometry(771, 541, 22, 22)
|
sync_button.setGeometry(771, 541, 22, 22)
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
gui/v2/ui/pages/__pycache__/id_page.cpython-312.pyc
Normal file
BIN
gui/v2/ui/pages/__pycache__/id_page.cpython-312.pyc
Normal file
Binary file not shown.
BIN
gui/v2/ui/pages/__pycache__/payment_details_page.cpython-312.pyc
Normal file
BIN
gui/v2/ui/pages/__pycache__/payment_details_page.cpython-312.pyc
Normal file
Binary file not shown.
BIN
gui/v2/ui/pages/__pycache__/plan_picker_page.cpython-312.pyc
Normal file
BIN
gui/v2/ui/pages/__pycache__/plan_picker_page.cpython-312.pyc
Normal file
Binary file not shown.
BIN
gui/v2/ui/pages/__pycache__/resume_page.cpython-312.pyc
Normal file
BIN
gui/v2/ui/pages/__pycache__/resume_page.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
gui/v2/ui/pages/__pycache__/sync_screen.cpython-312.pyc
Normal file
BIN
gui/v2/ui/pages/__pycache__/sync_screen.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
|
|
@ -54,10 +54,25 @@ class SyncScreen(Page):
|
||||||
self.button_go.clicked.connect(self.perform_sync)
|
self.button_go.clicked.connect(self.perform_sync)
|
||||||
self.button_back.clicked.connect(self.go_back)
|
self.button_back.clicked.connect(self.go_back)
|
||||||
|
|
||||||
|
def showEvent(self, event):
|
||||||
|
super().showEvent(event)
|
||||||
|
self.button_go.setVisible(True)
|
||||||
|
self.button_back.setVisible(True)
|
||||||
|
self.button_go.setEnabled(True)
|
||||||
|
self.button_back.setEnabled(True)
|
||||||
|
|
||||||
def go_back(self):
|
def go_back(self):
|
||||||
self.custom_window.navigator.navigate("menu")
|
self.custom_window.navigator.navigate("menu")
|
||||||
|
|
||||||
def perform_sync(self):
|
def perform_sync(self):
|
||||||
|
if self.connection_manager.is_synced():
|
||||||
|
self.button_go.setVisible(True)
|
||||||
|
self.button_back.setVisible(True)
|
||||||
|
self.button_go.setEnabled(True)
|
||||||
|
self.button_back.setEnabled(True)
|
||||||
|
self.custom_window.navigator.navigate("protocol")
|
||||||
|
return
|
||||||
|
|
||||||
self.button_go.setEnabled(False)
|
self.button_go.setEnabled(False)
|
||||||
self.button_back.setEnabled(False)
|
self.button_back.setEnabled(False)
|
||||||
self.update_status.update_status('Sync in progress...')
|
self.update_status.update_status('Sync in progress...')
|
||||||
|
|
@ -98,6 +113,8 @@ class SyncScreen(Page):
|
||||||
self.custom_window.update_values(
|
self.custom_window.update_values(
|
||||||
available_locations, available_browsers, status, is_tor, locations, all_browsers)
|
available_locations, available_browsers, status, is_tor, locations, all_browsers)
|
||||||
|
|
||||||
|
self.button_go.setEnabled(True)
|
||||||
|
self.button_back.setEnabled(True)
|
||||||
self.custom_window.navigator.navigate("protocol")
|
self.custom_window.navigator.navigate("protocol")
|
||||||
|
|
||||||
def update_after_sync(self, available_locations, available_browsers, locations, all_browsers=None):
|
def update_after_sync(self, available_locations, available_browsers, locations, all_browsers=None):
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from PyQt6.QtWidgets import QButtonGroup, QMessageBox, QPushButton
|
from PyQt6.QtWidgets import QApplication, QButtonGroup, QMessageBox, QPushButton
|
||||||
from PyQt6.QtGui import QIcon
|
from PyQt6.QtGui import QIcon
|
||||||
from PyQt6.QtCore import QSize
|
from PyQt6.QtCore import QSize
|
||||||
from PyQt6 import QtCore
|
from PyQt6 import QtCore
|
||||||
|
|
||||||
|
from core.controllers.tickets.TicketPayController import check_if_paid
|
||||||
|
|
||||||
|
from gui.v2.infrastructure.setup_observers import connection_observer, ticket_observer
|
||||||
from gui.v2.ui.pages.Page import Page
|
from gui.v2.ui.pages.Page import Page
|
||||||
from gui.v2.workers.ticketing_worker_thread import TicketingWorkerThread
|
from gui.v2.workers.ticketing_worker_thread import TicketingWorkerThread
|
||||||
|
|
||||||
|
|
@ -60,6 +63,22 @@ class TicketCryptoPickerPage(Page):
|
||||||
currency = selected_button.property('currency')
|
currency = selected_button.property('currency')
|
||||||
self.start_initiate_payment(currency)
|
self.start_initiate_payment(currency)
|
||||||
|
|
||||||
|
def check_if_paid_for_existing(self, temp_billing_code):
|
||||||
|
self.update_status.update_status("Checking if paid...")
|
||||||
|
result = check_if_paid(temp_billing_code, ticket_observer, connection_observer)
|
||||||
|
if isinstance(result, dict) and result.get('valid') and result.get('payment_status') == 'paid':
|
||||||
|
self.update_status.update_status("Already Paid!")
|
||||||
|
self.custom_window.navigator.navigate("ticket_prep")
|
||||||
|
prep_page = self.custom_window.navigator.get_cached("ticket_prep")
|
||||||
|
if prep_page:
|
||||||
|
prep_page.start_prep()
|
||||||
|
else:
|
||||||
|
self.update_status.update_status("Not yet paid.")
|
||||||
|
clipboard = QApplication.clipboard()
|
||||||
|
clipboard.setText(temp_billing_code)
|
||||||
|
not_paid_msg = f"The billing code is not yet showing paid for {temp_billing_code}. Right now, your clipboard has the billing code, to paste it in any text editor. If you did pay, either wait longer for blockchain confirmation, or contact customer support with the code in your clipboard now."
|
||||||
|
QMessageBox.information(None, "Not Paid", not_paid_msg)
|
||||||
|
|
||||||
def start_initiate_payment(self, currency):
|
def start_initiate_payment(self, currency):
|
||||||
self.update_status.update_status("Initiating payment...")
|
self.update_status.update_status("Initiating payment...")
|
||||||
self.worker = TicketingWorkerThread('INITIATE_PAYMENT', params={
|
self.worker = TicketingWorkerThread('INITIATE_PAYMENT', params={
|
||||||
|
|
@ -81,6 +100,12 @@ class TicketCryptoPickerPage(Page):
|
||||||
if error_code == 'already_exists' and not self.bypass_existing:
|
if error_code == 'already_exists' and not self.bypass_existing:
|
||||||
self._prompt_wipe_existing(invoice)
|
self._prompt_wipe_existing(invoice)
|
||||||
return
|
return
|
||||||
|
if error_code == 'billing_code_exists' and not self.bypass_existing:
|
||||||
|
temp_billing_code = getattr(invoice, 'temp_billing_code', None)
|
||||||
|
print(f"temp_billing_code is {temp_billing_code}")
|
||||||
|
if temp_billing_code:
|
||||||
|
self._prompt_wipe_billingcode(temp_billing_code)
|
||||||
|
return
|
||||||
if error_code:
|
if error_code:
|
||||||
msg = getattr(invoice, 'final_error_msg', None) or error_code
|
msg = getattr(invoice, 'final_error_msg', None) or error_code
|
||||||
self.update_status.update_status(f"Payment error: {msg}")
|
self.update_status.update_status(f"Payment error: {msg}")
|
||||||
|
|
@ -105,6 +130,21 @@ class TicketCryptoPickerPage(Page):
|
||||||
else:
|
else:
|
||||||
self.update_status.update_status("Cancelled.")
|
self.update_status.update_status("Cancelled.")
|
||||||
|
|
||||||
|
def _prompt_wipe_billingcode(self, temp_billing_code):
|
||||||
|
msg = QMessageBox(self)
|
||||||
|
msg.setWindowTitle("Existing billing code found")
|
||||||
|
msg.setText("You already have a ticket billing code. Do you want to use it? Only hit YES if you ALREADY paid.")
|
||||||
|
msg.setStandardButtons(QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No)
|
||||||
|
result = msg.exec()
|
||||||
|
if result == QMessageBox.StandardButton.Yes:
|
||||||
|
self.update_status.update_status("Reusing same code")
|
||||||
|
self.check_if_paid_for_existing(temp_billing_code)
|
||||||
|
else:
|
||||||
|
self.bypass_existing = True
|
||||||
|
currency_btn = self.buttonGroup.checkedButton()
|
||||||
|
if currency_btn:
|
||||||
|
self.start_initiate_payment(currency_btn.property('currency'))
|
||||||
|
|
||||||
def on_error(self, msg):
|
def on_error(self, msg):
|
||||||
self.update_status.update_status(f"Payment error: {msg}")
|
self.update_status.update_status(f"Payment error: {msg}")
|
||||||
|
|
||||||
|
|
|
||||||
BIN
gui/v2/ui/popups/__pycache__/qrcode_dialog.cpython-312.pyc
Normal file
BIN
gui/v2/ui/popups/__pycache__/qrcode_dialog.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -141,6 +141,13 @@ class Worker(QObject):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _maybe_auto_use_ticket(self):
|
def _maybe_auto_use_ticket(self):
|
||||||
|
profile_connection_type = self.profile.connection.code
|
||||||
|
|
||||||
|
if profile_connection_type != "wireguard":
|
||||||
|
error_msg = "Tickets are not yet supported for Tor. We are very sorry, but we're not able to develop all features for all products."
|
||||||
|
print(error_msg)
|
||||||
|
return None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
which_ticket, error_msg = do_we_use_a_random_ticket(ticket_observer)
|
which_ticket, error_msg = do_we_use_a_random_ticket(ticket_observer)
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue