Browse Source

Merge branch 'newest-reply-sorting-option' into 'master'

Add a newest reply/newest leaf sorting method for comments

Closes #111

See merge request tildes/tildes!150
merge-requests/150/merge
blankie 3 months ago
parent
commit
92440f914c
  1. 3
      tildes/tildes/enums.py
  2. 33
      tildes/tildes/models/comment/comment_tree.py

3
tildes/tildes/enums.py

@ -45,6 +45,7 @@ class CommentTreeSortOption(enum.Enum):
NEWEST = enum.auto()
POSTED = enum.auto()
RELEVANCE = enum.auto()
NEWEST_REPLY = enum.auto()
@property
def description(self) -> str:
@ -55,6 +56,8 @@ class CommentTreeSortOption(enum.Enum):
return "order posted"
elif self.name == "RELEVANCE":
return "relevance"
elif self.name == "NEWEST_REPLY":
return "newest reply"
return "most {}".format(self.name.lower())

33
tildes/tildes/models/comment/comment_tree.py

@ -92,6 +92,13 @@ class CommentTree:
comment.depth = 0
self.tree.append(comment)
@staticmethod
def _first_bottommost_reply(comment: Comment) -> Comment:
"""Continuously gets the first reply from a comment until there is no more."""
while comment.replies:
comment = comment.replies[0]
return comment
@staticmethod
def _sort_tree(tree: list[Comment], sort: CommentTreeSortOption) -> list[Comment]:
"""Sort the tree by the desired ordering (recursively).
@ -100,6 +107,15 @@ class CommentTree:
compare equal on the sorting method will be the same as the order that they were
originally in when passed to this function.
"""
# sort the tree's comments first, this will be important when sorting by newest
# reply
for comment in tree:
if not comment.has_visible_descendant:
# no need to bother sorting replies if none will be visible
continue
comment.replies = CommentTree._sort_tree(comment.replies, sort)
if sort == CommentTreeSortOption.NEWEST:
tree = sorted(tree, key=lambda c: c.created_time, reverse=True)
elif sort == CommentTreeSortOption.POSTED:
@ -108,13 +124,16 @@ class CommentTree:
tree = sorted(tree, key=lambda c: c.num_votes, reverse=True)
elif sort == CommentTreeSortOption.RELEVANCE:
tree = sorted(tree, key=lambda c: c.relevance_sorting_value, reverse=True)
for comment in tree:
if not comment.has_visible_descendant:
# no need to bother sorting replies if none will be visible
continue
comment.replies = CommentTree._sort_tree(comment.replies, sort)
elif sort == CommentTreeSortOption.NEWEST_REPLY:
# sort by the creation time of the first bottom-most reply in the
# entire tree, or the comment itself if there are no replies.
# the comment's first bottom-most reply is the newest reply since
# it has been sorted above
tree = sorted(
tree,
key=lambda c: CommentTree._first_bottommost_reply(c).created_time,
reverse=True,
)
return tree

Loading…
Cancel
Save