22from gi .repository import GdkPixbuf , GLib , Gtk
33from loguru import logger
44from widgets .rounded_image import CustomImage
5-
65from fabric .notifications .service import (
76 Notification ,
87 NotificationAction ,
1615from fabric .widgets .label import Label
1716from fabric .widgets .scrolledwindow import ScrolledWindow
1817import modules .icons as icons
18+ from datetime import datetime , timedelta # <-- Importamos para manejar fechas
1919
2020class ActionButton (Button ):
2121 def __init__ (self , action : NotificationAction , index : int , total : int , notification_box ):
@@ -128,11 +128,10 @@ def create_content(self, notification):
128128 Box (
129129 name = "notification-summary-box" ,
130130 orientation = "h" ,
131- # spacing=4,
132131 children = [
133132 Label (
134133 name = "notification-summary" ,
135- markup = notification .summary . replace ( " \n " , " " ) ,
134+ markup = notification .summary ,
136135 h_align = "start" ,
137136 ellipsization = "end" ,
138137 ),
@@ -145,7 +144,7 @@ def create_content(self, notification):
145144 ],
146145 ),
147146 Label (
148- markup = notification .body . replace ( " \n " , " " ) ,
147+ markup = notification .body ,
149148 h_align = "start" ,
150149 ellipsization = "end" ,
151150 ) if notification .body else Box (),
@@ -234,6 +233,7 @@ def unhover_button(self, button):
234233 if self ._container :
235234 self ._container .resume_all_timeouts ()
236235
236+
237237# This is a ScrolledWindow that contains a Box with notifications added to it when they timeout from the NotificationContainer
238238class NotificationHistory (ScrolledWindow ):
239239 def __init__ (self , ** kwargs ):
@@ -271,8 +271,10 @@ def add_notification(self, notification_box):
271271 oldest_notification = self .notifications_list .get_children ()[0 ]
272272 self .notifications_list .remove (oldest_notification )
273273
274- # Crear un método de destrucción personalizado
274+ # Modificar el método de destrucción para remover el timer del timestamp
275275 def on_container_destroy (container ):
276+ if hasattr (container , "_timestamp_timer_id" ) and container ._timestamp_timer_id :
277+ GLib .source_remove (container ._timestamp_timer_id )
276278 container .destroy ()
277279 # Actualizar separadores después de la destrucción
278280 GLib .idle_add (self .update_separators )
@@ -285,15 +287,34 @@ def on_container_destroy(container):
285287 h_expand = True ,
286288 )
287289
288- # Crear el hist_box sin los botones
289- hist_box = Box (
290- name = "notification-box-hist" ,
291- orientation = "v" ,
292- h_align = "fill" ,
293- h_expand = True ,
294- )
295-
296- # Creamos el contenido principal
290+ # Guardamos el momento de llegada de la notificación
291+ container .arrival_time = datetime .now ()
292+
293+ # Función para calcular el texto del label según el tiempo transcurrido
294+ def compute_time_label (arrival_time ):
295+ now = datetime .now ()
296+ if arrival_time .date () != now .date ():
297+ if arrival_time .date () == (now - timedelta (days = 1 )).date ():
298+ return " | Yesterday " + arrival_time .strftime ("%H:%M" )
299+ else :
300+ return arrival_time .strftime ("| %d/%m/%Y %H:%M" )
301+
302+ # Para el mismo día, aplicamos las reglas de tiempo transcurrido.
303+ delta = now - arrival_time
304+ seconds = delta .total_seconds ()
305+ if seconds < 60 :
306+ return " | Now"
307+ elif seconds < 3600 :
308+ minutes = int (seconds // 60 )
309+ return f" | { minutes } min" if minutes == 1 else f" | { minutes } mins"
310+ else :
311+ return arrival_time .strftime (" | %H:%M" )
312+
313+
314+ # Creamos el label de timestamp usando la hora de llegada
315+ time_label = Label (name = "notification-timestamp" , markup = compute_time_label (container .arrival_time ))
316+
317+ # Creamos el contenido principal, insertando el label de timestamp en la sección de texto
297318 content_box = Box (
298319 name = "notification-content" ,
299320 spacing = 8 ,
@@ -313,14 +334,15 @@ def on_container_destroy(container):
313334 name = "notification-text" ,
314335 orientation = "v" ,
315336 v_align = "center" ,
337+ h_expand = True ,
316338 children = [
317339 Box (
318340 name = "notification-summary-box" ,
319341 orientation = "h" ,
320342 children = [
321343 Label (
322344 name = "notification-summary" ,
323- markup = notification_box .notification .summary . replace ( " \n " , " " ) ,
345+ markup = notification_box .notification .summary ,
324346 h_align = "start" ,
325347 ellipsization = "end" ,
326348 ),
@@ -330,17 +352,17 @@ def on_container_destroy(container):
330352 h_align = "start" ,
331353 ellipsization = "end" ,
332354 ),
355+ time_label ,
333356 ],
334357 ),
335358 Label (
336359 name = "notification-body" ,
337- markup = notification_box .notification .body . replace ( " \n " , " " ) ,
360+ markup = notification_box .notification .body ,
338361 h_align = "start" ,
339362 ellipsization = "end" ,
340363 ) if notification_box .notification .body else Box (),
341364 ],
342365 ),
343- Box (h_expand = True ),
344366 Box (
345367 orientation = "v" ,
346368 children = [
@@ -355,11 +377,24 @@ def on_container_destroy(container):
355377 ],
356378 )
357379
380+ # Programamos la actualización asíncrona del label cada 10 segundos
381+ def update_timestamp ():
382+ time_label .set_markup (compute_time_label (container .arrival_time ))
383+ return True # seguir llamando
384+
385+ container ._timestamp_timer_id = GLib .timeout_add_seconds (10 , update_timestamp )
386+
358387 # Agregamos el contenido principal al hist_box
388+ hist_box = Box (
389+ name = "notification-box-hist" ,
390+ orientation = "v" ,
391+ h_align = "fill" ,
392+ h_expand = True ,
393+ )
359394 hist_box .add (content_box )
360395
361396 # Modificar el botón de cerrar para que use nuestro método personalizado
362- content_box .get_children ()[3 ].get_children ()[0 ].connect ( # Box con botón de cerrar
397+ content_box .get_children ()[2 ].get_children ()[0 ].connect (
363398 "clicked" ,
364399 lambda * _ : on_container_destroy (container )
365400 )
0 commit comments