Implement seamless auto-loading timeline navigation
- Remove explicit "Load more posts" items from timeline view - Auto-load more posts when down arrow pressed at timeline end - Create seamless infinite-scroll experience for better UX - Maintain focus on newly loaded content for smooth navigation - Reduce status message display time to 1 second for less interruption - Update accessibility name to "Timeline Tree" for consistency This creates a more natural browsing experience where users can continuously navigate through their timeline without manual loading prompts. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -116,7 +116,7 @@ class TimelineView(QTreeWidget):
|
||||
self.setFocusPolicy(Qt.StrongFocus)
|
||||
|
||||
# Set accessible properties
|
||||
self.setAccessibleName("Timeline")
|
||||
self.setAccessibleName("Timeline Tree")
|
||||
self.setAccessibleDescription("Timeline showing posts and conversations")
|
||||
|
||||
def set_timeline_type(self, timeline_type: str):
|
||||
@ -1151,13 +1151,10 @@ class TimelineView(QTreeWidget):
|
||||
)
|
||||
|
||||
def add_load_more_item(self):
|
||||
"""Add a 'Load more posts' item at the bottom of the timeline"""
|
||||
load_more_item = QTreeWidgetItem(["Load more posts (Press Enter)"])
|
||||
load_more_item.setData(0, Qt.UserRole, "load_more") # Special marker
|
||||
load_more_item.setData(
|
||||
0, Qt.AccessibleTextRole, "Load more posts from timeline"
|
||||
)
|
||||
self.addTopLevelItem(load_more_item)
|
||||
"""Legacy method - no longer adds visible 'Load more posts' item"""
|
||||
# Auto-loading on down arrow makes explicit load more items unnecessary
|
||||
# Keep method for compatibility but don't add any visible items
|
||||
pass
|
||||
|
||||
def load_more_posts(self):
|
||||
"""Load more posts from the current timeline"""
|
||||
@ -1200,11 +1197,8 @@ class TimelineView(QTreeWidget):
|
||||
)
|
||||
|
||||
if more_data:
|
||||
# Remember current "Load more" item position
|
||||
load_more_index = self.get_load_more_item_index()
|
||||
|
||||
# Remove current "Load more" item
|
||||
self.remove_load_more_item()
|
||||
# Get current position to add new posts
|
||||
insert_index = self.topLevelItemCount()
|
||||
|
||||
# Add new posts to existing list
|
||||
self.load_additional_timeline_data(more_data)
|
||||
@ -1213,24 +1207,18 @@ class TimelineView(QTreeWidget):
|
||||
self.oldest_post_id = more_data[-1]["id"]
|
||||
|
||||
# Add new posts to the tree without rebuilding everything
|
||||
self.add_new_posts_to_tree(more_data, load_more_index)
|
||||
self.add_new_posts_to_tree(more_data, insert_index)
|
||||
|
||||
# Add new "Load more" item at the end
|
||||
self.add_load_more_item()
|
||||
|
||||
# Focus on the first newly added post so user can arrow down to read them
|
||||
if (
|
||||
load_more_index is not None
|
||||
and load_more_index < self.topLevelItemCount()
|
||||
):
|
||||
first_new_item = self.topLevelItem(load_more_index)
|
||||
# Focus on the first newly added post so user can continue reading
|
||||
if insert_index < self.topLevelItemCount():
|
||||
first_new_item = self.topLevelItem(insert_index)
|
||||
if first_new_item:
|
||||
self.setCurrentItem(first_new_item)
|
||||
self.scrollToItem(first_new_item)
|
||||
|
||||
if hasattr(self, "parent") and hasattr(self.parent(), "status_bar"):
|
||||
self.parent().status_bar.showMessage(
|
||||
f"Loaded {len(more_data)} more posts", 2000
|
||||
f"Loaded {len(more_data)} more posts", 1000
|
||||
)
|
||||
else:
|
||||
if hasattr(self, "parent") and hasattr(self.parent(), "status_bar"):
|
||||
@ -1244,20 +1232,12 @@ class TimelineView(QTreeWidget):
|
||||
)
|
||||
|
||||
def get_load_more_item_index(self):
|
||||
"""Get the index of the 'Load more posts' item"""
|
||||
for i in range(self.topLevelItemCount()):
|
||||
item = self.topLevelItem(i)
|
||||
if item.data(0, Qt.UserRole) == "load_more":
|
||||
return i
|
||||
"""Legacy method - no longer needed as there are no load more items"""
|
||||
return None
|
||||
|
||||
def remove_load_more_item(self):
|
||||
"""Remove the 'Load more posts' item"""
|
||||
for i in range(self.topLevelItemCount()):
|
||||
item = self.topLevelItem(i)
|
||||
if item.data(0, Qt.UserRole) == "load_more":
|
||||
self.takeTopLevelItem(i)
|
||||
break
|
||||
"""Legacy method - no longer needed as there are no load more items"""
|
||||
pass
|
||||
|
||||
def load_additional_timeline_data(self, timeline_data):
|
||||
"""Load additional timeline data and append to existing posts"""
|
||||
@ -1371,7 +1351,7 @@ class TimelineView(QTreeWidget):
|
||||
return
|
||||
|
||||
post = item.data(0, Qt.UserRole)
|
||||
if not post or post == "load_more":
|
||||
if not post:
|
||||
return
|
||||
|
||||
menu = QMenu(self)
|
||||
@ -1632,7 +1612,7 @@ class TimelineView(QTreeWidget):
|
||||
self.logger.error(f"Error updating conversation display: {e}")
|
||||
|
||||
def keyPressEvent(self, event: QKeyEvent):
|
||||
"""Handle keyboard events, including Enter for poll voting and context menu keys"""
|
||||
"""Handle keyboard events, including Enter for poll voting and automatic loading"""
|
||||
key = event.key()
|
||||
current = self.currentItem()
|
||||
|
||||
@ -1648,15 +1628,22 @@ class TimelineView(QTreeWidget):
|
||||
self.customContextMenuRequested.emit(center)
|
||||
return
|
||||
|
||||
# Handle Enter key for polls, load more, and post details
|
||||
if (key == Qt.Key_Return or key == Qt.Key_Enter) and current:
|
||||
# Check for special items first
|
||||
special_data = current.data(0, Qt.UserRole)
|
||||
if special_data == "load_more":
|
||||
# Handle down arrow at end of timeline - automatically load more posts
|
||||
if key == Qt.Key_Down and current:
|
||||
# Check if we're at the last post in the timeline
|
||||
current_index = self.indexOfTopLevelItem(current)
|
||||
total_items = self.topLevelItemCount()
|
||||
|
||||
# If we're at the last post, automatically load more
|
||||
if current_index >= total_items - 1:
|
||||
# Only auto-load if we actually have an API client and more data might be available
|
||||
if self.activitypub_client and self.oldest_post_id:
|
||||
self.load_more_posts()
|
||||
return
|
||||
|
||||
# Check if current item has poll data
|
||||
# Handle Enter key for post details
|
||||
if (key == Qt.Key_Return or key == Qt.Key_Enter) and current:
|
||||
# Check if current item has post data
|
||||
try:
|
||||
post_index = self.indexOfTopLevelItem(current)
|
||||
if 0 <= post_index < len(self.posts):
|
||||
|
Reference in New Issue
Block a user