Show the account feed after it loads

Refresh fetched the account feed correctly -- the status line said "60 videos
in feed" -- and the page stayed empty with "No subscriptions yet" on it.

The empty-state hint added in 5.5.0 hides the grid so it can sit centred
rather than pinned under a large blank area. Every path that changes the grid
re-runs that check afterwards and shows it again; the account path was the one
that did not, so the grid stayed hidden from startup no matter what was loaded
into it. The local feed re-runs it and was unaffected, which is why this only
showed up for someone signed in.

Two related things while here. The empty-state message was written for local
subscriptions and is wrong advice in account mode, which does not use them --
it now says to press Refresh rather than to go and subscribe to something. And
the Subscriptions panel, which lists local subscriptions, is hidden in account
mode instead of sitting empty beside a full feed and implying something failed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-09 01:38:07 +02:00
parent ba05a4a7ef
commit 996d581a07
6 changed files with 45 additions and 10 deletions
+15
View File
@@ -8,6 +8,21 @@ Kept as the work happens, not assembled at release time. Format is
with its history. SageTube's own versions start below and are the ones this file with its history. SageTube's own versions start below and are the ones this file
records. records.
## 5.5.2 — 2026-08-09
### Fixed
- **The account feed loaded but never appeared.** Refresh reported "60 videos in
feed" above a "No subscriptions yet" message and an empty page: the empty-state
hint hides the grid so it can sit centred, and the account path set its entries
without re-running that check — so the grid stayed hidden from startup. The
local feed was unaffected, which is why it went unnoticed.
- The empty-state message was written for local subscriptions and was wrong
advice in account mode, where local subscriptions are not used at all. It now
says to press Refresh instead of telling you to go and subscribe to something.
- The Subscriptions panel is hidden in account mode rather than sitting empty
beside a full feed, implying something failed.
## 5.5.1 — 2026-08-09 ## 5.5.1 — 2026-08-09
### Fixed ### Fixed
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project] [project]
name = "sagetube" name = "sagetube"
version = "5.5.1" version = "5.5.2"
description = "Watch-first YouTube client with embedded mpv playback and yt-dlp downloading. Fork of YTSage." description = "Watch-first YouTube client with embedded mpv playback and yt-dlp downloading. Fork of YTSage."
authors = [ authors = [
{ name = "Houmeres", email = "admin@ecoposta.sk" }, { name = "Houmeres", email = "admin@ecoposta.sk" },
+1 -1
View File
@@ -10,5 +10,5 @@ match `version` in pyproject.toml and the repository's latest signed tag --
this package's tag line continues YTSage's, which is why it starts at 5.x. this package's tag line continues YTSage's, which is why it starts at 5.x.
""" """
__version__ = "5.5.1" __version__ = "5.5.2"
__author__ = "Houmeres" __author__ = "Houmeres"
+24 -6
View File
@@ -148,7 +148,10 @@ class FeedPage(QWidget):
splitter = QSplitter(Qt.Orientation.Horizontal, self) splitter = QSplitter(Qt.Orientation.Horizontal, self)
layout.addWidget(splitter, stretch=1) layout.addWidget(splitter, stretch=1)
side = QWidget() # Kept as an attribute: account mode does not use local subscriptions,
# so the panel is hidden there rather than sitting empty beside a full
# feed and implying something is missing.
self.subs_panel = side = QWidget()
side_layout = QVBoxLayout(side) side_layout = QVBoxLayout(side)
side_layout.setContentsMargins(0, 0, 4, 0) side_layout.setContentsMargins(0, 0, 4, 0)
subs_label = QLabel(_("feed.subscriptions")) subs_label = QLabel(_("feed.subscriptions"))
@@ -352,16 +355,26 @@ class FeedPage(QWidget):
Feed is the first tab now, so an empty one is the first thing a new Feed is the first tab now, so an empty one is the first thing a new
user sees. Say what to do about it rather than showing a blank grid. user sees. Say what to do about it rather than showing a blank grid.
""" """
account_mode = (self.mode_combo.currentData() or "local") == "account"
self.subs_panel.setVisible(not account_mode)
self.grid.empty_label.hide() self.grid.empty_label.hide()
if self.grid.card_count() > 0: if self.grid.card_count() > 0:
self.empty_hint.hide() self.empty_hint.hide()
self.grid.show() self.grid.show()
return return
self.empty_hint.setText(
_("feed.empty_no_subscriptions") # The message depends on the mode: account mode does not use local
if not LibraryManager.subscriptions() # subscriptions at all, so telling someone to go and subscribe to
else _("feed.empty_not_refreshed") # something would be wrong advice.
) if account_mode:
message = _("feed.empty_account")
elif not LibraryManager.subscriptions():
message = _("feed.empty_no_subscriptions")
else:
message = _("feed.empty_not_refreshed")
self.empty_hint.setText(message)
# Hide the empty grid so the hint sits in the middle of the page # Hide the empty grid so the hint sits in the middle of the page
# rather than pinned under a large blank area. # rather than pinned under a large blank area.
self.grid.hide() self.grid.hide()
@@ -383,10 +396,15 @@ class FeedPage(QWidget):
def _on_account_feed(self, entries: List[Dict[str, Any]]) -> None: def _on_account_feed(self, entries: List[Dict[str, Any]]) -> None:
self.grid.set_entries(entries) self.grid.set_entries(entries)
self.status_label.setText(_("feed.refreshed", count=len(entries))) self.status_label.setText(_("feed.refreshed", count=len(entries)))
# Without this the grid stays hidden behind the empty-state hint that
# was shown at startup, so a successful refresh reported "60 videos in
# feed" above a "No subscriptions yet" message and no videos.
self._update_empty_state()
def _on_account_error(self, message: str) -> None: def _on_account_error(self, message: str) -> None:
logger.error(f"Account feed failed: {message}") logger.error(f"Account feed failed: {message}")
self.status_label.setText(_("feed.account_failed", error=message[:200])) self.status_label.setText(_("feed.account_failed", error=message[:200]))
self._update_empty_state()
def _on_account_finished(self) -> None: def _on_account_finished(self) -> None:
self.refresh_btn.setEnabled(True) self.refresh_btn.setEnabled(True)
+2 -1
View File
@@ -760,7 +760,8 @@
"empty_not_refreshed": "Nothing here yet.\n\nPress Refresh to fetch the latest uploads from your subscriptions.", "empty_not_refreshed": "Nothing here yet.\n\nPress Refresh to fetch the latest uploads from your subscriptions.",
"sign_in": "Sign in with cookies…", "sign_in": "Sign in with cookies…",
"sign_in_tooltip": "Use your YouTube account via browser cookies, which enables the account feed", "sign_in_tooltip": "Use your YouTube account via browser cookies, which enables the account feed",
"account_requires_cookies": "Requires signing in with cookies" "account_requires_cookies": "Requires signing in with cookies",
"empty_account": "Nothing loaded yet.\n\nPress Refresh to fetch your YouTube subscription feed."
}, },
"account": { "account": {
"signed_out": "Not signed in", "signed_out": "Not signed in",
+2 -1
View File
@@ -143,7 +143,8 @@ class LocalizationManager:
"empty_not_refreshed": "Nothing here yet.\n\nPress Refresh to fetch the latest uploads from your subscriptions.", "empty_not_refreshed": "Nothing here yet.\n\nPress Refresh to fetch the latest uploads from your subscriptions.",
"sign_in": "Sign in with cookies…", "sign_in": "Sign in with cookies…",
"sign_in_tooltip": "Use your YouTube account via browser cookies, which enables the account feed", "sign_in_tooltip": "Use your YouTube account via browser cookies, which enables the account feed",
"account_requires_cookies": "Requires signing in with cookies" "account_requires_cookies": "Requires signing in with cookies",
"empty_account": "Nothing loaded yet.\n\nPress Refresh to fetch your YouTube subscription feed."
}, },
"cards": { "cards": {
"play": "▶ Play", "play": "▶ Play",