feat: Add branding change prompts and corresponding translations for restart notifications
This commit is contained in:
parent
ca7105a6bc
commit
2ecd299f31
5 changed files with 79 additions and 15 deletions
|
|
@ -58,6 +58,10 @@
|
|||
"dialog.language_changed.msg": "Die Spracheinstellung wurde aktualisiert. Starten Sie jetzt neu, um die ausgew\u00e4hlte Sprache \u00fcberall anzuwenden.",
|
||||
"dialog.language_changed.restart_now": "Jetzt neu starten",
|
||||
"dialog.language_changed.restart_later": "Sp\u00e4ter neu starten",
|
||||
"dialog.branding_changed.title": "Branding ge\u00e4ndert",
|
||||
"dialog.branding_changed.msg": "Das aktive Branding wurde geändert. Starten Sie jetzt neu, damit die aktualisierte visuelle Identität überall angewendet wird.",
|
||||
"dialog.branding_changed.restart_now": "Jetzt neu starten",
|
||||
"dialog.branding_changed.restart_later": "Sp\u00e4ter neu starten",
|
||||
"dialog.restart_failed.title": "Neustart fehlgeschlagen",
|
||||
"dialog.restart_failed.msg": "Die Anwendung konnte nicht automatisch neu gestartet werden:\n\n{error}\n\nBitte starten Sie manuell neu.",
|
||||
"dialog.update_timeout.title": "Zeitüberschreitung bei der Update-Pr\u00fcfung",
|
||||
|
|
|
|||
|
|
@ -58,6 +58,10 @@
|
|||
"dialog.language_changed.msg": "The language setting was updated. Restart now to apply the selected language everywhere.",
|
||||
"dialog.language_changed.restart_now": "Restart Now",
|
||||
"dialog.language_changed.restart_later": "Restart Later",
|
||||
"dialog.branding_changed.title": "Branding Changed",
|
||||
"dialog.branding_changed.msg": "The active branding was changed. Restart now so the updated visual identity is applied everywhere.",
|
||||
"dialog.branding_changed.restart_now": "Restart Now",
|
||||
"dialog.branding_changed.restart_later": "Restart Later",
|
||||
"dialog.restart_failed.title": "Restart Failed",
|
||||
"dialog.restart_failed.msg": "Could not automatically restart the application:\n\n{error}\n\nPlease restart manually.",
|
||||
"dialog.update_timeout.title": "Update Check Timeout",
|
||||
|
|
|
|||
|
|
@ -1958,6 +1958,7 @@ class MainWindow(QMainWindow):
|
|||
# Store current URL before opening dialog
|
||||
old_webapp_url = self.config.webapp_url
|
||||
old_language = self.config.language
|
||||
old_branding_id = self.config.active_branding_id
|
||||
|
||||
# Show dialog
|
||||
dialog = SettingsDialog(self.config, self)
|
||||
|
|
@ -1966,6 +1967,9 @@ class MainWindow(QMainWindow):
|
|||
# Check if webapp URL changed
|
||||
new_webapp_url = self.config.webapp_url
|
||||
language_changed = old_language != self.config.language
|
||||
branding_changed = old_branding_id != self.config.active_branding_id
|
||||
restart_prompt_shown = False
|
||||
|
||||
if old_webapp_url != new_webapp_url:
|
||||
logger.info(f"Web application URL changed: {old_webapp_url} → {new_webapp_url}")
|
||||
|
||||
|
|
@ -1975,6 +1979,7 @@ class MainWindow(QMainWindow):
|
|||
if domain_changed:
|
||||
logger.warning("Domain has changed - recommending restart")
|
||||
self._handle_domain_change_restart()
|
||||
restart_prompt_shown = True
|
||||
else:
|
||||
logger.info("Path changed but domain is same - reloading...")
|
||||
# Clear cache and navigate to home asynchronously
|
||||
|
|
@ -1982,7 +1987,16 @@ class MainWindow(QMainWindow):
|
|||
self.web_view.clear_cache_and_cookies()
|
||||
QTimer.singleShot(100, self._navigate_home)
|
||||
|
||||
if language_changed:
|
||||
if not restart_prompt_shown and branding_changed:
|
||||
logger.info(
|
||||
"Branding changed: %s → %s",
|
||||
old_branding_id,
|
||||
self.config.active_branding_id,
|
||||
)
|
||||
self._handle_branding_change_restart()
|
||||
restart_prompt_shown = True
|
||||
|
||||
if not restart_prompt_shown and language_changed:
|
||||
logger.info(f"Language changed: {old_language} → {self.config.language}")
|
||||
self._handle_language_change_restart()
|
||||
|
||||
|
|
@ -2046,21 +2060,42 @@ class MainWindow(QMainWindow):
|
|||
self.web_view.clear_cache_and_cookies()
|
||||
self._navigate_home()
|
||||
|
||||
def _handle_branding_change_restart(self) -> None:
|
||||
"""Handle branding change by prompting for an optional restart."""
|
||||
self._show_restart_prompt(
|
||||
title_key="dialog.branding_changed.title",
|
||||
message_key="dialog.branding_changed.msg",
|
||||
restart_now_key="dialog.branding_changed.restart_now",
|
||||
restart_later_key="dialog.branding_changed.restart_later",
|
||||
)
|
||||
|
||||
def _handle_language_change_restart(self) -> None:
|
||||
"""Handle language change by prompting for an optional restart."""
|
||||
self._show_restart_prompt(
|
||||
title_key="dialog.language_changed.title",
|
||||
message_key="dialog.language_changed.msg",
|
||||
restart_now_key="dialog.language_changed.restart_now",
|
||||
restart_later_key="dialog.language_changed.restart_later",
|
||||
)
|
||||
|
||||
def _show_restart_prompt(
|
||||
self,
|
||||
*,
|
||||
title_key: str,
|
||||
message_key: str,
|
||||
restart_now_key: str,
|
||||
restart_later_key: str,
|
||||
) -> None:
|
||||
"""Show a restart prompt for settings that require a full restart."""
|
||||
from PySide6.QtWidgets import QMessageBox
|
||||
|
||||
msg = QMessageBox(self)
|
||||
msg.setWindowTitle(tr("dialog.language_changed.title"))
|
||||
msg.setWindowTitle(tr(title_key))
|
||||
msg.setIcon(QMessageBox.Icon.Information)
|
||||
msg.setText(tr("dialog.language_changed.msg"))
|
||||
msg.setText(tr(message_key))
|
||||
|
||||
restart_now_btn = msg.addButton(
|
||||
tr("dialog.language_changed.restart_now"), QMessageBox.ButtonRole.AcceptRole
|
||||
)
|
||||
msg.addButton(
|
||||
tr("dialog.language_changed.restart_later"), QMessageBox.ButtonRole.RejectRole
|
||||
)
|
||||
restart_now_btn = msg.addButton(tr(restart_now_key), QMessageBox.ButtonRole.AcceptRole)
|
||||
msg.addButton(tr(restart_later_key), QMessageBox.ButtonRole.RejectRole)
|
||||
|
||||
msg.exec()
|
||||
|
||||
|
|
|
|||
|
|
@ -9,11 +9,14 @@ from webdrop_bridge.config import Config, ConfigurationError
|
|||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def clear_env():
|
||||
def clear_env(tmp_path):
|
||||
"""Clear environment variables before each test to avoid persistence."""
|
||||
# Save current env
|
||||
saved_env = os.environ.copy()
|
||||
|
||||
# Isolate runtime branding state from the developer machine
|
||||
os.environ["WEBDROP_BRANDING_DIR"] = str(tmp_path / "branding")
|
||||
|
||||
# Clear relevant variables
|
||||
for key in list(os.environ.keys()):
|
||||
if key.startswith(
|
||||
|
|
|
|||
|
|
@ -82,6 +82,25 @@ class TestMainWindowInitialization:
|
|||
assert window.drag_interceptor is not None
|
||||
|
||||
|
||||
class TestSettingsRestartBehavior:
|
||||
"""Test restart prompts for settings changes that require a restart."""
|
||||
|
||||
def test_branding_change_prompts_restart(self, qtbot, sample_config):
|
||||
"""Changing the active branding should trigger the restart flow."""
|
||||
window = MainWindow(sample_config)
|
||||
qtbot.addWidget(window)
|
||||
|
||||
with patch.object(window, "_handle_branding_change_restart") as mock_restart:
|
||||
with patch("webdrop_bridge.ui.settings_dialog.SettingsDialog") as mock_dialog_cls:
|
||||
mock_dialog = mock_dialog_cls.return_value
|
||||
mock_dialog.exec.side_effect = lambda: setattr(
|
||||
window.config, "active_branding_id", "agravity"
|
||||
)
|
||||
window._show_settings_dialog()
|
||||
|
||||
mock_restart.assert_called_once()
|
||||
|
||||
|
||||
class TestMainWindowDragIntegration:
|
||||
"""Test drag-and-drop integration."""
|
||||
|
||||
|
|
@ -228,7 +247,6 @@ class TestMainWindowOpenWith:
|
|||
else:
|
||||
raise AssertionError(f"Unexpected call #{call_count[0]} to subprocess.run")
|
||||
|
||||
|
||||
with patch("webdrop_bridge.ui.main_window.sys.platform", "darwin"):
|
||||
with patch("webdrop_bridge.ui.main_window.subprocess.run", side_effect=mock_run):
|
||||
assert window._open_with_app_chooser(str(test_file)) is True
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue