1
0
mirror of https://github.com/yattee/yattee.git synced 2024-12-12 21:30:32 +05:30
yattee/Model/NavigationModel.swift

339 lines
9.9 KiB
Swift
Raw Normal View History

2021-07-12 02:22:49 +05:30
import Foundation
2022-12-16 14:05:10 +05:30
import Siesta
2021-07-12 02:22:49 +05:30
import SwiftUI
2021-09-25 13:48:22 +05:30
final class NavigationModel: ObservableObject {
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
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-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"
#if os(tvOS)
2023-04-22 18:38:33 +05:30
case .settings:
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
}
@Published var tabSelection: TabSelection! { didSet {
if oldValue == tabSelection { multipleTapHandler() }
2023-09-24 01:19:41 +05:30
if tabSelection == nil, let item = recents.presentedItem {
2023-09-24 14:44:24 +05:30
Delay.by(0.2) { [weak self] in
2023-09-24 01:19:41 +05:30
self?.tabSelection = .recentlyOpened(item.tag)
}
}
}}
2021-07-12 02:22:49 +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
@Published var sidebarSectionChanged = false
2022-12-22 01:46:47 +05:30
@Published var presentingPlaybackSettings = 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
2023-05-25 17:58:29 +05:30
@Published var presentingHomeSettings = false
2021-09-25 13:48:22 +05:30
@Published var presentingChannelSheet = false
@Published var channelPresentedInSheet: Channel!
@Published var presentingShareSheet = false
@Published var shareURL: URL?
2022-06-25 04:18:57 +05:30
@Published var alert = Alert(title: Text("Error"))
@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-11-11 23:20:13 +05:30
@Published var presentingFileImporter = false
2024-02-02 04:24:16 +05:30
@Published var presentingSettingsImportSheet = false
@Published var presentingSettingsFileImporter = false
@Published var settingsImportURL: URL?
func openChannel(_ channel: Channel, navigationStyle: NavigationStyle) {
2022-04-16 23:14:07 +05:30
guard channel.id != Video.fixtureChannelID else {
return
}
hideKeyboard()
let presentingPlayer = player.presentingPlayer
presentingChannel = false
2022-05-29 23:56:56 +05:30
#if os(macOS)
2022-01-06 21:05:45 +05:30
Windows.main.open()
#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))
let navigateToChannel = {
#if os(iOS)
self.player.hide()
#endif
if navigationStyle == .sidebar {
self.sidebarSectionChanged.toggle()
self.tabSelection = .recentlyOpened(recent.tag)
} else {
2022-08-25 22:39:55 +05:30
withAnimation(Constants.overlayAnimation) {
self.presentingChannel = true
}
2022-06-30 13:35:32 +05:30
}
}
#if os(iOS)
if presentingPlayer {
presentChannelInSheet(channel)
} else {
navigateToChannel()
}
2023-05-23 02:31:54 +05:30
#elseif os(tvOS)
Delay.by(0.01) {
navigateToChannel()
}
#else
navigateToChannel()
#endif
}
func openChannelPlaylist(_ playlist: ChannelPlaylist, navigationStyle: NavigationStyle) {
presentingChannel = false
presentingPlaylist = false
2022-05-30 00:39:57 +05:30
let recent = RecentItem(from: playlist)
#if os(macOS)
Windows.main.open()
#else
player.hide()
#endif
hideKeyboard()
2022-11-27 16:12:16 +05:30
presentingChannel = false
let presentingPlayer = player.presentingPlayer
player.hide()
2022-08-10 00:44: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 {
self.sidebarSectionChanged.toggle()
self.tabSelection = .recentlyOpened(recent.tag)
2022-06-30 13:35:32 +05:30
} else {
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) {
self.presentingPlaylist = true
}
2022-07-09 05:51:04 +05:30
}
2022-06-30 13:35:32 +05:30
}
}
2022-06-25 04:18:57 +05:30
}
func openSearchQuery(_ searchQuery: String?) {
presentingChannel = false
presentingPlaylist = false
tabSelection = .search
2022-06-25 04:18:57 +05:30
hideKeyboard()
2022-08-10 00:44:05 +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)
var delay = 0.0
#if os(iOS)
if presentingPlayer { delay = 1.0 }
#endif
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: {
self.tabSelection ?? .search
2021-07-12 02:22:49 +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
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
2024-02-02 04:24:16 +05:30
presentingFileImporter = false
presentingSettingsImportSheet = false
2022-12-11 20:30:20 +05:30
}
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
}
func presentAlert(title: String, message: String? = nil) {
let message = message.isNil ? nil : Text(message!)
2024-02-02 04:24:16 +05:30
let alert = Alert(title: Text(title), message: message)
presentAlert(alert)
}
2022-12-16 14:05:10 +05:30
func presentRequestErrorAlert(_ error: RequestError) {
let errorDescription = String(format: "Verify you have stable connection with the server you are using (%@)", AccountsModel.shared.current.instance.longDescription)
presentAlert(title: "Connection Error", message: "\(error.userMessage)\n\n\(errorDescription)")
}
2022-08-21 21:09:06 +05:30
func presentAlert(_ alert: Alert) {
2024-02-02 04:24:16 +05:30
guard !presentingSettings else {
SettingsModel.shared.presentAlert(alert)
return
}
2022-08-21 21:09:06 +05:30
self.alert = alert
presentingAlert = true
}
func presentShareSheet(_ url: URL) {
shareURL = url
presentingShareSheet = true
}
func presentChannelInSheet(_ channel: Channel) {
channelPresentedInSheet = channel
presentingChannelSheet = true
}
func multipleTapHandler() {
switch tabSelection {
case .search:
self.search.focused = true
default:
print("not implemented")
}
}
2024-02-02 04:24:16 +05:30
func presentSettingsImportSheet(_ url: URL, forceSettings: Bool = false) {
guard !presentingSettings, !forceSettings else {
ImportExportSettingsModel.shared.reset()
SettingsModel.shared.presentSettingsImportSheet(url)
return
}
settingsImportURL = url
presentingSettingsImportSheet = 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