From 86c0d0442a9e8819c42f74f5183f29019e7b60d0 Mon Sep 17 00:00:00 2001 From: Storm Dragon Date: Sat, 16 Aug 2025 15:04:47 -0400 Subject: [PATCH] Add favorites timeline tab MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- CLAUDE.md | 2 ++ src/activitypub/client.py | 13 +++++++++++++ src/main_window.py | 3 +++ src/widgets/timeline_view.py | 10 ++++++++++ 4 files changed, 28 insertions(+) diff --git a/CLAUDE.md b/CLAUDE.md index acd8dc0..c40921a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -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 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. \ No newline at end of file diff --git a/src/activitypub/client.py b/src/activitypub/client.py index e43afb1..0272559 100644 --- a/src/activitypub/client.py +++ b/src/activitypub/client.py @@ -568,6 +568,19 @@ class ActivityPubClient: endpoint = f'/api/v1/statuses/{status_id}/unbookmark' 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: """Create a poll (used with post_status)""" return { diff --git a/src/main_window.py b/src/main_window.py index 64924c6..450077f 100644 --- a/src/main_window.py +++ b/src/main_window.py @@ -114,6 +114,7 @@ class MainWindow(QMainWindow): self.timeline_tabs.setAccessibleName("Timeline Selection") self.timeline_tabs.addTab(QWidget(), "Home") self.timeline_tabs.addTab(QWidget(), "Messages") + self.timeline_tabs.addTab(QWidget(), "Favorites") self.timeline_tabs.addTab(QWidget(), "Notifications") self.timeline_tabs.addTab(QWidget(), "Local") self.timeline_tabs.addTab(QWidget(), "Federated") @@ -784,6 +785,7 @@ class MainWindow(QMainWindow): timeline_names = [ "Home", "Messages", + "Favorites", "Notifications", "Local", "Federated", @@ -796,6 +798,7 @@ class MainWindow(QMainWindow): timeline_types = [ "home", "conversations", + "favorites", "notifications", "local", "federated", diff --git a/src/widgets/timeline_view.py b/src/widgets/timeline_view.py index d9c2bf1..f92ae76 100644 --- a/src/widgets/timeline_view.py +++ b/src/widgets/timeline_view.py @@ -267,6 +267,10 @@ class TimelineView(QTreeWidget): timeline_data = self.activitypub_client.get_bookmarks( 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": timeline_data = self.activitypub_client.get_blocked_accounts( limit=posts_per_page @@ -858,6 +862,8 @@ class TimelineView(QTreeWidget): self.show_empty_message("No followers yet.") elif self.timeline_type == "following": 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 for i, account_post in enumerate(self.posts): @@ -1194,6 +1200,10 @@ class TimelineView(QTreeWidget): more_data = self.activitypub_client.get_bookmarks( 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: more_data = self.activitypub_client.get_timeline( self.timeline_type, limit=posts_per_page, max_id=self.oldest_post_id