Custome message box, secure code, discord, config
This commit is contained in:
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
@@ -16,5 +16,8 @@
|
||||
"python.useEnvironmentsExtension": true,
|
||||
"terminal.integrated.persistentSessionReviveProcess": "never",
|
||||
"terminal.integrated.enablePersistentSessions": false,
|
||||
"terminal.integrated.hideOnStartup": "always"
|
||||
"terminal.integrated.hideOnStartup": "always",
|
||||
"[jsonc]": {
|
||||
"editor.defaultFormatter": "vscode.json-language-features"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ a = Analysis(
|
||||
},
|
||||
runtime_hooks=[],
|
||||
excludes=[
|
||||
# PySide6 - modules non utilisés
|
||||
# PySide6 - modules non utilisés
|
||||
'PySide6.Qt3DAnimation',
|
||||
'PySide6.Qt3DCore',
|
||||
'PySide6.Qt3DExtras',
|
||||
@@ -30,7 +30,7 @@ a = Analysis(
|
||||
'PySide6.QtDesigner',
|
||||
'PySide6.QtHelp',
|
||||
'PySide6.QtLocation',
|
||||
# 'PySide6.QtMultimedia',
|
||||
# 'PySide6.QtMultimedia', # Nécessaire pour l'audio
|
||||
'PySide6.QtMultimediaWidgets',
|
||||
# 'PySide6.QtNetwork', # Dépendance à QtMultimedia
|
||||
'PySide6.QtNetworkAuth',
|
||||
@@ -113,7 +113,7 @@ a = Analysis(
|
||||
# REPL / terminal
|
||||
"readline",
|
||||
"code",
|
||||
# "codeop",
|
||||
# "codeop", # Nécessaire
|
||||
"cmd",
|
||||
|
||||
# mail / network protocols non utilisés
|
||||
@@ -145,7 +145,7 @@ a = Analysis(
|
||||
"bz2",
|
||||
"lzma",
|
||||
"gzip",
|
||||
#"zipfile",
|
||||
#"zipfile", # Nécessaire à cause de pyinstaller
|
||||
"tarfile",
|
||||
"zipapp",
|
||||
|
||||
|
||||
60
src/main.py
60
src/main.py
@@ -5,8 +5,15 @@ from PySide6.QtCore import QResource
|
||||
from PySide6.QtGui import QFontDatabase, QFont
|
||||
from PySide6.QtWidgets import QApplication
|
||||
|
||||
# Imports pour la gestion de la configuration
|
||||
from config.config_manager import ConfigManager
|
||||
|
||||
# Imports pour la vérification Discord
|
||||
from tools.discord_tools import CheckDiscord
|
||||
from tools.custom_message_box import CustomMessageBox
|
||||
|
||||
# Ne pas supprimer ! Enregistre les ressources Qt
|
||||
import resources # noqa: F401 - required to register Qt resources
|
||||
import resources # noqa: F401 - required to register Qt resources
|
||||
|
||||
from ui.main_window import MainWindow
|
||||
from tools.constants import Resources
|
||||
@@ -15,9 +22,9 @@ from tools.constants import Resources
|
||||
# Bundle path resolution
|
||||
# ---------------------------------------------------------------------------
|
||||
bundle_dir = get_internal_dir()
|
||||
|
||||
QResource.registerResource(f"{bundle_dir}/resources.py")
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Font helper
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -37,12 +44,49 @@ def load_custom_font() -> str:
|
||||
if __name__ == "__main__":
|
||||
app = QApplication(sys.argv)
|
||||
|
||||
# Chargement des styles de l'application
|
||||
with open(f"{bundle_dir}/styles/styles.qss", 'r') as f:
|
||||
app.setStyleSheet(f.read())
|
||||
# 1. Initialisation UNIQUE du gestionnaire de config
|
||||
config = ConfigManager()
|
||||
|
||||
# Application de la font custom sur toute l'application'
|
||||
app.setFont(QFont(load_custom_font(), 16))
|
||||
# 2. Setup environnemental (Styles & Fonts)
|
||||
try:
|
||||
with open(f"{bundle_dir}/styles/styles.qss", 'r') as f:
|
||||
app.setStyleSheet(f.read())
|
||||
|
||||
app.setFont(QFont(load_custom_font(), 16))
|
||||
except Exception as e:
|
||||
print(f"Erreur lors du chargement des styles : {e}")
|
||||
|
||||
|
||||
# 3. Garde-fou Discord
|
||||
if not CheckDiscord.isdiscordrunning():
|
||||
msg = CustomMessageBox(
|
||||
title="La Tanière: Discord non détecté",
|
||||
message="Discord ne semble pas lancé.\n\n"
|
||||
"Tu dois avoir démarré Discord et y être connecté pour utiliser l'application.\n\n"
|
||||
"Lorsque cela sera fait, relance le launcher.",
|
||||
icon_type=CustomMessageBox.WARNING,
|
||||
buttons=CustomMessageBox.OK
|
||||
)
|
||||
msg.exec()
|
||||
sys.exit(0) # On quitte proprement sans lancer MainWindow
|
||||
|
||||
# On récupère l'ID stocké (sera "" si absent grâce au schéma)
|
||||
stored_user_id = config.get_discord_user()
|
||||
if not CheckDiscord.isuserconnected():
|
||||
msg = CustomMessageBox(
|
||||
title="La Tanière: connexion Discord",
|
||||
message="Tu n'est pas connecté à Discord\n\n"
|
||||
"Assure-toi que tu es connecté à Discord.\n\n"
|
||||
"Lorsque cela sera fait, relance le launcher.",
|
||||
icon_type=CustomMessageBox.WARNING,
|
||||
buttons=CustomMessageBox.OK
|
||||
)
|
||||
msg.exec()
|
||||
sys.exit(0) # On quitte proprement sans lancer MainWindow
|
||||
|
||||
# 4. Lancement de l'application si tout est OK
|
||||
window = MainWindow(bundle_dir, config)
|
||||
# Note: Assure-toi que self.show() est bien dans le __init__ de MainWindow
|
||||
# ou ajoute window.show() ici si tu l'en lèves du constructeur.
|
||||
|
||||
window = MainWindow(bundle_dir)
|
||||
sys.exit(app.exec())
|
||||
|
||||
168
src/tools/custom_message_box.py
Normal file
168
src/tools/custom_message_box.py
Normal file
@@ -0,0 +1,168 @@
|
||||
import sys
|
||||
from PySide6.QtWidgets import (QDialog, QVBoxLayout, QHBoxLayout,
|
||||
QLabel, QPushButton, QWidget, QGraphicsDropShadowEffect)
|
||||
from PySide6.QtCore import Qt, QPropertyAnimation, QEasingCurve
|
||||
from PySide6.QtGui import QColor
|
||||
|
||||
|
||||
class CustomMessageBox(QDialog):
|
||||
# Enums pour la configuration
|
||||
INFO = "info"
|
||||
WARNING = "warning"
|
||||
OK = "ok"
|
||||
OK_CANCEL = "ok_cancel"
|
||||
|
||||
def __init__(self, title="Notification", message="", icon_type="info", buttons="ok", parent=None):
|
||||
super().__init__(parent)
|
||||
|
||||
# --- CONFIGURATION FENÊTRE ---
|
||||
self.setWindowFlags(Qt.FramelessWindowHint | Qt.Dialog)
|
||||
self.setAttribute(Qt.WA_TranslucentBackground)
|
||||
self.setMinimumWidth(400)
|
||||
|
||||
color_main = "#101624"
|
||||
color_accent = "#248277" if icon_type == self.INFO else "#cf5b16"
|
||||
|
||||
# --- ANIMATION DE FONDU ---
|
||||
self.setWindowOpacity(0)
|
||||
self.fade_anim = QPropertyAnimation(self, b"windowOpacity")
|
||||
self.fade_anim.setDuration(350)
|
||||
self.fade_anim.setStartValue(0)
|
||||
self.fade_anim.setEndValue(1)
|
||||
self.fade_anim.setEasingCurve(QEasingCurve.OutCubic)
|
||||
|
||||
# --- UI SETUP ---
|
||||
self.container = QWidget(self)
|
||||
self.container.setObjectName("MainContainer")
|
||||
self.container.setStyleSheet(f"""
|
||||
QWidget#MainContainer {{
|
||||
background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
|
||||
stop:0 {color_main}, stop:1 {color_accent});
|
||||
border-radius: 15px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
}}
|
||||
QLabel {{ color: white; font-family: 'Segoe UI'; }}
|
||||
""")
|
||||
|
||||
# LAYOUT PRINCIPAL DU CONTAINER (Marges à 0 pour coller le bouton au bord)
|
||||
layout = QVBoxLayout(self.container)
|
||||
layout.setContentsMargins(0, 0, 0, 0)
|
||||
layout.setSpacing(0)
|
||||
|
||||
# 1. Barre de titre (Contenu collé en haut et à droite)
|
||||
title_bar_layout = QHBoxLayout()
|
||||
title_bar_layout.setContentsMargins(15, 0, 0, 0)
|
||||
title_bar_layout.setSpacing(0)
|
||||
|
||||
title_label = QLabel(title.upper())
|
||||
title_label.setStyleSheet(
|
||||
"font-weight: bold; font-size: 10px; color: rgba(255,255,255,0.7); letter-spacing: 1px;")
|
||||
|
||||
self.close_btn = QPushButton("✕")
|
||||
self.close_btn.setFixedSize(45, 35)
|
||||
self.close_btn.clicked.connect(self.reject)
|
||||
self.close_btn.setCursor(Qt.PointingHandCursor)
|
||||
self.close_btn.setStyleSheet("""
|
||||
QPushButton {
|
||||
background: transparent;
|
||||
color: white;
|
||||
border: none;
|
||||
font-size: 14px;
|
||||
/* Rayon identique au container (15px) pour épouser parfaitement le coin */
|
||||
border-top-right-radius: 15px;
|
||||
border-bottom-left-radius: 10px;
|
||||
}
|
||||
QPushButton:hover {
|
||||
background-color: #e74c3c;
|
||||
color: white;
|
||||
}
|
||||
""")
|
||||
|
||||
title_bar_layout.addWidget(title_label)
|
||||
title_bar_layout.addStretch()
|
||||
title_bar_layout.addWidget(self.close_btn)
|
||||
layout.addLayout(title_bar_layout)
|
||||
|
||||
# 2. SOUS-LAYOUT POUR LE CONTENU (Ici on remet des marges pour le texte)
|
||||
body_layout = QVBoxLayout()
|
||||
body_layout.setContentsMargins(20, 10, 20, 20)
|
||||
body_layout.setSpacing(15)
|
||||
|
||||
# Contenu central (Icône + Message)
|
||||
content_layout = QHBoxLayout()
|
||||
icon_label = QLabel()
|
||||
icon_text = "ℹ️" if icon_type == self.INFO else "⚠️"
|
||||
icon_label.setText(icon_text)
|
||||
icon_label.setStyleSheet("font-size: 35px; margin-right: 10px;")
|
||||
|
||||
msg_label = QLabel(message)
|
||||
msg_label.setStyleSheet("font-size: 14px; color: #f0f0f0;")
|
||||
msg_label.setWordWrap(True)
|
||||
|
||||
content_layout.addWidget(icon_label)
|
||||
content_layout.addWidget(msg_label, 1)
|
||||
body_layout.addLayout(content_layout)
|
||||
|
||||
# Boutons d'action
|
||||
btn_layout = QHBoxLayout()
|
||||
btn_layout.setSpacing(10)
|
||||
btn_layout.addStretch()
|
||||
|
||||
style_btn_base = """
|
||||
QPushButton {
|
||||
background: #2a313d; border-radius: 6px; color: white;
|
||||
padding: 8px 20px; font-weight: bold; font-size: 12px;
|
||||
border: 1px solid rgba(255,255,255,0.05);
|
||||
}
|
||||
QPushButton:hover { background: #363d4a; border: 1px solid white; }
|
||||
"""
|
||||
|
||||
if buttons == self.OK_CANCEL:
|
||||
self.btn_cancel = QPushButton("ANNULER")
|
||||
self.btn_cancel.setStyleSheet(style_btn_base)
|
||||
self.btn_cancel.clicked.connect(self.reject)
|
||||
btn_layout.addWidget(self.btn_cancel)
|
||||
|
||||
self.btn_ok = QPushButton("COMPRIS")
|
||||
style_btn_ok = style_btn_base.replace("#2a313d", "#248277")
|
||||
self.btn_ok.setStyleSheet(style_btn_ok)
|
||||
self.btn_ok.setCursor(Qt.PointingHandCursor)
|
||||
self.btn_ok.clicked.connect(self.accept)
|
||||
btn_layout.addWidget(self.btn_ok)
|
||||
|
||||
body_layout.addLayout(btn_layout)
|
||||
|
||||
# Ajout du body_layout dans le layout principal
|
||||
layout.addLayout(body_layout)
|
||||
|
||||
# --- OMBRE PORTÉE ---
|
||||
shadow = QGraphicsDropShadowEffect(self)
|
||||
shadow.setBlurRadius(20)
|
||||
shadow.setXOffset(0)
|
||||
shadow.setYOffset(8)
|
||||
shadow.setColor(QColor(0, 0, 0, 180))
|
||||
self.container.setGraphicsEffect(shadow)
|
||||
|
||||
final_layout = QVBoxLayout(self)
|
||||
final_layout.addWidget(self.container)
|
||||
|
||||
self.old_pos = None
|
||||
|
||||
def showEvent(self, event):
|
||||
super().showEvent(event)
|
||||
self.fade_anim.start()
|
||||
|
||||
def mousePressEvent(self, e):
|
||||
# On permet le déplacement uniquement si on clique sur la barre de titre
|
||||
# ou n'importe où sauf sur les boutons
|
||||
if e.button() == Qt.LeftButton:
|
||||
self.old_pos = e.globalPosition().toPoint()
|
||||
|
||||
def mouseMoveEvent(self, e):
|
||||
if self.old_pos:
|
||||
delta = e.globalPosition().toPoint() - self.old_pos
|
||||
self.move(self.x() + delta.x(), self.y() + delta.y())
|
||||
self.old_pos = e.globalPosition().toPoint()
|
||||
|
||||
def mouseReleaseEvent(self, e):
|
||||
self.old_pos = None
|
||||
@@ -1,8 +1,8 @@
|
||||
import psutil
|
||||
|
||||
from pypresence import Presence
|
||||
from get_server_token import GetServerTokenForDiscord
|
||||
from constants import Urls
|
||||
from tools.get_server_token import GetServerTokenForDiscord
|
||||
from tools.constants import Urls
|
||||
|
||||
class DiscordToken:
|
||||
@staticmethod
|
||||
|
||||
@@ -8,10 +8,10 @@ from PySide6.QtUiTools import QUiLoader
|
||||
from PySide6.QtWidgets import QMainWindow, QSizePolicy
|
||||
|
||||
from config.config_manager import ConfigManager
|
||||
from tools.constants import NO_DISCORD, NO_STAFF, Urls
|
||||
from controllers.audio_controller import AudioController
|
||||
from controllers.glow_animator import GlowAnimator
|
||||
from controllers.window_dragger import WindowDragger
|
||||
from tools.constants import NO_DISCORD, NO_STAFF, Urls
|
||||
from fake_patch_notes import patch_note
|
||||
|
||||
# For Linux Wayland to authorize moving window
|
||||
@@ -19,10 +19,10 @@ if platform.startswith('linux'):
|
||||
environ["QT_QPA_PLATFORM"] = "xcb"
|
||||
|
||||
class MainWindow(QMainWindow):
|
||||
def __init__(self, bundle_dir):
|
||||
def __init__(self, bundle_dir: str, config_manager: ConfigManager):
|
||||
super().__init__()
|
||||
|
||||
self.config = ConfigManager()
|
||||
self.config = config_manager
|
||||
|
||||
# UI
|
||||
self.ui = QUiLoader().load(f"{bundle_dir}/ui/mainwindow_vertical_pager.ui", self)
|
||||
|
||||
Reference in New Issue
Block a user