Give tvOS playlist not-found and empty states a focusable button

The not-found state had nothing focusable, and an empty remote playlist
this account does not own showed no left-column buttons either, so the
remote was stuck. Not found offers Retry (remote) or Open Playlists
(local); the empty remote playlist offers Refresh.
This commit is contained in:
Arkadiusz Fal
2026-10-16 23:55:14 +02:00
parent 3875c864b1
commit 5390f99b82
2 changed files with 45 additions and 6 deletions

View File

@@ -9391,6 +9391,17 @@
}
}
},
"playlist.notFound.openPlaylists" : {
"comment" : "tvOS button on the playlist-not-found screen that opens the Playlists list",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Open Playlists"
}
}
}
},
"playlist.play" : {
"comment" : "Play button in playlist toolbar menu",
"localizations" : {

View File

@@ -252,12 +252,7 @@ struct UnifiedPlaylistDetailView: View {
} else if let error = errorMessage {
errorView(error)
} else {
ContentUnavailableView(
String(localized: "playlist.notFound"),
systemImage: "list.bullet.rectangle",
description: Text(String(localized: "playlist.notFound.description"))
)
.frame(maxWidth: .infinity, maxHeight: .infinity)
notFoundView
}
}
#if !os(tvOS)
@@ -819,11 +814,44 @@ struct UnifiedPlaylistDetailView: View {
Label(String(localized: "playlist.empty"), systemImage: "music.note.list")
} description: {
Text(String(localized: "playlist.empty.description"))
} actions: {
#if os(tvOS)
// The left column has no buttons for an empty remote playlist this
// account does not own; without one the remote has nowhere to go.
if case .remote = source {
Button(String(localized: "common.refresh")) {
Task { await loadPlaylist() }
}
}
#endif
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.padding(.top, 40)
}
private var notFoundView: some View {
ContentUnavailableView {
Label(String(localized: "playlist.notFound"), systemImage: "list.bullet.rectangle")
} description: {
Text(String(localized: "playlist.notFound.description"))
} actions: {
#if os(tvOS)
// Nothing else on this screen is focusable, and as a sidebar
// playlist it is a tab root that Menu cannot pop.
if case .remote = source {
Button(String(localized: "common.retry")) {
Task { await loadPlaylist() }
}
} else {
Button(String(localized: "playlist.notFound.openPlaylists")) {
appEnvironment?.navigationCoordinator.router.select(.playlistsList)
}
}
#endif
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
private var videoList: some View {
#if os(tvOS)
let indexColumnWidth: CGFloat = 60