Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions dodo/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,14 @@
* 'thread': tree view, following the various subthreads
"""

thread_select_unread = False
"""When opening a thread, select the oldest unread matching message

If True, the oldest unread matching message is selected when opening a thread.
If all messages are read, the most recent message is selected instead.
If False (the default), the oldest matching message is selected.
"""

gnupg_home = None
"""Directory containg GnuPG keys

Expand Down
25 changes: 20 additions & 5 deletions dodo/thread.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,10 @@ def _fetch_matching_ids(self) -> set[str]:
return set(json.loads(r.stdout))

def get_last_msg_idx(self, parent: QModelIndex=QModelIndex()) -> QModelIndex:
if not parent.isValid():
if self.rowCount() == 0:
return QModelIndex()
return self.get_last_msg_idx(self.index(self.rowCount()-1, 0))
children = parent.internalPointer().children
if children:
return self.get_last_msg_idx(self.index(len(children)-1, 0, parent))
Expand Down Expand Up @@ -421,11 +425,22 @@ def find(self, msg_id: str) -> QModelIndex:

def default_message(self) -> QModelIndex:
"""Return the index of either the oldest matching message or the last message
in the thread."""
for idx in self.iterate_indices():
if self.message_at(idx)['id'] in self.matches:
return idx
return self.get_last_msg_idx()
in the thread.

If :func:`~dodo.settings.thread_select_unread` is True, prefer the oldest
unread matching message, falling back to the last message if all are read.
"""
if settings.thread_select_unread:
for idx in self.iterate_indices():
msg = self.message_at(idx)
if msg['id'] in self.matches and 'unread' in msg['tags']:
return idx
return self.get_last_msg_idx()
else:
for idx in self.iterate_indices():
if self.message_at(idx)['id'] in self.matches:
return idx
return self.get_last_msg_idx()

def default_collapsed(self) -> set[str]:
irrelevant_branches = set()
Expand Down