Files
yattee/Shared/Views/PopularView.swift
Arkadiusz Fal 9177abb0ec Fix iOS menu text disappearing in navigation headers
Extended the ZStack overlay fix to all iOS navigation header menus
where text labels would disappear when tapping the menu:

- HomeView: "Home" title menu
- PopularView: "Popular" title with icon menu
- TrendingView: Country/flag title menu
- PlaylistsView: Playlist title with thumbnail menu
- ChannelPlaylistView: Playlist title with thumbnail menu
- OpenVideosView: Playback mode picker menu

All menus now use the same pattern as PlaybackSettings:
- Visible static label layer in ZStack
- Invisible Menu overlay with .opacity(0)
- Prevents text disappearing and resizing animations
2025-11-23 14:16:21 +01:00

183 lines
5.4 KiB
Swift

import Defaults
import Siesta
import SwiftUI
struct PopularView: View {
@StateObject private var store = Store<[Video]>()
@ObservedObject private var accounts = AccountsModel.shared
@State private var error: RequestError?
@Default(.popularListingStyle) private var popularListingStyle
var resource: Resource? {
accounts.api.popular
}
var videos: [ContentItem] {
ContentItem.array(of: store.collection)
}
var body: some View {
VerticalCells(items: videos) { if shouldDisplayHeader { header } }
.onAppear {
resource?.addObserver(store)
resource?.loadIfNeeded()?
.onFailure { self.error = $0 }
.onSuccess { _ in self.error = nil }
}
.environment(\.listingStyle, popularListingStyle)
#if !os(tvOS)
.navigationTitle("Popular")
.background(
Button("Refresh") {
resource?.load()
.onFailure { self.error = $0 }
.onSuccess { _ in self.error = nil }
}
.keyboardShortcut("r")
.opacity(0)
)
#endif
#if os(iOS)
.toolbar {
ToolbarItem(placement: .principal) {
popularMenu
}
}
.navigationBarTitleDisplayMode(.inline)
.refreshControl { refreshControl in
resource?.load()
.onCompletion { _ in
refreshControl.endRefreshing()
}
.onFailure { self.error = $0 }
.onSuccess { _ in self.error = nil }
}
.backport
.refreshable {
DispatchQueue.main.async {
resource?.load()
.onFailure { self.error = $0 }
.onSuccess { _ in self.error = nil }
}
}
.navigationBarTitleDisplayMode(RefreshControl.navigationBarTitleDisplayMode)
#endif
#if os(macOS)
.toolbar {
ToolbarItem {
ListingStyleButtons(listingStyle: $popularListingStyle)
}
ToolbarItem {
HideWatchedButtons()
}
ToolbarItem {
HideShortsButtons()
}
}
#else
.onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)) { _ in
resource?.loadIfNeeded()?
.onFailure { self.error = $0 }
.onSuccess { _ in self.error = nil }
}
#endif
}
#if os(iOS)
private var popularMenu: some View {
ZStack {
HStack(spacing: 12) {
HStack(spacing: 6) {
Image(systemName: "chart.bar.fill")
.foregroundColor(.primary)
.imageScale(.small)
Text("Popular")
.font(.headline)
.foregroundColor(.primary)
}
Image(systemName: "chevron.down.circle.fill")
.foregroundColor(.accentColor)
.imageScale(.small)
}
Menu {
ListingStyleButtons(listingStyle: $popularListingStyle)
Section {
HideWatchedButtons()
HideShortsButtons()
}
Section {
SettingsButtons()
}
} label: {
HStack(spacing: 12) {
HStack(spacing: 6) {
Image(systemName: "chart.bar.fill")
.foregroundColor(.primary)
.imageScale(.small)
Text("Popular")
.font(.headline)
.foregroundColor(.primary)
}
Image(systemName: "chevron.down.circle.fill")
.foregroundColor(.accentColor)
.imageScale(.small)
}
.opacity(0)
}
}
.transaction { t in t.animation = nil }
}
#endif
var shouldDisplayHeader: Bool {
#if os(tvOS)
true
#else
false
#endif
}
var header: some View {
HStack {
Spacer()
ListingStyleButtons(listingStyle: $popularListingStyle)
HideWatchedButtons()
HideShortsButtons()
Button {
resource?.load()
.onFailure { self.error = $0 }
.onSuccess { _ in self.error = nil }
} label: {
Label("Refresh", systemImage: "arrow.clockwise")
.labelStyle(.iconOnly)
.imageScale(.small)
.font(.caption)
}
}
.padding(.leading, 30)
.padding(.bottom, 15)
.padding(.trailing, 30)
}
}
struct PopularView_Previews: PreviewProvider {
static var previews: some View {
NavigationView {
PopularView()
}
}
}