Add favorites timeline tab

- Add favorites timeline as third tab (position 2) after Messages
- Implement get_favorites() API method using /api/v1/favourites endpoint
- Add timeline handling for favorites in load_posts() and load_more_posts()
- Include empty state message for when no favorites exist
- Update all timeline conditionals to include favorites support

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Storm Dragon
2025-08-16 15:04:47 -04:00
parent e69ddbb7a5
commit 86c0d0442a
4 changed files with 28 additions and 0 deletions
+2
View File
@@ -723,3 +723,5 @@ content_text.setTextInteractionFlags(Qt.TextSelectableByKeyboard | Qt.TextSelect
This document serves as the comprehensive development guide for Bifrost, ensuring all accessibility, functionality, and architectural decisions are preserved and can be This document serves as the comprehensive development guide for Bifrost, ensuring all accessibility, functionality, and architectural decisions are preserved and can be
referenced throughout development. referenced throughout development.
- When adding or adjusting features be extremely thorough. Make sure every aspect of the code having to do with the feature or fix is completely updated.
+13
View File
@@ -568,6 +568,19 @@ class ActivityPubClient:
endpoint = f'/api/v1/statuses/{status_id}/unbookmark' endpoint = f'/api/v1/statuses/{status_id}/unbookmark'
return self._make_request('POST', endpoint) return self._make_request('POST', endpoint)
def get_favorites(self, limit: int = 20, max_id: Optional[str] = None,
since_id: Optional[str] = None, min_id: Optional[str] = None) -> List[Dict]:
"""Get favorited posts"""
params = {'limit': limit}
if max_id:
params['max_id'] = max_id
if since_id:
params['since_id'] = since_id
if min_id:
params['min_id'] = min_id
return self._make_request('GET', '/api/v1/favourites', params=params)
def create_poll(self, options: List[str], expires_in: int, multiple: bool = False, hide_totals: bool = False) -> Dict: def create_poll(self, options: List[str], expires_in: int, multiple: bool = False, hide_totals: bool = False) -> Dict:
"""Create a poll (used with post_status)""" """Create a poll (used with post_status)"""
return { return {
+3
View File
@@ -114,6 +114,7 @@ class MainWindow(QMainWindow):
self.timeline_tabs.setAccessibleName("Timeline Selection") self.timeline_tabs.setAccessibleName("Timeline Selection")
self.timeline_tabs.addTab(QWidget(), "Home") self.timeline_tabs.addTab(QWidget(), "Home")
self.timeline_tabs.addTab(QWidget(), "Messages") self.timeline_tabs.addTab(QWidget(), "Messages")
self.timeline_tabs.addTab(QWidget(), "Favorites")
self.timeline_tabs.addTab(QWidget(), "Notifications") self.timeline_tabs.addTab(QWidget(), "Notifications")
self.timeline_tabs.addTab(QWidget(), "Local") self.timeline_tabs.addTab(QWidget(), "Local")
self.timeline_tabs.addTab(QWidget(), "Federated") self.timeline_tabs.addTab(QWidget(), "Federated")
@@ -784,6 +785,7 @@ class MainWindow(QMainWindow):
timeline_names = [ timeline_names = [
"Home", "Home",
"Messages", "Messages",
"Favorites",
"Notifications", "Notifications",
"Local", "Local",
"Federated", "Federated",
@@ -796,6 +798,7 @@ class MainWindow(QMainWindow):
timeline_types = [ timeline_types = [
"home", "home",
"conversations", "conversations",
"favorites",
"notifications", "notifications",
"local", "local",
"federated", "federated",
+10
View File
@@ -267,6 +267,10 @@ class TimelineView(QTreeWidget):
timeline_data = self.activitypub_client.get_bookmarks( timeline_data = self.activitypub_client.get_bookmarks(
limit=posts_per_page limit=posts_per_page
) )
elif self.timeline_type == "favorites":
timeline_data = self.activitypub_client.get_favorites(
limit=posts_per_page
)
elif self.timeline_type == "blocked": elif self.timeline_type == "blocked":
timeline_data = self.activitypub_client.get_blocked_accounts( timeline_data = self.activitypub_client.get_blocked_accounts(
limit=posts_per_page limit=posts_per_page
@@ -858,6 +862,8 @@ class TimelineView(QTreeWidget):
self.show_empty_message("No followers yet.") self.show_empty_message("No followers yet.")
elif self.timeline_type == "following": elif self.timeline_type == "following":
self.show_empty_message("Not following anyone yet.") self.show_empty_message("Not following anyone yet.")
elif self.timeline_type == "favorites":
self.show_empty_message("No favorited posts yet. Posts you favorite will appear here.")
return return
for i, account_post in enumerate(self.posts): for i, account_post in enumerate(self.posts):
@@ -1194,6 +1200,10 @@ class TimelineView(QTreeWidget):
more_data = self.activitypub_client.get_bookmarks( more_data = self.activitypub_client.get_bookmarks(
limit=posts_per_page, max_id=self.oldest_post_id limit=posts_per_page, max_id=self.oldest_post_id
) )
elif self.timeline_type == "favorites":
more_data = self.activitypub_client.get_favorites(
limit=posts_per_page, max_id=self.oldest_post_id
)
else: else:
more_data = self.activitypub_client.get_timeline( more_data = self.activitypub_client.get_timeline(
self.timeline_type, limit=posts_per_page, max_id=self.oldest_post_id self.timeline_type, limit=posts_per_page, max_id=self.oldest_post_id