yattee/Model/NavigationModel.swift

274 lines
7.8 KiB
Swift
Raw Normal View History

2021-07-11 20:52:49 +00:00
import Foundation
import SwiftUI
2021-09-25 08:18:22 +00:00
final class NavigationModel: ObservableObject {
2022-08-15 12:49:12 +00:00
static var shared: NavigationModel!
2021-08-29 21:36:18 +00:00
enum TabSelection: Hashable {
2022-11-09 13:34:04 +00:00
case home
case subscriptions
case popular
case trending
case playlists
case channel(String)
case playlist(String)
case recentlyOpened(String)
case nowPlaying
case search
#if os(tvOS)
case settings
#endif
2021-10-24 21:36:24 +00:00
2022-03-27 18:38:59 +00:00
var stringValue: String {
switch self {
2022-11-09 13:34:04 +00:00
case .home:
2022-03-27 18:38:59 +00:00
return "favorites"
case .subscriptions:
return "subscriptions"
case .popular:
return "popular"
case .trending:
return "trending"
case .playlists:
return "playlists"
case let .channel(string):
return "channel\(string)"
case let .playlist(string):
return "playlist\(string)"
case .recentlyOpened:
return "recentlyOpened"
case .search:
return "search"
#if os(tvOS)
case .settings: // swiftlint:disable:this switch_case_alignment
return "settings"
#endif
2022-03-27 18:38:59 +00:00
default:
return ""
}
}
2021-10-24 21:36:24 +00:00
var playlistID: Playlist.ID? {
if case let .playlist(id) = self {
return id
}
return nil
}
2021-08-29 21:36:18 +00:00
}
@Published var tabSelection: TabSelection!
2021-07-11 20:52:49 +00:00
@Published var presentingAddToPlaylist = false
@Published var videoToAddToPlaylist: Video!
2021-08-29 21:36:18 +00:00
@Published var presentingPlaylistForm = false
@Published var editedPlaylist: Playlist!
@Published var presentingUnsubscribeAlert = false
@Published var channelToUnsubscribe: Channel!
2021-10-22 23:04:03 +00:00
@Published var presentingChannel = false
@Published var presentingPlaylist = false
@Published var sidebarSectionChanged = false
2022-11-10 17:11:28 +00:00
@Published var presentingOpenVideos = false
2021-09-25 08:18:22 +00:00
@Published var presentingSettings = false
2021-10-17 23:06:00 +00:00
@Published var presentingWelcomeScreen = false
2021-09-25 08:18:22 +00:00
@Published var presentingShareSheet = false
@Published var shareURL: URL?
2022-06-24 22:48:57 +00:00
@Published var alert = Alert(title: Text("Error"))
@Published var presentingAlert = false
2022-11-11 17:50:13 +00:00
@Published var presentingAlertInOpenVideos = false
2022-06-24 22:48:57 +00:00
#if os(macOS)
@Published var presentingAlertInVideoPlayer = false
#endif
2022-11-11 17:50:13 +00:00
@Published var presentingFileImporter = false
2021-12-17 16:34:55 +00:00
static func openChannel(
_ channel: Channel,
player: PlayerModel,
recents: RecentsModel,
2022-06-30 08:05:32 +00:00
navigation: NavigationModel,
navigationStyle: NavigationStyle
2021-12-17 16:34:55 +00:00
) {
2022-04-16 17:44:07 +00:00
guard channel.id != Video.fixtureChannelID else {
return
}
2022-08-09 19:14:05 +00:00
navigation.hideKeyboard()
let presentingPlayer = player.presentingPlayer
2022-06-24 22:48:57 +00:00
player.hide()
2022-05-29 18:26:56 +00:00
navigation.presentingChannel = false
#if os(macOS)
2022-01-06 15:35:45 +00:00
Windows.main.open()
#endif
2021-12-17 16:34:55 +00:00
2022-07-10 17:51:46 +00:00
let recent = RecentItem(from: channel)
recents.add(RecentItem(from: channel))
if navigationStyle == .sidebar {
navigation.sidebarSectionChanged.toggle()
navigation.tabSelection = .recentlyOpened(recent.tag)
} else {
var delay = 0.0
#if os(iOS)
if presentingPlayer { delay = 1.0 }
#endif
DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
2022-08-25 17:09:55 +00:00
withAnimation(Constants.overlayAnimation) {
navigation.presentingChannel = true
}
2022-06-30 08:05:32 +00:00
}
}
}
static func openChannelPlaylist(
_ playlist: ChannelPlaylist,
player: PlayerModel,
recents: RecentsModel,
2022-06-30 08:05:32 +00:00
navigation: NavigationModel,
navigationStyle: NavigationStyle
) {
2022-06-24 22:48:57 +00:00
navigation.presentingChannel = false
2022-05-29 19:09:57 +00:00
navigation.presentingPlaylist = false
let recent = RecentItem(from: playlist)
#if os(macOS)
Windows.main.open()
#else
player.hide()
#endif
2022-08-09 19:14:05 +00:00
navigation.hideKeyboard()
let presentingPlayer = player.presentingPlayer
player.hide()
2022-08-09 19:14:05 +00:00
2022-06-24 22:48:57 +00:00
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
recents.add(recent)
2022-06-30 08:05:32 +00:00
if navigationStyle == .sidebar {
navigation.sidebarSectionChanged.toggle()
navigation.tabSelection = .recentlyOpened(recent.tag)
} else {
var delay = 0.0
#if os(iOS)
if presentingPlayer { delay = 1.0 }
#endif
DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
2022-08-25 17:09:55 +00:00
withAnimation(Constants.overlayAnimation) {
navigation.presentingPlaylist = true
}
2022-07-09 00:21:04 +00:00
}
2022-06-30 08:05:32 +00:00
}
}
2022-06-24 22:48:57 +00:00
}
static func openSearchQuery(
_ searchQuery: String?,
player: PlayerModel,
recents: RecentsModel,
navigation: NavigationModel,
search: SearchModel
) {
navigation.presentingChannel = false
navigation.presentingPlaylist = false
navigation.tabSelection = .search
2022-08-09 19:14:05 +00:00
navigation.hideKeyboard()
let presentingPlayer = player.presentingPlayer
player.hide()
2022-09-28 14:27:01 +00:00
if let searchQuery {
2022-06-24 22:48:57 +00:00
let recent = RecentItem(from: searchQuery)
recents.add(recent)
var delay = 0.0
#if os(iOS)
if presentingPlayer { delay = 1.0 }
#endif
DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
2022-06-24 22:48:57 +00:00
search.queryText = searchQuery
search.changeQuery { query in query.query = searchQuery }
2021-12-17 16:34:55 +00:00
}
}
2022-06-24 22:48:57 +00:00
#if os(macOS)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
Windows.main.focus()
}
#endif
2021-12-17 16:34:55 +00:00
}
2021-09-28 23:01:49 +00:00
var tabSelectionBinding: Binding<TabSelection> {
Binding<TabSelection>(
2021-07-11 20:52:49 +00:00
get: {
self.tabSelection ?? .search
2021-07-11 20:52:49 +00:00
},
set: { newValue in
2021-09-28 23:01:49 +00:00
self.tabSelection = newValue
2021-07-11 20:52:49 +00:00
}
)
}
2021-08-29 21:36:18 +00:00
func presentAddToPlaylist(_ video: Video) {
videoToAddToPlaylist = video
presentingAddToPlaylist = true
}
2021-08-29 21:36:18 +00:00
func presentEditPlaylistForm(_ playlist: Playlist?) {
editedPlaylist = playlist
presentingPlaylistForm = editedPlaylist != nil
}
func presentNewPlaylistForm() {
editedPlaylist = nil
presentingPlaylistForm = true
}
2022-06-24 23:21:05 +00:00
func presentUnsubscribeAlert(_ channel: Channel, subscriptions: SubscriptionsModel) {
2021-08-29 21:36:18 +00:00
channelToUnsubscribe = channel
2022-06-24 23:21:05 +00:00
alert = Alert(
title: Text(
"Are you sure you want to unsubscribe from \(channelToUnsubscribe.name)?"
),
primaryButton: .destructive(Text("Unsubscribe")) { [weak self] in
if let id = self?.channelToUnsubscribe.id {
subscriptions.unsubscribe(id)
}
},
secondaryButton: .cancel()
)
presentingAlert = true
2021-08-29 21:36:18 +00:00
}
2022-03-26 14:22:29 +00:00
func hideKeyboard() {
#if os(iOS)
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
#endif
}
func presentAlert(title: String, message: String? = nil) {
let message = message.isNil ? nil : Text(message!)
alert = Alert(title: Text(title), message: message)
presentingAlert = true
}
2022-08-21 15:39:06 +00:00
func presentAlert(_ alert: Alert) {
self.alert = alert
presentingAlert = true
}
func presentShareSheet(_ url: URL) {
shareURL = url
presentingShareSheet = true
}
2021-07-11 20:52:49 +00:00
}
2021-08-29 21:36:18 +00:00
2021-09-25 08:18:22 +00:00
typealias TabSelection = NavigationModel.TabSelection