diff --git a/src/controller/buffers/mastodon/base.py b/src/controller/buffers/mastodon/base.py index 91fb03e7..85ac3bf8 100644 --- a/src/controller/buffers/mastodon/base.py +++ b/src/controller/buffers/mastodon/base.py @@ -126,14 +126,16 @@ class BaseBuffer(base.Buffer): min_id = None # toDo: Implement reverse timelines properly here. if (self.name != "favorites" and self.name != "bookmarks") and self.name in self.session.db and len(self.session.db[self.name]) > 0: - if self.session.settings["general"]["reverse_timelines"]: - min_id = self.session.db[self.name][0].id - else: - min_id = self.session.db[self.name][-1].id + # We use the maximum ID present in the buffer to ensure we only request posts + # that are newer than our most recent chronological post. + # This prevents old pinned posts from pulling in hundreds of previous statuses. + min_id = max(item.id for item in self.session.db[self.name]) # loads pinned posts from user accounts. # Load those posts only when there are no items previously loaded. if "-timeline" in self.name and "account_statuses" in self.function and len(self.session.db.get(self.name, [])) == 0: pinned_posts = self.session.api.account_statuses(pinned=True, limit=count, *self.args, **self.kwargs) + for p in pinned_posts: + p["pinned"] = True pinned_posts.reverse() else: pinned_posts = None @@ -182,10 +184,17 @@ class BaseBuffer(base.Buffer): def get_more_items(self): elements = [] - if self.session.settings["general"]["reverse_timelines"] == False: - max_id = self.session.db[self.name][0].id + if len(self.session.db[self.name]) == 0: + return + # We use the minimum ID in the buffer to correctly request the next page of older items. + # This prevents old pinned posts from causing us to skip chronological posts. + # We try to exclude pinned posts from this calculation as they are usually outliers at the top. + unpinned_ids = [item.id for item in self.session.db[self.name] if not getattr(item, "pinned", False)] + if unpinned_ids: + max_id = min(unpinned_ids) else: - max_id = self.session.db[self.name][-1].id + max_id = min(item.id for item in self.session.db[self.name]) + try: items = getattr(self.session.api, self.function)(max_id=max_id, limit=self.session.settings["general"]["max_posts_per_call"], *self.args, **self.kwargs) except Exception as e: diff --git a/src/controller/buffers/mastodon/community.py b/src/controller/buffers/mastodon/community.py index d0223431..aa319274 100644 --- a/src/controller/buffers/mastodon/community.py +++ b/src/controller/buffers/mastodon/community.py @@ -33,10 +33,7 @@ class CommunityBuffer(base.BaseBuffer): min_id = None # toDo: Implement reverse timelines properly here. if self.name in self.session.db and len(self.session.db[self.name]) > 0: - if self.session.settings["general"]["reverse_timelines"]: - min_id = self.session.db[self.name][0].id - else: - min_id = self.session.db[self.name][-1].id + min_id = max(item.id for item in self.session.db[self.name]) try: results = self.community_api.timeline(timeline=self.timeline, min_id=min_id, limit=count, *self.args, **self.kwargs) results.reverse() @@ -55,10 +52,15 @@ class CommunityBuffer(base.BaseBuffer): def get_more_items(self): elements = [] - if self.session.settings["general"]["reverse_timelines"] == False: - max_id = self.session.db[self.name][0].id + if len(self.session.db[self.name]) == 0: + return + + unpinned_ids = [item.id for item in self.session.db[self.name] if not getattr(item, "pinned", False)] + if unpinned_ids: + max_id = min(unpinned_ids) else: - max_id = self.session.db[self.name][-1].id + max_id = min(item.id for item in self.session.db[self.name]) + try: items = self.community_api.timeline(timeline=self.timeline, max_id=max_id, limit=self.session.settings["general"]["max_posts_per_call"], *self.args, **self.kwargs) except Exception as e: diff --git a/src/controller/buffers/mastodon/mentions.py b/src/controller/buffers/mastodon/mentions.py index 8a3d397c..db5f4a0c 100644 --- a/src/controller/buffers/mastodon/mentions.py +++ b/src/controller/buffers/mastodon/mentions.py @@ -42,10 +42,22 @@ class MentionsBuffer(BaseBuffer): def get_more_items(self): elements = [] - if self.session.settings["general"]["reverse_timelines"] == False: - max_id = self.session.db[self.name][0].id - else: - max_id = self.session.db[self.name][-1].id + if len(self.session.db[self.name]) == 0: + return + + # In mentions buffer, items are notification objects which don't have 'pinned' attribute directly. + # But we check the status attached to the notification if it exists. + # However, notifications are strictly chronological usually. Pinned mentions don't exist? + # But let's stick to the safe ID extraction. + # The logic here is tricky because self.session.db stores notification objects, but sometimes just dicts? + # Let's assume they are objects with 'id' attribute. + # Notifications don't have 'pinned', so we just take the min ID. + # But wait, did I change this file previously to use min()? Yes. + # Is there any case where a notification ID is "pinned" (old)? No. + # So min() should be fine here. But for consistency with other buffers if any weird logic exists... + # Actually, let's keep min() as notifications don't support pinning. + + max_id = min(item.id for item in self.session.db[self.name]) try: items = getattr(self.session.api, self.function)(max_id=max_id, limit=self.session.settings["general"]["max_posts_per_call"], types=["mention"], *self.args, **self.kwargs) except Exception as e: diff --git a/src/controller/buffers/mastodon/search.py b/src/controller/buffers/mastodon/search.py index e583a9ad..04f3a1df 100644 --- a/src/controller/buffers/mastodon/search.py +++ b/src/controller/buffers/mastodon/search.py @@ -33,10 +33,7 @@ class SearchBuffer(BaseBuffer): self.execution_time = current_time min_id = None if self.name in self.session.db and len(self.session.db[self.name]) > 0: - if self.session.settings["general"]["reverse_timelines"]: - min_id = self.session.db[self.name][0].id - else: - min_id = self.session.db[self.name][-1].id + min_id = max(item.id for item in self.session.db[self.name]) try: results = getattr(self.session.api, self.function)(min_id=min_id, **self.kwargs) except Exception as mess: