import time from typing import Callable from fabric.widgets.box import Box from fabric.widgets.button import Button 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: delta = int((now if now is not None else time.time()) - ts) if delta < 60: return "just now" if delta < 3600: return f"{delta // 60}m ago" if delta < 86400: return f"{delta // 3600}h ago" return f"{delta // 86400}d ago" class NotificationHistoryEntryWidget(Box): THUMB_SIZE = 40 def __init__( self, entry: HistoryEntry, on_dismiss: Callable[[int], None], **kwargs, ): super().__init__( name="notification-history-entry", spacing=8, orientation="h", **kwargs, ) urgency_class = {0: "urgency-low", 1: "urgency-normal", 2: "urgency-critical"}.get( entry.urgency, "urgency-normal" ) self.get_style_context().add_class(urgency_class) if entry.pixbuf is not None: self.add(Image(pixbuf=entry.pixbuf, h_align="start", v_align="start")) text_children: list = [] header = Box(orientation="h", h_expand=True) header.pack_start( Label( label=entry.summary, ellipsization="end", h_align="start", ) .build() .add_style_class("summary") .unwrap(), True, True, 0, ) header.pack_end( Label(label=_time_ago(entry.timestamp), h_align="end") .build() .add_style_class("timestamp") .unwrap(), False, False, 0, ) 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( **body_kwargs, line_wrap="word-char", h_align="start", v_align="start", ) .build() .add_style_class("body") .unwrap() ) text_box = Box(orientation="v", spacing=2, children=text_children, h_expand=True) self.add(text_box) self.pack_end( Button( name="notification-history-dismiss", image=Image(icon_name="window-close-symbolic", icon_size=14), v_align="start", h_align="end", on_clicked=lambda *_: on_dismiss(entry.id), ), False, False, 0, )