update: new vless and hysteria2 ui
|
|
@ -61,6 +61,7 @@ from gui.v2.actions.profile_data import (
|
|||
clear_profile_data,
|
||||
)
|
||||
from gui.v2.actions.database_health import GuiStorageDatabaseError
|
||||
from gui.v2.actions.profile_status import is_profile_enabled_for_gui
|
||||
from gui.v2.actions.ticket_failure import (
|
||||
save_ticket_verification_failure,
|
||||
get_ticket_verification_failure,
|
||||
|
|
@ -674,7 +675,7 @@ class CustomWindow(QMainWindow):
|
|||
self.connection_manager._connected_profiles.clear()
|
||||
for profile_id, profile in profiles.items():
|
||||
try:
|
||||
if ProfileController.is_enabled(profile):
|
||||
if is_profile_enabled_for_gui(profile):
|
||||
connected_profiles.append(profile_id)
|
||||
self.connection_manager.add_connected_profile(profile_id)
|
||||
except Exception:
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 259 KiB |
|
Before Width: | Height: | Size: 258 KiB |
|
Before Width: | Height: | Size: 259 KiB |
|
Before Width: | Height: | Size: 87 KiB |
BIN
gui/resources/images/vless_mini.png
Executable file
|
After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 220 KiB |
|
Before Width: | Height: | Size: 219 KiB |
|
Before Width: | Height: | Size: 220 KiB |
27
gui/v2/actions/profile_status.py
Executable file
|
|
@ -0,0 +1,27 @@
|
|||
from core.controllers.ProfileController import ProfileController
|
||||
from core.controllers.SystemStateController import SystemStateController
|
||||
from core.models.system.SystemProfile import SystemProfile
|
||||
|
||||
|
||||
SINGBOX_PROTOCOLS = ("hysteria2", "vless")
|
||||
|
||||
|
||||
def _connection_code(profile):
|
||||
connection = getattr(profile, "connection", None)
|
||||
return getattr(connection, "code", None)
|
||||
|
||||
|
||||
def _system_state_profile_id():
|
||||
state = SystemStateController.get()
|
||||
if state is None:
|
||||
return None
|
||||
try:
|
||||
return int(state.profile_id)
|
||||
except (TypeError, ValueError):
|
||||
return None
|
||||
|
||||
|
||||
def is_profile_enabled_for_gui(profile):
|
||||
if isinstance(profile, SystemProfile) and _connection_code(profile) in SINGBOX_PROTOCOLS:
|
||||
return _system_state_profile_id() == int(profile.id)
|
||||
return ProfileController.is_enabled(profile)
|
||||
20
gui/v2/actions/singbox_prereqs.py
Executable file
|
|
@ -0,0 +1,20 @@
|
|||
from core.services.helpers.install_dependencies import SUDO_SINGBOX_LOCATION
|
||||
from core.services.helpers.setup_sudo_scripts import (
|
||||
is_singbox_wrapper_ready,
|
||||
test_if_in_sudo_folder,
|
||||
)
|
||||
from core.utils.basic_operations.does_file_exist import does_file_exist
|
||||
|
||||
|
||||
def singbox_prereqs_installed():
|
||||
try:
|
||||
if not is_singbox_wrapper_ready():
|
||||
return False
|
||||
|
||||
sudo_scripts = test_if_in_sudo_folder()
|
||||
if not getattr(sudo_scripts, "valid", False):
|
||||
return False
|
||||
|
||||
return does_file_exist(SUDO_SINGBOX_LOCATION)
|
||||
except Exception:
|
||||
return False
|
||||
0
gui/v2/infrastructure/screen_size.py
Normal file → Executable file
|
|
@ -15,6 +15,18 @@ profile_observer = ProfileObserver()
|
|||
ticket_observer = TicketObserver()
|
||||
|
||||
|
||||
def _format_connecting_status(event):
|
||||
subject = getattr(event, 'subject', None)
|
||||
if isinstance(subject, dict):
|
||||
attempt_count = subject.get("attempt_count")
|
||||
maximum_attempts = subject.get("maximum_number_of_attempts")
|
||||
if attempt_count is not None and maximum_attempts is not None:
|
||||
return f'[{attempt_count}/{maximum_attempts}] Performing connection attempt...'
|
||||
if subject:
|
||||
return str(subject)
|
||||
return 'Connecting..'
|
||||
|
||||
|
||||
def setup_observers(update_status):
|
||||
profile_observer.subscribe(
|
||||
'created', lambda event: update_status('Profile Created'))
|
||||
|
|
@ -33,7 +45,7 @@ def setup_observers(update_status):
|
|||
client_observer.subscribe(
|
||||
'updating', lambda event: update_status('Updating client...'))
|
||||
client_observer.subscribe('update_progressing', lambda event: update_status(
|
||||
f'Current progress: {event.meta.get('progress'):.2f}%'))
|
||||
f"Current progress: {event.meta.get('progress'):.2f}%"))
|
||||
client_observer.subscribe('updated', lambda event: update_status(
|
||||
'Restart client to apply update.'))
|
||||
|
||||
|
|
@ -58,7 +70,7 @@ def setup_observers(update_status):
|
|||
# f'Downloaded {ApplicationController.get(event.subject.application_code).name}'))
|
||||
|
||||
connection_observer.subscribe('connecting', lambda event: update_status(
|
||||
f'[{event.subject.get("attempt_count")}/{event.subject.get("maximum_number_of_attempts")}] Performing connection attempt...'))
|
||||
_format_connecting_status(event)))
|
||||
|
||||
connection_observer.subscribe('tor_bootstrapping', lambda event: update_status(
|
||||
'Establishing Tor connection...'))
|
||||
|
|
|
|||
|
|
@ -94,3 +94,10 @@ class Page(QWidget):
|
|||
boton.setChecked(False)
|
||||
|
||||
self.button_next.setVisible(False)
|
||||
|
||||
def replace_click_handler(self, button, handler):
|
||||
try:
|
||||
button.clicked.disconnect()
|
||||
except TypeError:
|
||||
pass
|
||||
button.clicked.connect(handler)
|
||||
|
|
|
|||
|
|
@ -22,6 +22,11 @@ from gui.v2.workers.page_data_worker import PageDataWorker
|
|||
|
||||
|
||||
class EditorPage(Page):
|
||||
SINGBOX_PROTOCOLS = ("hysteria2", "vless")
|
||||
PROTOCOL_BUTTON_ASSETS = {
|
||||
"hysteria2": "hystria2",
|
||||
}
|
||||
|
||||
def __init__(self, page_stack, main_window, prepared=None):
|
||||
super().__init__("Editor", page_stack, main_window)
|
||||
self.page_stack = page_stack
|
||||
|
|
@ -208,6 +213,13 @@ class EditorPage(Page):
|
|||
"dimentions": self.connection_manager.get_available_resolutions(data_profile.get('id', ''))
|
||||
}, selected_profile_str)
|
||||
|
||||
elif protocol in self.SINGBOX_PROTOCOLS:
|
||||
self.process_and_show_labels(data_profile, {
|
||||
"protocol": [protocol],
|
||||
"connection": ['system-wide'],
|
||||
"location": self.connection_manager.get_location_list(),
|
||||
}, selected_profile_str)
|
||||
|
||||
elif protocol == "residential" or protocol == "hidetor":
|
||||
self.process_and_show_labels(data_profile, {
|
||||
"protocol": ['residential', 'wireguard', 'hidetor'],
|
||||
|
|
@ -263,6 +275,20 @@ class EditorPage(Page):
|
|||
else:
|
||||
self.brow_disp.hide()
|
||||
|
||||
if protocol in self.SINGBOX_PROTOCOLS:
|
||||
if protocol == "vless":
|
||||
self.display.setGeometry(0, 90, 540, 405)
|
||||
else:
|
||||
self.display.setGeometry(0, 60, 540, 405)
|
||||
self.display.show()
|
||||
self.display.setPixmap(self._encrypted_proxy_display_pixmap(
|
||||
protocol, location).scaled(
|
||||
self.display.size(),
|
||||
Qt.AspectRatioMode.KeepAspectRatio,
|
||||
Qt.TransformationMode.SmoothTransformation))
|
||||
self.garaje.hide()
|
||||
self.brow_disp.hide()
|
||||
|
||||
if protocol == "residential":
|
||||
self.display.setGeometry(0, 60, 540, 405)
|
||||
self.brow_disp.show()
|
||||
|
|
@ -301,7 +327,7 @@ class EditorPage(Page):
|
|||
l_name = f"{location_info.country_name}, {location_info.name}" if hasattr(
|
||||
location_info, 'country_name') else ""
|
||||
|
||||
if operator_name != 'Simplified Privacy' and operator_name != "" and protocol != 'hidetor':
|
||||
if operator_name != 'Simplified Privacy' and operator_name != "" and protocol not in ('hidetor', *self.SINGBOX_PROTOCOLS):
|
||||
text_color = "white"
|
||||
if profile_obj and profile_obj.is_session_profile():
|
||||
text_color = "black"
|
||||
|
|
@ -413,9 +439,12 @@ class EditorPage(Page):
|
|||
base_image = ScreenPage.create_resolution_button_image(
|
||||
self, current_value)
|
||||
else:
|
||||
image_path = os.path.join(
|
||||
self.btn_path, f"{data_profile.get(key, '')}_button.png")
|
||||
current_value = data_profile.get(key, '')
|
||||
if key == 'protocol':
|
||||
image_path = self._protocol_button_asset(current_value)
|
||||
else:
|
||||
image_path = os.path.join(
|
||||
self.btn_path, f"{current_value}_button.png")
|
||||
base_image = QPixmap(image_path)
|
||||
|
||||
if key == 'dimentions':
|
||||
|
|
@ -579,7 +608,7 @@ class EditorPage(Page):
|
|||
|
||||
prev_button.setVisible(True)
|
||||
next_button.setVisible(True)
|
||||
if key == 'protocol' or (protocol == 'wireguard' and key == 'connection'):
|
||||
if key == 'protocol' or (connection == 'system-wide' and key == 'connection'):
|
||||
prev_button.setDisabled(True)
|
||||
next_button.setDisabled(True)
|
||||
|
||||
|
|
@ -587,6 +616,44 @@ class EditorPage(Page):
|
|||
prev_button.setVisible(False)
|
||||
next_button.setVisible(False)
|
||||
|
||||
def _protocol_button_asset(self, protocol):
|
||||
asset_name = self.PROTOCOL_BUTTON_ASSETS.get(protocol, protocol)
|
||||
return os.path.join(self.btn_path, f"{asset_name}_button.png")
|
||||
|
||||
def _encrypted_proxy_display_pixmap(self, protocol, location):
|
||||
pixmap = QPixmap(os.path.join(self.btn_path, f"{protocol}.png"))
|
||||
if pixmap.isNull():
|
||||
pixmap = QPixmap(os.path.join(self.btn_path, "system_wide_global.png"))
|
||||
if pixmap.isNull():
|
||||
return pixmap
|
||||
|
||||
location_pixmap = QPixmap(os.path.join(
|
||||
self.btn_path, f"icon_mini_{location}.png"))
|
||||
if location_pixmap.isNull():
|
||||
location_pixmap = QPixmap(os.path.join(
|
||||
self.btn_path, "default_location_mini.png"))
|
||||
if location_pixmap.isNull():
|
||||
return pixmap
|
||||
|
||||
icon_size = max(42, min(72, int(min(pixmap.width(), pixmap.height()) * 0.22)))
|
||||
location_pixmap = location_pixmap.scaled(
|
||||
icon_size,
|
||||
icon_size,
|
||||
Qt.AspectRatioMode.KeepAspectRatio,
|
||||
Qt.TransformationMode.SmoothTransformation)
|
||||
x = int(pixmap.width() * 0.58)
|
||||
if protocol == 'hysteria2':
|
||||
y = int(pixmap.height() * 0.35)
|
||||
else:
|
||||
y = int(pixmap.height() * 0.30)
|
||||
x = min(max(0, x), max(0, pixmap.width() - location_pixmap.width()))
|
||||
y = min(max(0, y), max(0, pixmap.height() - location_pixmap.height()))
|
||||
|
||||
painter = QPainter(pixmap)
|
||||
painter.drawPixmap(x, y, location_pixmap)
|
||||
painter.end()
|
||||
return pixmap
|
||||
|
||||
def on_sync_complete_for_edit_profile(self, available_locations, available_browsers, status, is_tor, locations, all_browsers):
|
||||
if status:
|
||||
self.update_status.update_status('Sync complete.')
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@ class HidetorPage(Page):
|
|||
self.selected_location_icon = None
|
||||
self.connection_manager = main_window.connection_manager
|
||||
self.update_status = main_window
|
||||
self.button_next.clicked.connect(self.go_selected)
|
||||
self.replace_click_handler(self.button_next, self.go_selected)
|
||||
self.button_reverse.setVisible(True)
|
||||
self.button_reverse.clicked.connect(self.reverse)
|
||||
self.replace_click_handler(self.button_reverse, self.reverse)
|
||||
self.display.setGeometry(QtCore.QRect(5, 10, 390, 520))
|
||||
self.title.setGeometry(395, 40, 380, 40)
|
||||
self.title.setText("Pick a location")
|
||||
|
|
@ -91,7 +91,12 @@ class HidetorPage(Page):
|
|||
self.update_swarp_json()
|
||||
|
||||
def reverse(self):
|
||||
self.custom_window.navigator.navigate("protocol")
|
||||
profile_data = self.update_status.read_data()
|
||||
self.limpiar()
|
||||
if profile_data.get("protocol") == "residential":
|
||||
self.custom_window.navigator.navigate("residential")
|
||||
else:
|
||||
self.custom_window.navigator.navigate("protocol")
|
||||
|
||||
def go_selected(self):
|
||||
self.custom_window.navigator.navigate("browser")
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@ class LocationPage(Page):
|
|||
self.update_status = main_window
|
||||
self.button_reverse.setVisible(True)
|
||||
self.connection_manager = main_window.connection_manager
|
||||
self.button_reverse.clicked.connect(self.reverse)
|
||||
self.replace_click_handler(self.button_reverse, self.reverse)
|
||||
self.replace_click_handler(self.button_next, self.go_selected)
|
||||
self.display.setGeometry(QtCore.QRect(5, 10, 390, 520))
|
||||
self.title.setGeometry(395, 40, 380, 40)
|
||||
self.title.setText("Pick a location")
|
||||
|
|
@ -166,7 +167,6 @@ class LocationPage(Page):
|
|||
target_size, Qt.AspectRatioMode.KeepAspectRatio))
|
||||
self.selected_location_icon = location
|
||||
self.button_next.setVisible(True)
|
||||
self.button_next.clicked.connect(self.go_selected)
|
||||
self.update_swarp_json()
|
||||
|
||||
try:
|
||||
|
|
@ -179,10 +179,19 @@ class LocationPage(Page):
|
|||
self.verification_button.setEnabled(True)
|
||||
|
||||
def reverse(self):
|
||||
self.custom_window.navigator.navigate("protocol")
|
||||
profile_data = self.update_status.read_data()
|
||||
self.limpiar()
|
||||
if hasattr(self, 'initial_display'):
|
||||
self.initial_display.show()
|
||||
if hasattr(self, 'verification_button'):
|
||||
self.verification_button.setEnabled(False)
|
||||
if profile_data.get("protocol") == "wireguard":
|
||||
self.custom_window.navigator.navigate("wireguard")
|
||||
else:
|
||||
self.custom_window.navigator.navigate("protocol")
|
||||
|
||||
def go_selected(self):
|
||||
if self.connection_type == "system-wide":
|
||||
if self.update_swarp_json(get_connection=True) == "system-wide":
|
||||
self.custom_window.navigator.navigate("resume")
|
||||
else:
|
||||
self.custom_window.navigator.navigate("browser")
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ from core.models.system.SystemProfile import SystemProfile
|
|||
from gui.v2.infrastructure.setup_observers import ticket_observer
|
||||
from gui.v2.actions.database_health import GuiStorageDatabaseError
|
||||
from gui.v2.actions.profile_order import normalize_profile_order
|
||||
from gui.v2.actions.profile_status import is_profile_enabled_for_gui
|
||||
from gui.v2.ui.pages.Page import Page
|
||||
from gui.v2.ui.pages.location_verification_page import LocationVerificationPage
|
||||
from gui.v2.ui.styles.styles import SCROLLBAR_CYAN_QSS
|
||||
|
|
@ -375,7 +376,7 @@ class MenuPage(Page):
|
|||
self.IsSystem = 0
|
||||
for profile_id, profile in profiles.items():
|
||||
try:
|
||||
is_enabled = ProfileController.is_enabled(profile)
|
||||
is_enabled = is_profile_enabled_for_gui(profile)
|
||||
except Exception:
|
||||
is_enabled = False
|
||||
if is_enabled:
|
||||
|
|
@ -588,7 +589,7 @@ class MenuPage(Page):
|
|||
elif label_name == 'browser':
|
||||
if connection_type == 'system-wide':
|
||||
if protocol in ('hysteria2', 'vless'):
|
||||
return os.path.join(self.btn_path, "system_wide_global.png")
|
||||
return os.path.join(self.btn_path, "wireguard_system_wide.png")
|
||||
return os.path.join(self.btn_path, "wireguard_system_wide.png")
|
||||
else:
|
||||
return os.path.join(self.btn_path, f"{value[label_name]} latest_mini.png")
|
||||
|
|
@ -849,11 +850,12 @@ class MenuPage(Page):
|
|||
elif protocol.lower() in ["wireguard", "open", "residential", "hidetor", "hysteria2", "vless"]:
|
||||
label_principal = QLabel(self)
|
||||
label_principal.setGeometry(0, 90, 400, 300)
|
||||
pixmap = QPixmap(os.path.join(
|
||||
self.btn_path, f"{protocol}_{location}.png"))
|
||||
if pixmap.isNull() and protocol.lower() in ["hysteria2", "vless"]:
|
||||
if protocol.lower() in ["hysteria2", "vless"]:
|
||||
pixmap = self.build_encrypted_proxy_detail_pixmap(
|
||||
protocol.lower(), location)
|
||||
else:
|
||||
pixmap = QPixmap(os.path.join(
|
||||
self.btn_path, f"icon_{location}.png"))
|
||||
self.btn_path, f"{protocol}_{location}.png"))
|
||||
label_principal.setPixmap(pixmap)
|
||||
label_principal.setScaledContents(True)
|
||||
label_principal.show()
|
||||
|
|
@ -962,6 +964,38 @@ class MenuPage(Page):
|
|||
|
||||
self.current_profile_location = location
|
||||
|
||||
def build_encrypted_proxy_detail_pixmap(self, protocol, location):
|
||||
pixmap = QPixmap(os.path.join(self.btn_path, f"{protocol}.png"))
|
||||
if pixmap.isNull():
|
||||
return pixmap
|
||||
|
||||
location_pixmap = QPixmap(os.path.join(
|
||||
self.btn_path, f"icon_mini_{location}.png"))
|
||||
if location_pixmap.isNull():
|
||||
location_pixmap = QPixmap(os.path.join(
|
||||
self.btn_path, "default_location_mini.png"))
|
||||
if location_pixmap.isNull():
|
||||
return pixmap
|
||||
|
||||
icon_size = max(42, min(72, int(min(pixmap.width(), pixmap.height()) * 0.22)))
|
||||
location_pixmap = location_pixmap.scaled(
|
||||
icon_size,
|
||||
icon_size,
|
||||
Qt.AspectRatioMode.KeepAspectRatio,
|
||||
Qt.TransformationMode.SmoothTransformation)
|
||||
x = int(pixmap.width() * 0.58)
|
||||
if protocol == 'hysteria2':
|
||||
y = int(pixmap.height() * 0.35)
|
||||
else:
|
||||
y = int(pixmap.height() * 0.30)
|
||||
x = min(max(0, x), max(0, pixmap.width() - location_pixmap.width()))
|
||||
y = min(max(0, y), max(0, pixmap.height() - location_pixmap.height()))
|
||||
|
||||
painter = QPainter(pixmap)
|
||||
painter.drawPixmap(x, y, location_pixmap)
|
||||
painter.end()
|
||||
return pixmap
|
||||
|
||||
def show_profile_verification(self, profile_id):
|
||||
profile = self._safe_profile(profile_id)
|
||||
profile_location = getattr(profile, 'location', None)
|
||||
|
|
@ -1092,7 +1126,10 @@ class MenuPage(Page):
|
|||
def on_disconnect_done(self):
|
||||
self.disconnect_button.setEnabled(True)
|
||||
self.disconnect_system_wide_button.setEnabled(True)
|
||||
pass
|
||||
selected_profile_id = self.reverse_id
|
||||
self.refresh_menu_buttons()
|
||||
if selected_profile_id is not None and self._safe_profile(selected_profile_id):
|
||||
self.print_profile_details(f"Profile_{selected_profile_id}")
|
||||
|
||||
def _config_flag(self, section, key, default=False):
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ from core.models.Result import Result, ResultError
|
|||
|
||||
import sys
|
||||
|
||||
from gui.v2.actions.singbox_prereqs import singbox_prereqs_installed
|
||||
from gui.v2.ui.pages.Page import Page
|
||||
from gui.v2.workers.worker_thread import WorkerThread
|
||||
|
||||
|
|
@ -190,6 +191,10 @@ class NetworkingSetupPage(Page):
|
|||
def prepare_singbox_prereqs(self):
|
||||
if not self._is_singbox_mode():
|
||||
return
|
||||
if singbox_prereqs_installed():
|
||||
self._set_status("Singbox prerequisites are already installed. Creating profile...", "#2ecc71")
|
||||
QTimer.singleShot(200, self.finish_singbox_prereq_flow)
|
||||
return
|
||||
if not self._sudo_scripts_ready_for_singbox():
|
||||
self.manual_button.setDisabled(False)
|
||||
self.auto_button.setDisabled(False)
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@ class ProtocolPage(Page):
|
|||
self.connection_manager = main_window.connection_manager
|
||||
self.button_back.setVisible(True)
|
||||
self.update_status = main_window
|
||||
self.button_go.clicked.connect(self.go_selected)
|
||||
self.replace_click_handler(self.button_back, self.reverse)
|
||||
self.replace_click_handler(self.button_go, self.go_selected)
|
||||
self.coming_soon_label = QLabel("Coming soon", self)
|
||||
self.coming_soon_label.setGeometry(210, 50, 200, 40)
|
||||
self.coming_soon_label.setStyleSheet("font-size: 22px;")
|
||||
|
|
@ -104,3 +105,10 @@ class ProtocolPage(Page):
|
|||
|
||||
def find_menu_page(self):
|
||||
return self.custom_window.navigator.get_cached("menu")
|
||||
|
||||
def reverse(self):
|
||||
self.display.clear()
|
||||
for boton in self.buttons:
|
||||
boton.setChecked(False)
|
||||
self.button_go.setVisible(False)
|
||||
self.custom_window.navigator.navigate("menu")
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ class ResidentialPage(Page):
|
|||
self.update_status = main_window
|
||||
self.connection_choice = None
|
||||
self.button_reverse.setVisible(True)
|
||||
self.button_reverse.clicked.connect(self.reverse)
|
||||
self.button_go.clicked.connect(self.go_selected)
|
||||
self.replace_click_handler(self.button_reverse, self.reverse)
|
||||
self.replace_click_handler(self.button_go, self.go_selected)
|
||||
|
||||
self.display_1 = QLabel(self)
|
||||
self.display_1.setGeometry(QtCore.QRect(
|
||||
|
|
@ -98,4 +98,5 @@ class ResidentialPage(Page):
|
|||
self.update_status.write_data(inserted_data)
|
||||
|
||||
def reverse(self):
|
||||
self.button_go.setVisible(False)
|
||||
self.custom_window.navigator.navigate("protocol")
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ from PyQt6 import QtCore, QtGui
|
|||
from core.controllers.ProfileController import ProfileController
|
||||
|
||||
from gui.v2.actions.profile_order import append_profile_to_visual_order
|
||||
from gui.v2.actions.singbox_prereqs import singbox_prereqs_installed
|
||||
from gui.v2.ui.pages.Page import Page
|
||||
from gui.v2.ui.pages.location_page import LocationPage
|
||||
from gui.v2.ui.pages.screen_page import ScreenPage
|
||||
|
|
@ -28,13 +29,13 @@ class ResumePage(Page):
|
|||
self.btn_path = main_window.btn_path
|
||||
self.labels_creados = []
|
||||
self.additional_labels = []
|
||||
self.button_go.clicked.connect(self.copy_profile)
|
||||
self.replace_click_handler(self.button_go, self.copy_profile)
|
||||
self.button_back.setVisible(True)
|
||||
self.title.setGeometry(585, 40, 185, 40)
|
||||
self.title.setText("Profile Summary")
|
||||
self.display.setGeometry(QtCore.QRect(5, 50, 580, 435))
|
||||
self.buttonGroup = QButtonGroup(self)
|
||||
self.button_back.clicked.connect(self.reverse)
|
||||
self.replace_click_handler(self.button_back, self.reverse)
|
||||
self.create_arrow()
|
||||
self.create_interface_elements()
|
||||
|
||||
|
|
@ -382,7 +383,7 @@ class ResumePage(Page):
|
|||
new_profile = profile_data
|
||||
existing_profile_ids = tuple(profiles.keys())
|
||||
|
||||
if new_profile.get('protocol') in self.SINGBOX_PROTOCOLS:
|
||||
if new_profile.get('protocol') in self.SINGBOX_PROTOCOLS and not singbox_prereqs_installed():
|
||||
self.show_singbox_prereq_setup(new_profile, profile_id, existing_profile_ids)
|
||||
return
|
||||
|
||||
|
|
|
|||
|
|
@ -345,3 +345,6 @@ class ScreenPage(Page):
|
|||
|
||||
def gestionar_next(self):
|
||||
self.custom_window.navigator.navigate("resume")
|
||||
|
||||
def gestionar_back(self):
|
||||
self.custom_window.navigator.navigate("browser")
|
||||
|
|
|
|||
|
|
@ -24,10 +24,11 @@ class TorPage(Page):
|
|||
QPixmap(os.path.join(self.btn_path, "browser only.png")))
|
||||
self.display0.lower()
|
||||
|
||||
self.button_go.clicked.connect(self.go_selected)
|
||||
self.replace_click_handler(self.button_go, self.go_selected)
|
||||
|
||||
self.button_reverse.setVisible(True)
|
||||
self.button_reverse.clicked.connect(self.reverse_selected)
|
||||
self.replace_click_handler(self.button_reverse, self.reverse_selected)
|
||||
self.replace_click_handler(self.button_back, self.reverse_selected)
|
||||
|
||||
self.label = QLabel(self)
|
||||
self.label.setGeometry(440, 370, 86, 130)
|
||||
|
|
@ -72,6 +73,8 @@ class TorPage(Page):
|
|||
self.update_status.write_data(inserted_data)
|
||||
|
||||
def reverse_selected(self):
|
||||
self.limpiar()
|
||||
self.button_go.setVisible(False)
|
||||
self.custom_window.navigator.navigate("residential")
|
||||
|
||||
def go_selected(self):
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@ class WireGuardPage(Page):
|
|||
self.selected_protocol = None
|
||||
self.selected_protocol_icon = None
|
||||
self.button_back.setVisible(True)
|
||||
self.button_go.clicked.connect(self.go_selected)
|
||||
self.replace_click_handler(self.button_back, self.reverse)
|
||||
self.replace_click_handler(self.button_go, self.go_selected)
|
||||
self.additional_labels = []
|
||||
self.title.setGeometry(585, 40, 185, 40)
|
||||
self.title.setText("Pick a Protocol")
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import shlex
|
||||
import subprocess
|
||||
import inspect
|
||||
|
||||
from PyQt6.QtCore import QThread, pyqtSignal
|
||||
|
||||
|
|
@ -52,6 +53,18 @@ class WorkerThread(QThread):
|
|||
self.is_running = True
|
||||
self.is_disabling = False
|
||||
|
||||
def _disable_profile(self, profile):
|
||||
kwargs = {
|
||||
'profile_observer': profile_observer,
|
||||
'ticket_observer': ticket_observer,
|
||||
'connection_observer': connection_observer,
|
||||
}
|
||||
supported = inspect.signature(ProfileController.disable).parameters
|
||||
ProfileController.disable(
|
||||
profile,
|
||||
**{key: value for key, value in kwargs.items() if key in supported}
|
||||
)
|
||||
|
||||
def run(self):
|
||||
if self.action == 'LIST_PROFILES':
|
||||
self.list_profiles()
|
||||
|
|
@ -167,13 +180,11 @@ class WorkerThread(QThread):
|
|||
for profile_id in self.profile_data:
|
||||
profile = ProfileController.get(int(profile_id))
|
||||
if isinstance(profile, SessionProfile):
|
||||
ProfileController.disable(
|
||||
profile, ignore=True, profile_observer=profile_observer, ticket_observer=ticket_observer, connection_observer=connection_observer)
|
||||
self._disable_profile(profile)
|
||||
for profile_id in self.profile_data:
|
||||
profile = ProfileController.get(int(profile_id))
|
||||
if isinstance(profile, SystemProfile):
|
||||
ProfileController.disable(
|
||||
profile, ignore=True, profile_observer=profile_observer, ticket_observer=ticket_observer, connection_observer=connection_observer)
|
||||
self._disable_profile(profile)
|
||||
self.text_output.emit("All profiles were successfully disabled")
|
||||
except SudoScript as e:
|
||||
self.text_output.emit(str(e))
|
||||
|
|
@ -282,8 +293,7 @@ class WorkerThread(QThread):
|
|||
try:
|
||||
profile = ProfileController.get(int(self.profile_data['id']))
|
||||
if profile:
|
||||
ProfileController.disable(
|
||||
profile, profile_observer=profile_observer, ticket_observer=ticket_observer, connection_observer=connection_observer, wipe_assassin=True)
|
||||
self._disable_profile(profile)
|
||||
else:
|
||||
self.text_output.emit(
|
||||
f"No profile found with ID: {self.profile_data['id']}")
|
||||
|
|
|
|||