Staggered infinite scroll — posts appear one at a time
Posts from infinite scroll are queued and added individually with 50ms delay between each, creating a smooth flowing appearance instead of 40 empty cells appearing at once.
This commit is contained in:
parent
6f684bb491
commit
6524104008
@ -814,43 +814,57 @@ class BooruApp(QMainWindow):
|
|||||||
self._prefetch_adjacent(0)
|
self._prefetch_adjacent(0)
|
||||||
|
|
||||||
def _on_search_append(self, posts: list) -> None:
|
def _on_search_append(self, posts: list) -> None:
|
||||||
"""Append more posts to the grid (infinite scroll)."""
|
"""Queue posts and add them one at a time as thumbnails arrive."""
|
||||||
if not posts:
|
if not posts:
|
||||||
self._loading = False
|
self._loading = False
|
||||||
self._infinite_exhausted = True
|
self._infinite_exhausted = True
|
||||||
self._status.showMessage(f"{len(self._posts)} results (end)")
|
self._status.showMessage(f"{len(self._posts)} results (end)")
|
||||||
return
|
return
|
||||||
self._shown_post_ids.update(p.id for p in posts)
|
self._shown_post_ids.update(p.id for p in posts)
|
||||||
start = len(self._posts)
|
|
||||||
self._posts.extend(posts)
|
|
||||||
self._page_label.setText(f"Page {self._current_page}")
|
|
||||||
self._status.showMessage(f"{len(self._posts)} results")
|
|
||||||
|
|
||||||
thumbs = self._grid.append_posts(len(posts))
|
|
||||||
QTimer.singleShot(100, self._clear_loading)
|
QTimer.singleShot(100, self._clear_loading)
|
||||||
|
|
||||||
from ..core.config import saved_dir, saved_folder_dir
|
if not hasattr(self, '_append_queue'):
|
||||||
|
self._append_queue = []
|
||||||
|
self._append_queue.extend(posts)
|
||||||
|
self._drain_append_queue()
|
||||||
|
|
||||||
|
def _drain_append_queue(self) -> None:
|
||||||
|
"""Add queued posts to the grid one at a time with thumbnail fetch."""
|
||||||
|
if not getattr(self, '_append_queue', None):
|
||||||
|
return
|
||||||
|
|
||||||
|
from ..core.config import saved_dir
|
||||||
|
from ..core.cache import cached_path_for
|
||||||
site_id = self._site_combo.currentData()
|
site_id = self._site_combo.currentData()
|
||||||
_sd = saved_dir()
|
_sd = saved_dir()
|
||||||
_saved_ids: set[int] = set()
|
_saved_ids: set[int] = set()
|
||||||
if _sd.exists():
|
if _sd.exists():
|
||||||
_saved_ids = {int(f.stem) for f in _sd.iterdir() if f.is_file() and f.stem.isdigit()}
|
_saved_ids = {int(f.stem) for f in _sd.iterdir() if f.is_file() and f.stem.isdigit()}
|
||||||
|
|
||||||
for i, (post, thumb) in enumerate(zip(posts, thumbs)):
|
post = self._append_queue.pop(0)
|
||||||
if site_id and self._db.is_bookmarked(site_id, post.id):
|
idx = len(self._posts)
|
||||||
thumb.set_bookmarked(True)
|
self._posts.append(post)
|
||||||
saved = post.id in _saved_ids
|
thumbs = self._grid.append_posts(1)
|
||||||
thumb.set_saved_locally(saved)
|
thumb = thumbs[0]
|
||||||
from ..core.cache import cached_path_for
|
|
||||||
cached = cached_path_for(post.file_url)
|
|
||||||
if cached.exists():
|
|
||||||
thumb._cached_path = str(cached)
|
|
||||||
if post.preview_url:
|
|
||||||
self._fetch_thumbnail(start + i, post.preview_url)
|
|
||||||
|
|
||||||
# Prefetch new posts
|
if site_id and self._db.is_bookmarked(site_id, post.id):
|
||||||
if self._db.get_setting_bool("prefetch_adjacent") and posts:
|
thumb.set_bookmarked(True)
|
||||||
self._prefetch_adjacent(start)
|
thumb.set_saved_locally(post.id in _saved_ids)
|
||||||
|
cached = cached_path_for(post.file_url)
|
||||||
|
if cached.exists():
|
||||||
|
thumb._cached_path = str(cached)
|
||||||
|
if post.preview_url:
|
||||||
|
self._fetch_thumbnail(idx, post.preview_url)
|
||||||
|
|
||||||
|
self._status.showMessage(f"{len(self._posts)} results")
|
||||||
|
|
||||||
|
# Schedule next post
|
||||||
|
if self._append_queue:
|
||||||
|
QTimer.singleShot(50, self._drain_append_queue)
|
||||||
|
else:
|
||||||
|
# All done — prefetch
|
||||||
|
if self._db.get_setting_bool("prefetch_adjacent"):
|
||||||
|
self._prefetch_adjacent(idx)
|
||||||
|
|
||||||
def _fetch_thumbnail(self, index: int, url: str) -> None:
|
def _fetch_thumbnail(self, index: int, url: str) -> None:
|
||||||
async def _download():
|
async def _download():
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user