Replace environment objects with observed objects

This commit is contained in:
Arkadiusz Fal
2022-11-24 21:36:05 +01:00
parent 23fa0968c6
commit 0d333b5583
102 changed files with 427 additions and 723 deletions

View File

@@ -11,9 +11,8 @@ struct FavoriteItemView: View {
@Default(.favorites) private var favorites
@Binding private var dragging: FavoriteItem?
@EnvironmentObject<AccountsModel> private var accounts
@EnvironmentObject<PlaylistsModel> private var playlists
@ObservedObject private var accounts = AccountsModel.shared
private var playlists = PlaylistsModel.shared
private var favoritesModel = FavoritesModel.shared
init(

View File

@@ -8,7 +8,7 @@ struct HistoryView: View {
@FetchRequest(sortDescriptors: [.init(key: "watchedAt", ascending: false)])
var watches: FetchedResults<Watch>
@EnvironmentObject<PlayerModel> private var player
@ObservedObject private var player = PlayerModel.shared
var body: some View {
LazyVStack {

View File

@@ -4,8 +4,7 @@ import SwiftUI
import UniformTypeIdentifiers
struct HomeView: View {
@EnvironmentObject<AccountsModel> private var accounts
@EnvironmentObject<PlaylistsModel> private var playlists
@ObservedObject private var accounts = AccountsModel.shared
@State private var dragging: FavoriteItem?
@State private var presentingEditFavorites = false

View File

@@ -12,7 +12,7 @@ struct MenuCommands: Commands {
private var openVideosMenu: some Commands {
CommandGroup(after: .newItem) {
Button("Open Videos...") { model.navigation?.presentingOpenVideos = true }
Button("Open Videos...") { NavigationModel.shared.presentingOpenVideos = true }
.keyboardShortcut("t")
}
}
@@ -33,7 +33,7 @@ struct MenuCommands: Commands {
Button("Popular") {
setTabSelection(.popular)
}
.disabled(!(model.accounts?.app.supportsPopular ?? false))
.disabled(!AccountsModel.shared.app.supportsPopular)
.keyboardShortcut("3")
Button("Trending") {
@@ -51,36 +51,30 @@ struct MenuCommands: Commands {
}
private func setTabSelection(_ tabSelection: NavigationModel.TabSelection) {
guard let navigation = model.navigation else {
return
}
navigation.sidebarSectionChanged.toggle()
navigation.tabSelection = tabSelection
NavigationModel.shared.sidebarSectionChanged.toggle()
NavigationModel.shared.tabSelection = tabSelection
}
private var subscriptionsDisabled: Bool {
!(
(model.accounts?.app.supportsSubscriptions ?? false) && model.accounts?.signedIn ?? false
)
!(AccountsModel.shared.app.supportsSubscriptions && AccountsModel.shared.signedIn)
}
private var playbackMenu: some Commands {
CommandMenu("Playback") {
Button((model.player?.isPlaying ?? true) ? "Pause" : "Play") {
model.player?.togglePlay()
Button((PlayerModel.shared.isPlaying) ? "Pause" : "Play") {
PlayerModel.shared.togglePlay()
}
.disabled(model.player?.currentItem.isNil ?? true)
.disabled(PlayerModel.shared.currentItem.isNil)
.keyboardShortcut("p")
Button("Play Next") {
model.player?.advanceToNextItem()
PlayerModel.shared.advanceToNextItem()
}
.disabled(model.player?.queue.isEmpty ?? true)
.disabled(PlayerModel.shared.queue.isEmpty)
.keyboardShortcut("s")
Button(togglePlayerLabel) {
model.player?.togglePlayer()
PlayerModel.shared.togglePlayer()
}
.keyboardShortcut("o")
}
@@ -90,7 +84,7 @@ struct MenuCommands: Commands {
#if os(macOS)
"Show Player"
#else
(model.player?.presentingPlayer ?? true) ? "Hide Player" : "Show Player"
PlayerModel.shared.presentingPlayer ? "Hide Player" : "Show Player"
#endif
}
}

View File

@@ -2,7 +2,7 @@ import Defaults
import SwiftUI
struct AccountsMenuView: View {
@EnvironmentObject<AccountsModel> private var model
@ObservedObject private var model = AccountsModel.shared
@Default(.accounts) private var accounts
@Default(.instances) private var instances

View File

@@ -5,20 +5,11 @@ import SwiftUI
#endif
struct AppSidebarNavigation: View {
@EnvironmentObject<AccountsModel> private var accounts
@EnvironmentObject<NavigationModel> private var navigation
@ObservedObject private var accounts = AccountsModel.shared
private var navigation: NavigationModel { .shared }
#if os(iOS)
@State private var didApplyPrimaryViewWorkAround = false
@EnvironmentObject<CommentsModel> private var comments
@EnvironmentObject<InstancesModel> private var instances
@EnvironmentObject<PlayerModel> private var player
@EnvironmentObject<PlaylistsModel> private var playlists
@EnvironmentObject<RecentsModel> private var recents
@EnvironmentObject<SearchModel> private var search
@EnvironmentObject<SubscriptionsModel> private var subscriptions
@EnvironmentObject<ThumbnailsModel> private var thumbnailsModel
#endif
@Default(.showOpenActionsToolbarItem) private var showOpenActionsToolbarItem

View File

@@ -1,9 +1,10 @@
import SwiftUI
struct AppSidebarPlaylists: View {
@EnvironmentObject<NavigationModel> private var navigation
@EnvironmentObject<PlayerModel> private var player
@EnvironmentObject<PlaylistsModel> private var playlists
@ObservedObject private var accounts = AccountsModel.shared
@ObservedObject private var navigation = NavigationModel.shared
private var player = PlayerModel.shared
@ObservedObject private var playlists = PlaylistsModel.shared
var body: some View {
Section(header: Text("Playlists")) {
@@ -35,7 +36,7 @@ struct AppSidebarPlaylists: View {
@ViewBuilder func playlistLabel(_ playlist: Playlist) -> some View {
let label = Label(playlist.title, systemImage: RecentsModel.symbolSystemImage(playlist.title))
if player.accounts.app.userPlaylistsEndpointIncludesVideos, !playlist.videos.isEmpty {
if accounts.app.userPlaylistsEndpointIncludesVideos, !playlist.videos.isEmpty {
label
.backport
.badge(Text("\(playlist.videos.count)"))

View File

@@ -2,7 +2,8 @@ import Defaults
import SwiftUI
struct AppSidebarRecents: View {
@EnvironmentObject<RecentsModel> private var recents
@ObservedObject private var navigation = NavigationModel.shared
var recents = RecentsModel.shared
@Default(.recentlyOpened) private var recentItems
@@ -47,8 +48,8 @@ struct AppSidebarRecents: View {
}
struct RecentNavigationLink<DestinationContent: View>: View {
@EnvironmentObject<NavigationModel> private var navigation
@EnvironmentObject<RecentsModel> private var recents
var recents = RecentsModel.shared
@ObservedObject private var navigation = NavigationModel.shared
var recent: RecentItem
var systemImage: String?

View File

@@ -2,8 +2,8 @@ import Defaults
import SwiftUI
struct AppSidebarSubscriptions: View {
@EnvironmentObject<NavigationModel> private var navigation
@EnvironmentObject<SubscriptionsModel> private var subscriptions
@ObservedObject private var navigation = NavigationModel.shared
@ObservedObject private var subscriptions = SubscriptionsModel.shared
var body: some View {
Section(header: Text("Subscriptions")) {

View File

@@ -2,16 +2,10 @@ import Defaults
import SwiftUI
struct AppTabNavigation: View {
@EnvironmentObject<AccountsModel> private var accounts
@EnvironmentObject<CommentsModel> private var comments
@EnvironmentObject<InstancesModel> private var instances
@EnvironmentObject<NavigationModel> private var navigation
@EnvironmentObject<PlayerModel> private var player
@EnvironmentObject<PlaylistsModel> private var playlists
@EnvironmentObject<RecentsModel> private var recents
@EnvironmentObject<SearchModel> private var search
@EnvironmentObject<SubscriptionsModel> private var subscriptions
@EnvironmentObject<ThumbnailsModel> private var thumbnailsModel
@ObservedObject private var accounts = AccountsModel.shared
@ObservedObject private var navigation = NavigationModel.shared
private var player = PlayerModel.shared
@ObservedObject private var subscriptions = SubscriptionsModel.shared
@Default(.showHome) private var showHome
@Default(.showDocuments) private var showDocuments
@@ -187,11 +181,6 @@ struct AppTabNavigation: View {
.environment(\.managedObjectContext, persistenceController.container.viewContext)
.environment(\.inChannelView, true)
.environment(\.navigationStyle, .tab)
.environmentObject(accounts)
.environmentObject(navigation)
.environmentObject(player)
.environmentObject(subscriptions)
.environmentObject(thumbnailsModel)
.id("channelVideos")
.zIndex(player.presentingPlayer ? -1 : 2)
.transition(.move(edge: .bottom))
@@ -202,11 +191,6 @@ struct AppTabNavigation: View {
if navigation.presentingPlaylist {
ChannelPlaylistView()
.environment(\.managedObjectContext, persistenceController.container.viewContext)
.environmentObject(accounts)
.environmentObject(navigation)
.environmentObject(player)
.environmentObject(subscriptions)
.environmentObject(thumbnailsModel)
.id("channelPlaylist")
.zIndex(player.presentingPlayer ? -1 : 1)
.transition(.move(edge: .bottom))

View File

@@ -8,19 +8,11 @@ import Siesta
import SwiftUI
struct ContentView: View {
@EnvironmentObject<AccountsModel> private var accounts
@EnvironmentObject<CommentsModel> private var comments
@EnvironmentObject<InstancesModel> private var instances
@EnvironmentObject<NavigationModel> private var navigation
@EnvironmentObject<PlayerModel> private var player
@EnvironmentObject<PlaylistsModel> private var playlists
@EnvironmentObject<RecentsModel> private var recents
@EnvironmentObject<SearchModel> private var search
@EnvironmentObject<SettingsModel> private var settings
@EnvironmentObject<SubscriptionsModel> private var subscriptions
@EnvironmentObject<ThumbnailsModel> private var thumbnailsModel
@EnvironmentObject<MenuModel> private var menu
@ObservedObject private var accounts = AccountsModel.shared
@ObservedObject private var navigation = NavigationModel.shared
@ObservedObject private var player = PlayerModel.shared
private var playlists = PlaylistsModel.shared
private var subscriptions = SubscriptionsModel.shared
#if os(iOS)
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
@@ -44,7 +36,6 @@ struct ContentView: View {
AppSidebarNavigation()
#elseif os(tvOS)
TVNavigationView()
.environmentObject(settings)
#endif
}
.onChange(of: accounts.current) { _ in
@@ -55,99 +46,74 @@ struct ContentView: View {
subscriptions.load(force: true)
playlists.load(force: true)
}
.environmentObject(accounts)
.environmentObject(comments)
.environmentObject(instances)
.environmentObject(navigation)
.environmentObject(player)
.environmentObject(playlists)
.environmentObject(recents)
.environmentObject(search)
.environmentObject(subscriptions)
.environmentObject(thumbnailsModel)
#if os(iOS)
.overlay(videoPlayer)
.sheet(isPresented: $navigation.presentingShareSheet) {
if let shareURL = navigation.shareURL {
ShareSheet(activityItems: [shareURL])
}
.overlay(videoPlayer)
.sheet(isPresented: $navigation.presentingShareSheet) {
if let shareURL = navigation.shareURL {
ShareSheet(activityItems: [shareURL])
}
}
#endif
// iOS 14 has problem with multiple sheets in one view
// but it's ok when it's in background
.background(
EmptyView().sheet(isPresented: $navigation.presentingWelcomeScreen) {
WelcomeScreen()
.environmentObject(accounts)
.environmentObject(navigation)
}
)
.background(
EmptyView().sheet(isPresented: $navigation.presentingSettings) {
SettingsView()
.environmentObject(accounts)
.environmentObject(instances)
.environmentObject(settings)
.environmentObject(navigation)
.environmentObject(player)
}
)
// iOS 14 has problem with multiple sheets in one view
// but it's ok when it's in background
.background(
EmptyView().sheet(isPresented: $navigation.presentingWelcomeScreen) {
WelcomeScreen()
}
)
.background(
EmptyView().sheet(isPresented: $navigation.presentingSettings) {
SettingsView()
}
)
#if !os(tvOS)
.fileImporter(
isPresented: $navigation.presentingFileImporter,
allowedContentTypes: [.audiovisualContent],
allowsMultipleSelection: true
) { result in
do {
let selectedFiles = try result.get()
let urlsToOpen = selectedFiles.map { url in
if let bookmarkURL = URLBookmarkModel.shared.loadBookmark(url) {
return bookmarkURL
}
if url.startAccessingSecurityScopedResource() {
URLBookmarkModel.shared.saveBookmark(url)
}
return url
.fileImporter(
isPresented: $navigation.presentingFileImporter,
allowedContentTypes: [.audiovisualContent],
allowsMultipleSelection: true
) { result in
do {
let selectedFiles = try result.get()
let urlsToOpen = selectedFiles.map { url in
if let bookmarkURL = URLBookmarkModel.shared.loadBookmark(url) {
return bookmarkURL
}
OpenVideosModel.shared.openURLs(urlsToOpen)
} catch {
NavigationModel.shared.presentAlert(title: "Could not open Files")
if url.startAccessingSecurityScopedResource() {
URLBookmarkModel.shared.saveBookmark(url)
}
return url
}
NavigationModel.shared.presentingOpenVideos = false
OpenVideosModel.shared.openURLs(urlsToOpen)
} catch {
NavigationModel.shared.presentAlert(title: "Could not open Files")
}
.onOpenURL(perform: OpenURLHandler.shared.handle)
.background(
EmptyView().sheet(isPresented: $navigation.presentingAddToPlaylist) {
AddToPlaylistView(video: navigation.videoToAddToPlaylist)
.environmentObject(playlists)
}
)
.background(
EmptyView().sheet(isPresented: $navigation.presentingPlaylistForm) {
PlaylistFormView(playlist: $navigation.editedPlaylist)
.environmentObject(accounts)
.environmentObject(playlists)
}
)
NavigationModel.shared.presentingOpenVideos = false
}
.onOpenURL(perform: OpenURLHandler.shared.handle)
.background(
EmptyView().sheet(isPresented: $navigation.presentingAddToPlaylist) {
AddToPlaylistView(video: navigation.videoToAddToPlaylist)
}
)
.background(
EmptyView().sheet(isPresented: $navigation.presentingPlaylistForm) {
PlaylistFormView(playlist: $navigation.editedPlaylist)
}
)
#endif
.background(
EmptyView().sheet(isPresented: $navigation.presentingOpenVideos) {
OpenVideosView()
.environmentObject(accounts)
.environmentObject(navigation)
.environmentObject(player)
.environmentObject(recents)
.environmentObject(search)
}
)
.background(playerViewInitialize)
.alert(isPresented: $navigation.presentingAlert) { navigation.alert }
.background(
EmptyView().sheet(isPresented: $navigation.presentingOpenVideos) {
OpenVideosView()
}
)
.background(playerViewInitialize)
.alert(isPresented: $navigation.presentingAlert) { navigation.alert }
}
var navigationStyle: NavigationStyle {
@@ -174,16 +140,6 @@ struct ContentView: View {
var playerView: some View {
VideoPlayerView()
.environmentObject(accounts)
.environmentObject(comments)
.environmentObject(instances)
.environmentObject(navigation)
.environmentObject(player)
.environmentObject(playerControls)
.environmentObject(playlists)
.environmentObject(recents)
.environmentObject(subscriptions)
.environmentObject(thumbnailsModel)
.environment(\.navigationStyle, navigationStyle)
}

View File

@@ -2,8 +2,8 @@ import Defaults
import SwiftUI
struct Sidebar: View {
@EnvironmentObject<AccountsModel> private var accounts
@EnvironmentObject<NavigationModel> private var navigation
@ObservedObject private var accounts = AccountsModel.shared
@ObservedObject private var navigation = NavigationModel.shared
@Default(.showHome) private var showHome
@Default(.visibleSections) private var visibleSections

View File

@@ -7,11 +7,11 @@ struct OpenURLHandler {
static var shared = OpenURLHandler()
static let yatteeProtocol = "yattee://"
var accounts: AccountsModel!
var navigation: NavigationModel!
var recents: RecentsModel!
var player: PlayerModel!
var search: SearchModel!
var accounts: AccountsModel { .shared }
var navigation: NavigationModel { .shared }
var recents: RecentsModel { .shared }
var player: PlayerModel { .shared }
var search: SearchModel { .shared }
var navigationStyle = NavigationStyle.sidebar
func handle(_ url: URL) {
@@ -162,11 +162,8 @@ struct OpenURLHandler {
if var playlist: ChannelPlaylist = response.typedContent() {
playlist.id = playlistID
DispatchQueue.main.async {
NavigationModel.openChannelPlaylist(
NavigationModel.shared.openChannelPlaylist(
playlist,
player: player,
recents: recents,
navigation: navigation,
navigationStyle: navigationStyle
)
}
@@ -194,11 +191,8 @@ struct OpenURLHandler {
.onSuccess { response in
if let channel: Channel = response.typedContent() {
DispatchQueue.main.async {
NavigationModel.openChannel(
NavigationModel.shared.openChannel(
channel,
player: player,
recents: recents,
navigation: navigation,
navigationStyle: navigationStyle
)
}
@@ -228,7 +222,7 @@ struct OpenURLHandler {
return accounts.api.channelByName(name)
}
if let instance = InstancesModel.all.first(where: { $0.app.supportsOpeningChannelsByName }) {
if let instance = InstancesModel.shared.all.first(where: { $0.app.supportsOpeningChannelsByName }) {
return instance.anonymous.channelByName(name)
}
@@ -242,7 +236,7 @@ struct OpenURLHandler {
return accounts.api.channelByUsername(username)
}
if let instance = InstancesModel.all.first(where: { $0.app.supportsOpeningChannelsByName }) {
if let instance = InstancesModel.shared.all.first(where: { $0.app.supportsOpeningChannelsByName }) {
return instance.anonymous.channelByUsername(username)
}
@@ -254,13 +248,7 @@ struct OpenURLHandler {
if alertIfNoMainWindowOpen() { return }
#endif
NavigationModel.openSearchQuery(
parser.searchQuery,
player: player,
recents: recents,
navigation: navigation,
search: search
)
NavigationModel.shared.openSearchQuery(parser.searchQuery)
#if os(macOS)
focusMainWindow()

View File

@@ -4,11 +4,8 @@ import SwiftUI
#if os(iOS)
struct AppleAVPlayerView: UIViewRepresentable {
@EnvironmentObject<PlayerModel> private var player
func makeUIView(context _: Context) -> some UIView {
let playerLayerView = PlayerLayerView(frame: .zero)
playerLayerView.player = player
return playerLayerView
}
@@ -16,30 +13,15 @@ import SwiftUI
}
#else
struct AppleAVPlayerView: UIViewControllerRepresentable {
@EnvironmentObject<AccountsModel> private var accounts
@EnvironmentObject<CommentsModel> private var comments
@EnvironmentObject<NavigationModel> private var navigation
@EnvironmentObject<PlayerModel> private var player
@EnvironmentObject<PlaylistsModel> private var playlists
@EnvironmentObject<SubscriptionsModel> private var subscriptions
func makeUIViewController(context _: Context) -> AppleAVPlayerViewController {
let controller = AppleAVPlayerViewController()
controller.accountsModel = accounts
controller.commentsModel = comments
controller.navigationModel = navigation
controller.playerModel = player
controller.playlistsModel = playlists
controller.subscriptionsModel = subscriptions
player.avPlayerBackend.controller = controller
PlayerModel.shared.avPlayerBackend.controller = controller
return controller
}
func updateUIViewController(_: AppleAVPlayerViewController, context _: Context) {
player.rebuildTVMenu()
PlayerModel.shared.rebuildTVMenu()
}
}
#endif

View File

@@ -4,12 +4,11 @@ import SwiftUI
final class AppleAVPlayerViewController: UIViewController {
var playerLoaded = false
var accountsModel: AccountsModel!
var commentsModel: CommentsModel!
var navigationModel: NavigationModel!
var playerModel: PlayerModel!
var playlistsModel: PlaylistsModel!
var subscriptionsModel: SubscriptionsModel!
var accountsModel: AccountsModel { .shared }
var navigationModel: NavigationModel { .shared }
var playerModel: PlayerModel { .shared }
var playlistsModel: PlaylistsModel { .shared }
var subscriptionsModel: SubscriptionsModel { .shared }
var playerView = AVPlayerViewController()
let persistenceController = PersistenceController.shared
@@ -66,12 +65,6 @@ final class AppleAVPlayerViewController: UIViewController {
AnyView(
NowPlayingView(sections: sections, inInfoViewController: true)
.frame(maxHeight: 600)
.environmentObject(accountsModel)
.environmentObject(commentsModel)
.environmentObject(navigationModel)
.environmentObject(playerModel)
.environmentObject(playlistsModel)
.environmentObject(subscriptionsModel)
.environment(\.managedObjectContext, persistenceController.container.viewContext)
)
)

View File

@@ -2,8 +2,8 @@ import Defaults
import SwiftUI
struct ControlsOverlay: View {
@EnvironmentObject<PlayerModel> private var player
@EnvironmentObject<PlayerControlsModel> private var model
@ObservedObject private var player = PlayerModel.shared
private var model = PlayerControlsModel.shared
@State private var contentSize: CGSize = .zero
@@ -399,8 +399,5 @@ struct ControlsOverlay: View {
struct ControlsOverlay_Previews: PreviewProvider {
static var previews: some View {
ControlsOverlay()
.environmentObject(NetworkStateModel())
.environmentObject(PlayerModel())
.environmentObject(PlayerControlsModel())
}
}

View File

@@ -10,7 +10,7 @@ struct Buffering: View {
@Environment(\.verticalSizeClass) private var verticalSizeClass
#endif
@EnvironmentObject<PlayerModel> private var player
@ObservedObject private var player = PlayerModel.shared
@Default(.playerControlsLayout) private var regularPlayerControlsLayout
@Default(.fullScreenPlayerControlsLayout) private var fullScreenPlayerControlsLayout

View File

@@ -15,7 +15,5 @@ struct NetworkState_Previews: PreviewProvider {
networkState.bufferingState = 30
return NetworkState()
.environmentObject(networkState)
.environmentObject(PlayerModel())
}
}

View File

@@ -1,8 +1,8 @@
import SwiftUI
struct OpeningStream: View {
@EnvironmentObject<PlayerModel> private var player
@EnvironmentObject<NetworkStateModel> private var model
@ObservedObject private var player = PlayerModel.shared
@ObservedObject private var model = NetworkStateModel.shared
var body: some View {
Buffering(reason: reason, state: state)

View File

@@ -6,7 +6,7 @@ struct Seek: View {
@Environment(\.verticalSizeClass) private var verticalSizeClass
#endif
@EnvironmentObject<PlayerControlsModel> private var controls
@ObservedObject private var controls = PlayerControlsModel.shared
@StateObject private var model = SeekModel.shared
private var updateThrottle = Throttle(interval: 2)
@@ -137,6 +137,5 @@ struct Seek: View {
struct Seek_Previews: PreviewProvider {
static var previews: some View {
Seek()
.environmentObject(PlayerTimeModel())
}
}

View File

@@ -6,8 +6,8 @@ import SwiftUI
struct PlayerControls: View {
static let animation = Animation.easeInOut(duration: 0.2)
private var player: PlayerModel!
private var thumbnails: ThumbnailsModel!
private var player: PlayerModel { .shared }
private var thumbnails: ThumbnailsModel { .shared }
@ObservedObject private var model = PlayerControlsModel.shared
@@ -39,11 +39,6 @@ struct PlayerControls: View {
player.playingFullScreen ? fullScreenPlayerControlsLayout : regularPlayerControlsLayout
}
init(player: PlayerModel, thumbnails: ThumbnailsModel) {
self.player = player
self.thumbnails = thumbnails
}
var body: some View {
ZStack(alignment: .topLeading) {
Seek()
@@ -206,12 +201,12 @@ struct PlayerControls: View {
}
var detailsWidth: Double {
guard let player, player.playerSize.width.isFinite else { return 200 }
guard player.playerSize.width.isFinite else { return 200 }
return [player.playerSize.width, 600].min()!
}
var detailsHeight: Double {
guard let player, player.playerSize.height.isFinite else { return 200 }
guard player.playerSize.height.isFinite else { return 200 }
var inset = 0.0
#if os(iOS)
inset = SafeArea.insets.bottom
@@ -499,7 +494,7 @@ struct PlayerControls_Previews: PreviewProvider {
ZStack {
Color.gray
PlayerControls(player: PlayerModel(), thumbnails: ThumbnailsModel())
PlayerControls()
.injectFixtureEnvironmentObjects()
}
}

View File

@@ -3,8 +3,8 @@ import SwiftUI
struct TVControls: UIViewRepresentable {
var model: PlayerControlsModel!
var player: PlayerModel!
var thumbnails: ThumbnailsModel!
var player: PlayerModel { .shared }
var thumbnails: ThumbnailsModel { .shared }
@State private var direction = ""
@State private var controlsArea = UIView()
@@ -30,7 +30,7 @@ struct TVControls: UIViewRepresentable {
controlsArea.addGestureRecognizer(downSwipe)
controlsArea.addGestureRecognizer(tap)
let controls = UIHostingController(rootView: PlayerControls(player: player, thumbnails: thumbnails))
let controls = UIHostingController(rootView: PlayerControls())
controls.view.frame = .init(
origin: .init(x: SafeArea.insets.left, y: SafeArea.insets.top),
size: .init(

View File

@@ -45,9 +45,9 @@ struct TimelineView: View {
#endif
@ObservedObject private var playerTime = PlayerTimeModel.shared
@ObservedObject private var player = PlayerModel.shared
@EnvironmentObject<PlayerModel> private var player
@EnvironmentObject<PlayerControlsModel> private var controls
private var controls = PlayerControlsModel.shared
@Default(.playerControlsLayout) private var regularPlayerControlsLayout
@Default(.fullScreenPlayerControlsLayout) private var fullScreenPlayerControlsLayout
@@ -124,6 +124,8 @@ struct TimelineView: View {
.frame(minWidth: 35)
.padding(.leading, playerControlsLayout.timeLeadingEdgePadding)
.padding(.trailing, playerControlsLayout.timeTrailingEdgePadding)
.modifier(ControlBackgroundModifier())
.clipShape(RoundedRectangle(cornerRadius: 4))
ZStack(alignment: .center) {
ZStack(alignment: .leading) {
@@ -172,6 +174,8 @@ struct TimelineView: View {
.padding(.leading, playerControlsLayout.timeTrailingEdgePadding)
.padding(.trailing, playerControlsLayout.timeLeadingEdgePadding)
.frame(minWidth: 30, alignment: .trailing)
.modifier(ControlBackgroundModifier())
.clipShape(RoundedRectangle(cornerRadius: 4))
}
#if !os(tvOS)
.highPriorityGesture(
@@ -207,8 +211,6 @@ struct TimelineView: View {
}
)
#endif
.modifier(ControlBackgroundModifier())
.clipShape(RoundedRectangle(cornerRadius: 4))
.font(.system(size: playerControlsLayout.timeFontSize).monospacedDigit())
.zIndex(2)
}
@@ -369,14 +371,11 @@ struct TimelineView_Previews: PreviewProvider {
let playerModel = PlayerModel()
playerModel.currentItem = .init(Video.fixture)
let playerTimeModel = PlayerTimeModel.shared
playerTimeModel.player = playerModel
playerTimeModel.currentTime = .secondsInDefaultTimescale(33)
playerTimeModel.duration = .secondsInDefaultTimescale(100)
return VStack(spacing: 40) {
TimelineView()
}
.environmentObject(playerModel)
.environmentObject(PlayerControlsModel())
.padding()
}
}

View File

@@ -2,7 +2,7 @@ import Defaults
import SwiftUI
struct VideoDetailsOverlay: View {
@EnvironmentObject<PlayerControlsModel> private var controls
@ObservedObject private var controls = PlayerControlsModel.shared
@State private var detailsPage = VideoDetails.DetailsPage.queue

View File

@@ -4,8 +4,7 @@ struct PlayerBackendView: View {
#if os(iOS)
@Environment(\.verticalSizeClass) private var verticalSizeClass
#endif
@EnvironmentObject<PlayerModel> private var player
@EnvironmentObject<ThumbnailsModel> private var thumbnails
@ObservedObject private var player = PlayerModel.shared
var body: some View {
ZStack(alignment: .top) {
@@ -29,7 +28,7 @@ struct PlayerBackendView: View {
#if !os(tvOS)
PlayerGestures()
PlayerControls(player: player, thumbnails: thumbnails)
PlayerControls()
#if os(iOS)
.padding(.top, controlsTopPadding)
.padding(.bottom, controlsBottomPadding)

View File

@@ -1,8 +1,8 @@
import SwiftUI
struct PlayerGestures: View {
@EnvironmentObject<PlayerModel> private var player
@EnvironmentObject<PlayerControlsModel> private var model
private var player = PlayerModel.shared
@ObservedObject private var model = PlayerControlsModel.shared
var body: some View {
HStack(spacing: 0) {

View File

@@ -8,7 +8,7 @@ import Foundation
#if os(macOS)
final class PlayerLayerView: NSView {
var player: PlayerModel! { didSet {
var player = PlayerModel.shared { didSet {
wantsLayer = true
}}
@@ -26,7 +26,7 @@ import Foundation
}
#else
final class PlayerLayerView: UIView {
var player: PlayerModel!
var player: PlayerModel { .shared }
override init(frame: CGRect) {
super.init(frame: frame)

View File

@@ -9,7 +9,7 @@ struct PlayerQueueRow: View {
var autoplay = false
@Binding var fullScreen: Bool
@EnvironmentObject<PlayerModel> private var player
private var player = PlayerModel.shared
@Default(.closePiPOnNavigation) var closePiPOnNavigation

View File

@@ -2,10 +2,7 @@ import Defaults
import SwiftUI
struct RelatedView: View {
@EnvironmentObject<AccountsModel> private var accounts
@EnvironmentObject<NavigationModel> private var navigation
@EnvironmentObject<PlayerModel> private var player
@EnvironmentObject<PlaylistsModel> private var playlists
@ObservedObject private var player = PlayerModel.shared
var body: some View {
List {

View File

@@ -9,7 +9,7 @@ struct StreamControl: View {
}
#endif
@EnvironmentObject<PlayerModel> private var player
@ObservedObject private var player = PlayerModel.shared
var body: some View {
Group {

View File

@@ -5,7 +5,7 @@ import SwiftUI
struct ChapterView: View {
var chapter: Chapter
@EnvironmentObject<PlayerModel> private var player
var player = PlayerModel.shared
var body: some View {
Button {

View File

@@ -3,7 +3,7 @@ import SDWebImageSwiftUI
import SwiftUI
struct ChaptersView: View {
@EnvironmentObject<PlayerModel> private var player
@ObservedObject private var player = PlayerModel.shared
var body: some View {
if let chapters = player.currentVideo?.chapters, !chapters.isEmpty {

View File

@@ -14,11 +14,8 @@ struct CommentView: View {
@Environment(\.colorScheme) private var colorScheme
@Environment(\.navigationStyle) private var navigationStyle
@EnvironmentObject<CommentsModel> private var comments
@EnvironmentObject<NavigationModel> private var navigation
@EnvironmentObject<PlayerModel> private var player
@EnvironmentObject<RecentsModel> private var recents
@EnvironmentObject<SubscriptionsModel> private var subscriptions
@ObservedObject private var comments = CommentsModel.shared
var subscriptions = SubscriptionsModel.shared
var body: some View {
VStack(alignment: .leading) {
@@ -252,11 +249,8 @@ struct CommentView: View {
}
private func openChannelAction() {
NavigationModel.openChannel(
NavigationModel.shared.openChannel(
comment.channel,
player: player,
recents: recents,
navigation: navigation,
navigationStyle: navigationStyle
)
}
@@ -269,7 +263,6 @@ struct CommentView_Previews: PreviewProvider {
static var previews: some View {
CommentView(comment: fixture, repliesID: .constant(fixture.id))
.environmentObject(SubscriptionsModel())
.padding(5)
}
}

View File

@@ -4,7 +4,7 @@ struct CommentsView: View {
var embedInScrollView = false
@State private var repliesID: Comment.ID?
@EnvironmentObject<CommentsModel> private var comments
@ObservedObject private var comments = CommentsModel.shared
var body: some View {
Group {

View File

@@ -3,7 +3,7 @@ import SwiftUI
struct InspectorView: View {
var video: Video?
@EnvironmentObject<PlayerModel> private var player
@ObservedObject private var player = PlayerModel.shared
var body: some View {
ScrollView {

View File

@@ -9,10 +9,7 @@ struct PlayerQueueView: View {
@FetchRequest(sortDescriptors: [.init(key: "watchedAt", ascending: false)])
var watches: FetchedResults<Watch>
@EnvironmentObject<AccountsModel> private var accounts
@EnvironmentObject<NavigationModel> private var navigation
@EnvironmentObject<PlaylistsModel> private var playlists
@EnvironmentObject<PlayerModel> private var player
@ObservedObject private var player = PlayerModel.shared
@Default(.saveHistory) private var saveHistory

View File

@@ -2,10 +2,10 @@ import Defaults
import SwiftUI
struct VideoActions: View {
@EnvironmentObject<AccountsModel> private var accounts
@EnvironmentObject<NavigationModel> private var navigation
@EnvironmentObject<SubscriptionsModel> private var subscriptions
@EnvironmentObject<PlayerModel> private var player
@ObservedObject private var accounts = AccountsModel.shared
var navigation = NavigationModel.shared
@ObservedObject private var subscriptions = SubscriptionsModel.shared
@ObservedObject private var player = PlayerModel.shared
var video: Video?

View File

@@ -6,10 +6,7 @@ import Foundation
import SwiftUI
struct VideoDescription: View {
@EnvironmentObject<NavigationModel> private var navigation
@EnvironmentObject<PlayerModel> private var player
@EnvironmentObject<RecentsModel> private var recents
@EnvironmentObject<SearchModel> private var search
private var search: SearchModel { .shared }
@Default(.showKeywords) private var showKeywords
var video: Video
@@ -56,7 +53,7 @@ struct VideoDescription: View {
HStack {
ForEach(video.keywords, id: \.self) { keyword in
Button {
NavigationModel.openSearchQuery(keyword, player: player, recents: recents, navigation: navigation, search: search)
NavigationModel.shared.openSearchQuery(keyword)
} label: {
HStack(alignment: .center, spacing: 0) {
Text("#")
@@ -96,7 +93,8 @@ struct VideoDescription: View {
@State private var label = ActiveLabel()
@Environment(\.openURL) private var openURL
@EnvironmentObject<PlayerModel> private var player
var player = PlayerModel.shared
func makeUIView(context _: Context) -> some UIView {
customizeLabel()

View File

@@ -23,12 +23,9 @@ struct VideoDetails: View {
@Environment(\.colorScheme) private var colorScheme
@EnvironmentObject<AccountsModel> private var accounts
@EnvironmentObject<CommentsModel> private var comments
@EnvironmentObject<NavigationModel> private var navigation
@EnvironmentObject<PlayerModel> private var player
@EnvironmentObject<RecentsModel> private var recents
@EnvironmentObject<SubscriptionsModel> private var subscriptions
@ObservedObject private var accounts = AccountsModel.shared
let comments = CommentsModel.shared
@ObservedObject private var player = PlayerModel.shared
@Default(.enableReturnYouTubeDislike) private var enableReturnYouTubeDislike
@Default(.detailsToolbarPosition) private var detailsToolbarPosition
@@ -148,6 +145,7 @@ struct VideoDetails: View {
}
}
.contentShape(Rectangle())
.frame(maxHeight: .infinity)
}
@State private var detailsSize = CGSize.zero

View File

@@ -13,7 +13,7 @@ struct VideoDetailsToolbar: View {
@State private var startedToolPosition: CGRect = .zero
@State private var opacity = 1.0
@EnvironmentObject<PlayerModel> private var player
@ObservedObject private var player = PlayerModel.shared
@Default(.playerDetailsPageButtonLabelStyle) private var playerDetailsPageButtonLabelStyle
var body: some View {

View File

@@ -57,13 +57,10 @@ struct VideoPlayerView: View {
@State internal var orientationNotification: Any?
#endif
@EnvironmentObject<PlayerModel> internal var player
internal var player: PlayerModel! = PlayerModel.shared
#if os(macOS)
@EnvironmentObject<NavigationModel> internal var navigation
@EnvironmentObject<SearchModel> internal var search
#endif
#if os(tvOS)
@EnvironmentObject<ThumbnailsModel> private var thumbnails
@ObservedObject private var navigation = NavigationModel.shared
#endif
@Default(.horizontalPlayerGestureEnabled) var horizontalPlayerGestureEnabled
@@ -482,7 +479,7 @@ struct VideoPlayerView: View {
#if os(tvOS)
var tvControls: some View {
TVControls(player: player, thumbnails: thumbnails)
TVControls()
}
#endif
}

View File

@@ -13,8 +13,7 @@ struct AddToPlaylistView: View {
@Environment(\.colorScheme) private var colorScheme
@Environment(\.presentationMode) private var presentationMode
@EnvironmentObject<NavigationModel> private var navigation
@EnvironmentObject<PlaylistsModel> private var model
@ObservedObject private var model = PlaylistsModel.shared
var body: some View {
Group {
@@ -164,7 +163,7 @@ struct AddToPlaylistView: View {
Defaults[.lastUsedPlaylistID] = id
model.addVideo(playlistID: id, videoID: video.videoID, navigation: navigation)
model.addVideo(playlistID: id, videoID: video.videoID)
presentationMode.wrappedValue.dismiss()
}

View File

@@ -16,8 +16,8 @@ struct PlaylistFormView: View {
@Environment(\.colorScheme) private var colorScheme
@Environment(\.presentationMode) private var presentationMode
@EnvironmentObject<AccountsModel> private var accounts
@EnvironmentObject<PlaylistsModel> private var playlists
@ObservedObject private var accounts = AccountsModel.shared
@ObservedObject private var playlists = PlaylistsModel.shared
var editing: Bool {
playlist != nil

View File

@@ -14,9 +14,9 @@ struct PlaylistsView: View {
@StateObject private var channelPlaylist = Store<ChannelPlaylist>()
@StateObject private var userPlaylist = Store<Playlist>()
@EnvironmentObject<AccountsModel> private var accounts
@EnvironmentObject<PlayerModel> private var player
@EnvironmentObject<PlaylistsModel> private var model
@ObservedObject private var accounts = AccountsModel.shared
private var player = PlayerModel.shared
@ObservedObject private var model = PlaylistsModel.shared
@Namespace private var focusNamespace
@@ -26,7 +26,7 @@ struct PlaylistsView: View {
if videos.isEmpty {
videos = userPlaylist.item?.videos ?? channelPlaylist.item?.videos ?? []
if !player.accounts.app.userPlaylistsEndpointIncludesVideos {
if !accounts.app.userPlaylistsEndpointIncludesVideos {
var i = 0
for index in videos.indices {
@@ -44,9 +44,9 @@ struct PlaylistsView: View {
private var resource: Resource? {
guard let playlist = currentPlaylist else { return nil }
let resource = player.accounts.api.playlist(playlist.id)
let resource = accounts.api.playlist(playlist.id)
if player.accounts.app.userPlaylistsUseChannelPlaylistEndpoint {
if accounts.app.userPlaylistsUseChannelPlaylistEndpoint {
resource?.addObserver(channelPlaylist)
} else {
resource?.addObserver(userPlaylist)
@@ -150,11 +150,9 @@ struct PlaylistsView: View {
#if os(tvOS)
.fullScreenCover(isPresented: $showingNewPlaylist, onDismiss: selectCreatedPlaylist) {
PlaylistFormView(playlist: $createdPlaylist)
.environmentObject(accounts)
}
.fullScreenCover(isPresented: $showingEditPlaylist, onDismiss: selectEditedPlaylist) {
PlaylistFormView(playlist: $editedPlaylist)
.environmentObject(accounts)
}
.focusScope(focusNamespace)
#else
@@ -162,14 +160,12 @@ struct PlaylistsView: View {
EmptyView()
.sheet(isPresented: $showingNewPlaylist, onDismiss: selectCreatedPlaylist) {
PlaylistFormView(playlist: $createdPlaylist)
.environmentObject(accounts)
}
)
.background(
EmptyView()
.sheet(isPresented: $showingEditPlaylist, onDismiss: selectEditedPlaylist) {
PlaylistFormView(playlist: $editedPlaylist)
.environmentObject(accounts)
}
)
#endif

View File

@@ -4,9 +4,8 @@ import SwiftUI
struct SearchTextField: View {
@Environment(\.navigationStyle) private var navigationStyle
@EnvironmentObject<NavigationModel> private var navigation
@EnvironmentObject<RecentsModel> private var recents
@EnvironmentObject<SearchModel> private var state
private var navigation = NavigationModel.shared
@ObservedObject private var state = SearchModel.shared
@Binding var favoriteItem: FavoriteItem?
@@ -34,7 +33,7 @@ struct SearchTextField: View {
query.query = state.queryText
navigation.hideKeyboard()
}
recents.addQuery(state.queryText, navigation: navigation)
RecentsModel.shared.addQuery(state.queryText)
}
.disableAutocorrection(true)
#if os(macOS)

View File

@@ -1,9 +1,7 @@
import SwiftUI
struct SearchSuggestions: View {
@EnvironmentObject<NavigationModel> private var navigation
@EnvironmentObject<RecentsModel> private var recents
@EnvironmentObject<SearchModel> private var state
@ObservedObject private var state = SearchModel.shared
var body: some View {
List {
@@ -80,10 +78,10 @@ struct SearchSuggestions: View {
state.changeQuery { query in
query.query = queryText
navigation.hideKeyboard()
NavigationModel.shared.hideKeyboard()
}
recents.addQuery(queryText, navigation: navigation)
RecentsModel.shared.addQuery(queryText)
}
private var visibleSuggestions: [String] {

View File

@@ -14,17 +14,15 @@ struct SearchView: View {
#if os(tvOS)
@State private var searchDebounce = Debounce()
@State private var recentsDebounce = Debounce()
private var recents = RecentsModel.shared
#endif
@State private var favoriteItem: FavoriteItem?
@Environment(\.navigationStyle) private var navigationStyle
@EnvironmentObject<AccountsModel> private var accounts
@EnvironmentObject<NavigationModel> private var navigation
@EnvironmentObject<PlayerModel> private var player
@EnvironmentObject<RecentsModel> private var recents
@EnvironmentObject<SearchModel> private var state
@ObservedObject private var accounts = AccountsModel.shared
@ObservedObject private var state = SearchModel.shared
private var favorites = FavoritesModel.shared
@Default(.recentlyOpened) private var recentlyOpened
@@ -313,20 +311,17 @@ struct SearchView: View {
case .query:
state.queryText = item.title
state.changeQuery { query in query.query = item.title }
navigation.hideKeyboard()
NavigationModel.shared.hideKeyboard()
updateFavoriteItem()
recents.add(item)
RecentsModel.shared.add(item)
case .channel:
guard let channel = item.channel else {
return
}
NavigationModel.openChannel(
NavigationModel.shared.openChannel(
channel,
player: player,
recents: recents,
navigation: navigation,
navigationStyle: navigationStyle
)
case .playlist:
@@ -334,11 +329,8 @@ struct SearchView: View {
return
}
NavigationModel.openChannelPlaylist(
NavigationModel.shared.openChannelPlaylist(
playlist,
player: player,
recents: recents,
navigation: navigation,
navigationStyle: navigationStyle
)
}
@@ -359,7 +351,7 @@ struct SearchView: View {
private func removeButton(_ item: RecentItem) -> some View {
Button {
recents.close(item)
RecentsModel.shared.close(item)
recentsChanged.toggle()
} label: {
Label("Remove", systemImage: "trash")
@@ -368,12 +360,12 @@ struct SearchView: View {
private var clearHistoryButton: some View {
Button {
navigation.presentAlert(
NavigationModel.shared.presentAlert(
Alert(
title: Text("Are you sure you want to clear search history?"),
message: Text("This cannot be reverted"),
primaryButton: .destructive(Text("Clear")) {
recents.clear()
RecentsModel.shared.clear()
recentsChanged.toggle()
},
secondaryButton: .cancel()

View File

@@ -1,7 +1,7 @@
import SwiftUI
struct AccountsNavigationLink: View {
@EnvironmentObject<AccountsModel> private var accounts
@ObservedObject private var accounts = AccountsModel.shared
var instance: Instance
var body: some View {
@@ -30,6 +30,6 @@ struct AccountsNavigationLink: View {
if accounts.current?.instance == instance {
accounts.setCurrent(nil)
}
InstancesModel.remove(instance)
InstancesModel.shared.remove(instance)
}
}

View File

@@ -9,11 +9,6 @@ struct AdvancedSettings: View {
@Default(.countryOfPublicInstances) private var countryOfPublicInstances
@Default(.instances) private var instances
@EnvironmentObject<AccountsModel> private var accounts
@EnvironmentObject<NavigationModel> private var navigation
@EnvironmentObject<PlayerModel> private var player
@EnvironmentObject<SettingsModel> private var settings
@State private var countries = [String]()
@State private var filesToShare = [MPVClient.logFile]
@State private var presentingInstanceForm = false
@@ -39,7 +34,7 @@ struct AdvancedSettings: View {
#endif
}
.onChange(of: countryOfPublicInstances) { newCountry in
InstancesManifest.shared.setPublicAccount(newCountry, accounts: accounts, asCurrent: accounts.current?.isPublic ?? true)
InstancesManifest.shared.setPublicAccount(newCountry, asCurrent: AccountsModel.shared.current?.isPublic ?? true)
}
.sheet(isPresented: $presentingInstanceForm) {
InstanceForm(savedInstanceID: $savedFormInstanceID)

View File

@@ -22,7 +22,7 @@ struct BrowsingSettings: View {
@Default(.homeHistoryItems) private var homeHistoryItems
@Default(.visibleSections) private var visibleSections
@EnvironmentObject<AccountsModel> private var accounts
@ObservedObject private var accounts = AccountsModel.shared
@State private var homeHistoryItemsText = ""
#if os(iOS)

View File

@@ -2,8 +2,7 @@ import Defaults
import SwiftUI
struct EditFavorites: View {
@EnvironmentObject<PlaylistsModel> private var playlistsModel
private var playlistsModel = PlaylistsModel.shared
private var model = FavoritesModel.shared
@Default(.favorites) private var favorites

View File

@@ -4,8 +4,8 @@ import SwiftUI
struct HistorySettings: View {
static let watchedThresholds = [50, 60, 70, 80, 90, 95, 100]
@EnvironmentObject<PlayerModel> private var player
@EnvironmentObject<SettingsModel> private var settings
private var player = PlayerModel.shared
private var settings = SettingsModel.shared
@Default(.saveRecents) private var saveRecents
@Default(.saveLastPlayed) private var saveLastPlayed

View File

@@ -16,7 +16,7 @@ struct InstanceForm: View {
@Environment(\.colorScheme) private var colorScheme
@Environment(\.presentationMode) private var presentationMode
@EnvironmentObject<AccountsModel> private var accounts
@ObservedObject private var accounts = AccountsModel.shared
var body: some View {
VStack(alignment: .leading) {
@@ -140,7 +140,7 @@ struct InstanceForm: View {
return
}
let savedInstance = InstancesModel.add(app: app, name: name, url: url)
let savedInstance = InstancesModel.shared.add(app: app, name: name, url: url)
savedInstanceID = savedInstance.id
if accounts.isEmpty {

View File

@@ -13,7 +13,7 @@ struct InstanceSettings: View {
List {
Section(header: Text("Accounts".localized())) {
if instance.app.supportsAccounts {
ForEach(InstancesModel.accounts(instance.id), id: \.self) { account in
ForEach(InstancesModel.shared.accounts(instance.id), id: \.self) { account in
#if os(tvOS)
Button(account.description) {}
.contextMenu {
@@ -70,7 +70,7 @@ struct InstanceSettings: View {
frontendURL = instance.frontendURL ?? ""
}
.onChange(of: frontendURL) { newValue in
InstancesModel.setFrontendURL(instance, newValue)
InstancesModel.shared.setFrontendURL(instance, newValue)
}
.labelsHidden()
.autocapitalization(.none)
@@ -84,7 +84,7 @@ struct InstanceSettings: View {
proxiesVideos = instance.proxiesVideos
}
.onChange(of: proxiesVideos) { newValue in
InstancesModel.setProxiesVideos(instance, newValue)
InstancesModel.shared.setProxiesVideos(instance, newValue)
}
}
}

View File

@@ -6,9 +6,8 @@ struct LocationsSettings: View {
@State private var presentingInstanceForm = false
@State private var savedFormInstanceID: Instance.ID?
@EnvironmentObject<AccountsModel> private var accounts
@EnvironmentObject<NavigationModel> private var navigation
@EnvironmentObject<SettingsModel> private var model
@ObservedObject private var accounts = AccountsModel.shared
private var model = SettingsModel.shared
@Default(.countryOfPublicInstances) private var countryOfPublicInstances
@Default(.instances) private var instances
@@ -30,7 +29,7 @@ struct LocationsSettings: View {
}
.onAppear(perform: loadCountries)
.onChange(of: countryOfPublicInstances) { newCountry in
InstancesManifest.shared.setPublicAccount(newCountry, accounts: accounts, asCurrent: accounts.current?.isPublic ?? true)
InstancesManifest.shared.setPublicAccount(newCountry, asCurrent: accounts.current?.isPublic ?? true)
}
.onChange(of: instancesManifest) { _ in
countryOfPublicInstances = nil
@@ -74,7 +73,7 @@ struct LocationsSettings: View {
.disabled(countries.isEmpty)
Button {
InstancesManifest.shared.changePublicAccount(accounts, settings: model)
InstancesManifest.shared.changePublicAccount()
} label: {
if let account = accounts.current, account.isPublic {
Text("Switch to other public location")
@@ -89,7 +88,6 @@ struct LocationsSettings: View {
Section(header: SettingsHeader(text: "Custom Locations".localized())) {
#if os(macOS)
InstancesSettings()
.environmentObject(model)
#else
ForEach(instances) { instance in
AccountsNavigationLink(instance: instance)
@@ -137,8 +135,5 @@ struct LocationsSettings: View {
struct LocationsSettings_Previews: PreviewProvider {
static var previews: some View {
LocationsSettings()
.environmentObject(AccountsModel())
.environmentObject(NavigationModel())
.environmentObject(SettingsModel())
}
}

View File

@@ -35,8 +35,8 @@ struct PlayerSettings: View {
@Default(.enableReturnYouTubeDislike) private var enableReturnYouTubeDislike
@Default(.systemControlsCommands) private var systemControlsCommands
@EnvironmentObject<AccountsModel> private var accounts
@EnvironmentObject<PlayerModel> private var player
@ObservedObject private var accounts = AccountsModel.shared
private var player = PlayerModel.shared
#if os(iOS)
private var idiom: UIUserInterfaceIdiom {

View File

@@ -5,7 +5,7 @@ struct QualitySettings: View {
@State private var presentingProfileForm = false
@State private var editedProfileID: QualityProfile.ID?
@EnvironmentObject<SettingsModel> private var settings
@ObservedObject private var settings = SettingsModel.shared
@Default(.qualityProfiles) private var qualityProfiles
@Default(.batteryCellularProfile) private var batteryCellularProfile

View File

@@ -19,15 +19,13 @@ struct SettingsView: View {
@Environment(\.presentationMode) private var presentationMode
#endif
@EnvironmentObject<AccountsModel> private var accounts
@EnvironmentObject<NavigationModel> private var navigation
@EnvironmentObject<SettingsModel> private var model
@ObservedObject private var accounts = AccountsModel.shared
@ObservedObject private var model = SettingsModel.shared
@Default(.instances) private var instances
var body: some View {
settings
.environmentObject(model)
.alert(isPresented: $model.presentingAlert) { model.alert }
}

View File

@@ -13,7 +13,7 @@ struct TrendingView: View {
@State private var favoriteItem: FavoriteItem?
@EnvironmentObject<AccountsModel> private var accounts
@ObservedObject private var accounts = AccountsModel.shared
var trending: [ContentItem] {
ContentItem.array(of: store.collection)

View File

@@ -14,9 +14,7 @@ struct VideoCell: View {
@Environment(\.verticalSizeClass) private var verticalSizeClass
#endif
@EnvironmentObject<AccountsModel> private var accounts
@EnvironmentObject<RecentsModel> private var recents
@EnvironmentObject<ThumbnailsModel> private var thumbnails
@ObservedObject var thumbnails = ThumbnailsModel.shared
@Default(.channelOnThumbnail) private var channelOnThumbnail
@Default(.timeOnThumbnail) private var timeOnThumbnail
@@ -53,7 +51,6 @@ struct VideoCell: View {
.contentShape(RoundedRectangle(cornerRadius: thumbnailRoundingCornerRadius))
.contextMenu {
VideoContextMenuView(video: video)
.environmentObject(accounts)
}
}
@@ -310,11 +307,8 @@ struct VideoCell: View {
return
}
NavigationModel.openChannel(
NavigationModel.shared.openChannel(
video.channel,
player: player,
recents: recents,
navigation: navigation,
navigationStyle: navigationStyle
)
} label: {

View File

@@ -7,17 +7,10 @@ struct ChannelCell: View {
@Environment(\.navigationStyle) private var navigationStyle
@EnvironmentObject<NavigationModel> private var navigation
@EnvironmentObject<PlayerModel> private var player
@EnvironmentObject<RecentsModel> private var recents
var body: some View {
Button {
NavigationModel.openChannel(
NavigationModel.shared.openChannel(
channel,
player: player,
recents: recents,
navigation: navigation,
navigationStyle: navigationStyle
)
} label: {

View File

@@ -6,13 +6,12 @@ struct ChannelPlaylistCell: View {
@Environment(\.navigationStyle) private var navigationStyle
@EnvironmentObject<NavigationModel> private var navigation
@EnvironmentObject<RecentsModel> private var recents
var navigation = NavigationModel.shared
var body: some View {
Button {
let recent = RecentItem(from: playlist)
recents.add(recent)
RecentsModel.shared.add(recent)
navigation.presentingPlaylist = true
if navigationStyle == .sidebar {

View File

@@ -12,10 +12,9 @@ struct ChannelPlaylistView: View {
@Environment(\.colorScheme) private var colorScheme
@Environment(\.navigationStyle) private var navigationStyle
@EnvironmentObject<AccountsModel> private var accounts
@EnvironmentObject<NavigationModel> private var navigation
@EnvironmentObject<PlayerModel> private var player
@EnvironmentObject<RecentsModel> private var recents
@ObservedObject private var accounts = AccountsModel.shared
var player = PlayerModel.shared
@ObservedObject private var recents = RecentsModel.shared
private var items: [ContentItem] {
ContentItem.array(of: store.item?.videos ?? [])
@@ -89,7 +88,7 @@ struct ChannelPlaylistView: View {
if navigationStyle == .tab {
Button("Done") {
withAnimation(Constants.overlayAnimation) {
navigation.presentingPlaylist = false
NavigationModel.shared.presentingPlaylist = false
}
}
}

View File

@@ -15,14 +15,12 @@ struct ChannelVideosView: View {
#if os(iOS)
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
@EnvironmentObject<PlayerModel> private var player
#endif
@EnvironmentObject<AccountsModel> private var accounts
@EnvironmentObject<NavigationModel> private var navigation
@EnvironmentObject<RecentsModel> private var recents
@EnvironmentObject<SubscriptionsModel> private var subscriptions
@ObservedObject private var accounts = AccountsModel.shared
@ObservedObject private var navigation = NavigationModel.shared
@ObservedObject private var recents = RecentsModel.shared
@ObservedObject private var subscriptions = SubscriptionsModel.shared
@Namespace private var focusNamespace
var presentedChannel: Channel? {

View File

@@ -10,12 +10,11 @@ struct ControlsBar: View {
@Environment(\.navigationStyle) private var navigationStyle
@EnvironmentObject<AccountsModel> private var accounts
@EnvironmentObject<NavigationModel> private var navigation
@EnvironmentObject<PlayerModel> private var model
@EnvironmentObject<PlaylistsModel> private var playlists
@EnvironmentObject<RecentsModel> private var recents
@EnvironmentObject<SubscriptionsModel> private var subscriptions
@ObservedObject private var accounts = AccountsModel.shared
var navigation = NavigationModel.shared
@ObservedObject private var model = PlayerModel.shared
@ObservedObject private var playlists = PlaylistsModel.shared
@ObservedObject private var subscriptions = SubscriptionsModel.shared
@ObservedObject private var controls = PlayerControlsModel.shared
@@ -139,11 +138,8 @@ struct ControlsBar: View {
HStack(spacing: 8) {
Button {
if let video = model.currentVideo, !video.isLocal {
NavigationModel.openChannel(
navigation.openChannel(
video.channel,
player: model,
recents: recents,
navigation: navigation,
navigationStyle: navigationStyle
)
}
@@ -179,7 +175,7 @@ struct ControlsBar: View {
if let playlist = playlists.lastUsed, let video = model.currentVideo {
Button {
playlists.addVideo(playlistID: playlist.id, videoID: video.videoID, navigation: navigation)
playlists.addVideo(playlistID: playlist.id, videoID: video.videoID)
} label: {
Label("Add to \(playlist.title)", systemImage: "text.badge.star")
}
@@ -194,11 +190,8 @@ struct ControlsBar: View {
Section {
if !video.isLocal {
Button {
NavigationModel.openChannel(
navigation.openChannel(
video.channel,
player: model,
recents: recents,
navigation: navigation,
navigationStyle: navigationStyle
)
} label: {

View File

@@ -2,10 +2,8 @@ import SwiftUI
#if !os(macOS)
struct MPVPlayerView: UIViewControllerRepresentable {
@EnvironmentObject<PlayerModel> private var player
func makeUIViewController(context _: Context) -> some UIViewController {
player.mpvController
PlayerModel.shared.mpvController
}
func updateUIViewController(_: UIViewControllerType, context _: Context) {}
@@ -15,10 +13,8 @@ import SwiftUI
@State private var client = MPVClient()
@State private var layer = VideoLayer()
@EnvironmentObject<PlayerModel> private var player
func makeNSView(context _: Context) -> some NSView {
player.mpvBackend.client = client
PlayerModel.shared.mpvBackend.client = client
let view = MPVOGLView()

View File

@@ -4,7 +4,7 @@ struct OpenSettingsButton: View {
@Environment(\.presentationMode) private var presentationMode
#if !os(macOS)
@EnvironmentObject<NavigationModel> private var navigation
private var navigation: NavigationModel { .shared }
#endif
var body: some View {

View File

@@ -6,11 +6,7 @@ struct OpenVideosView: View {
@State private var playbackMode = OpenVideosModel.PlaybackMode.playNow
@State private var removeQueueItems = false
@EnvironmentObject<AccountsModel> private var accounts
@EnvironmentObject<NavigationModel> private var navigation
@EnvironmentObject<PlayerModel> private var player
@EnvironmentObject<RecentsModel> private var recents
@EnvironmentObject<SearchModel> private var search
@ObservedObject private var navigation = NavigationModel.shared
@Environment(\.openURL) private var openURL
@Environment(\.presentationMode) private var presentationMode
@@ -132,8 +128,8 @@ struct OpenVideosView: View {
openURLs(urlsToOpen)
} catch {
NavigationModel.shared.alert = Alert(title: Text("Could not open Files"))
NavigationModel.shared.presentingAlertInOpenVideos = true
navigation.alert = Alert(title: Text("Could not open Files"))
navigation.presentingAlertInOpenVideos = true
}
presentationMode.wrappedValue.dismiss()

View File

@@ -4,8 +4,9 @@ import SwiftUI
struct PlaylistVideosView: View {
let playlist: Playlist
@EnvironmentObject<PlayerModel> private var player
@EnvironmentObject<PlaylistsModel> private var model
@ObservedObject private var accounts = AccountsModel.shared
var player = PlayerModel.shared
@ObservedObject private var model = PlaylistsModel.shared
@StateObject private var channelPlaylist = Store<ChannelPlaylist>()
@StateObject private var userPlaylist = Store<Playlist>()
@@ -15,7 +16,7 @@ struct PlaylistVideosView: View {
if videos.isEmpty {
videos = userPlaylist.item?.videos ?? channelPlaylist.item?.videos ?? []
if !player.accounts.app.userPlaylistsEndpointIncludesVideos {
if !accounts.app.userPlaylistsEndpointIncludesVideos {
var i = 0
for index in videos.indices {
@@ -31,9 +32,9 @@ struct PlaylistVideosView: View {
}
private var resource: Resource? {
let resource = player.accounts.api.playlist(playlist.id)
let resource = accounts.api.playlist(playlist.id)
if player.accounts.app.userPlaylistsUseChannelPlaylistEndpoint {
if accounts.app.userPlaylistsUseChannelPlaylistEndpoint {
resource?.addObserver(channelPlaylist)
} else {
resource?.addObserver(userPlaylist)

View File

@@ -4,7 +4,7 @@ import SwiftUI
struct PopularView: View {
@StateObject private var store = Store<[Video]>()
@EnvironmentObject<AccountsModel> private var accounts
@ObservedObject private var accounts = AccountsModel.shared
var resource: Resource? {
accounts.api.popular

View File

@@ -3,9 +3,9 @@ import SwiftUI
struct ShareButton<LabelView: View>: View {
let contentItem: ContentItem
@EnvironmentObject<AccountsModel> private var accounts
@EnvironmentObject<NavigationModel> private var navigation
@EnvironmentObject<PlayerModel> private var player
@ObservedObject private var accounts = AccountsModel.shared
private var navigation: NavigationModel { .shared }
@ObservedObject private var player = PlayerModel.shared
let label: LabelView?

View File

@@ -5,7 +5,7 @@ struct SignInRequiredView<Content: View>: View {
let title: String
let content: Content
@EnvironmentObject<AccountsModel> private var accounts
@ObservedObject private var accounts = AccountsModel.shared
@Default(.instances) private var instances

View File

@@ -4,7 +4,7 @@ import SwiftUI
struct SubscriptionsView: View {
@StateObject private var store = Store<[Video]>()
@EnvironmentObject<AccountsModel> private var accounts
@ObservedObject private var accounts = AccountsModel.shared
var feed: Resource? {
accounts.api.feed

View File

@@ -11,12 +11,11 @@ struct VideoContextMenuView: View {
@Environment(\.navigationStyle) private var navigationStyle
@Environment(\.currentPlaylistID) private var playlistID
@EnvironmentObject<AccountsModel> private var accounts
@EnvironmentObject<NavigationModel> private var navigation
@EnvironmentObject<PlayerModel> private var player
@EnvironmentObject<PlaylistsModel> private var playlists
@EnvironmentObject<RecentsModel> private var recents
@EnvironmentObject<SubscriptionsModel> private var subscriptions
@ObservedObject private var accounts = AccountsModel.shared
@ObservedObject private var navigation = NavigationModel.shared
@ObservedObject private var player = PlayerModel.shared
@ObservedObject private var playlists = PlaylistsModel.shared
@ObservedObject private var subscriptions = SubscriptionsModel.shared
@FetchRequest private var watchRequest: FetchedResults<Watch>
@@ -261,11 +260,8 @@ struct VideoContextMenuView: View {
private var openChannelButton: some View {
Button {
NavigationModel.openChannel(
NavigationModel.shared.openChannel(
video.channel,
player: player,
recents: recents,
navigation: navigation,
navigationStyle: navigationStyle
)
} label: {
@@ -308,7 +304,7 @@ struct VideoContextMenuView: View {
@ViewBuilder private var addToLastPlaylistButton: some View {
if let playlist = playlists.lastUsed {
Button {
playlists.addVideo(playlistID: playlist.id, videoID: video.videoID, navigation: navigation)
playlists.addVideo(playlistID: playlist.id, videoID: video.videoID)
} label: {
Label("Add to \(playlist.title)", systemImage: "text.badge.star")
}

View File

@@ -5,7 +5,6 @@ import SwiftUI
struct WelcomeScreen: View {
@Environment(\.presentationMode) private var presentationMode
@EnvironmentObject<AccountsModel> private var accounts
@State private var store = [ManifestedInstance]()
var body: some View {
@@ -25,7 +24,7 @@ struct WelcomeScreen: View {
ForEach(countries, id: \.self) { country in
Button {
Defaults[.countryOfPublicInstances] = country
InstancesManifest.shared.setPublicAccount(country, accounts: accounts)
InstancesManifest.shared.setPublicAccount(country)
presentationMode.wrappedValue.dismiss()
} label: {

View File

@@ -32,19 +32,16 @@ struct YatteeApp: App {
@State private var configured = false
@StateObject private var accounts = AccountsModel()
@StateObject private var comments = CommentsModel()
@StateObject private var instances = InstancesModel()
@StateObject private var menu = MenuModel()
@StateObject private var navigation = NavigationModel()
@StateObject private var networkState = NetworkStateModel()
@StateObject private var player = PlayerModel()
@StateObject private var playlists = PlaylistsModel()
@StateObject private var recents = RecentsModel()
@StateObject private var search = SearchModel()
@StateObject private var settings = SettingsModel()
@StateObject private var subscriptions = SubscriptionsModel()
@StateObject private var thumbnails = ThumbnailsModel()
@StateObject private var comments = CommentsModel.shared
@StateObject private var instances = InstancesModel.shared
@StateObject private var menu = MenuModel.shared
@StateObject private var networkState = NetworkStateModel.shared
@StateObject private var player = PlayerModel.shared
@StateObject private var playlists = PlaylistsModel.shared
@StateObject private var recents = RecentsModel.shared
@StateObject private var settings = SettingsModel.shared
@StateObject private var subscriptions = SubscriptionsModel.shared
@StateObject private var thumbnails = ThumbnailsModel.shared
let persistenceController = PersistenceController.shared
@@ -55,20 +52,6 @@ struct YatteeApp: App {
ContentView()
.onAppear(perform: configure)
.environment(\.managedObjectContext, persistenceController.container.viewContext)
.environmentObject(accounts)
.environmentObject(comments)
.environmentObject(instances)
.environmentObject(navigation)
.environmentObject(networkState)
.environmentObject(player)
.environmentObject(playerControls)
.environmentObject(playlists)
.environmentObject(recents)
.environmentObject(settings)
.environmentObject(subscriptions)
.environmentObject(thumbnails)
.environmentObject(menu)
.environmentObject(search)
#if os(macOS)
.background(
HostingWindowFinder { window in
@@ -100,7 +83,7 @@ struct YatteeApp: App {
CommandGroup(replacing: .newItem, addition: {})
MenuCommands(model: Binding<MenuModel>(get: { menu }, set: { _ in }))
MenuCommands(model: Binding<MenuModel>(get: { MenuModel.shared }, set: { _ in }))
}
#endif
@@ -127,18 +110,7 @@ struct YatteeApp: App {
.onDisappear { player.presentingPlayer = false }
.environment(\.managedObjectContext, persistenceController.container.viewContext)
.environment(\.navigationStyle, .sidebar)
.environmentObject(accounts)
.environmentObject(comments)
.environmentObject(instances)
.environmentObject(navigation)
.environmentObject(networkState)
.environmentObject(player)
.environmentObject(playerControls)
.environmentObject(playlists)
.environmentObject(recents)
.environmentObject(search)
.environmentObject(subscriptions)
.environmentObject(thumbnails)
.handlesExternalEvents(preferring: Set(["player", "*"]), allowing: Set(["player", "*"]))
}
.handlesExternalEvents(matching: Set(["player", "*"]))
@@ -146,12 +118,6 @@ struct YatteeApp: App {
Settings {
SettingsView()
.environment(\.managedObjectContext, persistenceController.container.viewContext)
.environmentObject(accounts)
.environmentObject(instances)
.environmentObject(navigation)
.environmentObject(player)
.environmentObject(playerControls)
.environmentObject(settings)
}
#endif
}
@@ -171,39 +137,14 @@ struct YatteeApp: App {
migrateAccounts()
if !Defaults[.lastAccountIsPublic] {
accounts.configureAccount()
AccountsModel.shared.configureAccount()
}
if let countryOfPublicInstances = Defaults[.countryOfPublicInstances] {
InstancesManifest.shared.setPublicAccount(countryOfPublicInstances, accounts: accounts, asCurrent: accounts.current.isNil)
InstancesManifest.shared.setPublicAccount(countryOfPublicInstances, asCurrent: AccountsModel.shared.current.isNil)
}
playlists.accounts = accounts
search.accounts = accounts
subscriptions.accounts = accounts
comments.player = player
menu.accounts = accounts
menu.navigation = navigation
menu.player = player
player.accounts = accounts
player.comments = comments
player.navigation = navigation
PlayerModel.shared = player
PlayerTimeModel.shared.player = player
#if !os(tvOS)
OpenURLHandler.shared.accounts = accounts
OpenURLHandler.shared.navigation = navigation
OpenURLHandler.shared.recents = recents
OpenURLHandler.shared.player = player
OpenURLHandler.shared.search = search
#endif
if !accounts.current.isNil {
if !AccountsModel.shared.current.isNil {
player.restoreQueue()
}
@@ -219,9 +160,7 @@ struct YatteeApp: App {
}
#endif
navigation.tabSelection = section ?? .search
NavigationModel.shared = navigation
NavigationModel.shared.tabSelection = section ?? .search
subscriptions.load()
playlists.load()