Setting for app tab navigation section

This commit is contained in:
Arkadiusz Fal 2021-11-07 21:51:22 +01:00
parent 3ca2105b9b
commit 278c4cad69
9 changed files with 150 additions and 66 deletions

View File

@ -57,6 +57,10 @@ extension Defaults.Keys {
static let trendingCategory = Key<TrendingCategory>("trendingCategory", default: .default) static let trendingCategory = Key<TrendingCategory>("trendingCategory", default: .default)
static let trendingCountry = Key<Country>("trendingCountry", default: .us) static let trendingCountry = Key<Country>("trendingCountry", default: .us)
#if os(iOS)
static let tabNavigationSection = Key<TabNavigationSectionSetting>("tabNavigationSection", default: .trending)
#endif
} }
enum ResolutionSetting: String, CaseIterable, Defaults.Serializable { enum ResolutionSetting: String, CaseIterable, Defaults.Serializable {
@ -92,3 +96,9 @@ enum PlayerSidebarSetting: String, CaseIterable, Defaults.Serializable {
#endif #endif
} }
} }
#if os(iOS)
enum TabNavigationSectionSetting: String, Defaults.Serializable {
case trending, popular
}
#endif

View File

@ -25,43 +25,58 @@ struct FavoriteItemView: View {
} }
var body: some View { var body: some View {
VStack(alignment: .leading, spacing: 2) { Group {
Text(label) if isVisible {
.font(.title3.bold()) VStack(alignment: .leading, spacing: 2) {
.foregroundColor(.secondary) Text(label)
.contextMenu { .font(.title3.bold())
Button { .foregroundColor(.secondary)
favoritesModel.remove(item) .contextMenu {
} label: { Button {
Label("Remove from Favorites", systemImage: "trash") favoritesModel.remove(item)
} } label: {
Label("Remove from Favorites", systemImage: "trash")
}
}
.contentShape(Rectangle())
#if os(tvOS)
.padding(.leading, 40)
#else
.padding(.leading, 15)
#endif
HorizontalCells(items: store.contentItems)
} }
.contentShape(Rectangle()) .contentShape(Rectangle())
#if os(tvOS) .opacity(dragging?.id == item.id ? 0.5 : 1)
.padding(.leading, 40) .onAppear {
#else resource?.addObserver(store)
.padding(.leading, 15) resource?.loadIfNeeded()
#endif }
#if !os(tvOS)
HorizontalCells(items: store.contentItems) .onDrag {
} dragging = item
return NSItemProvider(object: item.id as NSString)
.contentShape(Rectangle()) }
.opacity(dragging?.id == item.id ? 0.5 : 1) .onDrop(
.onAppear { of: [UTType.text],
resource?.addObserver(store) delegate: DropFavorite(item: item, favorites: $favorites, current: $dragging)
resource?.loadIfNeeded() )
} #endif
#if !os(tvOS)
.onDrag {
dragging = item
return NSItemProvider(object: item.id as NSString)
} }
.onDrop( }
of: [UTType.text], }
delegate: DropFavorite(item: item, favorites: $favorites, current: $dragging)
) private var isVisible: Bool {
#endif switch item.section {
case .subscriptions:
return accounts.app.supportsSubscriptions
case .popular:
return accounts.app.supportsPopular
default:
return true
}
} }
private var resource: Resource? { private var resource: Resource? {

View File

@ -8,6 +8,8 @@ struct AppTabNavigation: View {
@EnvironmentObject<RecentsModel> private var recents @EnvironmentObject<RecentsModel> private var recents
@EnvironmentObject<SearchModel> private var search @EnvironmentObject<SearchModel> private var search
@Default(.tabNavigationSection) private var tabNavigationSection
var body: some View { var body: some View {
TabView(selection: navigation.tabSelectionBinding) { TabView(selection: navigation.tabSelectionBinding) {
NavigationView { NavigationView {
@ -20,7 +22,7 @@ struct AppTabNavigation: View {
} }
.tag(TabSelection.favorites) .tag(TabSelection.favorites)
if accounts.app.supportsSubscriptions { if subscriptionsVisible {
NavigationView { NavigationView {
LazyView(SubscriptionsView()) LazyView(SubscriptionsView())
.toolbar { toolbarContent } .toolbar { toolbarContent }
@ -32,29 +34,21 @@ struct AppTabNavigation: View {
.tag(TabSelection.subscriptions) .tag(TabSelection.subscriptions)
} }
// TODO: reenable with settings if subscriptionsVisible {
if accounts.app.supportsPopular && false { if accounts.app.supportsPopular {
NavigationView { if tabNavigationSection == .popular {
LazyView(PopularView()) popularNavigationView
.toolbar { toolbarContent } } else {
trendingNavigationView
}
} }
.tabItem { } else {
Label("Popular", systemImage: "chart.bar") if accounts.app.supportsPopular {
.accessibility(label: Text("Popular")) popularNavigationView
} }
.tag(TabSelection.popular) trendingNavigationView
} }
NavigationView {
LazyView(TrendingView())
.toolbar { toolbarContent }
}
.tabItem {
Label("Trending", systemImage: "chart.line.uptrend.xyaxis")
.accessibility(label: Text("Trending"))
}
.tag(TabSelection.trending)
if accounts.app.supportsUserPlaylists { if accounts.app.supportsUserPlaylists {
NavigationView { NavigationView {
LazyView(PlaylistsView()) LazyView(PlaylistsView())
@ -125,6 +119,34 @@ struct AppTabNavigation: View {
} }
} }
private var subscriptionsVisible: Bool {
accounts.app.supportsSubscriptions && !(accounts.current?.anonymous ?? true)
}
private var popularNavigationView: some View {
NavigationView {
LazyView(PopularView())
.toolbar { toolbarContent }
}
.tabItem {
Label("Popular", systemImage: "chart.bar")
.accessibility(label: Text("Popular"))
}
.tag(TabSelection.popular)
}
private var trendingNavigationView: some View {
NavigationView {
LazyView(TrendingView())
.toolbar { toolbarContent }
}
.tabItem {
Label("Trending", systemImage: "chart.line.uptrend.xyaxis")
.accessibility(label: Text("Trending"))
}
.tag(TabSelection.trending)
}
private var playerNavigationLink: some View { private var playerNavigationLink: some View {
NavigationLink(isActive: $player.playerNavigationLinkActive, destination: { NavigationLink(isActive: $player.playerNavigationLinkActive, destination: {
VideoPlayerView() VideoPlayerView()

View File

@ -85,6 +85,7 @@ struct ContentView: View {
} }
.sheet(isPresented: $navigation.presentingPlaylistForm) { .sheet(isPresented: $navigation.presentingPlaylistForm) {
PlaylistFormView(playlist: $navigation.editedPlaylist) PlaylistFormView(playlist: $navigation.editedPlaylist)
.environmentObject(accounts)
.environmentObject(playlists) .environmentObject(playlists)
} }
.sheet(isPresented: $navigation.presentingSettings, onDismiss: openWelcomeScreenIfAccountEmpty) { .sheet(isPresented: $navigation.presentingSettings, onDismiss: openWelcomeScreenIfAccountEmpty) {

View File

@ -8,15 +8,17 @@ final class PlayerViewController: UIViewController {
var playerModel: PlayerModel! var playerModel: PlayerModel!
var playerViewController = AVPlayerViewController() var playerViewController = AVPlayerViewController()
var aspectRatio: Double? { #if !os(tvOS)
let ratio = Double(playerViewController.videoBounds.width) / Double(playerViewController.videoBounds.height) var aspectRatio: Double? {
let ratio = Double(playerViewController.videoBounds.width) / Double(playerViewController.videoBounds.height)
if !ratio.isFinite { guard ratio.isFinite else {
return VideoPlayerView.defaultAspectRatio return VideoPlayerView.defaultAspectRatio // swiftlint:disable:this implicit_return
}
return [ratio, 1.0].max()!
} }
#endif
return [ratio, 1.0].max()!
}
override func viewWillAppear(_ animated: Bool) { override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated) super.viewWillAppear(animated)

View File

@ -14,7 +14,7 @@ struct PlaylistFormView: View {
@Environment(\.dismiss) private var dismiss @Environment(\.dismiss) private var dismiss
@EnvironmentObject<InvidiousAPI> private var api @EnvironmentObject<AccountsModel> private var accounts
@EnvironmentObject<PlaylistsModel> private var playlists @EnvironmentObject<PlaylistsModel> private var playlists
var editing: Bool { var editing: Bool {
@ -185,7 +185,7 @@ struct PlaylistFormView: View {
} }
var resource: Resource? { var resource: Resource? {
editing ? api.playlist(playlist.id) : api.playlists editing ? accounts.api.playlist(playlist.id) : accounts.api.playlists
} }
var visibilityFormItem: some View { var visibilityFormItem: some View {
@ -230,7 +230,7 @@ struct PlaylistFormView: View {
} }
func deletePlaylistAndDismiss() { func deletePlaylistAndDismiss() {
api.playlist(playlist.id)?.request(.delete).onSuccess { _ in accounts.api.playlist(playlist.id)?.request(.delete).onSuccess { _ in
playlist = nil playlist = nil
playlists.load(force: true) playlists.load(force: true)
dismiss() dismiss()

View File

@ -51,16 +51,20 @@ struct PlaylistsView: View {
#if os(tvOS) #if os(tvOS)
.fullScreenCover(isPresented: $showingNewPlaylist, onDismiss: selectCreatedPlaylist) { .fullScreenCover(isPresented: $showingNewPlaylist, onDismiss: selectCreatedPlaylist) {
PlaylistFormView(playlist: $createdPlaylist) PlaylistFormView(playlist: $createdPlaylist)
.environmentObject(accounts)
} }
.fullScreenCover(isPresented: $showingEditPlaylist, onDismiss: selectEditedPlaylist) { .fullScreenCover(isPresented: $showingEditPlaylist, onDismiss: selectEditedPlaylist) {
PlaylistFormView(playlist: $editedPlaylist) PlaylistFormView(playlist: $editedPlaylist)
.environmentObject(accounts)
} }
#else #else
.sheet(isPresented: $showingNewPlaylist, onDismiss: selectCreatedPlaylist) { .sheet(isPresented: $showingNewPlaylist, onDismiss: selectCreatedPlaylist) {
PlaylistFormView(playlist: $createdPlaylist) PlaylistFormView(playlist: $createdPlaylist)
.environmentObject(accounts)
} }
.sheet(isPresented: $showingEditPlaylist, onDismiss: selectEditedPlaylist) { .sheet(isPresented: $showingEditPlaylist, onDismiss: selectEditedPlaylist) {
PlaylistFormView(playlist: $editedPlaylist) PlaylistFormView(playlist: $editedPlaylist)
.environmentObject(accounts)
} }
#endif #endif
.toolbar { .toolbar {

View File

@ -4,11 +4,18 @@ import SwiftUI
struct BrowsingSettings: View { struct BrowsingSettings: View {
@Default(.channelOnThumbnail) private var channelOnThumbnail @Default(.channelOnThumbnail) private var channelOnThumbnail
@Default(.timeOnThumbnail) private var timeOnThumbnail @Default(.timeOnThumbnail) private var timeOnThumbnail
#if os(iOS)
@Default(.tabNavigationSection) private var tabNavigationSection
#endif
var body: some View { var body: some View {
Section(header: SettingsHeader(text: "Thumbnails")) { Section(header: SettingsHeader(text: "Browsing"), footer: footer) {
Toggle("Display channel names on thumbnails", isOn: $channelOnThumbnail) Toggle("Display channel names on thumbnails", isOn: $channelOnThumbnail)
Toggle("Display video length on thumbnails", isOn: $timeOnThumbnail) Toggle("Display video length on thumbnails", isOn: $timeOnThumbnail)
#if os(iOS)
preferredTabPicker
#endif
} }
.frame(minWidth: 0, maxWidth: .infinity, alignment: .leading) .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
@ -16,6 +23,23 @@ struct BrowsingSettings: View {
Spacer() Spacer()
#endif #endif
} }
var footer: some View {
#if os(iOS)
Text("This tab will be displayed when there is no space to display all tabs")
#else
EmptyView()
#endif
}
#if os(iOS)
var preferredTabPicker: some View {
Picker("Preferred tab", selection: $tabNavigationSection) {
Text("Trending").tag(TabNavigationSectionSetting.trending)
Text("Popular").tag(TabNavigationSectionSetting.popular)
}
}
#endif
} }
struct BrowsingSettings_Previews: PreviewProvider { struct BrowsingSettings_Previews: PreviewProvider {

View File

@ -44,7 +44,12 @@ struct EditFavorites: View {
ForEach(model.addableItems()) { item in ForEach(model.addableItems()) { item in
HStack { HStack {
Text(label(item)) HStack {
Text(label(item))
Spacer()
Text("only with Invidious")
.foregroundColor(.secondary)
}
Spacer() Spacer()
@ -52,6 +57,7 @@ struct EditFavorites: View {
model.add(item) model.add(item)
} label: { } label: {
Label("Add to Favorites", systemImage: "heart") Label("Add to Favorites", systemImage: "heart")
.font(.system(size: 30))
} }
} }
} }