From 5f4d42d6c8e3714e6aa845f3bddc53efe24aa31b Mon Sep 17 00:00:00 2001 From: Ethan Pippin Date: Thu, 14 Oct 2021 22:50:30 -0600 Subject: [PATCH] Move coordinators to shared --- .../Views/ConnectToServerView.swift | 168 ++++++------------ JellyfinPlayer tvOS/Views/SplashView.swift | 14 +- JellyfinPlayer.xcodeproj/project.pbxproj | 84 ++++++--- .../Components/PillHStackView.swift | 4 - .../Components/PortraitHStackView.swift | 8 - .../Coordinators/MainCoordinator.swift | 97 ---------- .../Coordinators/iOSMainCoordinator.swift | 83 +++++++++ .../ConnectToServerCoodinator.swift | 0 .../Coordinators/FilterCoordinator.swift | 0 .../Coordinators/HomeCoordinator.swift | 0 .../Coordinators/ItemCoordinator.swift | 0 .../Coordinators/LibraryCoordinator.swift | 0 .../Coordinators/LibraryListCoordinator.swift | 0 .../Coordinators/MainTabCoordinator.swift | 0 .../Coordinators/SearchCoordinator.swift | 0 .../Coordinators/ServerListCoordinator.swift | 0 .../Coordinators/SettingsCoordinator.swift | 0 .../Coordinators/UserListCoordinator.swift | 0 .../Coordinators/UserSignInCoordinator.swift | 0 .../Coordinators/VideoPlayerCoordinator.swift | 0 Shared/Objects/PillStackable.swift | 14 ++ Shared/Objects/PortraitImageStackable.swift | 18 ++ 22 files changed, 233 insertions(+), 257 deletions(-) delete mode 100644 JellyfinPlayer/Coordinators/MainCoordinator.swift create mode 100644 JellyfinPlayer/Coordinators/iOSMainCoordinator.swift rename {JellyfinPlayer => Shared}/Coordinators/ConnectToServerCoodinator.swift (100%) rename {JellyfinPlayer => Shared}/Coordinators/FilterCoordinator.swift (100%) rename {JellyfinPlayer => Shared}/Coordinators/HomeCoordinator.swift (100%) rename {JellyfinPlayer => Shared}/Coordinators/ItemCoordinator.swift (100%) rename {JellyfinPlayer => Shared}/Coordinators/LibraryCoordinator.swift (100%) rename {JellyfinPlayer => Shared}/Coordinators/LibraryListCoordinator.swift (100%) rename {JellyfinPlayer => Shared}/Coordinators/MainTabCoordinator.swift (100%) rename {JellyfinPlayer => Shared}/Coordinators/SearchCoordinator.swift (100%) rename {JellyfinPlayer => Shared}/Coordinators/ServerListCoordinator.swift (100%) rename {JellyfinPlayer => Shared}/Coordinators/SettingsCoordinator.swift (100%) rename {JellyfinPlayer => Shared}/Coordinators/UserListCoordinator.swift (100%) rename {JellyfinPlayer => Shared}/Coordinators/UserSignInCoordinator.swift (100%) rename {JellyfinPlayer => Shared}/Coordinators/VideoPlayerCoordinator.swift (100%) create mode 100644 Shared/Objects/PillStackable.swift create mode 100644 Shared/Objects/PortraitImageStackable.swift diff --git a/JellyfinPlayer tvOS/Views/ConnectToServerView.swift b/JellyfinPlayer tvOS/Views/ConnectToServerView.swift index 9a5e8ec3..ce981f88 100644 --- a/JellyfinPlayer tvOS/Views/ConnectToServerView.swift +++ b/JellyfinPlayer tvOS/Views/ConnectToServerView.swift @@ -1,141 +1,73 @@ -/* JellyfinPlayer/Swiftfin is subject to the terms of the Mozilla Public +/* + * JellyfinPlayer/Swiftfin is subject to the terms of the Mozilla Public * License, v2.0. If a copy of the MPL was not distributed with this * file, you can obtain one at https://mozilla.org/MPL/2.0/. * * Copyright 2021 Aiden Vigue & Jellyfin Contributors */ -import JellyfinAPI import SwiftUI +import Stinsen struct ConnectToServerView: View { + @StateObject var viewModel = ConnectToServerViewModel() - @State var username = "" - @State var password = "" @State var uri = "" - + var body: some View { - VStack(alignment: .leading) { - if viewModel.isConnectedServer { - Section(header: Text(viewModel.lastPublicUsers.isEmpty || username == "" ? "Login to \(SessionManager.main.currentLogin.server.name)": "")) { - if viewModel.lastPublicUsers.isEmpty || username == "" { - TextField(NSLocalizedString("Username", comment: ""), text: $username) - .disableAutocorrection(true) - .autocapitalization(.none) - } else { - HStack { - Spacer() - ImageView(src: URL(string: "\(SessionManager.main.currentLogin.server.uri)/Users/\(viewModel.selectedPublicUser.id ?? "")/Images/Primary?width=500&quality=80&tag=\(viewModel.selectedPublicUser.primaryImageTag ?? "")")!) - .frame(width: 250, height: 250) - .cornerRadius(125.0) - Spacer() - } - } - - SecureField(NSLocalizedString("Password", comment: ""), text: $password) - .disableAutocorrection(true) - .autocapitalization(.none) - } - - Section { - HStack { - Button { - if !viewModel.lastPublicUsers.isEmpty { - username = "" - viewModel.showPublicUsers() - } else { - viewModel.isConnectedServer = false - } - } label: { - Spacer() - HStack { - Text("Back") - } - Spacer() - } - - Button { - viewModel.login() - } label: { - Spacer() - if viewModel.isLoading { - ProgressView() - } else { - Text("Login") - } - Spacer() - }.disabled(viewModel.isLoading || username.isEmpty) + List { + Section { + TextField(NSLocalizedString("Server URL", comment: ""), text: $uri) + .disableAutocorrection(true) + .autocapitalization(.none) + .keyboardType(.URL) + Button { + viewModel.connectToServer(uri: uri) + } label: { + HStack { + Text("Connect") + Spacer() + if viewModel.isLoading { + ProgressView() } } } - } else { - if !viewModel.isLoading { - - Form { - Section(header: Text("Server Information")) { - TextField(NSLocalizedString("Server URL", comment: ""), text: $uri) - .disableAutocorrection(true) - .autocapitalization(.none) - .keyboardType(.URL) - Button { - viewModel.connectToServer() - } label: { - HStack { - Text("Connect") - Spacer() - } - if viewModel.isLoading { - ProgressView() - } - } - .disabled(viewModel.isLoading || uri.isEmpty) - } - Section(header: Text("Local Servers")) { - if self.viewModel.searching { - ProgressView() - } - ForEach(self.viewModel.servers, id: \.id) { server in - Button(action: { - print(server.url) - viewModel.connectToServer(at: server.url) - }, label: { - HStack { - VStack(alignment: .leading) { - Text(server.name) - .font(.headline) - Text(server.host) - .font(.subheadline) - } - Spacer() - Image(systemName: "chevron.forward") - .padding() - } - - }) - .disabled(viewModel.isLoading) - } - } - .onAppear(perform: self.viewModel.discoverServers) - } - } else { + .disabled(viewModel.isLoading || uri.isEmpty) + } header: { + Text("Connect to a Jellyfin server") + } + + Section(header: Text("Local Servers")) { + if viewModel.searching { ProgressView() } + ForEach(viewModel.discoveredServers.sorted(by: { $0.name < $1.name }), id: \.id) { discoveredServer in + Button(action: { + viewModel.connectToServer(uri: discoveredServer.url.absoluteString) + }, label: { + HStack { + Text(discoveredServer.name) + .font(.headline) + Text("• \(discoveredServer.host)") + .font(.subheadline) + .foregroundColor(.secondary) + Spacer() + if viewModel.isLoading { + ProgressView() + } + } + + }) + } } + .onAppear(perform: self.viewModel.discoverServers) + .headerProminence(.increased) } - .padding(.leading, 90) - .padding(.trailing, 90) .alert(item: $viewModel.errorMessage) { _ in - Alert(title: Text("Error"), message: Text(viewModel.errorMessage as? String ?? ""), dismissButton: .default(Text("Ok"))) + Alert(title: Text(viewModel.alertTitle), + message: Text(viewModel.errorMessage?.displayMessage ?? "Unknown Error"), + dismissButton: .cancel()) } - .onChange(of: uri) { uri in - viewModel.uriSubject.send(uri) - } - .onChange(of: username) { username in - viewModel.usernameSubject.send(username) - } - .onChange(of: password) { password in - viewModel.passwordSubject.send(password) - } - .navigationTitle(viewModel.isConnectedServer ? NSLocalizedString("Who's watching?", comment: "") : NSLocalizedString("Connect to Jellyfin", comment: "")) + .navigationTitle("Connect") } } diff --git a/JellyfinPlayer tvOS/Views/SplashView.swift b/JellyfinPlayer tvOS/Views/SplashView.swift index 3756ecd9..234da126 100644 --- a/JellyfinPlayer tvOS/Views/SplashView.swift +++ b/JellyfinPlayer tvOS/Views/SplashView.swift @@ -10,19 +10,21 @@ import SwiftUI struct SplashView: View { + @StateObject var viewModel = SplashViewModel() - + var body: some View { Group { - if viewModel.isLoggedIn { - NavigationView { - MainTabView() - }.padding(.all, -1) - } else { + if SessionManager.main.currentLogin == nil { NavigationView { ConnectToServerView() } .navigationViewStyle(StackNavigationViewStyle()) + } else { + NavigationView { + MainTabView() + } + .ignoresSafeArea() } } } diff --git a/JellyfinPlayer.xcodeproj/project.pbxproj b/JellyfinPlayer.xcodeproj/project.pbxproj index 187141fe..edfd69d6 100644 --- a/JellyfinPlayer.xcodeproj/project.pbxproj +++ b/JellyfinPlayer.xcodeproj/project.pbxproj @@ -173,7 +173,6 @@ 6220D0BA26D6092100B8E046 /* FilterCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6220D0B926D6092100B8E046 /* FilterCoordinator.swift */; }; 6220D0C026D61C5000B8E046 /* ItemCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6220D0BF26D61C5000B8E046 /* ItemCoordinator.swift */; }; 6220D0C626D62D8700B8E046 /* VideoPlayerCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6220D0C526D62D8700B8E046 /* VideoPlayerCoordinator.swift */; }; - 6220D0C726D62D8700B8E046 /* VideoPlayerCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6220D0C526D62D8700B8E046 /* VideoPlayerCoordinator.swift */; }; 6220D0C926D63F3700B8E046 /* Stinsen in Frameworks */ = {isa = PBXBuildFile; productRef = 6220D0C826D63F3700B8E046 /* Stinsen */; }; 6220D0CC26D640C400B8E046 /* AppURLHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6220D0CB26D640C400B8E046 /* AppURLHandler.swift */; }; 6225FCCB2663841E00E067F6 /* ParallaxHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6225FCCA2663841E00E067F6 /* ParallaxHeader.swift */; }; @@ -202,14 +201,13 @@ 628B95372670CB800091AF3B /* JellyfinWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 628B95362670CB800091AF3B /* JellyfinWidget.swift */; }; 628B953C2670D2430091AF3B /* StringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 621338922660107500A81A2A /* StringExtensions.swift */; }; 62C29E9C26D0FE4200C1D2E7 /* Stinsen in Frameworks */ = {isa = PBXBuildFile; productRef = 62C29E9B26D0FE4200C1D2E7 /* Stinsen */; }; - 62C29E9F26D1016600C1D2E7 /* MainCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62C29E9E26D1016600C1D2E7 /* MainCoordinator.swift */; }; + 62C29E9F26D1016600C1D2E7 /* iOSMainCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62C29E9E26D1016600C1D2E7 /* iOSMainCoordinator.swift */; }; 62C29EA126D102A500C1D2E7 /* MainTabCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62C29EA026D102A500C1D2E7 /* MainTabCoordinator.swift */; }; 62C29EA326D1030F00C1D2E7 /* ConnectToServerCoodinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62C29EA226D1030F00C1D2E7 /* ConnectToServerCoodinator.swift */; }; 62C29EA626D1036A00C1D2E7 /* HomeCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62C29EA526D1036A00C1D2E7 /* HomeCoordinator.swift */; }; 62C29EA826D103D500C1D2E7 /* LibraryListCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62C29EA726D103D500C1D2E7 /* LibraryListCoordinator.swift */; }; 62CB3F4B2685BB77003D0A6F /* DefaultsExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62CB3F4A2685BB77003D0A6F /* DefaultsExtension.swift */; }; 62CB3F4C2685BB77003D0A6F /* DefaultsExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62CB3F4A2685BB77003D0A6F /* DefaultsExtension.swift */; }; - 62D8535B26FC631300FDFC59 /* MainCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62C29E9E26D1016600C1D2E7 /* MainCoordinator.swift */; }; 62E632DA267D2BC40063E547 /* LatestMediaViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62E632D9267D2BC40063E547 /* LatestMediaViewModel.swift */; }; 62E632DC267D2E130063E547 /* LibrarySearchViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62E632DB267D2E130063E547 /* LibrarySearchViewModel.swift */; }; 62E632DD267D2E130063E547 /* LibrarySearchViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62E632DB267D2E130063E547 /* LibrarySearchViewModel.swift */; }; @@ -264,24 +262,18 @@ E13DD3E127176BD3009D4DAF /* ServerListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E13DD3E027176BD3009D4DAF /* ServerListViewModel.swift */; }; E13DD3E227176BD3009D4DAF /* ServerListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E13DD3E027176BD3009D4DAF /* ServerListViewModel.swift */; }; E13DD3E527177D15009D4DAF /* ServerListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E13DD3E427177D15009D4DAF /* ServerListView.swift */; }; - E13DD3E627177D15009D4DAF /* ServerListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E13DD3E427177D15009D4DAF /* ServerListView.swift */; }; E13DD3E927177ED6009D4DAF /* ServerListCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E13DD3E827177ED6009D4DAF /* ServerListCoordinator.swift */; }; - E13DD3EA27177ED6009D4DAF /* ServerListCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E13DD3E827177ED6009D4DAF /* ServerListCoordinator.swift */; }; E13DD3EC27178A54009D4DAF /* UserSignInViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E13DD3EB27178A54009D4DAF /* UserSignInViewModel.swift */; }; E13DD3ED27178A54009D4DAF /* UserSignInViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E13DD3EB27178A54009D4DAF /* UserSignInViewModel.swift */; }; E13DD3EF27178F87009D4DAF /* SwiftfinNotificationCenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = E13DD3EE27178F87009D4DAF /* SwiftfinNotificationCenter.swift */; }; E13DD3F027178F87009D4DAF /* SwiftfinNotificationCenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = E13DD3EE27178F87009D4DAF /* SwiftfinNotificationCenter.swift */; }; E13DD3F227179378009D4DAF /* UserSignInCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E13DD3F127179378009D4DAF /* UserSignInCoordinator.swift */; }; - E13DD3F327179378009D4DAF /* UserSignInCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E13DD3F127179378009D4DAF /* UserSignInCoordinator.swift */; }; E13DD3F5271793BB009D4DAF /* UserSignInView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E13DD3F4271793BB009D4DAF /* UserSignInView.swift */; }; - E13DD3F6271793BB009D4DAF /* UserSignInView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E13DD3F4271793BB009D4DAF /* UserSignInView.swift */; }; E13DD3F72717E87D009D4DAF /* SwiftfinNotificationCenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = E13DD3EE27178F87009D4DAF /* SwiftfinNotificationCenter.swift */; }; E13DD3F92717E961009D4DAF /* UserListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E13DD3F82717E961009D4DAF /* UserListViewModel.swift */; }; E13DD3FA2717E961009D4DAF /* UserListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E13DD3F82717E961009D4DAF /* UserListViewModel.swift */; }; E13DD3FC2717EAE8009D4DAF /* UserListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E13DD3FB2717EAE8009D4DAF /* UserListView.swift */; }; - E13DD3FD2717EAE8009D4DAF /* UserListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E13DD3FB2717EAE8009D4DAF /* UserListView.swift */; }; E13DD4022717EE79009D4DAF /* UserListCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E13DD4012717EE79009D4DAF /* UserListCoordinator.swift */; }; - E13DD4032717EE79009D4DAF /* UserListCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E13DD4012717EE79009D4DAF /* UserListCoordinator.swift */; }; E14F7D0726DB36EF007C3AE6 /* ItemPortraitMainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E14F7D0626DB36EF007C3AE6 /* ItemPortraitMainView.swift */; }; E14F7D0926DB36F7007C3AE6 /* ItemLandscapeMainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E14F7D0826DB36F7007C3AE6 /* ItemLandscapeMainView.swift */; }; E173DA5026D048D600CC4EB7 /* ServerDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E173DA4F26D048D600CC4EB7 /* ServerDetailView.swift */; }; @@ -292,13 +284,29 @@ E18845F826DEA9C900B0C5B7 /* ItemViewBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = E18845F726DEA9C900B0C5B7 /* ItemViewBody.swift */; }; E188460026DECB9E00B0C5B7 /* ItemLandscapeTopBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E18845FF26DECB9E00B0C5B7 /* ItemLandscapeTopBarView.swift */; }; E188460426DEF04800B0C5B7 /* EpisodeCardVStackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E188460326DEF04800B0C5B7 /* EpisodeCardVStackView.swift */; }; + E193D4D827193CAC00900D82 /* PortraitImageStackable.swift in Sources */ = {isa = PBXBuildFile; fileRef = E193D4D727193CAC00900D82 /* PortraitImageStackable.swift */; }; + E193D4D927193CAC00900D82 /* PortraitImageStackable.swift in Sources */ = {isa = PBXBuildFile; fileRef = E193D4D727193CAC00900D82 /* PortraitImageStackable.swift */; }; + E193D4DB27193CCA00900D82 /* PillStackable.swift in Sources */ = {isa = PBXBuildFile; fileRef = E193D4DA27193CCA00900D82 /* PillStackable.swift */; }; + E193D4DC27193CCA00900D82 /* PillStackable.swift in Sources */ = {isa = PBXBuildFile; fileRef = E193D4DA27193CCA00900D82 /* PillStackable.swift */; }; + E193D53227193F7B00900D82 /* ConnectToServerCoodinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62C29EA226D1030F00C1D2E7 /* ConnectToServerCoodinator.swift */; }; + E193D53327193F7D00900D82 /* FilterCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6220D0B926D6092100B8E046 /* FilterCoordinator.swift */; }; + E193D53427193F7F00900D82 /* HomeCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62C29EA526D1036A00C1D2E7 /* HomeCoordinator.swift */; }; + E193D53527193F8100900D82 /* ItemCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6220D0BF26D61C5000B8E046 /* ItemCoordinator.swift */; }; + E193D53627193F8500900D82 /* LibraryCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6220D0B326D5ED8000B8E046 /* LibraryCoordinator.swift */; }; + E193D53727193F8700900D82 /* LibraryListCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62C29EA726D103D500C1D2E7 /* LibraryListCoordinator.swift */; }; + E193D53827193F8C00900D82 /* MainTabCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62C29EA026D102A500C1D2E7 /* MainTabCoordinator.swift */; }; + E193D53927193F8E00900D82 /* SearchCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6220D0B626D5EE1100B8E046 /* SearchCoordinator.swift */; }; + E193D53A27193F9000900D82 /* ServerListCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E13DD3E827177ED6009D4DAF /* ServerListCoordinator.swift */; }; + E193D53B27193F9200900D82 /* SettingsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6220D0B026D5EC9900B8E046 /* SettingsCoordinator.swift */; }; + E193D53C27193F9500900D82 /* UserListCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E13DD4012717EE79009D4DAF /* UserListCoordinator.swift */; }; + E193D53D27193F9700900D82 /* UserSignInCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E13DD3F127179378009D4DAF /* UserSignInCoordinator.swift */; }; + E193D53E27193F9A00900D82 /* VideoPlayerCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6220D0C526D62D8700B8E046 /* VideoPlayerCoordinator.swift */; }; E1AD104A26D94822003E4A08 /* DetailItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1AD104926D94822003E4A08 /* DetailItem.swift */; }; E1AD104B26D94822003E4A08 /* DetailItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1AD104926D94822003E4A08 /* DetailItem.swift */; }; E1AD104D26D96CE3003E4A08 /* BaseItemDtoExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1AD104C26D96CE3003E4A08 /* BaseItemDtoExtensions.swift */; }; E1AD104E26D96CE3003E4A08 /* BaseItemDtoExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1AD104C26D96CE3003E4A08 /* BaseItemDtoExtensions.swift */; }; E1AD105426D97161003E4A08 /* BaseItemDtoExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1AD104C26D96CE3003E4A08 /* BaseItemDtoExtensions.swift */; }; E1AD105626D981CE003E4A08 /* PortraitHStackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1AD105526D981CE003E4A08 /* PortraitHStackView.swift */; }; - E1AD105726D981CE003E4A08 /* PortraitHStackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1AD105526D981CE003E4A08 /* PortraitHStackView.swift */; }; E1AD105926D9A543003E4A08 /* LazyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 621338B22660A07800A81A2A /* LazyView.swift */; }; E1AD105C26D9ABDD003E4A08 /* PillHStackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1AD105B26D9ABDD003E4A08 /* PillHStackView.swift */; }; E1AD105F26D9ADDD003E4A08 /* NameGUIDPairExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1AD105E26D9ADDD003E4A08 /* NameGUIDPairExtensions.swift */; }; @@ -485,7 +493,7 @@ 628B952A2670CABE0091AF3B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 628B95362670CB800091AF3B /* JellyfinWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JellyfinWidget.swift; sourceTree = ""; }; 628B953B2670D1FC0091AF3B /* WidgetExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = WidgetExtension.entitlements; sourceTree = ""; }; - 62C29E9E26D1016600C1D2E7 /* MainCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainCoordinator.swift; sourceTree = ""; }; + 62C29E9E26D1016600C1D2E7 /* iOSMainCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iOSMainCoordinator.swift; sourceTree = ""; }; 62C29EA026D102A500C1D2E7 /* MainTabCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTabCoordinator.swift; sourceTree = ""; }; 62C29EA226D1030F00C1D2E7 /* ConnectToServerCoodinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectToServerCoodinator.swift; sourceTree = ""; }; 62C29EA526D1036A00C1D2E7 /* HomeCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeCoordinator.swift; sourceTree = ""; }; @@ -536,6 +544,8 @@ E18845F726DEA9C900B0C5B7 /* ItemViewBody.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemViewBody.swift; sourceTree = ""; }; E18845FF26DECB9E00B0C5B7 /* ItemLandscapeTopBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemLandscapeTopBarView.swift; sourceTree = ""; }; E188460326DEF04800B0C5B7 /* EpisodeCardVStackView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EpisodeCardVStackView.swift; sourceTree = ""; }; + E193D4D727193CAC00900D82 /* PortraitImageStackable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PortraitImageStackable.swift; sourceTree = ""; }; + E193D4DA27193CCA00900D82 /* PillStackable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PillStackable.swift; sourceTree = ""; }; E1AD104926D94822003E4A08 /* DetailItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailItem.swift; sourceTree = ""; }; E1AD104C26D96CE3003E4A08 /* BaseItemDtoExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseItemDtoExtensions.swift; sourceTree = ""; }; E1AD105526D981CE003E4A08 /* PortraitHStackView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PortraitHStackView.swift; sourceTree = ""; }; @@ -708,6 +718,7 @@ children = ( E12186DF2718F2030010884C /* App */, 535870662669D21700D05A09 /* Assets.xcassets */, + E193D4DD27193DC400900D82 /* Coordinators */, 536D3D77267BB9650004248C /* Components */, 535870702669D21700D05A09 /* Info.plist */, 53ABFDDA267972BF00886593 /* JellyfinPlayer tvOS.entitlements */, @@ -730,13 +741,14 @@ 535870752669D60C00D05A09 /* Shared */ = { isa = PBXGroup; children = ( - E13DD3C0271648EC009D4DAF /* SwiftfinStore */, + 62C29E9D26D0FE5900C1D2E7 /* Coordinators */, E1FCD08E26C466F3007C8DCF /* Errors */, 621338912660106C00A81A2A /* Extensions */, 535870AB2669D8D300D05A09 /* Objects */, AE8C3157265D6F5E008AA076 /* Resources */, 091B5A852683142E00D78B61 /* ServerDiscovery */, 62EC352A26766657000E9F2D /* Singleton */, + E13DD3C0271648EC009D4DAF /* SwiftfinStore */, 532175392671BCED005491E6 /* ViewModels */, E1AD105326D96F5A003E4A08 /* Views */, ); @@ -749,6 +761,8 @@ E1AD104926D94822003E4A08 /* DetailItem.swift */, 53192D5C265AA78A008A4215 /* DeviceProfileBuilder.swift */, 62EC353326766B03000E9F2D /* DeviceRotationViewModifier.swift */, + E193D4D727193CAC00900D82 /* PortraitImageStackable.swift */, + E193D4DA27193CCA00900D82 /* PillStackable.swift */, 535870AC2669D8DD00D05A09 /* Typings.swift */, E1F0204D26CCCA74001C1C3B /* VideoPlayerJumpLength.swift */, ); @@ -799,7 +813,7 @@ 62ECA01926FA6D6900E8EBB7 /* AppURLHandler */, 5377CBF8263B596B003A4E83 /* Assets.xcassets */, 53F866422687A45400DCD1D7 /* Components */, - 62C29E9D26D0FE5900C1D2E7 /* Coordinators */, + E193D53F27193FA800900D82 /* Coordinators */, 5377CC02263B596B003A4E83 /* Info.plist */, 53AD124C2670278D0094A276 /* JellyfinPlayer.entitlements */, 5377CBFA263B596B003A4E83 /* Preview Content */, @@ -1016,7 +1030,6 @@ 6220D0BF26D61C5000B8E046 /* ItemCoordinator.swift */, 6220D0B326D5ED8000B8E046 /* LibraryCoordinator.swift */, 62C29EA726D103D500C1D2E7 /* LibraryListCoordinator.swift */, - 62C29E9E26D1016600C1D2E7 /* MainCoordinator.swift */, 62C29EA026D102A500C1D2E7 /* MainTabCoordinator.swift */, 6220D0B626D5EE1100B8E046 /* SearchCoordinator.swift */, E13DD3E827177ED6009D4DAF /* ServerListCoordinator.swift */, @@ -1172,6 +1185,21 @@ path = Landscape; sourceTree = ""; }; + E193D4DD27193DC400900D82 /* Coordinators */ = { + isa = PBXGroup; + children = ( + ); + path = Coordinators; + sourceTree = ""; + }; + E193D53F27193FA800900D82 /* Coordinators */ = { + isa = PBXGroup; + children = ( + 62C29E9E26D1016600C1D2E7 /* iOSMainCoordinator.swift */, + ); + path = Coordinators; + sourceTree = ""; + }; E1AD105226D96D5F003E4A08 /* JellyfinAPIExtensions */ = { isa = PBXGroup; children = ( @@ -1557,8 +1585,11 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + E193D53627193F8500900D82 /* LibraryCoordinator.swift in Sources */, 531069572684E7EE00CFFDBA /* InfoTabBarViewController.swift in Sources */, E18845F626DD631E00B0C5B7 /* BaseItemDto+Stackable.swift in Sources */, + E193D4DC27193CCA00900D82 /* PillStackable.swift in Sources */, + E193D53327193F7D00900D82 /* FilterCoordinator.swift in Sources */, 6267B3DC2671139500A7371D /* ImageExtensions.swift in Sources */, 531069592684E7EE00CFFDBA /* SubtitlesView.swift in Sources */, C4E5081D2703F8370045C9AB /* LibrarySearchView.swift in Sources */, @@ -1570,10 +1601,10 @@ 53ABFDDE267974E300886593 /* SplashView.swift in Sources */, 53ABFDE8267974EF00886593 /* SplashViewModel.swift in Sources */, 62E632DE267D2E170063E547 /* LatestMediaViewModel.swift in Sources */, - E13DD3F327179378009D4DAF /* UserSignInCoordinator.swift in Sources */, E1FCD09726C47118007C8DCF /* ErrorMessage.swift in Sources */, - E13DD3EA27177ED6009D4DAF /* ServerListCoordinator.swift in Sources */, + E193D53527193F8100900D82 /* ItemCoordinator.swift in Sources */, 53116A19268B947A003024C9 /* PlainLinkButton.swift in Sources */, + E193D53E27193F9A00900D82 /* VideoPlayerCoordinator.swift in Sources */, 536D3D88267C17350004248C /* PublicUserButton.swift in Sources */, 62E632EA267D3FF50063E547 /* SeasonItemViewModel.swift in Sources */, 53CD2A40268A49C2002ABD4E /* ItemView.swift in Sources */, @@ -1599,14 +1630,18 @@ 62E632F4267D54030063E547 /* ItemViewModel.swift in Sources */, 6267B3D826710B9800A7371D /* CollectionExtensions.swift in Sources */, 62E632E7267D3F5B0063E547 /* EpisodeItemViewModel.swift in Sources */, + E193D53727193F8700900D82 /* LibraryListCoordinator.swift in Sources */, E100720726BDABC100CE3E31 /* MediaPlayButtonRowView.swift in Sources */, + E193D53927193F8E00900D82 /* SearchCoordinator.swift in Sources */, + E193D4D927193CAC00900D82 /* PortraitImageStackable.swift in Sources */, 535870A52669D8AE00D05A09 /* ParallaxHeader.swift in Sources */, 53272532268BF09D0035FBF1 /* MediaViewActionButton.swift in Sources */, 531690F0267ABF72005D8AB9 /* NextUpView.swift in Sources */, + E193D53427193F7F00900D82 /* HomeCoordinator.swift in Sources */, E11B1B6D2718CD68006DA3E8 /* JellyfinAPIError.swift in Sources */, + E193D53D27193F9700900D82 /* UserSignInCoordinator.swift in Sources */, 535870A72669D8AE00D05A09 /* MultiSelectorView.swift in Sources */, E1AD104E26D96CE3003E4A08 /* BaseItemDtoExtensions.swift in Sources */, - E13DD4032717EE79009D4DAF /* UserListCoordinator.swift in Sources */, 62E632DD267D2E130063E547 /* LibrarySearchViewModel.swift in Sources */, 536D3D81267BDFC60004248C /* PortraitItemElement.swift in Sources */, 531690E5267ABD5C005D8AB9 /* MainTabView.swift in Sources */, @@ -1617,37 +1652,36 @@ 5398514626B64DBB00101B49 /* SearchablePickerView.swift in Sources */, 53ABFDEE26799DCD00886593 /* ImageView.swift in Sources */, 62CB3F4C2685BB77003D0A6F /* DefaultsExtension.swift in Sources */, - 62D8535B26FC631300FDFC59 /* MainCoordinator.swift in Sources */, 62E632E4267D3BA60063E547 /* MovieItemViewModel.swift in Sources */, 53649AB2269D019100A2D8B7 /* LogManager.swift in Sources */, E13DD3D6271693CD009D4DAF /* SwiftfinStoreDefaults.swift in Sources */, - E13DD3FD2717EAE8009D4DAF /* UserListView.swift in Sources */, 535870AA2669D8AE00D05A09 /* BlurHashDecode.swift in Sources */, 53ABFDE5267974EF00886593 /* ViewModel.swift in Sources */, C45B29BB26FAC5B600CEF5E0 /* ColorExtension.swift in Sources */, 531069582684E7EE00CFFDBA /* MediaInfoView.swift in Sources */, - 6220D0C726D62D8700B8E046 /* VideoPlayerCoordinator.swift in Sources */, 53272537268C1DBB0035FBF1 /* SeasonItemView.swift in Sources */, 09389CC526814E4500AE350E /* DeviceProfileBuilder.swift in Sources */, + E193D53C27193F9500900D82 /* UserListCoordinator.swift in Sources */, E13DD3C927164B1E009D4DAF /* UIDeviceExtensions.swift in Sources */, 535870A62669D8AE00D05A09 /* LazyView.swift in Sources */, + E193D53A27193F9000900D82 /* ServerListCoordinator.swift in Sources */, 6220D0AE26D5EABB00B8E046 /* ViewExtensions.swift in Sources */, 5321753E2671DE9C005491E6 /* Typings.swift in Sources */, E1F0204F26CCCA74001C1C3B /* VideoPlayerJumpLength.swift in Sources */, 53ABFDEB2679753200886593 /* ConnectToServerView.swift in Sources */, 536D3D76267BA9BB0004248C /* MainTabViewModel.swift in Sources */, - E13DD3F6271793BB009D4DAF /* UserSignInView.swift in Sources */, 5310695C2684E7EE00CFFDBA /* VideoPlayerViewController.swift in Sources */, C4E5081B2703F82A0045C9AB /* LibraryListView.swift in Sources */, + E193D53B27193F9200900D82 /* SettingsCoordinator.swift in Sources */, 536D3D74267BA8170004248C /* BackgroundManager.swift in Sources */, 535870632669D21600D05A09 /* JellyfinPlayer_tvOSApp.swift in Sources */, - E13DD3E627177D15009D4DAF /* ServerListView.swift in Sources */, + E193D53227193F7B00900D82 /* ConnectToServerCoodinator.swift in Sources */, 53ABFDE4267974EF00886593 /* LibraryListViewModel.swift in Sources */, 5364F456266CA0DC0026ECBA /* BaseItemPersonExtensions.swift in Sources */, 5364F456266CA0DC0026ECBA /* BaseItemPersonExtensions.swift in Sources */, 531690FA267AD6EC005D8AB9 /* PlainNavigationLinkButton.swift in Sources */, E131691826C583BC0074BFEE /* LogConstructor.swift in Sources */, - E1AD105726D981CE003E4A08 /* PortraitHStackView.swift in Sources */, + E193D53827193F8C00900D82 /* MainTabCoordinator.swift in Sources */, E13DD3C327164941009D4DAF /* SwiftfinStore.swift in Sources */, 09389CC826819B4600AE350E /* VideoPlayerModel.swift in Sources */, ); @@ -1669,7 +1703,7 @@ 625CB5732678C32A00530A6E /* HomeViewModel.swift in Sources */, 62C29EA826D103D500C1D2E7 /* LibraryListCoordinator.swift in Sources */, 62E632DC267D2E130063E547 /* LibrarySearchViewModel.swift in Sources */, - 62C29E9F26D1016600C1D2E7 /* MainCoordinator.swift in Sources */, + 62C29E9F26D1016600C1D2E7 /* iOSMainCoordinator.swift in Sources */, 5389276E263C25100035E14B /* ContinueWatchingView.swift in Sources */, 53F866442687A45F00DCD1D7 /* PortraitItemView.swift in Sources */, E1AD105626D981CE003E4A08 /* PortraitHStackView.swift in Sources */, @@ -1734,6 +1768,8 @@ E13DD3C227164941009D4DAF /* SwiftfinStore.swift in Sources */, E1AD104A26D94822003E4A08 /* DetailItem.swift in Sources */, 62E632E0267D30CA0063E547 /* LibraryViewModel.swift in Sources */, + E193D4DB27193CCA00900D82 /* PillStackable.swift in Sources */, + E193D4D827193CAC00900D82 /* PortraitImageStackable.swift in Sources */, 624C21752685CF60007F1390 /* SearchablePickerView.swift in Sources */, E173DA5026D048D600CC4EB7 /* ServerDetailView.swift in Sources */, 62EC352F267666A5000E9F2D /* SessionManager.swift in Sources */, diff --git a/JellyfinPlayer/Components/PillHStackView.swift b/JellyfinPlayer/Components/PillHStackView.swift index e0b5d0fc..d9ce7769 100644 --- a/JellyfinPlayer/Components/PillHStackView.swift +++ b/JellyfinPlayer/Components/PillHStackView.swift @@ -9,10 +9,6 @@ import SwiftUI -protocol PillStackable { - var title: String { get } -} - struct PillHStackView: View { let title: String diff --git a/JellyfinPlayer/Components/PortraitHStackView.swift b/JellyfinPlayer/Components/PortraitHStackView.swift index 4d97d34a..db9febec 100644 --- a/JellyfinPlayer/Components/PortraitHStackView.swift +++ b/JellyfinPlayer/Components/PortraitHStackView.swift @@ -9,14 +9,6 @@ import SwiftUI -public protocol PortraitImageStackable { - func imageURLContsructor(maxWidth: Int) -> URL - var title: String { get } - var description: String? { get } - var blurHash: String { get } - var failureInitials: String { get } -} - struct PortraitImageHStackView: View { let items: [ItemType] diff --git a/JellyfinPlayer/Coordinators/MainCoordinator.swift b/JellyfinPlayer/Coordinators/MainCoordinator.swift deleted file mode 100644 index eb7ac771..00000000 --- a/JellyfinPlayer/Coordinators/MainCoordinator.swift +++ /dev/null @@ -1,97 +0,0 @@ -// -/* - * SwiftFin is subject to the terms of the Mozilla Public - * License, v2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * Copyright 2021 Aiden Vigue & Jellyfin Contributors - */ - -import Foundation -import Nuke -import Stinsen -import SwiftUI -#if !os(tvOS) - import WidgetKit -#endif - -#if os(iOS) - final class MainCoordinator: NavigationCoordinatable { - var stack: NavigationStack - - @Root var mainTab = makeMainTab - @Root var serverList = makeServerList - - init() { - if SessionManager.main.currentLogin != nil { - self.stack = NavigationStack(initial: \MainCoordinator.mainTab) - } else { - self.stack = NavigationStack(initial: \MainCoordinator.serverList) - } - - ImageCache.shared.costLimit = 125 * 1024 * 1024 // 125MB memory - DataLoader.sharedUrlCache.diskCapacity = 1000 * 1024 * 1024 // 1000MB disk - - #if !os(tvOS) - WidgetCenter.shared.reloadAllTimelines() - UIScrollView.appearance().keyboardDismissMode = .onDrag - #endif - - // Back bar button item setup - let backButtonBackgroundImage = UIImage(systemName: "chevron.backward.circle.fill") - let barAppearance = UINavigationBar.appearance() - barAppearance.backIndicatorImage = backButtonBackgroundImage - barAppearance.backIndicatorTransitionMaskImage = backButtonBackgroundImage - barAppearance.tintColor = UIColor(Color.jellyfinPurple) - - // Notification setup for state - let nc = SwiftfinNotificationCenter.main - nc.addObserver(self, selector: #selector(didLogIn), name: SwiftfinNotificationCenter.Keys.didSignIn, object: nil) - nc.addObserver(self, selector: #selector(didLogOut), name: SwiftfinNotificationCenter.Keys.didSignOut, object: nil) - nc.addObserver(self, selector: #selector(processDeepLink), name: SwiftfinNotificationCenter.Keys.processDeepLink, object: nil) - } - - @objc func didLogIn() { - LogManager.shared.log.info("Received `didSignIn` from NSNotificationCenter.") - root(\.mainTab) - } - - @objc func didLogOut() { - LogManager.shared.log.info("Received `didSignOut` from NSNotificationCenter.") - root(\.serverList) - } - - @objc func processDeepLink(_ notification: Notification) { - guard let deepLink = notification.object as? DeepLink else { return } - if let coordinator = hasRoot(\.mainTab) { - switch deepLink { - case let .item(item): - coordinator.focusFirst(\.home) - .child - .popToRoot() - .route(to: \.item, item) - } - } - } - - func makeMainTab() -> MainTabCoordinator { - MainTabCoordinator() - } - - func makeServerList() -> NavigationViewCoordinator { - NavigationViewCoordinator(ServerListCoordinator()) - } - } - -#elseif os(tvOS) - // temp for fixing build error - final class MainCoordinator: NavigationCoordinatable { - var stack = NavigationStack(initial: \MainCoordinator.mainTab) - - @Root var mainTab = makeEmpty - - @ViewBuilder func makeEmpty() -> some View { - EmptyView() - } - } -#endif diff --git a/JellyfinPlayer/Coordinators/iOSMainCoordinator.swift b/JellyfinPlayer/Coordinators/iOSMainCoordinator.swift new file mode 100644 index 00000000..e49d433a --- /dev/null +++ b/JellyfinPlayer/Coordinators/iOSMainCoordinator.swift @@ -0,0 +1,83 @@ +// +/* + * SwiftFin is subject to the terms of the Mozilla Public + * License, v2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * Copyright 2021 Aiden Vigue & Jellyfin Contributors + */ + +import Foundation +import Nuke +import Stinsen +import SwiftUI +#if !os(tvOS) + import WidgetKit +#endif + +final class MainCoordinator: NavigationCoordinatable { + var stack: NavigationStack + + @Root var mainTab = makeMainTab + @Root var serverList = makeServerList + + init() { + if SessionManager.main.currentLogin != nil { + self.stack = NavigationStack(initial: \MainCoordinator.mainTab) + } else { + self.stack = NavigationStack(initial: \MainCoordinator.serverList) + } + + ImageCache.shared.costLimit = 125 * 1024 * 1024 // 125MB memory + DataLoader.sharedUrlCache.diskCapacity = 1000 * 1024 * 1024 // 1000MB disk + + #if !os(tvOS) + WidgetCenter.shared.reloadAllTimelines() + UIScrollView.appearance().keyboardDismissMode = .onDrag + #endif + + // Back bar button item setup + let backButtonBackgroundImage = UIImage(systemName: "chevron.backward.circle.fill") + let barAppearance = UINavigationBar.appearance() + barAppearance.backIndicatorImage = backButtonBackgroundImage + barAppearance.backIndicatorTransitionMaskImage = backButtonBackgroundImage + barAppearance.tintColor = UIColor(Color.jellyfinPurple) + + // Notification setup for state + let nc = SwiftfinNotificationCenter.main + nc.addObserver(self, selector: #selector(didLogIn), name: SwiftfinNotificationCenter.Keys.didSignIn, object: nil) + nc.addObserver(self, selector: #selector(didLogOut), name: SwiftfinNotificationCenter.Keys.didSignOut, object: nil) + nc.addObserver(self, selector: #selector(processDeepLink), name: SwiftfinNotificationCenter.Keys.processDeepLink, object: nil) + } + + @objc func didLogIn() { + LogManager.shared.log.info("Received `didSignIn` from NSNotificationCenter.") + root(\.mainTab) + } + + @objc func didLogOut() { + LogManager.shared.log.info("Received `didSignOut` from NSNotificationCenter.") + root(\.serverList) + } + + @objc func processDeepLink(_ notification: Notification) { + guard let deepLink = notification.object as? DeepLink else { return } + if let coordinator = hasRoot(\.mainTab) { + switch deepLink { + case let .item(item): + coordinator.focusFirst(\.home) + .child + .popToRoot() + .route(to: \.item, item) + } + } + } + + func makeMainTab() -> MainTabCoordinator { + MainTabCoordinator() + } + + func makeServerList() -> NavigationViewCoordinator { + NavigationViewCoordinator(ServerListCoordinator()) + } +} diff --git a/JellyfinPlayer/Coordinators/ConnectToServerCoodinator.swift b/Shared/Coordinators/ConnectToServerCoodinator.swift similarity index 100% rename from JellyfinPlayer/Coordinators/ConnectToServerCoodinator.swift rename to Shared/Coordinators/ConnectToServerCoodinator.swift diff --git a/JellyfinPlayer/Coordinators/FilterCoordinator.swift b/Shared/Coordinators/FilterCoordinator.swift similarity index 100% rename from JellyfinPlayer/Coordinators/FilterCoordinator.swift rename to Shared/Coordinators/FilterCoordinator.swift diff --git a/JellyfinPlayer/Coordinators/HomeCoordinator.swift b/Shared/Coordinators/HomeCoordinator.swift similarity index 100% rename from JellyfinPlayer/Coordinators/HomeCoordinator.swift rename to Shared/Coordinators/HomeCoordinator.swift diff --git a/JellyfinPlayer/Coordinators/ItemCoordinator.swift b/Shared/Coordinators/ItemCoordinator.swift similarity index 100% rename from JellyfinPlayer/Coordinators/ItemCoordinator.swift rename to Shared/Coordinators/ItemCoordinator.swift diff --git a/JellyfinPlayer/Coordinators/LibraryCoordinator.swift b/Shared/Coordinators/LibraryCoordinator.swift similarity index 100% rename from JellyfinPlayer/Coordinators/LibraryCoordinator.swift rename to Shared/Coordinators/LibraryCoordinator.swift diff --git a/JellyfinPlayer/Coordinators/LibraryListCoordinator.swift b/Shared/Coordinators/LibraryListCoordinator.swift similarity index 100% rename from JellyfinPlayer/Coordinators/LibraryListCoordinator.swift rename to Shared/Coordinators/LibraryListCoordinator.swift diff --git a/JellyfinPlayer/Coordinators/MainTabCoordinator.swift b/Shared/Coordinators/MainTabCoordinator.swift similarity index 100% rename from JellyfinPlayer/Coordinators/MainTabCoordinator.swift rename to Shared/Coordinators/MainTabCoordinator.swift diff --git a/JellyfinPlayer/Coordinators/SearchCoordinator.swift b/Shared/Coordinators/SearchCoordinator.swift similarity index 100% rename from JellyfinPlayer/Coordinators/SearchCoordinator.swift rename to Shared/Coordinators/SearchCoordinator.swift diff --git a/JellyfinPlayer/Coordinators/ServerListCoordinator.swift b/Shared/Coordinators/ServerListCoordinator.swift similarity index 100% rename from JellyfinPlayer/Coordinators/ServerListCoordinator.swift rename to Shared/Coordinators/ServerListCoordinator.swift diff --git a/JellyfinPlayer/Coordinators/SettingsCoordinator.swift b/Shared/Coordinators/SettingsCoordinator.swift similarity index 100% rename from JellyfinPlayer/Coordinators/SettingsCoordinator.swift rename to Shared/Coordinators/SettingsCoordinator.swift diff --git a/JellyfinPlayer/Coordinators/UserListCoordinator.swift b/Shared/Coordinators/UserListCoordinator.swift similarity index 100% rename from JellyfinPlayer/Coordinators/UserListCoordinator.swift rename to Shared/Coordinators/UserListCoordinator.swift diff --git a/JellyfinPlayer/Coordinators/UserSignInCoordinator.swift b/Shared/Coordinators/UserSignInCoordinator.swift similarity index 100% rename from JellyfinPlayer/Coordinators/UserSignInCoordinator.swift rename to Shared/Coordinators/UserSignInCoordinator.swift diff --git a/JellyfinPlayer/Coordinators/VideoPlayerCoordinator.swift b/Shared/Coordinators/VideoPlayerCoordinator.swift similarity index 100% rename from JellyfinPlayer/Coordinators/VideoPlayerCoordinator.swift rename to Shared/Coordinators/VideoPlayerCoordinator.swift diff --git a/Shared/Objects/PillStackable.swift b/Shared/Objects/PillStackable.swift new file mode 100644 index 00000000..4d0296eb --- /dev/null +++ b/Shared/Objects/PillStackable.swift @@ -0,0 +1,14 @@ +// + /* + * SwiftFin is subject to the terms of the Mozilla Public + * License, v2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * Copyright 2021 Aiden Vigue & Jellyfin Contributors + */ + +import Foundation + +protocol PillStackable { + var title: String { get } +} diff --git a/Shared/Objects/PortraitImageStackable.swift b/Shared/Objects/PortraitImageStackable.swift new file mode 100644 index 00000000..e866de31 --- /dev/null +++ b/Shared/Objects/PortraitImageStackable.swift @@ -0,0 +1,18 @@ +// + /* + * SwiftFin is subject to the terms of the Mozilla Public + * License, v2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * Copyright 2021 Aiden Vigue & Jellyfin Contributors + */ + +import Foundation + +public protocol PortraitImageStackable { + func imageURLContsructor(maxWidth: Int) -> URL + var title: String { get } + var description: String? { get } + var blurHash: String { get } + var failureInitials: String { get } +}