refactor: Moved bridge event handling to use typed DTOs

- Introduce event type and action fields in `BaseEvent`
- Register common events in the event factory
- Default event creation to the generic event type
- Improve WebKit bridge logging and update example messages
This commit is contained in:
2026-10-13 18:29:32 -05:00
parent 0559b69e7e
commit 15e124edee
10 changed files with 78 additions and 30 deletions
+30 -18
View File
@@ -1,9 +1,11 @@
# Python imports # Python imports
import base64 import base64
import json
# Lib imports # Lib imports
# Application imports # Application imports
from libs.event_factory import Event_Factory, App_Event_Types
@@ -21,21 +23,31 @@ class BridgeController:
event_system.subscribe("handle-bridge-event", self.handle_bridge_event) event_system.subscribe("handle-bridge-event", self.handle_bridge_event)
def handle_bridge_event(self, event): def handle_bridge_event(self, event_str: str):
match event.topic: event = Event_Factory.create_event( **json.loads(event_str) )
case "save":
event_system.emit(f"handle-file-event-{event.originator}", (event,)) if isinstance(event, App_Event_Types.DisplayMessageEvent):
case "close": match event.topic:
event_system.emit(f"handle-file-event-{event.originator}", (event,)) case "alert":
case "load_buffer": message = base64.b64decode( event.message.encode() ).decode("utf-8")
event_system.emit(f"handle-file-event-{event.originator}", (event,)) logger.info(f"\nMessage Topic: {event.topic}\nMessage Content: {message}")
case "load_file": case "error":
event_system.emit(f"handle-file-event-{event.originator}", (event,)) message = base64.b64decode( event.message.encode() ).decode("utf-8")
case "alert": logger.info(message)
content = base64.b64decode( event.content.encode() ).decode("utf-8") case _:
logger.info(f"\nMessage Topic: {event.topic}\nMessage Content: {content}") ...
case "error": elif isinstance(event, App_Event_Types.GenericEvent):
content = base64.b64decode( event.content.encode() ).decode("utf-8") match event.action:
logger.info(content) case "save":
case _: event_system.emit(f"handle-file-event-{event.originator}", (event,))
... case "close":
event_system.emit(f"handle-file-event-{event.originator}", (event,))
case "load_buffer":
event_system.emit(f"handle-file-event-{event.originator}", (event,))
case "load_file":
event_system.emit(f"handle-file-event-{event.originator}", (event,))
case "alert":
content = base64.b64decode( event.content.encode() ).decode("utf-8")
logger.info(f"\nEvent Action: {event.action}\nEvent Content: {content}")
case _:
...
+5 -2
View File
@@ -28,8 +28,11 @@
window.addEventListener("load", () => { window.addEventListener("load", () => {
window.webkit.messageHandlers.logger.postMessage("Hello, World!"); window.webkit.messageHandlers.logger.postMessage("Hello, World!");
// const message = '{"topic": "alert", "content": "' + btoa("Hello, World!") + '"}'; // Note: Events can be generic which means that without 'event_type'
// window.webkit.messageHandlers.backend.postMessage(message); // it's mapped to GenericEvent which is just BaseEvent under the hood.
// const message = '{"action": "alert", "content": "' + btoa("Hello, World!") + '"}';
const message = '{"event_type": "display_message", "topic": "alert", "message": "' + btoa("Hello, World!") + '"}';
window.webkit.messageHandlers.backend.postMessage(message);
}); });
</script> </script>
</body> </body>
+4 -6
View File
@@ -1,6 +1,5 @@
# Python imports # Python imports
from pathlib import Path from pathlib import Path
import json
# Lib imports # Lib imports
import gi import gi
@@ -13,7 +12,7 @@ from gi.repository import WebKit2
# Application imports # Application imports
from libs.settings.webkit.webkit_ui_settings import WebkitUISettings from libs.settings.webkit.webkit_ui_settings import WebkitUISettings
from libs.dto.base_event import BaseEvent
class WebkitUI(WebKit2.WebView): class WebkitUI(WebKit2.WebView):
@@ -54,8 +53,8 @@ class WebkitUI(WebKit2.WebView):
content_manager.register_script_message_handler("backend") content_manager.register_script_message_handler("backend")
def _on_tls_errors(self, webview, uri, certificate, errors): def _on_tls_errors(self, webview, uri, certificate, errors):
print("TLS error:", uri) logger.info("TLS error:", uri)
print("Errors:", errors) logger.info("Errors:", errors)
webview.get_website_data_manager().get_tls_errors_policy() webview.get_website_data_manager().get_tls_errors_policy()
webview.get_context().allow_tls_certificate_for_host( webview.get_context().allow_tls_certificate_for_host(
@@ -76,8 +75,7 @@ class WebkitUI(WebKit2.WebView):
message = js_value.to_string() message = js_value.to_string()
try: try:
event = BaseEvent( **json.loads(message) ) event_system.emit("handle-bridge-event", (message,))
event_system.emit("handle-bridge-event", (event,))
except Exception as e: except Exception as e:
logger.info(e) logger.info(e)
+1 -1
View File
@@ -2,4 +2,4 @@
Libs DTO(s) Package Libs DTO(s) Package
""" """
from .base_event import BaseEvent from .base_event import BaseEvent
+2 -1
View File
@@ -9,7 +9,8 @@ from dataclasses import dataclass, field
@dataclass(slots = True) @dataclass(slots = True)
class BaseEvent: class BaseEvent:
topic: str = None event_type: str = "base"
action: str = ""
content: any = None content: any = None
raw_content: any = None raw_content: any = None
success: callable = None success: callable = None
+7
View File
@@ -0,0 +1,7 @@
"""
Libs Common DTO(s) Package
"""
from .generic_event import GenericEvent
from .display_message_event import DisplayMessageEvent
@@ -0,0 +1,13 @@
# Python imports
from dataclasses import dataclass, field
# Lib imports
# Application imports
from ...base_event import BaseEvent
class DisplayMessageEvent(BaseEvent):
topic: str = None
message: str = None
@@ -0,0 +1,12 @@
# Python imports
from dataclasses import dataclass, field
# Lib imports
# Application imports
from ...base_event import BaseEvent
class GenericEvent(BaseEvent):
event_type: str = "generic"
+1 -1
View File
@@ -1,5 +1,5 @@
""" """
Libs Code DTO(s) Events Package Libs Files DTO(s) Events Package
""" """
+3 -1
View File
@@ -9,6 +9,7 @@ import re
from .singleton import Singleton from .singleton import Singleton
from .dto.base_event import BaseEvent from .dto.base_event import BaseEvent
from .dto.common import events as common
from .dto.code import events as code from .dto.code import events as code
from .dto.files import events as files from .dto.files import events as files
@@ -19,6 +20,7 @@ class EventFactory(Singleton):
self._event_classes: Dict[str, Type[BaseEvent]] = {} self._event_classes: Dict[str, Type[BaseEvent]] = {}
self._auto_register_events( common.__dict__.items() )
self._auto_register_events( files.__dict__.items() ) self._auto_register_events( files.__dict__.items() )
self._auto_register_events( code.__dict__.items() ) self._auto_register_events( code.__dict__.items() )
@@ -51,7 +53,7 @@ class EventFactory(Singleton):
logger.debug(f"Unregistered {i} event types:") logger.debug(f"Unregistered {i} event types:")
def create_event(self, event_type: str, **kwargs) -> BaseEvent: def create_event(self, event_type: str = "generic", **kwargs) -> BaseEvent:
if event_type not in self._event_classes: if event_type not in self._event_classes:
raise ValueError(f"Unknown event type: {event_type}") raise ValueError(f"Unknown event type: {event_type}")