summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2021-05-13 16:27:34 +0200
committerAnton Khirnov <anton@khirnov.net>2021-05-13 16:27:34 +0200
commitec0a3a8406cb34103eb0610c4c8aa3dc330f3c3c (patch)
tree58b2fa7c46658038c048e058790391c0482045a6
parent954d79c47d4c123d1dafc2c670d79685b7ce84b1 (diff)
buffers/thread: do not construct the message widgets until they are needed
-rw-r--r--alot/buffers/thread.py40
1 files changed, 24 insertions, 16 deletions
diff --git a/alot/buffers/thread.py b/alot/buffers/thread.py
index d47faa31..33405be4 100644
--- a/alot/buffers/thread.py
+++ b/alot/buffers/thread.py
@@ -5,6 +5,7 @@
import asyncio
import enum
+from functools import cached_property
import logging
import urwid
@@ -18,6 +19,16 @@ class _ThreadBufFocus(enum.Enum):
TREE = enum.auto()
MESSAGE = enum.auto()
+class _LazyMessageWidget:
+ msg = None
+
+ def __init__(self, msg):
+ self.msg = msg
+
+ @cached_property
+ def wgt(self):
+ return MessageWidget(self.msg)
+
class ThreadBuffer(Buffer):
"""displays a thread as a tree of messages."""
@@ -28,7 +39,7 @@ class ThreadBuffer(Buffer):
# list of the widgets containing the message body
# indexed by its depth-first position in the thread tree
- _msg_widgets = None
+ _messages = None
# widget showing the thread tree
_msgtree_widget = None
# decorations around the msgtree widget
@@ -87,9 +98,9 @@ class ThreadBuffer(Buffer):
def _update_cur_msg(self):
pos = self._msgtree_widget.body.focus
- if pos is not None and pos < len(self._msg_widgets):
+ if pos is not None and pos < len(self._messages):
logging.debug('displaying message %s ', pos)
- self._cur_msg_holder.original_widget = self._msg_widgets[pos]
+ self._cur_msg_holder.original_widget = self._messages[pos].wgt
def translated_tags_str(self, intersection=False):
tags = self.thread.get_tags(intersection=intersection)
@@ -108,7 +119,7 @@ class ThreadBuffer(Buffer):
return info
def rebuild(self):
- self._msg_widgets = []
+ self._messages = []
self._msgtree_widget.body.clear()
self._cur_msg_holder.original_widget = urwid.SolidFill()
@@ -119,11 +130,8 @@ class ThreadBuffer(Buffer):
list_walker = self._msgtree_widget.body
for pos, msg in enumerate(self.thread.message_list):
- msg_wgt = MessageWidget(msg)
- wgt = ThreadNode(msg, self.thread, pos, self._indent_width)
-
- self._msg_widgets.append(msg_wgt)
- list_walker.append(wgt)
+ self._messages.append(_LazyMessageWidget(msg))
+ list_walker.append(ThreadNode(msg, self.thread, pos, self._indent_width))
# approximate weight for one terminal line
# substract 3 for decoration and panels
@@ -133,11 +141,11 @@ class ThreadBuffer(Buffer):
# the number of messages in it plus 2 (for surrounding decoration) -
# scaled to approximately one line per message - up to maximum weight of
# half the screen
- tree_weight = min(line_weight * (len(self._msg_widgets) + 2), 0.5)
+ tree_weight = min(line_weight * (len(self._messages) + 2), 0.5)
self.msgtree_weight = tree_weight
- if len(self._msg_widgets) > 0:
- self._cur_msg_holder.original_widget = self._msg_widgets[0]
+ if len(self._messages) > 0:
+ self._cur_msg_holder.original_widget = self._messages[0].wgt
@property
def msgtree_weight(self):
@@ -155,7 +163,7 @@ class ThreadBuffer(Buffer):
def get_selected_message_widget(self):
"""Return currently focused :class:`MessageWidget`."""
pos = self.get_selected_message_position()
- return self._msg_widgets[pos]
+ return self._messages[pos].wgt
def get_selected_message(self):
"""Return focussed :class:`~alot.db.message.Message`."""
@@ -176,8 +184,8 @@ class ThreadBuffer(Buffer):
"""
Iterate over all the message widgets in this buffer
"""
- for w in self._msg_widgets:
- yield w
+ for m in self._messages:
+ yield m.wgt
def set_focus(self, pos):
"Set the focus in the underlying body widget."
@@ -267,7 +275,7 @@ class ThreadBuffer(Buffer):
raise ValueError('Invalid focus_propery direction: ' + str(direction))
for pos in walk:
- if prop(self._msg_widgets[pos]):
+ if prop(self._messages[pos].wgt):
self.set_focus(pos)
break