From 3e4a1d7118d9fae7250ea129b598390388e4fc32 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Wed, 21 May 2025 18:25:03 +0200 Subject: [PATCH] use toast messages --- .../tools/launcher/models/actions.py | 12 ++- client/ayon_core/tools/launcher/ui/window.py | 94 ++++++++++++------- 2 files changed, 69 insertions(+), 37 deletions(-) diff --git a/client/ayon_core/tools/launcher/models/actions.py b/client/ayon_core/tools/launcher/models/actions.py index ad1ea3835f..25335a7ecf 100644 --- a/client/ayon_core/tools/launcher/models/actions.py +++ b/client/ayon_core/tools/launcher/models/actions.py @@ -1,5 +1,6 @@ import os import copy +import uuid from dataclasses import dataclass, asdict from urllib.parse import urlencode, urlparse from typing import Any, Optional @@ -244,6 +245,7 @@ class ActionsModel: error_message = None action_label = identifier action_items = self._get_action_items(project_name) + trigger_id = uuid.uuid4().hex try: action = self._actions[identifier] action_item = action_items[identifier] @@ -251,6 +253,7 @@ class ActionsModel: self._controller.emit_event( "action.trigger.started", { + "trigger_id": trigger_id, "identifier": identifier, "full_label": action_label, } @@ -265,6 +268,7 @@ class ActionsModel: self._controller.emit_event( "action.trigger.finished", { + "trigger_id": trigger_id, "identifier": identifier, "failed": failed, "error_message": error_message, @@ -307,10 +311,13 @@ class ActionsModel: if form_data is not None: context["formData"] = form_data + trigger_id = uuid.uuid4().hex + failed = False try: self._controller.emit_event( "webaction.trigger.started", { + "trigger_id": trigger_id, "identifier": identifier, "full_label": action_label, } @@ -329,6 +336,7 @@ class ActionsModel: handle_response = self._handle_webaction_response(response.data) except Exception: + failed = True self.log.warning("Action trigger failed.", exc_info=True) handle_response = WebactionResponse( "unknown", @@ -338,8 +346,10 @@ class ActionsModel: data = handle_response.to_data() data.update({ + "trigger_failed": failed, + "trigger_id": trigger_id, "identifier": identifier, - "action_label": action_label, + "full_label": action_label, "project_name": project_name, "folder_id": folder_id, "task_id": task_id, diff --git a/client/ayon_core/tools/launcher/ui/window.py b/client/ayon_core/tools/launcher/ui/window.py index 3f3e4bb1de..7236e3dbf4 100644 --- a/client/ayon_core/tools/launcher/ui/window.py +++ b/client/ayon_core/tools/launcher/ui/window.py @@ -1,9 +1,9 @@ from qtpy import QtWidgets, QtCore, QtGui -from ayon_core import style -from ayon_core import resources +from ayon_core import style, resources from ayon_core.tools.launcher.control import BaseLauncherController +from ayon_core.tools.utils import MessageOverlayObject from .projects_widget import ProjectsWidget from .hierarchy_page import HierarchyPage @@ -41,6 +41,8 @@ class LauncherWindow(QtWidgets.QWidget): self._controller = controller + overlay_object = MessageOverlayObject(self) + # Main content - Pages & Actions content_body = QtWidgets.QSplitter(self) @@ -78,26 +80,18 @@ class LauncherWindow(QtWidgets.QWidget): content_body.setSizes([580, 160]) # Footer - footer_widget = QtWidgets.QWidget(self) - - # - Message label - message_label = QtWidgets.QLabel(footer_widget) - + # footer_widget = QtWidgets.QWidget(self) + # # action_history = ActionHistory(footer_widget) # action_history.setStatusTip("Show Action History") - - footer_layout = QtWidgets.QHBoxLayout(footer_widget) - footer_layout.setContentsMargins(0, 0, 0, 0) - footer_layout.addWidget(message_label, 1) + # + # footer_layout = QtWidgets.QHBoxLayout(footer_widget) + # footer_layout.setContentsMargins(0, 0, 0, 0) # footer_layout.addWidget(action_history, 0) layout = QtWidgets.QVBoxLayout(self) layout.addWidget(content_body, 1) - layout.addWidget(footer_widget, 0) - - message_timer = QtCore.QTimer() - message_timer.setInterval(self.message_interval) - message_timer.setSingleShot(True) + # layout.addWidget(footer_widget, 0) actions_refresh_timer = QtCore.QTimer() actions_refresh_timer.setInterval(self.refresh_interval) @@ -109,7 +103,6 @@ class LauncherWindow(QtWidgets.QWidget): page_slide_anim.setEasingCurve(QtCore.QEasingCurve.OutQuad) projects_page.refreshed.connect(self._on_projects_refresh) - message_timer.timeout.connect(self._on_message_timeout) actions_refresh_timer.timeout.connect( self._on_actions_refresh_timeout) page_slide_anim.valueChanged.connect( @@ -137,6 +130,8 @@ class LauncherWindow(QtWidgets.QWidget): self._on_webaction_trigger_finished, ) + self._overlay_object = overlay_object + self._controller = controller self._is_on_projects_page = True @@ -149,11 +144,8 @@ class LauncherWindow(QtWidgets.QWidget): self._projects_page = projects_page self._hierarchy_page = hierarchy_page self._actions_widget = actions_widget - - self._message_label = message_label # self._action_history = action_history - self._message_timer = message_timer self._actions_refresh_timer = actions_refresh_timer self._page_slide_anim = page_slide_anim @@ -193,13 +185,6 @@ class LauncherWindow(QtWidgets.QWidget): else: self._refresh_on_activate = True - def _echo(self, message): - self._message_label.setText(str(message)) - self._message_timer.start() - - def _on_message_timeout(self): - self._message_label.setText("") - def _on_project_selection_change(self, event): project_name = event["project_name"] self._selected_project_name = project_name @@ -223,16 +208,38 @@ class LauncherWindow(QtWidgets.QWidget): self._hierarchy_page.refresh() self._actions_widget.refresh() + def _show_toast_message(self, message, success=True, message_id=None): + message_type = None + if not success: + message_type = "error" + + self._overlay_object.add_message( + message, message_type, message_id=message_id + ) + def _on_action_trigger_started(self, event): - self._echo("Running action: {}".format(event["full_label"])) + self._show_toast_message( + "Running action: {}".format(event["full_label"]), + message_id=event["trigger_id"], + ) def _on_action_trigger_finished(self, event): - if not event["failed"]: - return - self._echo("Failed: {}".format(event["error_message"])) + action_label = event["full_label"] + if event["failed"]: + message = f"Failed to run action: {action_label}" + else: + message = f"Action finished: {action_label}" + self._show_toast_message( + message, + not event["failed"], + message_id=event["trigger_id"], + ) def _on_webaction_trigger_started(self, event): - self._echo("Running webaction: {}".format(event["full_label"])) + self._show_toast_message( + "Running webaction: {}".format(event["full_label"]), + message_id=event["trigger_id"], + ) def _on_webaction_trigger_finished(self, event): clipboard_text = event["clipboard_text"] @@ -240,12 +247,27 @@ class LauncherWindow(QtWidgets.QWidget): clipboard = QtWidgets.QApplication.clipboard() clipboard.setText(clipboard_text) - # TODO use toast messages - if event["message"]: - self._echo(event["message"]) + action_label = event["full_label"] + # Avoid to show exception message + if event["trigger_failed"]: + self._show_toast_message( + f"Failed to run action: {action_label}", + message_id=event["trigger_id"] + ) + return + # Failed to run webaction, e.g. because of missing webaction handling + # - not reported by server if event["error_message"]: - self._echo(event["message"]) + self._show_toast_message( + event["error_message"], + success=False, + message_id=event["trigger_id"] + ) + return + + if event["message"]: + self._show_toast_message(event["message"]) if event["form"]: self._actions_widget.handle_webaction_form_event(event)