mirror of
https://github.com/yattee/yattee.git
synced 2024-11-10 00:08:21 +00:00
Setting for app tab navigation section
This commit is contained in:
parent
3ca2105b9b
commit
278c4cad69
@ -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
|
||||||
|
@ -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? {
|
||||||
|
@ -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()
|
||||||
|
@ -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) {
|
||||||
|
@ -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)
|
||||||
|
@ -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()
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user