M src/pages.py => src/pages.py +37 -15
@@ 16,6 16,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import datetime
import html
+from dataclasses import dataclass
from dateutil.tz import UTC
@@ 34,7 35,7 @@ from .widgets import VBox
from . import models
from .utils import convert_markdown_links, clean_markup, margin
-
+from .utils import InterruptibleTimeout
@Gtk.Template(resource_path="/net/kirgroup/confy/pages/info.ui")
class PageInfo(Gtk.Box):
@@ 210,6 211,17 @@ class PageList(Gtk.Box):
self.emit("row-activated")
+@dataclass
+class ListBuilderCtx:
+ lastobj = None
+ listbox = None
+ data = []
+ guard = None
+
+ def __repr__(self):
+ return f"<ListBuilderCtx lastobj={self.lastobj}, listbox={self.listbox}>"
+
+
@Gtk.Template(resource_path="/net/kirgroup/confy/pages/events.ui")
class PageEvents(Gtk.Box):
__gtype_name__ = "CPageEvents"
@@ 225,6 237,8 @@ class PageEvents(Gtk.Box):
search_button = Gtk.Template.Child()
searchbar = Gtk.Template.Child()
+ timeout = InterruptibleTimeout()
+
def get_value(self):
return self._value
@@ 333,30 347,38 @@ class PageEvents(Gtk.Box):
def update(self, *args):
data = self.get_objects()
+ self.timeout.stop()
+
# empty box
w = self.pagebox.get_last_child()
while w:
self.pagebox.remove(w)
w = self.pagebox.get_last_child()
- lastobj = None
- listbox = None
- for idx, obj in enumerate(data):
- header = self.build_header(obj, lastobj)
+ ctx = ListBuilderCtx()
+ ctx.data = data
+ ctx.guard = self.timeout = InterruptibleTimeout(50, self.build_list, ctx)
+
+ def build_list(self, ctx):
+ for idx, obj in enumerate(ctx.data):
+ if ctx.guard.must_stop():
+ return False
+
+ header = self.build_header(obj, ctx.lastobj)
if header:
- if listbox:
- self.pagebox.append(listbox)
- listbox = None
+ ctx.listbox = None
self.pagebox.append(header)
row = self.build_row(obj)
- if listbox is None:
- listbox = self.build_listbox()
- listbox.append(row)
- lastobj = obj
-
- if listbox:
- self.pagebox.append(listbox)
+ if ctx.listbox is None:
+ ctx.listbox = self.build_listbox()
+ self.pagebox.append(ctx.listbox)
+ ctx.listbox.append(row)
+ ctx.lastobj = obj
+ if idx > 10:
+ return True
+
+ return False
def build_listbox(self):
lb = Gtk.ListBox(margin_bottom=20)
M src/utils.py => src/utils.py +26 -0
@@ 1,6 1,8 @@
import re
import html
+from gi.repository import GLib
+
def convert_markdown_links(text):
"""converts markdown links to html hyperlinks"""
return re.sub("\[([^]]+?)\]\(([^)\s]+?)(?:\s.*?)?\)", r'<a href="\2">\1</a>', text)
@@ 27,3 29,27 @@ def clean_markup(text):
def margin(val):
return dict(margin_end=val, margin_start=val, margin_top=val, margin_bottom=val)
+
+class InterruptibleTimeout:
+ def __init__(self, intervall=0, callback=None, data=None):
+ self._running = False
+ self._requested_stop = True
+ self._callback = callback
+ if callback:
+ self._running = True
+ self._requested_stop = False
+ GLib.timeout_add(intervall, self._on_timeout, data)
+
+ def _on_timeout(self, data):
+ if self._requested_stop:
+ res = False
+ else:
+ res = self._callback(data)
+ self._running = res
+ return res
+
+ def stop(self):
+ self._requested_stop = True
+
+ def must_stop(self):
+ return self._requested_stop