mirror of
https://github.com/yattee/yattee.git
synced 2024-12-22 13:33:42 +00:00
Browser player bar as overlay
This commit is contained in:
parent
7df397b662
commit
74d65f6ab8
@ -4,57 +4,55 @@ struct DocumentsView: View {
|
|||||||
@ObservedObject private var model = DocumentsModel.shared
|
@ObservedObject private var model = DocumentsModel.shared
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
BrowserPlayerControls {
|
ScrollView(.vertical, showsIndicators: false) {
|
||||||
ScrollView(.vertical, showsIndicators: false) {
|
if model.directoryContents.isEmpty {
|
||||||
if model.directoryContents.isEmpty {
|
NoDocumentsView()
|
||||||
NoDocumentsView()
|
} else {
|
||||||
} else {
|
ForEach(model.sortedDirectoryContents, id: \.absoluteString) { url in
|
||||||
ForEach(model.sortedDirectoryContents, id: \.absoluteString) { url in
|
let video = Video.local(model.standardizedURL(url) ?? url)
|
||||||
let video = Video.local(model.standardizedURL(url) ?? url)
|
PlayerQueueRow(
|
||||||
PlayerQueueRow(
|
item: PlayerQueueItem(video)
|
||||||
item: PlayerQueueItem(video)
|
)
|
||||||
)
|
.contextMenu {
|
||||||
.contextMenu {
|
VideoContextMenuView(video: video)
|
||||||
VideoContextMenuView(video: video)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.id(model.refreshID)
|
|
||||||
.transition(.opacity)
|
|
||||||
}
|
|
||||||
Color.clear.padding(.bottom, 50)
|
|
||||||
}
|
|
||||||
.onAppear {
|
|
||||||
if model.directoryURL.isNil {
|
|
||||||
model.goToTop()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.toolbar {
|
|
||||||
ToolbarItem(placement: .navigationBarLeading) {
|
|
||||||
if model.canGoBack {
|
|
||||||
Button {
|
|
||||||
withAnimation {
|
|
||||||
model.goBack()
|
|
||||||
}
|
|
||||||
} label: {
|
|
||||||
HStack(spacing: 6) {
|
|
||||||
Label("Go back", systemImage: "chevron.left")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.transaction { t in t.animation = .none }
|
|
||||||
.disabled(!model.canGoBack)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.id(model.refreshID)
|
||||||
|
.transition(.opacity)
|
||||||
}
|
}
|
||||||
.navigationTitle(model.directoryLabel)
|
Color.clear.padding(.bottom, 50)
|
||||||
.padding(.horizontal)
|
}
|
||||||
.navigationBarTitleDisplayMode(RefreshControl.navigationBarTitleDisplayMode)
|
.onAppear {
|
||||||
.backport
|
if model.directoryURL.isNil {
|
||||||
.refreshable {
|
model.goToTop()
|
||||||
DispatchQueue.main.async {
|
}
|
||||||
self.refresh()
|
}
|
||||||
|
.toolbar {
|
||||||
|
ToolbarItem(placement: .navigationBarLeading) {
|
||||||
|
if model.canGoBack {
|
||||||
|
Button {
|
||||||
|
withAnimation {
|
||||||
|
model.goBack()
|
||||||
|
}
|
||||||
|
} label: {
|
||||||
|
HStack(spacing: 6) {
|
||||||
|
Label("Go back", systemImage: "chevron.left")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.transaction { t in t.animation = .none }
|
||||||
|
.disabled(!model.canGoBack)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.navigationTitle(model.directoryLabel)
|
||||||
|
.padding(.horizontal)
|
||||||
|
.navigationBarTitleDisplayMode(RefreshControl.navigationBarTitleDisplayMode)
|
||||||
|
.backport
|
||||||
|
.refreshable {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.refresh()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func refresh() {
|
func refresh() {
|
||||||
|
@ -33,159 +33,157 @@ struct HomeView: View {
|
|||||||
private var navigation: NavigationModel { .shared }
|
private var navigation: NavigationModel { .shared }
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
BrowserPlayerControls {
|
ScrollView(.vertical, showsIndicators: false) {
|
||||||
ScrollView(.vertical, showsIndicators: false) {
|
HStack {
|
||||||
HStack {
|
#if os(tvOS)
|
||||||
#if os(tvOS)
|
Group {
|
||||||
Group {
|
|
||||||
if showOpenActionsInHome {
|
|
||||||
OpenVideosButton(text: "Open Video", imageSystemName: "globe") {
|
|
||||||
NavigationModel.shared.presentingOpenVideos = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
OpenVideosButton(text: "Settings", imageSystemName: "gear") {
|
|
||||||
NavigationModel.shared.presentingSettings = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if showOpenActionsInHome {
|
if showOpenActionsInHome {
|
||||||
OpenVideosButton(text: "Files", imageSystemName: "folder") {
|
OpenVideosButton(text: "Open Video", imageSystemName: "globe") {
|
||||||
NavigationModel.shared.presentingFileImporter = true
|
|
||||||
}
|
|
||||||
OpenVideosButton(text: "Paste", imageSystemName: "doc.on.clipboard.fill") {
|
|
||||||
OpenVideosModel.shared.openURLsFromClipboard(playbackMode: .playNow)
|
|
||||||
}
|
|
||||||
OpenVideosButton(imageSystemName: "ellipsis") {
|
|
||||||
NavigationModel.shared.presentingOpenVideos = true
|
NavigationModel.shared.presentingOpenVideos = true
|
||||||
}
|
}
|
||||||
.frame(maxWidth: 40)
|
|
||||||
}
|
}
|
||||||
#endif
|
OpenVideosButton(text: "Settings", imageSystemName: "gear") {
|
||||||
}
|
NavigationModel.shared.presentingSettings = true
|
||||||
#if os(iOS)
|
}
|
||||||
.padding(.top, RefreshControl.navigationBarTitleDisplayMode == .inline ? 15 : 0)
|
}
|
||||||
#else
|
#else
|
||||||
.padding(.top, 15)
|
if showOpenActionsInHome {
|
||||||
|
OpenVideosButton(text: "Files", imageSystemName: "folder") {
|
||||||
|
NavigationModel.shared.presentingFileImporter = true
|
||||||
|
}
|
||||||
|
OpenVideosButton(text: "Paste", imageSystemName: "doc.on.clipboard.fill") {
|
||||||
|
OpenVideosModel.shared.openURLsFromClipboard(playbackMode: .playNow)
|
||||||
|
}
|
||||||
|
OpenVideosButton(imageSystemName: "ellipsis") {
|
||||||
|
NavigationModel.shared.presentingOpenVideos = true
|
||||||
|
}
|
||||||
|
.frame(maxWidth: 40)
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
#if os(iOS)
|
||||||
|
.padding(.top, RefreshControl.navigationBarTitleDisplayMode == .inline ? 15 : 0)
|
||||||
|
#else
|
||||||
|
.padding(.top, 15)
|
||||||
|
#endif
|
||||||
|
#if os(tvOS)
|
||||||
|
.padding(.horizontal, 40)
|
||||||
|
#else
|
||||||
|
.padding(.horizontal, 15)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if !accounts.current.isNil, showFavoritesInHome {
|
||||||
#if os(tvOS)
|
#if os(tvOS)
|
||||||
.padding(.horizontal, 40)
|
ForEach(Defaults[.favorites]) { item in
|
||||||
|
FavoriteItemView(item: item, dragging: $dragging)
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
.padding(.horizontal, 15)
|
ForEach(favorites) { item in
|
||||||
#endif
|
FavoriteItemView(item: item, dragging: $dragging)
|
||||||
|
#if os(macOS)
|
||||||
if !accounts.current.isNil, showFavoritesInHome {
|
.workaroundForVerticalScrollingBug()
|
||||||
#if os(tvOS)
|
|
||||||
ForEach(Defaults[.favorites]) { item in
|
|
||||||
FavoriteItemView(item: item, dragging: $dragging)
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
ForEach(favorites) { item in
|
|
||||||
FavoriteItemView(item: item, dragging: $dragging)
|
|
||||||
#if os(macOS)
|
|
||||||
.workaroundForVerticalScrollingBug()
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#if os(iOS)
|
|
||||||
if homeRecentDocumentsItems > 0 {
|
|
||||||
VStack {
|
|
||||||
HStack {
|
|
||||||
sectionLabel("Recent Documents")
|
|
||||||
|
|
||||||
Spacer()
|
|
||||||
|
|
||||||
Button {
|
|
||||||
recentDocumentsID = UUID()
|
|
||||||
} label: {
|
|
||||||
Label("Refresh", systemImage: "arrow.clockwise")
|
|
||||||
.font(.headline)
|
|
||||||
.labelStyle(.iconOnly)
|
|
||||||
.foregroundColor(.secondary)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RecentDocumentsView(limit: homeRecentDocumentsItems)
|
|
||||||
.id(recentDocumentsID)
|
|
||||||
}
|
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
|
||||||
#if os(tvOS)
|
|
||||||
.padding(.trailing, 40)
|
|
||||||
#else
|
|
||||||
.padding(.trailing, 15)
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
if homeHistoryItems > 0 {
|
#if os(iOS)
|
||||||
|
if homeRecentDocumentsItems > 0 {
|
||||||
VStack {
|
VStack {
|
||||||
HStack {
|
HStack {
|
||||||
sectionLabel("History")
|
sectionLabel("Recent Documents")
|
||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
|
|
||||||
Button {
|
Button {
|
||||||
navigation.presentAlert(
|
recentDocumentsID = UUID()
|
||||||
Alert(
|
|
||||||
title: Text("Are you sure you want to clear history of watched videos?"),
|
|
||||||
message: Text("It cannot be reverted"),
|
|
||||||
primaryButton: .destructive(Text("Clear All")) {
|
|
||||||
PlayerModel.shared.removeHistory()
|
|
||||||
historyID = UUID()
|
|
||||||
},
|
|
||||||
secondaryButton: .cancel()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
} label: {
|
} label: {
|
||||||
Label("Clear History", systemImage: "trash")
|
Label("Refresh", systemImage: "arrow.clockwise")
|
||||||
.font(.headline)
|
.font(.headline)
|
||||||
.labelStyle(.iconOnly)
|
.labelStyle(.iconOnly)
|
||||||
.foregroundColor(.secondary)
|
.foregroundColor(.secondary)
|
||||||
}
|
}
|
||||||
.buttonStyle(.plain)
|
|
||||||
}
|
}
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
|
||||||
#if os(tvOS)
|
|
||||||
.padding(.trailing, 40)
|
|
||||||
#else
|
|
||||||
.padding(.trailing, 15)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
HistoryView(limit: homeHistoryItems)
|
RecentDocumentsView(limit: homeRecentDocumentsItems)
|
||||||
.id(historyID)
|
.id(recentDocumentsID)
|
||||||
}
|
}
|
||||||
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
|
#if os(tvOS)
|
||||||
|
.padding(.trailing, 40)
|
||||||
|
#else
|
||||||
|
.padding(.trailing, 15)
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !os(tvOS)
|
if homeHistoryItems > 0 {
|
||||||
Color.clear.padding(.bottom, 60)
|
VStack {
|
||||||
#endif
|
HStack {
|
||||||
}
|
sectionLabel("History")
|
||||||
.onAppear {
|
Spacer()
|
||||||
Defaults.observe(.favorites) { _ in
|
Button {
|
||||||
favoritesChanged.toggle()
|
navigation.presentAlert(
|
||||||
|
Alert(
|
||||||
|
title: Text("Are you sure you want to clear history of watched videos?"),
|
||||||
|
message: Text("It cannot be reverted"),
|
||||||
|
primaryButton: .destructive(Text("Clear All")) {
|
||||||
|
PlayerModel.shared.removeHistory()
|
||||||
|
historyID = UUID()
|
||||||
|
},
|
||||||
|
secondaryButton: .cancel()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} label: {
|
||||||
|
Label("Clear History", systemImage: "trash")
|
||||||
|
.font(.headline)
|
||||||
|
.labelStyle(.iconOnly)
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
}
|
||||||
|
.buttonStyle(.plain)
|
||||||
|
}
|
||||||
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
|
#if os(tvOS)
|
||||||
|
.padding(.trailing, 40)
|
||||||
|
#else
|
||||||
|
.padding(.trailing, 15)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
HistoryView(limit: homeHistoryItems)
|
||||||
|
.id(historyID)
|
||||||
}
|
}
|
||||||
.tieToLifetime(of: accounts)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.redrawOn(change: favoritesChanged)
|
#if !os(tvOS)
|
||||||
|
Color.clear.padding(.bottom, 60)
|
||||||
#if os(tvOS)
|
|
||||||
.edgesIgnoringSafeArea(.horizontal)
|
|
||||||
#else
|
|
||||||
.navigationTitle("Home")
|
|
||||||
#endif
|
|
||||||
#if os(macOS)
|
|
||||||
.background(Color.secondaryBackground)
|
|
||||||
.frame(minWidth: 360)
|
|
||||||
#endif
|
|
||||||
#if os(iOS)
|
|
||||||
.navigationBarTitleDisplayMode(RefreshControl.navigationBarTitleDisplayMode)
|
|
||||||
#endif
|
|
||||||
#if !os(macOS)
|
|
||||||
.onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)) { _ in
|
|
||||||
favoritesChanged.toggle()
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
.onAppear {
|
||||||
|
Defaults.observe(.favorites) { _ in
|
||||||
|
favoritesChanged.toggle()
|
||||||
|
}
|
||||||
|
.tieToLifetime(of: accounts)
|
||||||
|
}
|
||||||
|
|
||||||
|
.redrawOn(change: favoritesChanged)
|
||||||
|
|
||||||
|
#if os(tvOS)
|
||||||
|
.edgesIgnoringSafeArea(.horizontal)
|
||||||
|
#else
|
||||||
|
.navigationTitle("Home")
|
||||||
|
#endif
|
||||||
|
#if os(macOS)
|
||||||
|
.background(Color.secondaryBackground)
|
||||||
|
.frame(minWidth: 360)
|
||||||
|
#endif
|
||||||
|
#if os(iOS)
|
||||||
|
.navigationBarTitleDisplayMode(RefreshControl.navigationBarTitleDisplayMode)
|
||||||
|
#endif
|
||||||
|
#if !os(macOS)
|
||||||
|
.onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)) { _ in
|
||||||
|
favoritesChanged.toggle()
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
func sectionLabel(_ label: String) -> some View {
|
func sectionLabel(_ label: String) -> some View {
|
||||||
|
9
Shared/Modifiers/PlayerOverlayModifier.swift
Normal file
9
Shared/Modifiers/PlayerOverlayModifier.swift
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import Foundation
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct PlayerOverlayModifier: ViewModifier {
|
||||||
|
func body(content: Content) -> some View {
|
||||||
|
content
|
||||||
|
.overlay(ControlsBar(fullScreen: .constant(false)), alignment: .bottom)
|
||||||
|
}
|
||||||
|
}
|
@ -42,15 +42,13 @@ struct AppSidebarNavigation: View {
|
|||||||
.frame(minWidth: sidebarMinWidth)
|
.frame(minWidth: sidebarMinWidth)
|
||||||
|
|
||||||
VStack {
|
VStack {
|
||||||
BrowserPlayerControls {
|
HStack {
|
||||||
HStack {
|
Spacer()
|
||||||
Spacer()
|
Image(systemName: "4k.tv")
|
||||||
Image(systemName: "4k.tv")
|
.renderingMode(.original)
|
||||||
.renderingMode(.original)
|
.font(.system(size: 60))
|
||||||
.font(.system(size: 60))
|
.foregroundColor(.accentColor)
|
||||||
.foregroundColor(.accentColor)
|
Spacer()
|
||||||
Spacer()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ struct AppSidebarPlaylists: View {
|
|||||||
Section(header: Text("Playlists")) {
|
Section(header: Text("Playlists")) {
|
||||||
ForEach(playlists.playlists.sorted { $0.title.lowercased() < $1.title.lowercased() }) { playlist in
|
ForEach(playlists.playlists.sorted { $0.title.lowercased() < $1.title.lowercased() }) { playlist in
|
||||||
NavigationLink(tag: TabSelection.playlist(playlist.id), selection: $navigation.tabSelection) {
|
NavigationLink(tag: TabSelection.playlist(playlist.id), selection: $navigation.tabSelection) {
|
||||||
LazyView(PlaylistVideosView(playlist))
|
LazyView(PlaylistVideosView(playlist).modifier(PlayerOverlayModifier()))
|
||||||
} label: {
|
} label: {
|
||||||
playlistLabel(playlist)
|
playlistLabel(playlist)
|
||||||
}
|
}
|
||||||
|
@ -16,17 +16,17 @@ struct AppSidebarRecents: View {
|
|||||||
switch recent.type {
|
switch recent.type {
|
||||||
case .channel:
|
case .channel:
|
||||||
RecentNavigationLink(recent: recent) {
|
RecentNavigationLink(recent: recent) {
|
||||||
LazyView(ChannelVideosView(channel: recent.channel!))
|
LazyView(ChannelVideosView(channel: recent.channel!).modifier(PlayerOverlayModifier()))
|
||||||
}
|
}
|
||||||
|
|
||||||
case .playlist:
|
case .playlist:
|
||||||
RecentNavigationLink(recent: recent, systemImage: "list.and.film") {
|
RecentNavigationLink(recent: recent, systemImage: "list.and.film") {
|
||||||
LazyView(ChannelPlaylistView(playlist: recent.playlist!))
|
LazyView(ChannelPlaylistView(playlist: recent.playlist!).modifier(PlayerOverlayModifier()))
|
||||||
}
|
}
|
||||||
|
|
||||||
case .query:
|
case .query:
|
||||||
RecentNavigationLink(recent: recent, systemImage: "magnifyingglass") {
|
RecentNavigationLink(recent: recent, systemImage: "magnifyingglass") {
|
||||||
LazyView(SearchView(recent.query!))
|
LazyView(SearchView(recent.query!).modifier(PlayerOverlayModifier()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ struct AppSidebarSubscriptions: View {
|
|||||||
Section(header: Text("Subscriptions")) {
|
Section(header: Text("Subscriptions")) {
|
||||||
ForEach(subscriptions.all) { channel in
|
ForEach(subscriptions.all) { channel in
|
||||||
NavigationLink(tag: TabSelection.channel(channel.id), selection: $navigation.tabSelection) {
|
NavigationLink(tag: TabSelection.channel(channel.id), selection: $navigation.tabSelection) {
|
||||||
LazyView(ChannelVideosView(channel: channel))
|
LazyView(ChannelVideosView(channel: channel).modifier(PlayerOverlayModifier()))
|
||||||
} label: {
|
} label: {
|
||||||
Label(channel.name, systemImage: RecentsModel.symbolSystemImage(channel.name))
|
Label(channel.name, systemImage: RecentsModel.symbolSystemImage(channel.name))
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ struct AppTabNavigation: View {
|
|||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
TabView(selection: navigation.tabSelectionBinding) {
|
TabView(selection: navigation.tabSelectionBinding) {
|
||||||
let tabs = Group {
|
Group {
|
||||||
if showHome {
|
if showHome {
|
||||||
homeNavigationView
|
homeNavigationView
|
||||||
}
|
}
|
||||||
@ -45,13 +45,7 @@ struct AppTabNavigation: View {
|
|||||||
searchNavigationView
|
searchNavigationView
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.overlay(ControlsBar(fullScreen: .constant(false)), alignment: .bottom)
|
||||||
if #available(iOS 16, tvOS 16, *) {
|
|
||||||
tabs
|
|
||||||
.toolbar(accounts.isEmpty ? .hidden : .visible, for: .tabBar)
|
|
||||||
} else {
|
|
||||||
tabs
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.id(accounts.current?.id ?? "")
|
.id(accounts.current?.id ?? "")
|
||||||
@ -196,3 +190,9 @@ struct AppTabNavigation: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct AppTabNavigation_Preview: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
AppTabNavigation()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -45,7 +45,7 @@ struct Sidebar: View {
|
|||||||
var mainNavigationLinks: some View {
|
var mainNavigationLinks: some View {
|
||||||
Section(header: Text("Videos")) {
|
Section(header: Text("Videos")) {
|
||||||
if showHome {
|
if showHome {
|
||||||
NavigationLink(destination: LazyView(HomeView()), tag: TabSelection.home, selection: $navigation.tabSelection) {
|
NavigationLink(destination: LazyView(HomeView().modifier(PlayerOverlayModifier())), tag: TabSelection.home, selection: $navigation.tabSelection) {
|
||||||
Label("Home", systemImage: "house")
|
Label("Home", systemImage: "house")
|
||||||
.accessibility(label: Text("Home"))
|
.accessibility(label: Text("Home"))
|
||||||
}
|
}
|
||||||
@ -54,7 +54,7 @@ struct Sidebar: View {
|
|||||||
|
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
if showDocuments {
|
if showDocuments {
|
||||||
NavigationLink(destination: LazyView(DocumentsView()), tag: TabSelection.documents, selection: $navigation.tabSelection) {
|
NavigationLink(destination: LazyView(DocumentsView().modifier(PlayerOverlayModifier())), tag: TabSelection.documents, selection: $navigation.tabSelection) {
|
||||||
Label("Documents", systemImage: "folder")
|
Label("Documents", systemImage: "folder")
|
||||||
.accessibility(label: Text("Documents"))
|
.accessibility(label: Text("Documents"))
|
||||||
}
|
}
|
||||||
@ -66,7 +66,7 @@ struct Sidebar: View {
|
|||||||
if visibleSections.contains(.subscriptions),
|
if visibleSections.contains(.subscriptions),
|
||||||
accounts.app.supportsSubscriptions && accounts.signedIn
|
accounts.app.supportsSubscriptions && accounts.signedIn
|
||||||
{
|
{
|
||||||
NavigationLink(destination: LazyView(SubscriptionsView()), tag: TabSelection.subscriptions, selection: $navigation.tabSelection) {
|
NavigationLink(destination: LazyView(SubscriptionsView().modifier(PlayerOverlayModifier())), tag: TabSelection.subscriptions, selection: $navigation.tabSelection) {
|
||||||
Label("Subscriptions", systemImage: "star.circle")
|
Label("Subscriptions", systemImage: "star.circle")
|
||||||
.accessibility(label: Text("Subscriptions"))
|
.accessibility(label: Text("Subscriptions"))
|
||||||
}
|
}
|
||||||
@ -74,7 +74,7 @@ struct Sidebar: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if visibleSections.contains(.popular), accounts.app.supportsPopular {
|
if visibleSections.contains(.popular), accounts.app.supportsPopular {
|
||||||
NavigationLink(destination: LazyView(PopularView()), tag: TabSelection.popular, selection: $navigation.tabSelection) {
|
NavigationLink(destination: LazyView(PopularView().modifier(PlayerOverlayModifier())), tag: TabSelection.popular, selection: $navigation.tabSelection) {
|
||||||
Label("Popular", systemImage: "arrow.up.right.circle")
|
Label("Popular", systemImage: "arrow.up.right.circle")
|
||||||
.accessibility(label: Text("Popular"))
|
.accessibility(label: Text("Popular"))
|
||||||
}
|
}
|
||||||
@ -82,14 +82,14 @@ struct Sidebar: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if visibleSections.contains(.trending) {
|
if visibleSections.contains(.trending) {
|
||||||
NavigationLink(destination: LazyView(TrendingView()), tag: TabSelection.trending, selection: $navigation.tabSelection) {
|
NavigationLink(destination: LazyView(TrendingView().modifier(PlayerOverlayModifier())), tag: TabSelection.trending, selection: $navigation.tabSelection) {
|
||||||
Label("Trending", systemImage: "chart.bar")
|
Label("Trending", systemImage: "chart.bar")
|
||||||
.accessibility(label: Text("Trending"))
|
.accessibility(label: Text("Trending"))
|
||||||
}
|
}
|
||||||
.id("trending")
|
.id("trending")
|
||||||
}
|
}
|
||||||
|
|
||||||
NavigationLink(destination: LazyView(SearchView()), tag: TabSelection.search, selection: $navigation.tabSelection) {
|
NavigationLink(destination: LazyView(SearchView().modifier(PlayerOverlayModifier())), tag: TabSelection.search, selection: $navigation.tabSelection) {
|
||||||
Label("Search", systemImage: "magnifyingglass")
|
Label("Search", systemImage: "magnifyingglass")
|
||||||
.accessibility(label: Text("Search"))
|
.accessibility(label: Text("Search"))
|
||||||
}
|
}
|
||||||
|
@ -56,30 +56,28 @@ struct PlaylistsView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
BrowserPlayerControls {
|
SignInRequiredView(title: "Playlists".localized()) {
|
||||||
SignInRequiredView(title: "Playlists".localized()) {
|
Section {
|
||||||
Section {
|
VStack {
|
||||||
VStack {
|
#if os(tvOS)
|
||||||
#if os(tvOS)
|
toolbar
|
||||||
toolbar
|
#endif
|
||||||
#endif
|
if currentPlaylist != nil, items.isEmpty {
|
||||||
if currentPlaylist != nil, items.isEmpty {
|
hintText("Playlist is empty\n\nTap and hold on a video and then \n\"Add to Playlist\"".localized())
|
||||||
hintText("Playlist is empty\n\nTap and hold on a video and then \n\"Add to Playlist\"".localized())
|
} else if model.all.isEmpty {
|
||||||
} else if model.all.isEmpty {
|
hintText("You have no playlists\n\nTap on \"New Playlist\" to create one".localized())
|
||||||
hintText("You have no playlists\n\nTap on \"New Playlist\" to create one".localized())
|
} else {
|
||||||
} else {
|
Group {
|
||||||
Group {
|
#if os(tvOS)
|
||||||
#if os(tvOS)
|
HorizontalCells(items: items)
|
||||||
HorizontalCells(items: items)
|
.padding(.top, 40)
|
||||||
.padding(.top, 40)
|
Spacer()
|
||||||
Spacer()
|
#else
|
||||||
#else
|
VerticalCells(items: items)
|
||||||
VerticalCells(items: items)
|
.environment(\.scrollViewBottomPadding, 70)
|
||||||
.environment(\.scrollViewBottomPadding, 70)
|
#endif
|
||||||
#endif
|
|
||||||
}
|
|
||||||
.environment(\.currentPlaylistID, currentPlaylist?.id)
|
|
||||||
}
|
}
|
||||||
|
.environment(\.currentPlaylistID, currentPlaylist?.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ struct SearchView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
BrowserPlayerControls {
|
VStack {
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
VStack {
|
VStack {
|
||||||
if accounts.app.supportsSearchSuggestions, state.query.query != state.queryText {
|
if accounts.app.supportsSearchSuggestions, state.query.query != state.queryText {
|
||||||
|
@ -10,47 +10,45 @@ struct SubscriptionsView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
BrowserPlayerControls {
|
SignInRequiredView(title: "Subscriptions".localized()) {
|
||||||
SignInRequiredView(title: "Subscriptions".localized()) {
|
VerticalCells(items: videos) {
|
||||||
VerticalCells(items: videos) {
|
HStack {
|
||||||
HStack {
|
Spacer()
|
||||||
Spacer()
|
|
||||||
|
|
||||||
CacheStatusHeader(refreshTime: model.formattedFeedTime, isLoading: model.isLoading)
|
CacheStatusHeader(refreshTime: model.formattedFeedTime, isLoading: model.isLoading)
|
||||||
|
|
||||||
#if os(tvOS)
|
#if os(tvOS)
|
||||||
Button {
|
Button {
|
||||||
model.loadResources(force: true)
|
model.loadResources(force: true)
|
||||||
} label: {
|
} label: {
|
||||||
Label("Refresh", systemImage: "arrow.clockwise")
|
Label("Refresh", systemImage: "arrow.clockwise")
|
||||||
.labelStyle(.iconOnly)
|
.labelStyle(.iconOnly)
|
||||||
.imageScale(.small)
|
.imageScale(.small)
|
||||||
.font(.caption2)
|
.font(.caption2)
|
||||||
}
|
}
|
||||||
.padding(.horizontal, 10)
|
.padding(.horizontal, 10)
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.environment(\.loadMoreContentHandler) { model.loadNextPage() }
|
|
||||||
.onAppear {
|
|
||||||
model.loadResources()
|
|
||||||
}
|
|
||||||
.onChange(of: accounts.current) { _ in
|
|
||||||
model.reset()
|
|
||||||
model.loadResources(force: true)
|
|
||||||
}
|
|
||||||
#if os(iOS)
|
|
||||||
.refreshControl { refreshControl in
|
|
||||||
model.loadResources(force: true) {
|
|
||||||
refreshControl.endRefreshing()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.backport
|
|
||||||
.refreshable {
|
|
||||||
await model.loadResources(force: true)
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
.environment(\.loadMoreContentHandler) { model.loadNextPage() }
|
||||||
|
.onAppear {
|
||||||
|
model.loadResources()
|
||||||
|
}
|
||||||
|
.onChange(of: accounts.current) { _ in
|
||||||
|
model.reset()
|
||||||
|
model.loadResources(force: true)
|
||||||
|
}
|
||||||
|
#if os(iOS)
|
||||||
|
.refreshControl { refreshControl in
|
||||||
|
model.loadResources(force: true) {
|
||||||
|
refreshControl.endRefreshing()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.backport
|
||||||
|
.refreshable {
|
||||||
|
await model.loadResources(force: true)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !os(tvOS)
|
#if !os(tvOS)
|
||||||
|
@ -33,20 +33,18 @@ struct TrendingView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
BrowserPlayerControls {
|
Section {
|
||||||
Section {
|
VStack(spacing: 0) {
|
||||||
VStack(spacing: 0) {
|
#if os(tvOS)
|
||||||
#if os(tvOS)
|
toolbar
|
||||||
toolbar
|
HorizontalCells(items: trending)
|
||||||
HorizontalCells(items: trending)
|
.padding(.top, 40)
|
||||||
.padding(.top, 40)
|
|
||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
#else
|
#else
|
||||||
VerticalCells(items: trending)
|
VerticalCells(items: trending)
|
||||||
.environment(\.scrollViewBottomPadding, 70)
|
.environment(\.scrollViewBottomPadding, 70)
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,79 +0,0 @@
|
|||||||
import Foundation
|
|
||||||
import SDWebImageSwiftUI
|
|
||||||
import SwiftUI
|
|
||||||
|
|
||||||
struct BrowserPlayerControls<Content: View, Toolbar: View>: View {
|
|
||||||
enum Context {
|
|
||||||
case browser, player
|
|
||||||
}
|
|
||||||
|
|
||||||
let content: Content
|
|
||||||
let toolbar: Toolbar?
|
|
||||||
|
|
||||||
init(
|
|
||||||
context _: Context? = nil,
|
|
||||||
@ViewBuilder toolbar: @escaping () -> Toolbar? = { nil },
|
|
||||||
@ViewBuilder content: @escaping () -> Content
|
|
||||||
) {
|
|
||||||
self.content = content()
|
|
||||||
self.toolbar = toolbar()
|
|
||||||
}
|
|
||||||
|
|
||||||
init(
|
|
||||||
context: Context? = nil,
|
|
||||||
@ViewBuilder content: @escaping () -> Content
|
|
||||||
) where Toolbar == EmptyView {
|
|
||||||
self.init(context: context, toolbar: { EmptyView() }, content: content)
|
|
||||||
}
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
#if os(tvOS)
|
|
||||||
return content
|
|
||||||
#else
|
|
||||||
// TODO: remove
|
|
||||||
#if DEBUG
|
|
||||||
if #available(iOS 15.0, macOS 12.0, *) {
|
|
||||||
Self._printChanges()
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return ZStack(alignment: .bottomLeading) {
|
|
||||||
content
|
|
||||||
.frame(maxHeight: .infinity)
|
|
||||||
|
|
||||||
#if !os(tvOS)
|
|
||||||
VStack(spacing: 0) {
|
|
||||||
#if os(iOS)
|
|
||||||
toolbar
|
|
||||||
.frame(height: 35)
|
|
||||||
.frame(maxWidth: .infinity)
|
|
||||||
.borderTop(height: 0.4, color: Color("ControlsBorderColor"))
|
|
||||||
.modifier(ControlBackgroundModifier())
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ControlsBar(fullScreen: .constant(false))
|
|
||||||
.edgesIgnoringSafeArea(.bottom)
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct PlayerControlsView_Previews: PreviewProvider {
|
|
||||||
static var previews: some View {
|
|
||||||
BrowserPlayerControls(context: .player, toolbar: {
|
|
||||||
Button("Button") {}
|
|
||||||
}) {
|
|
||||||
BrowserPlayerControls {
|
|
||||||
VStack {
|
|
||||||
Spacer()
|
|
||||||
TextField("A", text: .constant("abc"))
|
|
||||||
Spacer()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.offset(y: -100)
|
|
||||||
}
|
|
||||||
.injectFixtureEnvironmentObjects()
|
|
||||||
}
|
|
||||||
}
|
|
@ -38,14 +38,10 @@ struct ChannelPlaylistView: View {
|
|||||||
var body: some View {
|
var body: some View {
|
||||||
if navigationStyle == .tab {
|
if navigationStyle == .tab {
|
||||||
NavigationView {
|
NavigationView {
|
||||||
BrowserPlayerControls {
|
|
||||||
content
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
BrowserPlayerControls {
|
|
||||||
content
|
content
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
content
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,14 +42,10 @@ struct ChannelVideosView: View {
|
|||||||
var body: some View {
|
var body: some View {
|
||||||
if navigationStyle == .tab {
|
if navigationStyle == .tab {
|
||||||
NavigationView {
|
NavigationView {
|
||||||
BrowserPlayerControls {
|
|
||||||
content
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
BrowserPlayerControls {
|
|
||||||
content
|
content
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
content
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,39 +52,37 @@ struct PlaylistVideosView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
BrowserPlayerControls {
|
VerticalCells(items: contentItems)
|
||||||
VerticalCells(items: contentItems)
|
.onAppear {
|
||||||
.onAppear {
|
guard contentItems.isEmpty else { return }
|
||||||
guard contentItems.isEmpty else { return }
|
resource?.load()
|
||||||
resource?.load()
|
}
|
||||||
}
|
.onChange(of: model.reloadPlaylists) { _ in
|
||||||
.onChange(of: model.reloadPlaylists) { _ in
|
resource?.load()
|
||||||
resource?.load()
|
}
|
||||||
}
|
#if !os(tvOS)
|
||||||
#if !os(tvOS)
|
.navigationTitle("\(playlist.title) Playlist")
|
||||||
.navigationTitle("\(playlist.title) Playlist")
|
#endif
|
||||||
#endif
|
.toolbar {
|
||||||
}
|
ToolbarItem(placement: playlistButtonsPlacement) {
|
||||||
.toolbar {
|
HStack {
|
||||||
ToolbarItem(placement: playlistButtonsPlacement) {
|
FavoriteButton(item: FavoriteItem(section: .channelPlaylist(playlist.id, playlist.title)))
|
||||||
HStack {
|
|
||||||
FavoriteButton(item: FavoriteItem(section: .channelPlaylist(playlist.id, playlist.title)))
|
|
||||||
|
|
||||||
Button {
|
|
||||||
player.play(videos)
|
|
||||||
} label: {
|
|
||||||
Label("Play All", systemImage: "play")
|
|
||||||
}
|
|
||||||
.contextMenu {
|
|
||||||
Button {
|
Button {
|
||||||
player.play(videos, shuffling: true)
|
player.play(videos)
|
||||||
} label: {
|
} label: {
|
||||||
Label("Shuffle All", systemImage: "shuffle")
|
Label("Play All", systemImage: "play")
|
||||||
|
}
|
||||||
|
.contextMenu {
|
||||||
|
Button {
|
||||||
|
player.play(videos, shuffling: true)
|
||||||
|
} label: {
|
||||||
|
Label("Shuffle All", systemImage: "shuffle")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private var playlistButtonsPlacement: ToolbarItemPlacement {
|
private var playlistButtonsPlacement: ToolbarItemPlacement {
|
||||||
|
@ -15,24 +15,20 @@ struct PopularView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
BrowserPlayerControls {
|
VerticalCells(items: videos)
|
||||||
VerticalCells(items: videos)
|
.onAppear {
|
||||||
.onAppear {
|
resource?.addObserver(store)
|
||||||
resource?.addObserver(store)
|
resource?.loadIfNeeded()
|
||||||
resource?.loadIfNeeded()
|
|
||||||
}
|
|
||||||
#if !os(tvOS)
|
|
||||||
.navigationTitle("Popular")
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#if !os(tvOS)
|
|
||||||
.background(
|
|
||||||
Button("Refresh") {
|
|
||||||
resource?.load()
|
|
||||||
}
|
}
|
||||||
.keyboardShortcut("r")
|
#if !os(tvOS)
|
||||||
.opacity(0)
|
.navigationTitle("Popular")
|
||||||
)
|
.background(
|
||||||
|
Button("Refresh") {
|
||||||
|
resource?.load()
|
||||||
|
}
|
||||||
|
.keyboardShortcut("r")
|
||||||
|
.opacity(0)
|
||||||
|
)
|
||||||
#endif
|
#endif
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
.refreshControl { refreshControl in
|
.refreshControl { refreshControl in
|
||||||
|
@ -61,10 +61,8 @@ struct SignInRequiredView<Content: View>: View {
|
|||||||
|
|
||||||
struct SignInRequiredView_Previews: PreviewProvider {
|
struct SignInRequiredView_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
BrowserPlayerControls {
|
SignInRequiredView(title: "Subscriptions") {
|
||||||
SignInRequiredView(title: "Subscriptions") {
|
Text("Only when signed in")
|
||||||
Text("Only when signed in")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -754,6 +754,9 @@
|
|||||||
37C7A1D6267BFD9D0010EAD6 /* SponsorBlockSegment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37C7A1D4267BFD9D0010EAD6 /* SponsorBlockSegment.swift */; };
|
37C7A1D6267BFD9D0010EAD6 /* SponsorBlockSegment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37C7A1D4267BFD9D0010EAD6 /* SponsorBlockSegment.swift */; };
|
||||||
37C7A1D7267BFD9D0010EAD6 /* SponsorBlockSegment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37C7A1D4267BFD9D0010EAD6 /* SponsorBlockSegment.swift */; };
|
37C7A1D7267BFD9D0010EAD6 /* SponsorBlockSegment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37C7A1D4267BFD9D0010EAD6 /* SponsorBlockSegment.swift */; };
|
||||||
37C7A1DA267CACF50010EAD6 /* TrendingCountry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3705B17F267B4DFB00704544 /* TrendingCountry.swift */; };
|
37C7A1DA267CACF50010EAD6 /* TrendingCountry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3705B17F267B4DFB00704544 /* TrendingCountry.swift */; };
|
||||||
|
37C89322294532220032AFD3 /* PlayerOverlayModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37C89321294532220032AFD3 /* PlayerOverlayModifier.swift */; };
|
||||||
|
37C89323294532220032AFD3 /* PlayerOverlayModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37C89321294532220032AFD3 /* PlayerOverlayModifier.swift */; };
|
||||||
|
37C89324294532220032AFD3 /* PlayerOverlayModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37C89321294532220032AFD3 /* PlayerOverlayModifier.swift */; };
|
||||||
37CC3F45270CE30600608308 /* PlayerQueueItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37CC3F44270CE30600608308 /* PlayerQueueItem.swift */; };
|
37CC3F45270CE30600608308 /* PlayerQueueItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37CC3F44270CE30600608308 /* PlayerQueueItem.swift */; };
|
||||||
37CC3F46270CE30600608308 /* PlayerQueueItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37CC3F44270CE30600608308 /* PlayerQueueItem.swift */; };
|
37CC3F46270CE30600608308 /* PlayerQueueItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37CC3F44270CE30600608308 /* PlayerQueueItem.swift */; };
|
||||||
37CC3F47270CE30600608308 /* PlayerQueueItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37CC3F44270CE30600608308 /* PlayerQueueItem.swift */; };
|
37CC3F47270CE30600608308 /* PlayerQueueItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37CC3F44270CE30600608308 /* PlayerQueueItem.swift */; };
|
||||||
@ -820,9 +823,6 @@
|
|||||||
37E04C0F275940FB00172673 /* VerticalScrollingFix.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37E04C0E275940FB00172673 /* VerticalScrollingFix.swift */; };
|
37E04C0F275940FB00172673 /* VerticalScrollingFix.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37E04C0E275940FB00172673 /* VerticalScrollingFix.swift */; };
|
||||||
37E084AC2753D95F00039B7D /* AccountsNavigationLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37E084AB2753D95F00039B7D /* AccountsNavigationLink.swift */; };
|
37E084AC2753D95F00039B7D /* AccountsNavigationLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37E084AB2753D95F00039B7D /* AccountsNavigationLink.swift */; };
|
||||||
37E084AD2753D95F00039B7D /* AccountsNavigationLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37E084AB2753D95F00039B7D /* AccountsNavigationLink.swift */; };
|
37E084AD2753D95F00039B7D /* AccountsNavigationLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37E084AB2753D95F00039B7D /* AccountsNavigationLink.swift */; };
|
||||||
37E2EEAB270656EC00170416 /* BrowserPlayerControls.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37E2EEAA270656EC00170416 /* BrowserPlayerControls.swift */; };
|
|
||||||
37E2EEAC270656EC00170416 /* BrowserPlayerControls.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37E2EEAA270656EC00170416 /* BrowserPlayerControls.swift */; };
|
|
||||||
37E2EEAD270656EC00170416 /* BrowserPlayerControls.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37E2EEAA270656EC00170416 /* BrowserPlayerControls.swift */; };
|
|
||||||
37E64DD126D597EB00C71877 /* SubscriptionsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37E64DD026D597EB00C71877 /* SubscriptionsModel.swift */; };
|
37E64DD126D597EB00C71877 /* SubscriptionsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37E64DD026D597EB00C71877 /* SubscriptionsModel.swift */; };
|
||||||
37E64DD226D597EB00C71877 /* SubscriptionsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37E64DD026D597EB00C71877 /* SubscriptionsModel.swift */; };
|
37E64DD226D597EB00C71877 /* SubscriptionsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37E64DD026D597EB00C71877 /* SubscriptionsModel.swift */; };
|
||||||
37E64DD326D597EB00C71877 /* SubscriptionsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37E64DD026D597EB00C71877 /* SubscriptionsModel.swift */; };
|
37E64DD326D597EB00C71877 /* SubscriptionsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37E64DD026D597EB00C71877 /* SubscriptionsModel.swift */; };
|
||||||
@ -1324,6 +1324,7 @@
|
|||||||
37C3A24C272360470087A57A /* ChannelPlaylist+Fixtures.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ChannelPlaylist+Fixtures.swift"; sourceTree = "<group>"; };
|
37C3A24C272360470087A57A /* ChannelPlaylist+Fixtures.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ChannelPlaylist+Fixtures.swift"; sourceTree = "<group>"; };
|
||||||
37C3A250272366440087A57A /* ChannelPlaylistView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelPlaylistView.swift; sourceTree = "<group>"; };
|
37C3A250272366440087A57A /* ChannelPlaylistView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelPlaylistView.swift; sourceTree = "<group>"; };
|
||||||
37C7A1D4267BFD9D0010EAD6 /* SponsorBlockSegment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SponsorBlockSegment.swift; sourceTree = "<group>"; };
|
37C7A1D4267BFD9D0010EAD6 /* SponsorBlockSegment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SponsorBlockSegment.swift; sourceTree = "<group>"; };
|
||||||
|
37C89321294532220032AFD3 /* PlayerOverlayModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerOverlayModifier.swift; sourceTree = "<group>"; };
|
||||||
37CC3F44270CE30600608308 /* PlayerQueueItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerQueueItem.swift; sourceTree = "<group>"; };
|
37CC3F44270CE30600608308 /* PlayerQueueItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerQueueItem.swift; sourceTree = "<group>"; };
|
||||||
37CC3F4B270CFE1700608308 /* PlayerQueueView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerQueueView.swift; sourceTree = "<group>"; };
|
37CC3F4B270CFE1700608308 /* PlayerQueueView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerQueueView.swift; sourceTree = "<group>"; };
|
||||||
37CC3F4F270D010D00608308 /* VideoBanner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoBanner.swift; sourceTree = "<group>"; };
|
37CC3F4F270D010D00608308 /* VideoBanner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoBanner.swift; sourceTree = "<group>"; };
|
||||||
@ -1362,7 +1363,6 @@
|
|||||||
37DD9DC22785D63A00539416 /* UIResponder+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIResponder+Extensions.swift"; sourceTree = "<group>"; };
|
37DD9DC22785D63A00539416 /* UIResponder+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIResponder+Extensions.swift"; sourceTree = "<group>"; };
|
||||||
37E04C0E275940FB00172673 /* VerticalScrollingFix.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerticalScrollingFix.swift; sourceTree = "<group>"; };
|
37E04C0E275940FB00172673 /* VerticalScrollingFix.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerticalScrollingFix.swift; sourceTree = "<group>"; };
|
||||||
37E084AB2753D95F00039B7D /* AccountsNavigationLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountsNavigationLink.swift; sourceTree = "<group>"; };
|
37E084AB2753D95F00039B7D /* AccountsNavigationLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountsNavigationLink.swift; sourceTree = "<group>"; };
|
||||||
37E2EEAA270656EC00170416 /* BrowserPlayerControls.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrowserPlayerControls.swift; sourceTree = "<group>"; };
|
|
||||||
37E64DD026D597EB00C71877 /* SubscriptionsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionsModel.swift; sourceTree = "<group>"; };
|
37E64DD026D597EB00C71877 /* SubscriptionsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionsModel.swift; sourceTree = "<group>"; };
|
||||||
37E6D79B2944AE1A00550C3D /* SubscriptionsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionsViewModel.swift; sourceTree = "<group>"; };
|
37E6D79B2944AE1A00550C3D /* SubscriptionsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionsViewModel.swift; sourceTree = "<group>"; };
|
||||||
37E6D79F2944CD3800550C3D /* CacheStatusHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CacheStatusHeader.swift; sourceTree = "<group>"; };
|
37E6D79F2944CD3800550C3D /* CacheStatusHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CacheStatusHeader.swift; sourceTree = "<group>"; };
|
||||||
@ -1743,7 +1743,7 @@
|
|||||||
371AAE2826CEC7D900901972 /* Views */ = {
|
371AAE2826CEC7D900901972 /* Views */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
37E2EEAA270656EC00170416 /* BrowserPlayerControls.swift */,
|
37E6D79F2944CD3800550C3D /* CacheStatusHeader.swift */,
|
||||||
3743B86727216D3600261544 /* ChannelCell.swift */,
|
3743B86727216D3600261544 /* ChannelCell.swift */,
|
||||||
37C3A24827235FAA0087A57A /* ChannelPlaylistCell.swift */,
|
37C3A24827235FAA0087A57A /* ChannelPlaylistCell.swift */,
|
||||||
37C3A250272366440087A57A /* ChannelPlaylistView.swift */,
|
37C3A250272366440087A57A /* ChannelPlaylistView.swift */,
|
||||||
@ -1766,7 +1766,6 @@
|
|||||||
376B2E0626F920D600B1D64D /* SignInRequiredView.swift */,
|
376B2E0626F920D600B1D64D /* SignInRequiredView.swift */,
|
||||||
37B17D9F268A1F25006AEE9B /* VideoContextMenuView.swift */,
|
37B17D9F268A1F25006AEE9B /* VideoContextMenuView.swift */,
|
||||||
37E70922271CD43000D34DDE /* WelcomeScreen.swift */,
|
37E70922271CD43000D34DDE /* WelcomeScreen.swift */,
|
||||||
37E6D79F2944CD3800550C3D /* CacheStatusHeader.swift */,
|
|
||||||
);
|
);
|
||||||
path = Views;
|
path = Views;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -1987,8 +1986,9 @@
|
|||||||
3761AC0526F0F96100AA496F /* Modifiers */ = {
|
3761AC0526F0F96100AA496F /* Modifiers */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
37F64FE326FE70A60081B69E /* RedrawOnModifier.swift */,
|
|
||||||
37D2E0CF28B67DBC00F64D52 /* AnimationCompletionObserverModifier.swift */,
|
37D2E0CF28B67DBC00F64D52 /* AnimationCompletionObserverModifier.swift */,
|
||||||
|
37C89321294532220032AFD3 /* PlayerOverlayModifier.swift */,
|
||||||
|
37F64FE326FE70A60081B69E /* RedrawOnModifier.swift */,
|
||||||
);
|
);
|
||||||
path = Modifiers;
|
path = Modifiers;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -3014,6 +3014,7 @@
|
|||||||
37EAD86F267B9ED100D9E01B /* Segment.swift in Sources */,
|
37EAD86F267B9ED100D9E01B /* Segment.swift in Sources */,
|
||||||
375168D62700FAFF008F96A6 /* Debounce.swift in Sources */,
|
375168D62700FAFF008F96A6 /* Debounce.swift in Sources */,
|
||||||
37E64DD126D597EB00C71877 /* SubscriptionsModel.swift in Sources */,
|
37E64DD126D597EB00C71877 /* SubscriptionsModel.swift in Sources */,
|
||||||
|
37C89322294532220032AFD3 /* PlayerOverlayModifier.swift in Sources */,
|
||||||
376578892685471400D4EA09 /* Playlist.swift in Sources */,
|
376578892685471400D4EA09 /* Playlist.swift in Sources */,
|
||||||
37B4E803277D0A72004BF56A /* AppDelegate.swift in Sources */,
|
37B4E803277D0A72004BF56A /* AppDelegate.swift in Sources */,
|
||||||
37FD77002932C4DA00D91A5F /* URL+ByReplacingYatteeProtocol.swift in Sources */,
|
37FD77002932C4DA00D91A5F /* URL+ByReplacingYatteeProtocol.swift in Sources */,
|
||||||
@ -3031,7 +3032,6 @@
|
|||||||
37B044B726F7AB9000E1419D /* SettingsView.swift in Sources */,
|
37B044B726F7AB9000E1419D /* SettingsView.swift in Sources */,
|
||||||
377FC7E3267A084A00A6BBAF /* VideoCell.swift in Sources */,
|
377FC7E3267A084A00A6BBAF /* VideoCell.swift in Sources */,
|
||||||
37C3A251272366440087A57A /* ChannelPlaylistView.swift in Sources */,
|
37C3A251272366440087A57A /* ChannelPlaylistView.swift in Sources */,
|
||||||
37E2EEAB270656EC00170416 /* BrowserPlayerControls.swift in Sources */,
|
|
||||||
370B79CC286279BA0045DB77 /* UIViewController+HideHomeIndicator.swift in Sources */,
|
370B79CC286279BA0045DB77 /* UIViewController+HideHomeIndicator.swift in Sources */,
|
||||||
37E8B0EC27B326C00024006F /* TimelineView.swift in Sources */,
|
37E8B0EC27B326C00024006F /* TimelineView.swift in Sources */,
|
||||||
37494EA729200E0B000DF176 /* DocumentsModel.swift in Sources */,
|
37494EA729200E0B000DF176 /* DocumentsModel.swift in Sources */,
|
||||||
@ -3178,6 +3178,7 @@
|
|||||||
3738535529451DC800D2D0CB /* BookmarksCacheModel.swift in Sources */,
|
3738535529451DC800D2D0CB /* BookmarksCacheModel.swift in Sources */,
|
||||||
379F1420289ECE7F00DE48B5 /* QualitySettings.swift in Sources */,
|
379F1420289ECE7F00DE48B5 /* QualitySettings.swift in Sources */,
|
||||||
3751BA8027E64244007B1A60 /* VideoLayer.swift in Sources */,
|
3751BA8027E64244007B1A60 /* VideoLayer.swift in Sources */,
|
||||||
|
37C89323294532220032AFD3 /* PlayerOverlayModifier.swift in Sources */,
|
||||||
375EC96B289F232600751258 /* QualityProfilesModel.swift in Sources */,
|
375EC96B289F232600751258 /* QualityProfilesModel.swift in Sources */,
|
||||||
374C053627242D9F009BDDBE /* SponsorBlockSettings.swift in Sources */,
|
374C053627242D9F009BDDBE /* SponsorBlockSettings.swift in Sources */,
|
||||||
377FF890291A99580028EB0B /* HistoryView.swift in Sources */,
|
377FF890291A99580028EB0B /* HistoryView.swift in Sources */,
|
||||||
@ -3270,7 +3271,6 @@
|
|||||||
3751B4B327836902000B7DF4 /* SearchPage.swift in Sources */,
|
3751B4B327836902000B7DF4 /* SearchPage.swift in Sources */,
|
||||||
3782B9532755667600990149 /* String+Format.swift in Sources */,
|
3782B9532755667600990149 /* String+Format.swift in Sources */,
|
||||||
37635FE5291EA6CF00C11E79 /* OpenVideosButton.swift in Sources */,
|
37635FE5291EA6CF00C11E79 /* OpenVideosButton.swift in Sources */,
|
||||||
37E2EEAC270656EC00170416 /* BrowserPlayerControls.swift in Sources */,
|
|
||||||
3776ADD7287381240078EBC4 /* Captions.swift in Sources */,
|
3776ADD7287381240078EBC4 /* Captions.swift in Sources */,
|
||||||
37E70924271CD43000D34DDE /* WelcomeScreen.swift in Sources */,
|
37E70924271CD43000D34DDE /* WelcomeScreen.swift in Sources */,
|
||||||
37F5E8B7291BE9D0006C15F5 /* URLBookmarkModel.swift in Sources */,
|
37F5E8B7291BE9D0006C15F5 /* URLBookmarkModel.swift in Sources */,
|
||||||
@ -3547,6 +3547,7 @@
|
|||||||
37192D5928B179D60012EEDD /* ChaptersView.swift in Sources */,
|
37192D5928B179D60012EEDD /* ChaptersView.swift in Sources */,
|
||||||
37B767DD2677C3CA0098BAA8 /* PlayerModel.swift in Sources */,
|
37B767DD2677C3CA0098BAA8 /* PlayerModel.swift in Sources */,
|
||||||
373CFAF12697A78B003CB2C6 /* AddToPlaylistView.swift in Sources */,
|
373CFAF12697A78B003CB2C6 /* AddToPlaylistView.swift in Sources */,
|
||||||
|
37C89324294532220032AFD3 /* PlayerOverlayModifier.swift in Sources */,
|
||||||
3784CDE427772EE40055BBF2 /* Watch.swift in Sources */,
|
3784CDE427772EE40055BBF2 /* Watch.swift in Sources */,
|
||||||
3730D8A02712E2B70020ED53 /* NowPlayingView.swift in Sources */,
|
3730D8A02712E2B70020ED53 /* NowPlayingView.swift in Sources */,
|
||||||
37169AA42729D98A0011DE61 /* InstancesBridge.swift in Sources */,
|
37169AA42729D98A0011DE61 /* InstancesBridge.swift in Sources */,
|
||||||
@ -3589,7 +3590,6 @@
|
|||||||
378AE945274EF00A006A4EE1 /* Color+Background.swift in Sources */,
|
378AE945274EF00A006A4EE1 /* Color+Background.swift in Sources */,
|
||||||
3743CA54270F284F00E4D32B /* View+Borders.swift in Sources */,
|
3743CA54270F284F00E4D32B /* View+Borders.swift in Sources */,
|
||||||
371F2F1C269B43D300E4A7AB /* NavigationModel.swift in Sources */,
|
371F2F1C269B43D300E4A7AB /* NavigationModel.swift in Sources */,
|
||||||
37E2EEAD270656EC00170416 /* BrowserPlayerControls.swift in Sources */,
|
|
||||||
37BA794526DBA973002A0235 /* PlaylistsModel.swift in Sources */,
|
37BA794526DBA973002A0235 /* PlaylistsModel.swift in Sources */,
|
||||||
37B17DA0268A1F89006AEE9B /* VideoContextMenuView.swift in Sources */,
|
37B17DA0268A1F89006AEE9B /* VideoContextMenuView.swift in Sources */,
|
||||||
37BE0BD726A1D4A90092E2DB /* AppleAVPlayerViewController.swift in Sources */,
|
37BE0BD726A1D4A90092E2DB /* AppleAVPlayerViewController.swift in Sources */,
|
||||||
|
Loading…
Reference in New Issue
Block a user