diff --git a/gui/__main__.py b/gui/__main__.py index a4f4663..9c6cfb9 100755 --- a/gui/__main__.py +++ b/gui/__main__.py @@ -1,5 +1,5 @@ from PyQt6.QtWidgets import QComboBox,QButtonGroup, QLineEdit,QMainWindow, QLabel, QWidget, QVBoxLayout, QStackedWidget, QApplication, QPushButton, QTextEdit, QFrame, QHBoxLayout, QVBoxLayout, QScrollArea, QSystemTrayIcon, QMessageBox, QGridLayout, QCheckBox, QStackedLayout, QGroupBox, QDialog -from PyQt6.QtGui import QIcon, QPixmap,QIcon, QPixmap, QTransform, QPainter, QColor, QFont, QFontDatabase +from PyQt6.QtGui import QIcon, QPixmap,QIcon, QPixmap, QTransform, QPainter, QColor, QFont, QFontDatabase, QTextOption from PyQt6 import QtGui from PyQt6 import QtCore from PyQt6.QtCore import Qt,QSize,QThread,pyqtSignal, QTimer, QPointF, QRect, QMutex, QMutexLocker, QObject @@ -148,11 +148,11 @@ class WorkerThread(QThread): for profile_id in self.profile_data: profile = ProfileController.get(int(profile_id)) if isinstance(profile, SessionProfile): - ProfileController.disable(profile, force=True, profile_observer=profile_observer) + ProfileController.disable(profile, ignore=True, profile_observer=profile_observer) for profile_id in self.profile_data: profile = ProfileController.get(int(profile_id)) if isinstance(profile, SystemProfile): - ProfileController.disable(profile, force=True, profile_observer=profile_observer) + ProfileController.disable(profile, ignore=True, profile_observer=profile_observer) self.text_output.emit("All profiles were successfully disabled") except Exception: self.text_output.emit("An error occurred when disabling profile") @@ -461,6 +461,15 @@ class CustomWindow(QMainWindow): sync_screen = self.page_stack.findChild(SyncScreen) if status: sync_screen.update_after_sync(available_locations, available_browsers, locations, all_browsers) + menu_page = self.page_stack.findChild(MenuPage) + if menu_page and hasattr(menu_page, 'buttons'): + for button in menu_page.buttons: + parent = button.parent() + if parent: + verification_icons = parent.findChildren(QPushButton) + for icon in verification_icons: + if icon.geometry().width() == 20 and icon.geometry().height() == 20: + icon.setEnabled(True) else: self.update_status('Sync failed. Please try again later.') @@ -1193,7 +1202,7 @@ class Worker(QObject): return if self.profile: try: - ProfileController.enable(self.profile, force=self.force, profile_observer=profile_observer, + ProfileController.enable(self.profile, ignore=self.force, profile_observer=profile_observer, application_version_observer=application_version_observer, connection_observer=connection_observer) except (InvalidSubscriptionError, MissingSubscriptionError) as e: @@ -1322,7 +1331,16 @@ class MenuPage(Page): #self.label.setStyleSheet("background-color: rgba(0, 255, 0, 51);") self.create_interface_elements() # Establecer el color de fondo y el color del texto utilizando hojas de estilo - + def showEvent(self, event): + super().showEvent(event) + if hasattr(self, 'buttons'): + for button in self.buttons: + parent = button.parent() + if parent: + verification_icons = parent.findChildren(QPushButton) + for icon in verification_icons: + if icon.geometry().width() == 20 and icon.geometry().height() == 20: + icon.setEnabled(self.connection_manager.is_synced()) def on_update_check_finished(self): reply = QMessageBox.question(self, 'Update Available', @@ -1467,6 +1485,8 @@ class MenuPage(Page): self.boton_just.setEnabled(False) self.boton_just_session.setEnabled(False) self.boton_edit.setEnabled(False) + if hasattr(self, 'verification_button'): + self.verification_button.setEnabled(False) self.profiles_data = self.match_core_profiles(ProfileController.get_all()) self.number_of_profiles = len(self.profiles_data) @@ -1543,6 +1563,35 @@ class MenuPage(Page): self.buttons.append(button) button.clicked.connect(lambda checked, pid=profile_id: self.print_profile_details(f"Profile_{pid}")) + + profile = ProfileController.get(profile_id) + if profile and profile.location and profile.location.operator: + verification_icon = QPushButton(parent_label) + icon_size = 23 + button_width = 175 + icon_x = button_width - icon_size - 50 + icon_y = 0 + verification_icon.setGeometry(icon_x, icon_y, icon_size, icon_size) + verification_icon.setIcon(QIcon(os.path.join(self.btn_path, "verification_icon.png"))) + verification_icon.setIconSize(QSize(icon_size, icon_size)) + verification_icon.setStyleSheet(f""" + QPushButton {{ + background: transparent; + border: none; + }} + QPushButton:hover {{ + background: rgba(255, 255, 255, 0.2); + border-radius: 3px; + }} + QPushButton:disabled {{ + opacity: 0.3; + }} + """) + verification_icon.setCursor(QtCore.Qt.CursorShape.PointingHandCursor) + verification_icon.setEnabled(self.connection_manager.is_synced()) + verification_icon.clicked.connect(lambda checked, pid=profile_id: self.show_profile_verification(pid)) + verification_icon.show() + return button def create_profile_name_label(self, parent_label, name): @@ -1654,6 +1703,14 @@ class MenuPage(Page): self.boton_just.setEnabled(True) self.boton_just_session.setEnabled(True) self.boton_create.setEnabled(True) + if hasattr(self, 'buttons'): + for button in self.buttons: + parent = button.parent() + if parent: + verification_icons = parent.findChildren(QPushButton) + for icon in verification_icons: + if icon.geometry().width() == 20 and icon.geometry().height() == 20: + icon.setEnabled(self.connection_manager.is_synced()) #self.boton_settings.setEnabled(True) @@ -1774,7 +1831,34 @@ class MenuPage(Page): # Actualizar perfil para editar editar_profile = {"profile_number": profile_number, "name": name, "protocol": protocol} self.page_stack.currentWidget().add_selected_profile(editar_profile) + + self.current_profile_location = location + def show_profile_verification(self, profile_id): + profile = ProfileController.get(profile_id) + if not profile or not profile.location: + return + + location_key = f'{profile.location.country_code}_{profile.location.code}' + location_info = self.connection_manager.get_location_info(location_key) + if not location_info: + return + + location_icon_name = None + btn_path = self.btn_path + + for icon_file in os.listdir(btn_path): + if icon_file.startswith('button_') and icon_file.endswith('.png'): + icon_name = icon_file.replace('button_', '').replace('.png', '') + test_loc = self.connection_manager.get_location_info(icon_name) + if test_loc and test_loc.country_code == location_info.country_code and test_loc.code == location_info.code: + location_icon_name = icon_name + break + + if location_icon_name: + verification_page = LocationVerificationPage(self.page_stack, self.update_status, location_icon_name, self) + self.page_stack.addWidget(verification_page) + self.page_stack.setCurrentIndex(self.page_stack.indexOf(verification_page)) def launch(self): pass @@ -2833,6 +2917,7 @@ class HidetorPage(Page): self.button_reverse.clicked.connect(self.reverse) self.display.setGeometry(QtCore.QRect(5, 10, 390, 520)) self.title.setGeometry(395, 40, 380, 40); self.title.setText("Pick a location") + def create_interface_elements(self, available_locations): self.buttonGroup = QButtonGroup(self) @@ -2849,7 +2934,7 @@ class HidetorPage(Page): icon_path = os.path.join(self.btn_path, f"button_{icon_name}.png") boton.setIcon(QIcon(icon_path)) fallback_path = os.path.join(self.btn_path, "default_location_button.png") - provider = locations.provider_name if locations and hasattr(locations, 'provider_name') else None + provider = locations.operator.name if locations and hasattr(locations, 'operator') else None if boton.icon().isNull(): if locations and hasattr(locations, 'country_name'): base_image = LocationPage.create_location_button_image(f'{locations.country_code}_{locations.code}', fallback_path, provider) @@ -2866,7 +2951,32 @@ class HidetorPage(Page): boton.setIcon(QIcon(base_image)) self.buttons.append(boton) self.buttonGroup.addButton(boton, j) - boton.clicked.connect(lambda _, location=icon_name: self.show_location(location)) + boton.location_icon_name = icon_name + boton.setCursor(QtCore.Qt.CursorShape.PointingHandCursor) + boton.clicked.connect(lambda checked, loc=icon_name: self.show_location(loc)) + + if locations and locations.operator: + verification_icon = QPushButton(self) + icon_size = 30 + button_x, button_y, button_width, button_height = geometry + icon_x = button_x + button_width - icon_size + 10 + icon_y = button_y + verification_icon.setGeometry(icon_x, icon_y, icon_size, icon_size) + verification_icon.setIcon(QIcon(os.path.join(self.btn_path, "verification_icon.png"))) + verification_icon.setIconSize(QSize(icon_size - 4, icon_size - 4)) + verification_icon.setStyleSheet(f""" + QPushButton {{ + background: transparent; + border: none; + }} + QPushButton:hover {{ + background: rgba(255, 255, 255, 0.2); + border-radius: 3px; + }} + """) + verification_icon.setCursor(QtCore.Qt.CursorShape.PointingHandCursor) + verification_icon.clicked.connect(lambda checked, loc=icon_name: self.show_location_verification(loc)) + verification_icon.show() def update_swarp_json(self): inserted_data = { @@ -2881,6 +2991,7 @@ class HidetorPage(Page): self.selected_location_icon = location self.button_next.setVisible(True) self.update_swarp_json() + def reverse(self): self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(ProtocolPage))) @@ -2888,6 +2999,11 @@ class HidetorPage(Page): def go_selected(self): self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(BrowserPage))) + def show_location_verification(self, location_icon_name): + verification_page = LocationVerificationPage(self.page_stack, self.update_status, location_icon_name, self) + self.page_stack.addWidget(verification_page) + self.page_stack.setCurrentIndex(self.page_stack.indexOf(verification_page)) + class ResidentialPage(Page): def __init__(self, page_stack, main_window, parent=None): super().__init__("Wireguard", page_stack, main_window, parent) @@ -3140,6 +3256,8 @@ class LocationPage(Page): self.button_next.setVisible(False) for button in self.buttons: button.setChecked(False) + if hasattr(self, 'verification_button'): + self.verification_button.setEnabled(False) def create_interface_elements(self, available_locations): self.buttonGroup = QButtonGroup(self) @@ -3155,7 +3273,7 @@ class LocationPage(Page): icon_path = os.path.join(self.btn_path, f"button_{icon_name}.png") boton.setIcon(QIcon(icon_path)) fallback_path = os.path.join(self.btn_path, "default_location_button.png") - provider = locations.provider_name if locations and hasattr(locations, 'provider_name') else None + provider = locations.operator.name if locations and hasattr(locations, 'operator') else None if boton.icon().isNull(): if locations and hasattr(locations, 'country_name'): base_image = LocationPage.create_location_button_image(f'{locations.country_code}_{locations.code}', fallback_path, provider) @@ -3173,7 +3291,32 @@ class LocationPage(Page): self.buttons.append(boton) self.buttonGroup.addButton(boton, j) - boton.clicked.connect(lambda _, location=icon_name: self.show_location(location)) + boton.location_icon_name = icon_name + boton.setCursor(QtCore.Qt.CursorShape.PointingHandCursor) + boton.clicked.connect(lambda checked, loc=icon_name: self.show_location(loc)) + + if locations and locations.operator: + verification_icon = QPushButton(self) + icon_size = 30 + button_x, button_y, button_width, button_height = geometry + icon_x = button_x + button_width - icon_size + 10 + icon_y = button_y + verification_icon.setGeometry(icon_x, icon_y, icon_size, icon_size) + verification_icon.setIcon(QIcon(os.path.join(self.btn_path, "verification_icon.png"))) + verification_icon.setIconSize(QSize(icon_size - 4, icon_size - 4)) + verification_icon.setStyleSheet(f""" + QPushButton {{ + background: transparent; + border: none; + }} + QPushButton:hover {{ + background: rgba(255, 255, 255, 0.2); + border-radius: 3px; + }} + """) + verification_icon.setCursor(QtCore.Qt.CursorShape.PointingHandCursor) + verification_icon.clicked.connect(lambda checked, loc=icon_name: self.show_location_verification(loc)) + verification_icon.show() def update_swarp_json(self, get_connection=False): profile_data = self.update_status.read_data() @@ -3194,6 +3337,7 @@ class LocationPage(Page): self.button_next.clicked.connect(self.go_selected) self.update_swarp_json() + def reverse(self): self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(ProtocolPage))) @@ -3203,6 +3347,11 @@ class LocationPage(Page): else: self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(BrowserPage))) + def show_location_verification(self, location_icon_name): + verification_page = LocationVerificationPage(self.page_stack, self.update_status, location_icon_name, self) + self.page_stack.addWidget(verification_page) + self.page_stack.setCurrentIndex(self.page_stack.indexOf(verification_page)) + @staticmethod def create_location_button_image(location_name, fallback_image_path, provider=None, existing_icon_path=None): if existing_icon_path: @@ -3273,22 +3422,30 @@ class LocationPage(Page): painter.setTransform(QTransform()) if provider: - provider_font = QApplication.font() - provider_font.setPointSize(8) - provider_font.setWeight(QFont.Weight.Normal) - painter.setFont(provider_font) + provider_label_font = QApplication.font() + provider_label_font.setPointSize(8) + provider_label_font.setWeight(QFont.Weight.Bold) + painter.setFont(provider_label_font) painter.setPen(QColor(128, 128, 128)) provider_label = "Provider:" provider_label_rect = painter.fontMetrics().boundingRect(provider_label) + + provider_text_font = QApplication.font() + provider_text_font.setPointSize(7) + provider_text_font.setWeight(QFont.Weight.Normal) + painter.setFont(provider_text_font) provider_text_rect = painter.fontMetrics().boundingRect(provider) provider_x = ((base_image.width() - max(provider_label_rect.width(), provider_text_rect.width())) // 2) - 30 provider_y = 50 px = int(provider_x) py = int(provider_y) - painter.drawText(px, py, provider_label) - painter.drawText(px, py + provider_label_rect.height() + 2, provider) + + painter.setFont(provider_label_font) + painter.drawText(px + 20, py + 2, provider_label) + painter.setFont(provider_text_font) + painter.drawText(px + 5, py + provider_label_rect.height() + 2, provider) finally: painter.end() return base_image @@ -3795,6 +3952,11 @@ class ResumePage(Page): else: self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(ScreenPage))) + def show_location_verification(self, location_icon_name): + verification_page = LocationVerificationPage(self.page_stack, self.update_status, location_icon_name, self) + self.page_stack.addWidget(verification_page) + self.page_stack.setCurrentIndex(self.page_stack.indexOf(verification_page)) + def create_arrow(self): self.arrow_label = QLabel(self) self.arrow_label.setGeometry(400, 115, 200, 200) @@ -3824,7 +3986,7 @@ class ResumePage(Page): if os.path.exists(icon_path): label.setPixmap(QPixmap(icon_path)) locations = self.connection_manager.get_location_info(icon_name) - provider = locations.provider_name if locations and hasattr(locations, 'provider_name') else None + provider = locations.operator.name if locations and hasattr(locations, 'operator') else None if label.pixmap().isNull(): if locations and hasattr(locations, 'country_name'): label.setPixmap(LocationPage.create_location_button_image(f'{locations.country_code}_{locations.code}', os.path.join(self.btn_path, "default_location_button.png"), provider)) @@ -3884,26 +4046,32 @@ class ResumePage(Page): elif item == 'location': icon_path = os.path.join(self.btn_path, f"button_{text}.png") geometry = (585, initial_y + i * label_height, 185, 75) - parent_label = QLabel(self) + parent_label = QPushButton(self) parent_label.setGeometry(*geometry) - parent_label.setPixmap(QPixmap(icon_path)) + parent_label.setFlat(True) + parent_label.setStyleSheet("background: transparent; border: none;") + location_pixmap = QPixmap(icon_path) locations = self.connection_manager.get_location_info(text) - provider = locations.provider_name if locations and hasattr(locations, 'provider_name') else None + provider = locations.operator.name if locations and hasattr(locations, 'operator') else None fallback_path = os.path.join(self.btn_path, "default_location_button.png") - if parent_label.pixmap().isNull(): + if location_pixmap.isNull(): if locations and hasattr(locations, 'country_name'): base_image = LocationPage.create_location_button_image(f'{locations.country_code}_{locations.code}', fallback_path, provider) - parent_label.setPixmap(base_image) + parent_label.setIcon(QIcon(base_image)) else: base_image = LocationPage.create_location_button_image('', fallback_path, provider) - parent_label.setPixmap(base_image) + parent_label.setIcon(QIcon(base_image)) else: if locations and hasattr(locations, 'country_name'): base_image = LocationPage.create_location_button_image(f'{locations.country_code}_{locations.code}', fallback_path, provider, icon_path) - parent_label.setPixmap(base_image) + parent_label.setIcon(QIcon(base_image)) else: base_image = LocationPage.create_location_button_image('', fallback_path, provider, icon_path) - parent_label.setPixmap(base_image) + parent_label.setIcon(QIcon(base_image)) + parent_label.setIconSize(QSize(185, 75)) + parent_label.location_icon_name = text + parent_label.setCursor(QtCore.Qt.CursorShape.PointingHandCursor) + parent_label.clicked.connect(lambda checked, loc=text: self.show_location_verification(loc)) parent_label.show() self.labels_creados.append(parent_label) elif item == 'dimentions': @@ -4340,7 +4508,7 @@ class EditorPage(Page): image_path = os.path.join(self.btn_path, f"button_{current_value}.png") base_image = QPixmap(image_path) locations = self.connection_manager.get_location_info(current_value) - provider = locations.provider_name if locations and hasattr(locations, 'provider_name') else None + provider = locations.operator.name if locations and hasattr(locations, 'operator') else None fallback_path = os.path.join(self.btn_path, "default_location_button.png") if base_image.isNull(): if locations and hasattr(locations, 'country_name'): @@ -4705,6 +4873,237 @@ class EditorPage(Page): resume_page = self.find_resume_page() if resume_page: resume_page.handle_core_action_create_profile('CREATE_SESSION_PROFILE', profile_data, 'session') + +class LocationVerificationPage(Page): + def __init__(self, page_stack, main_window, location_icon_name, previous_page, parent=None): + super().__init__("LocationVerification", page_stack, main_window, parent) + self.location_icon_name = location_icon_name + self.previous_page = previous_page + self.connection_manager = main_window.connection_manager + self.font_style = f"font-family: '{main_window.open_sans_family}';" + self.verification_info = {} + self.verification_checkmarks = {} + self.verification_full_values = {} + self.verification_labels = {} + self.verification_copy_buttons = {} + self.verification_display_names = { + "operator_name": "Operator Name", + "nostr_public_key": "Nostr Key", + "hydraveil_public_key": "HydraVeil Key", + "nostr_attestation_event_reference": "Nostr Verification" + } + self.setup_ui() + + def setup_ui(self): + location_display = QLabel(self) + location_display.setGeometry(10, 0, 390, 520) + location_display.setAlignment(Qt.AlignmentFlag.AlignCenter) + + icon_path = os.path.join(self.btn_path, f"icon_{self.location_icon_name}.png") + location_pixmap = QPixmap(icon_path) + fallback_path = os.path.join(self.btn_path, "default_location_button.png") + + if location_pixmap.isNull(): + location_pixmap = QPixmap(fallback_path) + + location_display.setPixmap(location_pixmap.scaled(390, 520, Qt.AspectRatioMode.KeepAspectRatio, Qt.TransformationMode.SmoothTransformation)) + location_display.show() + + title = QLabel("Verification Information", self) + title.setGeometry(350, 50, 350, 30) + title.setStyleSheet(f"color: #808080; font-size: 20px; font-weight: bold; {self.font_style}") + title.show() + + info_items = [ + ("Operator Name", "operator_name", 130), + ("Nostr Key", "nostr_public_key", 180), + ("HydraVeil Key", "hydraveil_public_key", 230), + ("Nostr Verification", "nostr_attestation_event_reference", 280), + ] + + label_x = 350 + label_width = 150 + label_height = 30 + value_x = 510 + value_width = 210 + value_height = 30 + checkmark_x = 725 + checkmark_width = 30 + checkmark_height = 30 + copy_button_x = 750 + copy_button_width = 30 + copy_button_height = 30 + + for label_text, key, y_pos in info_items: + label_widget = QLabel(label_text + ":", self) + label_widget.setGeometry(label_x, y_pos, label_width, label_height) + label_widget.setStyleSheet(f"color: white; font-size: 18px; {self.font_style}") + label_widget.setAlignment(Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter) + label_widget.show() + self.verification_labels[key] = label_widget + + value_widget = QLabel("N/A", self) + value_widget.setGeometry(value_x, y_pos, value_width, value_height) + value_widget.setStyleSheet(f"color: white; font-size: 16px; {self.font_style}") + value_widget.setAlignment(Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter) + value_widget.show() + + checkmark_widget = QLabel("✓", self) + checkmark_widget.setGeometry(checkmark_x, y_pos, checkmark_width, checkmark_height) + checkmark_widget.setStyleSheet(f"color: #4CAF50; font-size: 28px; font-weight: bold; {self.font_style}") + checkmark_widget.setAlignment(Qt.AlignmentFlag.AlignCenter) + checkmark_widget.hide() + + self.verification_info[key] = value_widget + self.verification_checkmarks[key] = checkmark_widget + + copy_button = QPushButton(self) + copy_button.setGeometry(copy_button_x, y_pos, copy_button_width, copy_button_height) + copy_button.setIcon(QIcon(os.path.join(self.btn_path, "paste_button.png"))) + copy_button.setIconSize(QSize(24, 24)) + copy_button.setStyleSheet(f""" + QPushButton {{ + background: transparent; + border: none; + }} + QPushButton:hover {{ + background: rgba(255, 255, 255, 0.1); + border-radius: 4px; + }} + """) + copy_button.clicked.connect(lambda checked=False, k=key: self.copy_verification_value(k)) + copy_button.show() + self.verification_copy_buttons[key] = copy_button + + self.back_button = QPushButton(self) + self.back_button.setGeometry(720, 525, 48, 35) + self.back_button.setIcon(QIcon(os.path.join(self.btn_path, "back.png"))) + self.back_button.setIconSize(QSize(48, 35)) + self.back_button.setStyleSheet(f""" + QPushButton {{ + background: transparent; + border: none; + }} + QPushButton:hover {{ + background: rgba(255, 255, 255, 0.1); + border-radius: 4px; + }} + """) + self.back_button.clicked.connect(self.go_back) + self.back_button.show() + + self.update_verification_info() + + def truncate_text_by_width(self, text, widget, max_width): + if not text or text == "N/A": + return text + + metrics = widget.fontMetrics() + text_width = metrics.horizontalAdvance(text) + + if text_width <= max_width: + return text + + ellipsis = "..." + ellipsis_width = metrics.horizontalAdvance(ellipsis) + available_width = max_width - ellipsis_width + + if available_width <= 0: + return ellipsis + + start_chars = 1 + end_chars = 1 + + while True: + start_text = text[:start_chars] + end_text = text[-end_chars:] + combined_width = metrics.horizontalAdvance(start_text + ellipsis + end_text) + + if combined_width <= max_width: + if start_chars + end_chars >= len(text): + return text + start_chars += 1 + if start_chars + end_chars >= len(text): + return text + end_chars += 1 + else: + if start_chars > 1: + start_chars -= 1 + if end_chars > 1: + end_chars -= 1 + break + + if start_chars + end_chars >= len(text): + return text + + return text[:start_chars] + ellipsis + text[-end_chars:] + + def update_verification_info(self): + locations = self.connection_manager.get_location_info(self.location_icon_name) + value_width = 210 + + if not locations: + for key, widget in self.verification_info.items(): + widget.setText("N/A") + self.verification_full_values[key] = "N/A" + if key in self.verification_checkmarks: + self.verification_checkmarks[key].hide() + return + + operator = None + if locations.operator: + operator = locations.operator + + if operator: + operator_name = operator.name or "N/A" + self.verification_full_values["operator_name"] = operator_name + display_operator = self.truncate_text_by_width(operator_name, self.verification_info["operator_name"], value_width) + self.verification_info["operator_name"].setText(display_operator) + + nostr_key = operator.nostr_public_key or "N/A" + self.verification_full_values["nostr_public_key"] = nostr_key + display_nostr = self.truncate_text_by_width(nostr_key, self.verification_info["nostr_public_key"], value_width) + self.verification_info["nostr_public_key"].setText(display_nostr) + + hydraveil_key = operator.public_key or "N/A" + self.verification_full_values["hydraveil_public_key"] = hydraveil_key + display_hydraveil = self.truncate_text_by_width(hydraveil_key, self.verification_info["hydraveil_public_key"], value_width) + self.verification_info["hydraveil_public_key"].setText(display_hydraveil) + + nostr_verification = operator.nostr_attestation_event_reference or "N/A" + self.verification_full_values["nostr_attestation_event_reference"] = nostr_verification + display_nostr_verif = self.truncate_text_by_width(nostr_verification, self.verification_info["nostr_attestation_event_reference"], value_width) + self.verification_info["nostr_attestation_event_reference"].setText(display_nostr_verif) + else: + self.verification_info["operator_name"].setText("N/A") + self.verification_full_values["operator_name"] = "N/A" + self.verification_info["nostr_public_key"].setText("N/A") + self.verification_full_values["nostr_public_key"] = "N/A" + self.verification_info["hydraveil_public_key"].setText("N/A") + self.verification_full_values["hydraveil_public_key"] = "N/A" + self.verification_info["nostr_attestation_event_reference"].setText("N/A") + self.verification_full_values["nostr_attestation_event_reference"] = "N/A" + + for key, widget in self.verification_info.items(): + if key in self.verification_checkmarks: + full_value = self.verification_full_values.get(key, "") + if full_value and full_value != "N/A": + self.verification_checkmarks[key].show() + else: + self.verification_checkmarks[key].hide() + + def copy_verification_value(self, key): + full_value = self.verification_full_values.get(key, "") + if full_value and full_value != "N/A": + clipboard = QApplication.clipboard() + clipboard.setText(full_value) + display_name = self.verification_display_names.get(key, "Verification value") + self.custom_window.update_status(f"{display_name} copied to clipboard") + + def go_back(self): + if self.previous_page: + self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.previous_page)) + class Settings(Page): def __init__(self, page_stack, main_window, parent=None): super().__init__("Settings", page_stack, main_window, parent) @@ -5789,23 +6188,22 @@ class Settings(Page): checkmark_widget.hide() container_layout.addWidget(checkmark_widget) - if key == "nostr_attestation_event_reference": - copy_button = QPushButton() - copy_button.setIcon(QIcon(os.path.join(self.btn_path, "paste_button.png"))) - copy_button.setIconSize(QSize(24, 24)) - copy_button.setFixedSize(30, 30) - copy_button.setStyleSheet(f""" - QPushButton {{ - background: transparent; - border: none; - }} - QPushButton:hover {{ - background: rgba(255, 255, 255, 0.1); - border-radius: 4px; - }} - """) - copy_button.clicked.connect(lambda checked=False, k=key: self.copy_verification_value(k)) - container_layout.addWidget(copy_button) + copy_button = QPushButton() + copy_button.setIcon(QIcon(os.path.join(self.btn_path, "paste_button.png"))) + copy_button.setIconSize(QSize(24, 24)) + copy_button.setFixedSize(30, 30) + copy_button.setStyleSheet(f""" + QPushButton {{ + background: transparent; + border: none; + }} + QPushButton:hover {{ + background: rgba(255, 255, 255, 0.1); + border-radius: 4px; + }} + """) + copy_button.clicked.connect(lambda checked=False, k=key: self.copy_verification_value(k)) + container_layout.addWidget(copy_button) verification_layout.addWidget(container) self.verification_info[key] = value_widget @@ -5896,7 +6294,14 @@ class Settings(Page): if full_value and full_value != "N/A": clipboard = QApplication.clipboard() clipboard.setText(full_value) - self.update_status.update_status("Verification value copied to clipboard") + verification_display_names = { + "operator_name": "Operator Name", + "nostr_public_key": "Nostr Key", + "hydraveil_public_key": "HydraVeil Key", + "nostr_attestation_event_reference": "Nostr Verification" + } + display_name = verification_display_names.get(key, "Verification value") + self.update_status.update_status(f"{display_name} copied to clipboard") def update_subscription_info(self, index): if index < 0: @@ -7735,15 +8140,18 @@ class FastRegistrationPage(Page): self.buttons.append(next_button) def create_location_section(self): - label = QLabel("Location", self) + label = QPushButton(self) label.setGeometry(435, 250, 185, 75) + label.setFlat(True) + label.setStyleSheet("background: transparent; border: none;") if self.selected_values['location']: image_path = os.path.join(self.btn_path, f"button_{self.selected_values['location']}.png") location_image = QPixmap(image_path) locations = self.connection_manager.get_location_info(self.selected_values['location']) - provider = locations.provider_name if locations and hasattr(locations, 'provider_name') else None + provider = locations.operator.name if locations and hasattr(locations, 'operator') else None fallback_path = os.path.join(self.btn_path, "default_location_button.png") + if location_image.isNull(): if locations and hasattr(locations, 'country_name'): location_image = LocationPage.create_location_button_image(f'{locations.country_code}_{locations.code}', fallback_path, provider) @@ -7757,8 +8165,12 @@ class FastRegistrationPage(Page): else: location_image = QPixmap(os.path.join(self.btn_path, "default_location_button.png")) - label.setPixmap(location_image) - label.setScaledContents(True) + label.setIcon(QIcon(location_image)) + label.setIconSize(QSize(185, 75)) + if self.selected_values['location']: + label.location_icon_name = self.selected_values['location'] + label.setCursor(QtCore.Qt.CursorShape.PointingHandCursor) + label.clicked.connect(lambda checked, loc=self.selected_values['location']: self.show_location_verification(loc)) label.show() self.labels.append(label) @@ -7954,6 +8366,11 @@ class FastRegistrationPage(Page): def go_back(self): self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(MenuPage))) + def show_location_verification(self, location_icon_name): + verification_page = LocationVerificationPage(self.page_stack, self.update_status, location_icon_name, self) + self.page_stack.addWidget(verification_page) + self.page_stack.setCurrentIndex(self.page_stack.indexOf(verification_page)) + def create_profile(self): profile_name = self.name.text() if not profile_name: diff --git a/gui/resources/images/verification_icon.png b/gui/resources/images/verification_icon.png new file mode 100755 index 0000000..0cc8083 Binary files /dev/null and b/gui/resources/images/verification_icon.png differ