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 2 months ago
parent
commit
4fdc708b11
  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() NEWEST = enum.auto()
POSTED = enum.auto() POSTED = enum.auto()
RELEVANCE = enum.auto() RELEVANCE = enum.auto()
NEWEST_REPLY = enum.auto()
@property @property
def description(self) -> str: def description(self) -> str:
@ -55,6 +56,8 @@ class CommentTreeSortOption(enum.Enum):
return "order posted" return "order posted"
elif self.name == "RELEVANCE": elif self.name == "RELEVANCE":
return "relevance" return "relevance"
elif self.name == "NEWEST_REPLY":
return "newest reply"
return "most {}".format(self.name.lower()) return "most {}".format(self.name.lower())

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

@ -92,6 +92,13 @@ class CommentTree:
comment.depth = 0 comment.depth = 0
self.tree.append(comment) 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 @staticmethod
def _sort_tree(tree: list[Comment], sort: CommentTreeSortOption) -> list[Comment]: def _sort_tree(tree: list[Comment], sort: CommentTreeSortOption) -> list[Comment]:
"""Sort the tree by the desired ordering (recursively). """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 compare equal on the sorting method will be the same as the order that they were
originally in when passed to this function. 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: if sort == CommentTreeSortOption.NEWEST:
tree = sorted(tree, key=lambda c: c.created_time, reverse=True) tree = sorted(tree, key=lambda c: c.created_time, reverse=True)
elif sort == CommentTreeSortOption.POSTED: elif sort == CommentTreeSortOption.POSTED:
@ -108,13 +124,16 @@ class CommentTree:
tree = sorted(tree, key=lambda c: c.num_votes, reverse=True) tree = sorted(tree, key=lambda c: c.num_votes, reverse=True)
elif sort == CommentTreeSortOption.RELEVANCE: elif sort == CommentTreeSortOption.RELEVANCE:
tree = sorted(tree, key=lambda c: c.relevance_sorting_value, reverse=True) 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 return tree

Loading…
Cancel
Save