suggestions tab added, state and size save in progress

This commit is contained in:
Louis Mazin 2025-07-18 18:38:16 +02:00
parent 9a61d20a57
commit fb44f09610
11 changed files with 231 additions and 41 deletions

View File

@ -3,7 +3,7 @@ import json
from pathlib import Path from pathlib import Path
# Load config.json # Load config.json
config_path = Path("config.json") config_path = Path("../config.json")
with config_path.open("r", encoding="utf-8") as f: with config_path.open("r", encoding="utf-8") as f:
config = json.load(f) config = json.load(f)
@ -24,7 +24,8 @@ icon = getenv("ICON_PATH", "")
# Data files to bundle # Data files to bundle
datas = [ datas = [
("data/assets/*", "data/assets/"), ("data/assets/*", "data/assets/"),
("data/", "data/") ("data/", "data/"),
("config.json", ".")
] ]
binaries = [] binaries = []

View File

@ -18,8 +18,7 @@ class SettingsManager:
with open(defaults_path, 'r', encoding='utf-8') as f: with open(defaults_path, 'r', encoding='utf-8') as f:
self.default_settings = json.load(f) self.default_settings = json.load(f)
config_path = path.join(paths.get_current_dir(), "config.json") with open(paths.resource_path("config.json"), 'r', encoding='utf-8') as f:
with open(config_path, 'r', encoding='utf-8') as f:
self.config = json.load(f) self.config = json.load(f)
self.settings = QSettings(path.join(paths.get_user_data_dir(self.get_config("app_name")), self.get_config("app_name") + ".ini"), QSettings.Format.IniFormat) self.settings = QSettings(path.join(paths.get_user_data_dir(self.get_config("app_name")), self.get_config("app_name") + ".ini"), QSettings.Format.IniFormat)
@ -49,7 +48,7 @@ class SettingsManager:
self.settings.setValue("lang", lang_code) self.settings.setValue("lang", lang_code)
self.observer_manager.notify(NotificationType.LANGUAGE) self.observer_manager.notify(NotificationType.LANGUAGE)
# Window size and fullscreen # Window size and maximized
def get_window_size(self) -> dict: def get_window_size(self) -> dict:
return self.settings.value("window_size", self.default_settings.get("window_size")) return self.settings.value("window_size", self.default_settings.get("window_size"))
@ -59,18 +58,8 @@ class SettingsManager:
new_size = {"width": width, "height": height} new_size = {"width": width, "height": height}
self.settings.setValue("window_size", new_size) self.settings.setValue("window_size", new_size)
def get_fullscreen(self) -> bool: def get_maximized(self) -> bool:
return self.settings.value("fullscreen", self.default_settings.get("fullscreen")) return self.settings.value("maximized", self.default_settings.get("maximized")) == "true"
def set_fullscreen(self, fullscreen: bool, width: int, height: int): def set_maximized(self, maximized: bool):
self.settings.setValue("fullscreen", fullscreen) self.settings.setValue("maximized", maximized)
self.settings.setValue("fullscreen_size", {"width": width, "height": height})
def get_fullscreen_size(self) -> dict:
return self.settings.value("fullscreen_size", self.default_settings.get("fullscreen_size"))
def set_fullscreen_size(self, width: int, height: int) -> None:
current_size = self.get_fullscreen_size()
if current_size["width"] != width or current_size["height"] != height:
new_size = {"width": width, "height": height}
self.settings.setValue("fullscreen_size", new_size)

View File

@ -1,9 +1,11 @@
from PyQt6.QtWidgets import QMainWindow from PyQt6.QtWidgets import QMainWindow
from PyQt6.QtGui import QIcon from PyQt6.QtGui import QIcon
from PyQt6.QtWidgets import QApplication from PyQt6.QtWidgets import QApplication
from PyQt6.QtCore import QSize
from app.core.main_manager import MainManager, NotificationType from app.core.main_manager import MainManager, NotificationType
from app.ui.widgets.tabs_widget import TabsWidget, MenuDirection, ButtonPosition, BorderSide from app.ui.widgets.tabs_widget import TabsWidget, MenuDirection, ButtonPosition, BorderSide
from app.ui.windows.settings_window import SettingsWindow from app.ui.windows.settings_window import SettingsWindow
from app.ui.windows.suggestion_window import SuggestionWindow
import app.utils.paths as paths import app.utils.paths as paths
class MainWindow(QMainWindow): class MainWindow(QMainWindow):
@ -11,6 +13,7 @@ class MainWindow(QMainWindow):
super().__init__() super().__init__()
self.main_manager = MainManager() self.main_manager = MainManager()
self.language_manager = self.main_manager.get_language_manager() self.language_manager = self.main_manager.get_language_manager()
self.theme_manager = self.main_manager.get_theme_manager() self.theme_manager = self.main_manager.get_theme_manager()
self.settings_manager = self.main_manager.get_settings_manager() self.settings_manager = self.main_manager.get_settings_manager()
@ -19,24 +22,62 @@ class MainWindow(QMainWindow):
# Configurer la fenêtre avant de créer les widgets # Configurer la fenêtre avant de créer les widgets
app = QApplication.instance() app = QApplication.instance()
self.settings_manager.dpi = app.primaryScreen().devicePixelRatio()
size = app.primaryScreen().size() size = app.primaryScreen().size()
self.settings_manager.minScreenSize = min(size.height(),size.width()) self.settings_manager.minScreenSize = min(size.height(),size.width())
configWidth = int(self.settings_manager.get_fullscreen_size()["width"] if self.settings_manager.get_fullscreen() else self.settings_manager.get_window_size()["width"] /self.settings_manager.dpi)
configHeight = int(self.settings_manager.get_fullscreen_size()["height"] if self.settings_manager.get_fullscreen() else self.settings_manager.get_window_size()["height"] /self.settings_manager.dpi)
self.setMinimumSize(600, 400) self.setMinimumSize(600, 400)
self.resize(configWidth, configHeight)
self.setWindowTitle(self.settings_manager.get_config("app_name")) self.setWindowTitle(self.settings_manager.get_config("app_name"))
self.setStyleSheet(self.theme_manager.get_sheet()) self.setStyleSheet(self.theme_manager.get_sheet())
self.setWindowIcon(QIcon(paths.get_asset_path("icon"))) self.setWindowIcon(QIcon(paths.get_asset_path("icon")))
# Apply saved window state
self.apply_saved_window_state()
self.setup_ui() self.setup_ui()
def apply_saved_window_state(self):
"""Apply saved window size and maximized state"""
window_size = self.settings_manager.get_window_size()
self.current_size = QSize(window_size["width"], window_size["height"])
self.previous_size = self.current_size
self.resize(self.current_size)
if self.settings_manager.get_maximized():
self.showMaximized()
if hasattr(self, 'current_size'):
print(self.current_size)
def changeEvent(self, event):
"""Handle window state changes"""
super().changeEvent(event)
if event.type() == event.Type.WindowStateChange:
# Si on quitte le mode maximisé, sauvegarder la taille actuelle
if self.isMaximized():
self.current_size = self.previous_size
self.settings_manager.set_maximized(self.isMaximized())
if hasattr(self, 'current_size'):
print(self.current_size)
def resizeEvent(self, a0):
self.previous_size = self.current_size
self.current_size = self.size()
self.settings_manager.set_window_size(
self.current_size.width(),
self.current_size.height()
)
def closeEvent(self, event):
"""Handle application close event"""
super().closeEvent(event)
def setup_ui(self): def setup_ui(self):
self.side_menu = TabsWidget(self,MenuDirection.HORIZONTAL,70,None,10,1,BorderSide.TOP) self.side_menu = TabsWidget(self,MenuDirection.HORIZONTAL,70,None,10,1,BorderSide.TOP)
self.settings_window = SettingsWindow(self) self.settings_window = SettingsWindow(self)
self.side_menu.add_widget(self.settings_window,"",paths.get_asset_svg_path("settings"), position=ButtonPosition.CENTER) self.side_menu.add_widget(self.settings_window,"",paths.get_asset_svg_path("settings"), position=ButtonPosition.CENTER)
self.suggestion_window = SuggestionWindow(self)
self.side_menu.add_widget(self.suggestion_window,"",paths.get_asset_svg_path("suggestion"), position=ButtonPosition.CENTER)
self.setCentralWidget(self.side_menu) self.setCentralWidget(self.side_menu)
def update_theme(self): def update_theme(self):

View File

@ -1,4 +1,4 @@
from PyQt6.QtWidgets import QWidget, QVBoxLayout, QComboBox, QLabel, QHBoxLayout, QSizePolicy from PyQt6.QtWidgets import QWidget, QVBoxLayout, QComboBox, QLabel, QHBoxLayout
from PyQt6.QtCore import Qt from PyQt6.QtCore import Qt
from app.core.main_manager import MainManager, NotificationType from app.core.main_manager import MainManager, NotificationType

View File

@ -0,0 +1,146 @@
from PyQt6.QtWidgets import QWidget, QVBoxLayout, QTextEdit, QPushButton, QLabel, QMessageBox, QHBoxLayout
from PyQt6.QtCore import Qt, QThread, pyqtSignal
import time
import smtplib
import os
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from app.core.main_manager import MainManager, NotificationType
class EmailSender(QThread):
success = pyqtSignal()
error = pyqtSignal(str)
def __init__(self, subject, message):
super().__init__()
self.subject = subject
self.message = message
def run(self):
try:
# Get email configuration from environment variables
password = 'xprqegxuqixgljyi'
email = 'louismazindev@gmail.com'
smtp_server = 'smtp.gmail.com'
smtp_port = 587
if not password:
# Fallback to simulation if no credentials are configured
self._simulate_email_sending()
return
# Create message
msg = MIMEMultipart()
msg['From'] = email
msg['To'] = email
msg['Subject'] = self.subject
# Add body to email
msg.attach(MIMEText(self.message, 'plain'))
# Create SMTP session
server = smtplib.SMTP(smtp_server, smtp_port)
server.starttls() # Enable TLS encryption
# Login with app password
server.login(email, password)
# Send email
text = msg.as_string()
server.sendmail(email, email, text)
server.quit()
self.success.emit()
except Exception as e:
self.error.emit()
def _simulate_email_sending(self):
"""Fallback simulation when no email credentials are configured"""
time.sleep(2) # Simulate network delay
print("=== EMAIL SIMULATION (No credentials configured) ===")
print(f"Subject: {self.subject}")
print(f"Message: {self.message}")
print("=" * 55)
self.success.emit()
class SuggestionWindow(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.main_manager = MainManager.get_instance()
self.language_manager = self.main_manager.get_language_manager()
self.settings_manager = self.main_manager.get_settings_manager()
self.observer_manager = self.main_manager.get_observer_manager()
self.observer_manager.subscribe(NotificationType.LANGUAGE, self.update_language)
self.setup_ui()
def setup_ui(self):
layout = QVBoxLayout(self)
layout.setAlignment(Qt.AlignmentFlag.AlignTop)
layout.setSpacing(20)
layout.setContentsMargins(20, 20, 20, 20)
# Title
self.title_label = QLabel(self.language_manager.get_text("suggestion_text"), self)
self.title_label.setStyleSheet("font-size: 18px; font-weight: bold; margin-bottom: 10px;")
layout.addWidget(self.title_label)
# Text area for suggestion
self.text_edit = QTextEdit(self)
self.text_edit.setPlaceholderText(self.language_manager.get_text("suggestion_placeholder"))
self.text_edit.setMinimumHeight(200)
layout.addWidget(self.text_edit)
# Button layout
button_layout = QHBoxLayout()
button_layout.addStretch()
# Send button
self.send_button = QPushButton(self.language_manager.get_text("send_suggestion"), self)
self.send_button.clicked.connect(self.send_suggestion)
button_layout.addWidget(self.send_button)
layout.addLayout(button_layout)
layout.addStretch()
def send_suggestion(self):
message = self.text_edit.toPlainText().strip()
if not message:
return
# Disable send button during sending
self.send_button.setEnabled(False)
self.send_button.setText(self.language_manager.get_text("sending"))
# Create subject with app name
subject = f"Suggestion for {self.settings_manager.get_config('app_name')}"
# Create and start email sender thread
self.email_sender = EmailSender(subject, message)
self.email_sender.success.connect(self.on_email_sent)
self.email_sender.error.connect(self.on_email_error)
self.email_sender.start()
def on_email_sent(self):
self.send_button.setEnabled(True)
self.send_button.setText(self.language_manager.get_text("send_suggestion"))
QMessageBox.information(self,
self.language_manager.get_text("success"),
self.language_manager.get_text("suggestion_sent_success"))
self.text_edit.clear()
def on_email_error(self):
self.send_button.setEnabled(True)
self.send_button.setText(self.language_manager.get_text("send_suggestion"))
QMessageBox.critical(self,
self.language_manager.get_text("error"),
f"{self.language_manager.get_text('suggestion_send_error')}")
def update_language(self):
self.title_label.setText(self.language_manager.get_text("suggestion_text"))
self.text_edit.setPlaceholderText(self.language_manager.get_text("suggestion_placeholder"))
self.send_button.setText(self.language_manager.get_text("send_suggestion"))

View File

@ -46,14 +46,3 @@ def get_user_data_dir(app_name: str) -> Path:
if not path.exists(user_data_path): if not path.exists(user_data_path):
mkdir(user_data_path) mkdir(user_data_path)
return user_data_path return user_data_path
def get_current_dir() -> Path:
"""
Return the directory where the exe or main script is located.
"""
if getattr(sys, 'frozen', False):
# If the application is frozen (PyInstaller)
return str(Path(sys.executable).parent)
else:
# If running in a normal Python environment
return str(Path(__file__).parent.parent.parent)

View File

@ -1 +1 @@
<ns0:svg xmlns:ns0="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="100px" height="100px" fill="#000000" stroke="#000000"><ns0:path d="M 22.205078 2 A 1.0001 1.0001 0 0 0 21.21875 2.8378906 L 20.246094 8.7929688 C 19.076509 9.1331971 17.961243 9.5922728 16.910156 10.164062 L 11.996094 6.6542969 A 1.0001 1.0001 0 0 0 10.708984 6.7597656 L 6.8183594 10.646484 A 1.0001 1.0001 0 0 0 6.7070312 11.927734 L 10.164062 16.873047 C 9.583454 17.930271 9.1142098 19.051824 8.765625 20.232422 L 2.8359375 21.21875 A 1.0001 1.0001 0 0 0 2.0019531 22.205078 L 2.0019531 27.705078 A 1.0001 1.0001 0 0 0 2.8261719 28.691406 L 8.7597656 29.742188 C 9.1064607 30.920739 9.5727226 32.043065 10.154297 33.101562 L 6.6542969 37.998047 A 1.0001 1.0001 0 0 0 6.7597656 39.285156 L 10.648438 43.175781 A 1.0001 1.0001 0 0 0 11.927734 43.289062 L 16.882812 39.820312 C 17.936999 40.39548 19.054994 40.857928 20.228516 41.201172 L 21.21875 47.164062 A 1.0001 1.0001 0 0 0 22.205078 48 L 27.705078 48 A 1.0001 1.0001 0 0 0 28.691406 47.173828 L 29.751953 41.1875 C 30.920633 40.838997 32.033372 40.369697 33.082031 39.791016 L 38.070312 43.291016 A 1.0001 1.0001 0 0 0 39.351562 43.179688 L 43.240234 39.287109 A 1.0001 1.0001 0 0 0 43.34375 37.996094 L 39.787109 33.058594 C 40.355783 32.014958 40.813915 30.908875 41.154297 29.748047 L 47.171875 28.693359 A 1.0001 1.0001 0 0 0 47.998047 27.707031 L 47.998047 22.207031 A 1.0001 1.0001 0 0 0 47.160156 21.220703 L 41.152344 20.238281 C 40.80968 19.078827 40.350281 17.974723 39.78125 16.931641 L 43.289062 11.933594 A 1.0001 1.0001 0 0 0 43.177734 10.652344 L 39.287109 6.7636719 A 1.0001 1.0001 0 0 0 37.996094 6.6601562 L 33.072266 10.201172 C 32.023186 9.6248101 30.909713 9.1579916 29.738281 8.8125 L 28.691406 2.828125 A 1.0001 1.0001 0 0 0 27.705078 2 L 22.205078 2 z M 23.056641 4 L 26.865234 4 L 27.861328 9.6855469 A 1.0001 1.0001 0 0 0 28.603516 10.484375 C 30.066026 10.848832 31.439607 11.426549 32.693359 12.185547 A 1.0001 1.0001 0 0 0 33.794922 12.142578 L 38.474609 8.7792969 L 41.167969 11.472656 L 37.835938 16.220703 A 1.0001 1.0001 0 0 0 37.796875 17.310547 C 38.548366 18.561471 39.118333 19.926379 39.482422 21.380859 A 1.0001 1.0001 0 0 0 40.291016 22.125 L 45.998047 23.058594 L 45.998047 26.867188 L 40.279297 27.871094 A 1.0001 1.0001 0 0 0 39.482422 28.617188 C 39.122545 30.069817 38.552234 31.434687 37.800781 32.685547 A 1.0001 1.0001 0 0 0 37.845703 33.785156 L 41.224609 38.474609 L 38.53125 41.169922 L 33.791016 37.84375 A 1.0001 1.0001 0 0 0 32.697266 37.808594 C 31.44975 38.567585 30.074755 39.148028 28.617188 39.517578 A 1.0001 1.0001 0 0 0 27.876953 40.3125 L 26.867188 46 L 23.052734 46 L 22.111328 40.337891 A 1.0001 1.0001 0 0 0 21.365234 39.53125 C 19.90185 39.170557 18.522094 38.59371 17.259766 37.835938 A 1.0001 1.0001 0 0 0 16.171875 37.875 L 11.46875 41.169922 L 8.7734375 38.470703 L 12.097656 33.824219 A 1.0001 1.0001 0 0 0 12.138672 32.724609 C 11.372652 31.458855 10.793319 30.079213 10.427734 28.609375 A 1.0001 1.0001 0 0 0 9.6328125 27.867188 L 4.0019531 26.867188 L 4.0019531 23.052734 L 9.6289062 22.117188 A 1.0001 1.0001 0 0 0 10.435547 21.373047 C 10.804273 19.898143 11.383325 18.518729 12.146484 17.255859 A 1.0001 1.0001 0 0 0 12.111328 16.164062 L 8.8261719 11.46875 L 11.523438 8.7734375 L 16.185547 12.105469 A 1.0001 1.0001 0 0 0 17.28125 12.148438 C 18.536908 11.394293 19.919867 10.822081 21.384766 10.462891 A 1.0001 1.0001 0 0 0 22.132812 9.6523438 L 23.056641 4 z M 25 17 C 20.593567 17 17 20.593567 17 25 C 17 29.406433 20.593567 33 25 33 C 29.406433 33 33 29.406433 33 25 C 33 20.593567 29.406433 17 25 17 z M 25 19 C 28.325553 19 31 21.674447 31 25 C 31 28.325553 28.325553 31 25 31 C 21.674447 31 19 28.325553 19 25 C 19 21.674447 21.674447 19 25 19 z" fill="#000000" stroke="#000000" /></ns0:svg> <ns0:svg xmlns:ns0="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="100px" height="100px" fill="#D1D1D6" stroke="#D1D1D6"><ns0:path d="M 22.205078 2 A 1.0001 1.0001 0 0 0 21.21875 2.8378906 L 20.246094 8.7929688 C 19.076509 9.1331971 17.961243 9.5922728 16.910156 10.164062 L 11.996094 6.6542969 A 1.0001 1.0001 0 0 0 10.708984 6.7597656 L 6.8183594 10.646484 A 1.0001 1.0001 0 0 0 6.7070312 11.927734 L 10.164062 16.873047 C 9.583454 17.930271 9.1142098 19.051824 8.765625 20.232422 L 2.8359375 21.21875 A 1.0001 1.0001 0 0 0 2.0019531 22.205078 L 2.0019531 27.705078 A 1.0001 1.0001 0 0 0 2.8261719 28.691406 L 8.7597656 29.742188 C 9.1064607 30.920739 9.5727226 32.043065 10.154297 33.101562 L 6.6542969 37.998047 A 1.0001 1.0001 0 0 0 6.7597656 39.285156 L 10.648438 43.175781 A 1.0001 1.0001 0 0 0 11.927734 43.289062 L 16.882812 39.820312 C 17.936999 40.39548 19.054994 40.857928 20.228516 41.201172 L 21.21875 47.164062 A 1.0001 1.0001 0 0 0 22.205078 48 L 27.705078 48 A 1.0001 1.0001 0 0 0 28.691406 47.173828 L 29.751953 41.1875 C 30.920633 40.838997 32.033372 40.369697 33.082031 39.791016 L 38.070312 43.291016 A 1.0001 1.0001 0 0 0 39.351562 43.179688 L 43.240234 39.287109 A 1.0001 1.0001 0 0 0 43.34375 37.996094 L 39.787109 33.058594 C 40.355783 32.014958 40.813915 30.908875 41.154297 29.748047 L 47.171875 28.693359 A 1.0001 1.0001 0 0 0 47.998047 27.707031 L 47.998047 22.207031 A 1.0001 1.0001 0 0 0 47.160156 21.220703 L 41.152344 20.238281 C 40.80968 19.078827 40.350281 17.974723 39.78125 16.931641 L 43.289062 11.933594 A 1.0001 1.0001 0 0 0 43.177734 10.652344 L 39.287109 6.7636719 A 1.0001 1.0001 0 0 0 37.996094 6.6601562 L 33.072266 10.201172 C 32.023186 9.6248101 30.909713 9.1579916 29.738281 8.8125 L 28.691406 2.828125 A 1.0001 1.0001 0 0 0 27.705078 2 L 22.205078 2 z M 23.056641 4 L 26.865234 4 L 27.861328 9.6855469 A 1.0001 1.0001 0 0 0 28.603516 10.484375 C 30.066026 10.848832 31.439607 11.426549 32.693359 12.185547 A 1.0001 1.0001 0 0 0 33.794922 12.142578 L 38.474609 8.7792969 L 41.167969 11.472656 L 37.835938 16.220703 A 1.0001 1.0001 0 0 0 37.796875 17.310547 C 38.548366 18.561471 39.118333 19.926379 39.482422 21.380859 A 1.0001 1.0001 0 0 0 40.291016 22.125 L 45.998047 23.058594 L 45.998047 26.867188 L 40.279297 27.871094 A 1.0001 1.0001 0 0 0 39.482422 28.617188 C 39.122545 30.069817 38.552234 31.434687 37.800781 32.685547 A 1.0001 1.0001 0 0 0 37.845703 33.785156 L 41.224609 38.474609 L 38.53125 41.169922 L 33.791016 37.84375 A 1.0001 1.0001 0 0 0 32.697266 37.808594 C 31.44975 38.567585 30.074755 39.148028 28.617188 39.517578 A 1.0001 1.0001 0 0 0 27.876953 40.3125 L 26.867188 46 L 23.052734 46 L 22.111328 40.337891 A 1.0001 1.0001 0 0 0 21.365234 39.53125 C 19.90185 39.170557 18.522094 38.59371 17.259766 37.835938 A 1.0001 1.0001 0 0 0 16.171875 37.875 L 11.46875 41.169922 L 8.7734375 38.470703 L 12.097656 33.824219 A 1.0001 1.0001 0 0 0 12.138672 32.724609 C 11.372652 31.458855 10.793319 30.079213 10.427734 28.609375 A 1.0001 1.0001 0 0 0 9.6328125 27.867188 L 4.0019531 26.867188 L 4.0019531 23.052734 L 9.6289062 22.117188 A 1.0001 1.0001 0 0 0 10.435547 21.373047 C 10.804273 19.898143 11.383325 18.518729 12.146484 17.255859 A 1.0001 1.0001 0 0 0 12.111328 16.164062 L 8.8261719 11.46875 L 11.523438 8.7734375 L 16.185547 12.105469 A 1.0001 1.0001 0 0 0 17.28125 12.148438 C 18.536908 11.394293 19.919867 10.822081 21.384766 10.462891 A 1.0001 1.0001 0 0 0 22.132812 9.6523438 L 23.056641 4 z M 25 17 C 20.593567 17 17 20.593567 17 25 C 17 29.406433 20.593567 33 25 33 C 29.406433 33 33 29.406433 33 25 C 33 20.593567 29.406433 17 25 17 z M 25 19 C 28.325553 19 31 21.674447 31 25 C 31 28.325553 28.325553 31 25 31 C 21.674447 31 19 28.325553 19 25 C 19 21.674447 21.674447 19 25 19 z" fill="#D1D1D6" stroke="#D1D1D6" /></ns0:svg>

View File

@ -0,0 +1,9 @@
<ns0:svg xmlns:ns0="http://www.w3.org/2000/svg" fill="#4A4A4A" width="800px" height="800px" viewBox="0 0 64 64" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;" version="1.1" xml:space="preserve" stroke="#4A4A4A">
<ns0:g id="ICON">
<ns0:path d="M59,43l-54,0l-0,-9c-0,-0.552 -0.448,-1 -1,-1c-0.552,-0 -1,0.448 -1,1c-0,5.651 -0,11.154 -0,14c-0,0.796 0.316,1.559 0.879,2.121c0.562,0.563 1.325,0.879 2.121,0.879l4,0c0.552,0 1,-0.448 1,-1c-0,-0.552 -0.448,-1 -1,-1l-4,0c-0.265,-0 -0.52,-0.105 -0.707,-0.293c-0.188,-0.187 -0.293,-0.442 -0.293,-0.707l-0,-3l54,0l-0,3c0,0.265 -0.105,0.52 -0.293,0.707c-0.187,0.188 -0.442,0.293 -0.707,0.293l-44,0c-0.552,0 -1,0.448 -1,1c0,0.552 0.448,1 1,1l12.606,0c-0.16,2.682 -0.855,6.147 -3.417,8l-1.689,0c-0.552,-0 -1,0.448 -1,1c-0,0.552 0.448,1 1,1l21,0c0.552,-0 1,-0.448 1,-1c-0,-0.552 -0.448,-1 -1,-1l-1.689,0c-2.562,-1.854 -3.257,-5.318 -3.417,-8l20.606,0c0.796,-0 1.559,-0.316 2.121,-0.879c0.563,-0.562 0.879,-1.325 0.879,-2.121c-0,-6.028 -0,-23.972 -0,-30c0,-0.796 -0.316,-1.559 -0.879,-2.121c-0.562,-0.563 -1.325,-0.879 -2.121,-0.879l-11,0c-0.552,0 -1,0.448 -1,1c0,0.552 0.448,1 1,1l11,-0c0.265,0 0.52,0.105 0.707,0.293c0.188,0.187 0.293,0.442 0.293,0.707l-0,25Zm-23.606,8l-6.788,0c-0.155,2.531 -0.785,5.68 -2.585,8l11.958,0c-1.8,-2.32 -2.43,-5.47 -2.585,-8Zm-6.394,-9l6.5,0c0.552,0 1,-0.448 1,-1c0,-0.552 -0.448,-1 -1,-1l-6.5,0c-0.552,0 -1,0.448 -1,1c0,0.552 0.448,1 1,1Zm-22,-4l0,2c0,0.552 0.448,1 1,1c0.552,-0 1,-0.448 1,-1l0,-2c0,-0.552 -0.448,-1 -1,-1c-0.552,-0 -1,0.448 -1,1Zm20.5,1l9.5,0c0.552,-0 1,-0.448 1,-1c-0,-0.552 -0.448,-1 -1,-1l-9.5,0c-0.552,-0 -1,0.448 -1,1c-0,0.552 0.448,1 1,1Zm2.501,-3l-3.406,0c-0.261,0 -0.511,-0.102 -0.698,-0.284c-3.344,-3.257 -6.897,-8.272 -6.897,-14.756c0,-7.152 5.824,-12.96 13,-12.96c7.176,0 13,5.808 13,12.96c-0,6.484 -3.553,11.499 -6.897,14.756c-0.187,0.182 -0.437,0.284 -0.698,0.284l-3.405,0c0,0 -1,-0.003 -1,-1l0,-11l-2,0l0,10.999c0,0.652 -0.447,1.001 -0.999,1.001Zm-21.001,-1l0,-13c0,-0.552 -0.448,-1 -1,-1c-0.552,-0 -1,0.448 -1,1l0,13c0,0.552 0.448,1 1,1c0.552,-0 1,-0.448 1,-1Zm26,-1c0.871,-0 1.995,-0 1.995,-0c2.941,-2.949 6.005,-7.36 6.005,-13.04c0,-6.05 -4.93,-10.96 -11,-10.96c-6.07,0 -11,4.91 -11,10.96c-0,5.68 3.064,10.091 6.005,13.04l1.995,0l0,-10l-2,0c-2.208,0 -4,-1.792 -4,-4c0,-2.208 1.792,-4 4,-4c2.208,0 4,1.792 4,4l0,2l2,0l0,-2c0,-2.208 1.792,-4 4,-4c2.208,0 4,1.792 4,4c0,2.208 -1.792,4 -4,4l-2,0l0,10Zm-18,-19l-11,0c-0.796,0 -1.559,0.316 -2.121,0.879c-0.563,0.562 -0.879,1.325 -0.879,2.121c-0,2.509 -0,7.081 -0,12c-0,0.552 0.448,1 1,1c0.552,0 1,-0.448 1,-1l-0,-12c-0,-0.265 0.105,-0.52 0.293,-0.707c0.187,-0.188 0.442,-0.293 0.707,-0.293c0,0 11,0 11,0c0.552,0 1,-0.448 1,-1c0,-0.552 -0.448,-1 -1,-1Zm18,7l2,0c1.104,0 2,-0.896 2,-2c0,-1.104 -0.896,-2 -2,-2c-1.104,0 -2,0.896 -2,2l0,2Zm-6,0l0,-2c0,-1.104 -0.896,-2 -2,-2c-1.104,0 -2,0.896 -2,2c0,1.104 0.896,2 2,2l2,0Zm-2.509,-14.792l-1,-1.732c-0.276,-0.478 -0.888,-0.642 -1.366,-0.366c-0.478,0.276 -0.642,0.888 -0.366,1.366l1,1.732c0.276,0.478 0.888,0.642 1.366,0.366c0.478,-0.276 0.642,-0.888 0.366,-1.366Zm12.75,1l1,-1.732c0.276,-0.478 0.112,-1.09 -0.366,-1.366c-0.478,-0.276 -1.09,-0.112 -1.366,0.366l-1,1.732c-0.276,0.478 -0.112,1.09 0.366,1.366c0.478,0.276 1.09,0.112 1.366,-0.366Zm-6.241,-2.208l0,-2c0,-0.552 -0.448,-1 -1,-1c-0.552,-0 -1,0.448 -1,1l0,2c0,0.552 0.448,1 1,1c0.552,-0 1,-0.448 1,-1Z" fill="#4A4A4A" stroke="#4A4A4A" />
</ns0:g>
</ns0:svg>

View File

@ -6,5 +6,13 @@
"settings": "Settings", "settings": "Settings",
"theme": "Theme :", "theme": "Theme :",
"dark_theme": "Dark Theme", "dark_theme": "Dark Theme",
"light_theme": "Light Theme" "light_theme": "Light Theme",
"suggestion_text": "Do you have a question or an idea to improve this application? Send me a message!",
"suggestion_placeholder": "Type your message here...",
"send_suggestion": "Send",
"sending": "Sending...",
"success": "Success",
"error": "Error",
"suggestion_sent_success": "Your message has been sent successfully!",
"suggestion_send_error": "Error sending message. Try again later."
} }

View File

@ -6,5 +6,13 @@
"settings": "Paramètres", "settings": "Paramètres",
"theme": "Thème :", "theme": "Thème :",
"dark_theme": "Thème Sombre", "dark_theme": "Thème Sombre",
"light_theme": "Thème Clair" "light_theme": "Thème Clair",
"suggestion_text": "Vous avez une question ou une idée pour améliorer cette application ? Envoyez-moi un message !",
"suggestion_placeholder": "Tapez votre message ici...",
"send_suggestion": "Envoyer",
"sending": "Envoi...",
"success": "Succès",
"error": "Erreur",
"suggestion_sent_success": "Votre message a été envoyé avec succès !",
"suggestion_send_error": "Erreur lors de l'envoi du message. Essayez à nouveau plus tard."
} }

View File

@ -2,6 +2,5 @@
"theme": "dark", "theme": "dark",
"lang": "fr", "lang": "fr",
"window_size": {"width": 1000, "height": 600}, "window_size": {"width": 1000, "height": 600},
"fullscreen": true, "maximize": true
"fullscreen_size": {"width": 1000, "height": 600}
} }