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