feat: notification markup support
This commit is contained in:
28
sims/utils/markup.py
Normal file
28
sims/utils/markup.py
Normal file
@@ -0,0 +1,28 @@
|
||||
import re
|
||||
from html import escape as html_escape
|
||||
|
||||
import gi
|
||||
|
||||
gi.require_version("Pango", "1.0")
|
||||
from gi.repository import GLib, Pango
|
||||
|
||||
# Pango cannot render <img ...> from the freedesktop notification spec; strip it.
|
||||
_IMG_RE = re.compile(r"<img\b[^>]*/?>", re.IGNORECASE)
|
||||
|
||||
|
||||
def render_body_markup(body: str) -> tuple[str, bool]:
|
||||
"""Return ``(text, is_markup)`` for a notification body.
|
||||
|
||||
If the body parses as Pango markup, ``text`` is the cleaned-up markup
|
||||
string and ``is_markup`` is True. Otherwise ``text`` is the XML-escaped
|
||||
plain text and ``is_markup`` is False.
|
||||
"""
|
||||
if not body:
|
||||
return "", False
|
||||
|
||||
candidate = _IMG_RE.sub("", body)
|
||||
try:
|
||||
Pango.parse_markup(candidate, -1, "\0")
|
||||
except GLib.Error:
|
||||
return html_escape(body, quote=False), False
|
||||
return candidate, True
|
||||
@@ -6,6 +6,8 @@ from fabric.widgets.image import Image
|
||||
from fabric.widgets.label import Label
|
||||
from gi.repository import GdkPixbuf
|
||||
|
||||
from sims.utils.markup import render_body_markup
|
||||
|
||||
NOTIFICATION_IMAGE_SIZE = 64
|
||||
|
||||
|
||||
@@ -76,9 +78,11 @@ class NotificationWidget(Box):
|
||||
)
|
||||
|
||||
if body:
|
||||
body_text, body_is_markup = render_body_markup(body)
|
||||
body_kwargs = {"markup": body_text} if body_is_markup else {"label": body_text}
|
||||
text_children.append(
|
||||
Label(
|
||||
label=body,
|
||||
**body_kwargs,
|
||||
line_wrap="word-char",
|
||||
v_align="start",
|
||||
h_align="start",
|
||||
|
||||
@@ -7,6 +7,7 @@ from fabric.widgets.image import Image
|
||||
from fabric.widgets.label import Label
|
||||
|
||||
from sims.services.notification_history import HistoryEntry
|
||||
from sims.utils.markup import render_body_markup
|
||||
|
||||
|
||||
def _time_ago(ts: float, now: float | None = None) -> str:
|
||||
@@ -71,9 +72,11 @@ class NotificationHistoryEntryWidget(Box):
|
||||
text_children.append(header)
|
||||
|
||||
if entry.body:
|
||||
body_text, body_is_markup = render_body_markup(entry.body)
|
||||
body_kwargs = {"markup": body_text} if body_is_markup else {"label": body_text}
|
||||
text_children.append(
|
||||
Label(
|
||||
label=entry.body,
|
||||
**body_kwargs,
|
||||
line_wrap="word-char",
|
||||
h_align="start",
|
||||
v_align="start",
|
||||
|
||||
Reference in New Issue
Block a user