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
import base64
import json
# Lib 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)
def handle_bridge_event(self, event):
match event.topic:
case "save":
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"\nMessage Topic: {event.topic}\nMessage Content: {content}")
case "error":
content = base64.b64decode( event.content.encode() ).decode("utf-8")
logger.info(content)
case _:
...
def handle_bridge_event(self, event_str: str):
event = Event_Factory.create_event( **json.loads(event_str) )
if isinstance(event, App_Event_Types.DisplayMessageEvent):
match event.topic:
case "alert":
message = base64.b64decode( event.message.encode() ).decode("utf-8")
logger.info(f"\nMessage Topic: {event.topic}\nMessage Content: {message}")
case "error":
message = base64.b64decode( event.message.encode() ).decode("utf-8")
logger.info(message)
case _:
...
elif isinstance(event, App_Event_Types.GenericEvent):
match event.action:
case "save":
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.webkit.messageHandlers.logger.postMessage("Hello, World!");
// const message = '{"topic": "alert", "content": "' + btoa("Hello, World!") + '"}';
// window.webkit.messageHandlers.backend.postMessage(message);
// Note: Events can be generic which means that without 'event_type'
// 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>
</body>
+4 -6
View File
@@ -1,6 +1,5 @@
# Python imports
from pathlib import Path
import json
# Lib imports
import gi
@@ -13,7 +12,7 @@ from gi.repository import WebKit2
# Application imports
from libs.settings.webkit.webkit_ui_settings import WebkitUISettings
from libs.dto.base_event import BaseEvent
class WebkitUI(WebKit2.WebView):
@@ -54,8 +53,8 @@ class WebkitUI(WebKit2.WebView):
content_manager.register_script_message_handler("backend")
def _on_tls_errors(self, webview, uri, certificate, errors):
print("TLS error:", uri)
print("Errors:", errors)
logger.info("TLS error:", uri)
logger.info("Errors:", errors)
webview.get_website_data_manager().get_tls_errors_policy()
webview.get_context().allow_tls_certificate_for_host(
@@ -76,8 +75,7 @@ class WebkitUI(WebKit2.WebView):
message = js_value.to_string()
try:
event = BaseEvent( **json.loads(message) )
event_system.emit("handle-bridge-event", (event,))
event_system.emit("handle-bridge-event", (message,))
except Exception as e:
logger.info(e)
+2 -1
View File
@@ -9,7 +9,8 @@ from dataclasses import dataclass, field
@dataclass(slots = True)
class BaseEvent:
topic: str = None
event_type: str = "base"
action: str = ""
content: any = None
raw_content: any = 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 .dto.base_event import BaseEvent
from .dto.common import events as common
from .dto.code import events as code
from .dto.files import events as files
@@ -19,6 +20,7 @@ class EventFactory(Singleton):
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( code.__dict__.items() )
@@ -51,7 +53,7 @@ class EventFactory(Singleton):
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:
raise ValueError(f"Unknown event type: {event_type}")