diff --git a/Shared/Coordinators/MainCoordinator/MainTabType.swift b/Shared/Coordinators/MainCoordinator/MainTabType.swift index 9f72bd717..d9167a628 100644 --- a/Shared/Coordinators/MainCoordinator/MainTabType.swift +++ b/Shared/Coordinators/MainCoordinator/MainTabType.swift @@ -13,77 +13,62 @@ import SwiftUI enum MainTabTypes: String, CaseIterable, Defaults.Serializable, Displayable { - case home - #if os(tvOS) case boxSets - case tvShows + case home + case media case movies - case settings - #endif case search - case media + case tvShows var displayTitle: String { switch self { - case .home: - return L10n.home - #if os(tvOS) case .boxSets: return L10n.collections - case .tvShows: - return L10n.tvShows + case .home: + return L10n.home + case .media: + return L10n.media case .movies: return L10n.movies - case .settings: - return L10n.settings - #endif case .search: return L10n.search - case .media: - return L10n.media + case .tvShows: + return L10n.tvShows } } var displayIcon: Image { switch self { - case .home: - return Image(systemName: "house") - #if os(tvOS) case .boxSets: return Image(systemName: "folder") - case .tvShows: - return Image(systemName: "tv") - .symbolRenderingMode(.monochrome) + case .home: + return Image(systemName: "house") + case .media: + return Image(systemName: "rectangle.stack") case .movies: return Image(systemName: "film") - case .settings: - return Image(systemName: "gearshape.fill") - #endif case .search: return Image(systemName: "magnifyingglass") - case .media: - return Image(systemName: "rectangle.stack") + case .tvShows: + return Image(systemName: "tv") + .symbolRenderingMode(.monochrome) } } var keyPath: AnyKeyPath? { switch self { - case .home: - return \MainTabCoordinator.home - #if os(tvOS) case .boxSets: return \MainTabCoordinator.boxSets - case .tvShows: - return \MainTabCoordinator.tvShows + case .home: + return \MainTabCoordinator.home + case .media: + return \MainTabCoordinator.media case .movies: return \MainTabCoordinator.movies - case .settings: - return \MainTabCoordinator.settings - #endif case .search: return \MainTabCoordinator.search - case .media: - return \MainTabCoordinator.media + case .tvShows: + return \MainTabCoordinator.tvShows } } } diff --git a/Shared/Coordinators/MainCoordinator/iOSMainTabCoordinator.swift b/Shared/Coordinators/MainCoordinator/iOSMainTabCoordinator.swift index 28f753b95..cad72ab0a 100644 --- a/Shared/Coordinators/MainCoordinator/iOSMainTabCoordinator.swift +++ b/Shared/Coordinators/MainCoordinator/iOSMainTabCoordinator.swift @@ -40,7 +40,10 @@ final class MainTabCoordinator: TabCoordinatable { @ViewBuilder func makeHomeTab(isActive: Bool) -> some View { - makeTab(image: Image(systemName: "house"), title: L10n.home) + makeTab( + image: Image(systemName: "house"), + title: L10n.home + ) } func makeSearch() -> NavigationViewCoordinator { @@ -55,7 +58,10 @@ final class MainTabCoordinator: TabCoordinatable { @ViewBuilder func makeSearchTab(isActive: Bool) -> some View { - makeTab(image: Image(systemName: "magnifyingglass"), title: L10n.search) + makeTab( + image: Image(systemName: "magnifyingglass"), + title: L10n.search + ) } func makeMedia() -> NavigationViewCoordinator { @@ -70,7 +76,10 @@ final class MainTabCoordinator: TabCoordinatable { @ViewBuilder func makeMediaTab(isActive: Bool) -> some View { - makeTab(image: Image(systemName: "rectangle.stack.fill"), title: L10n.media) + makeTab( + image: Image(systemName: "rectangle.stack.fill"), + title: L10n.media + ) } @ViewBuilder @@ -95,16 +104,13 @@ final class MainTabCoordinator: TabCoordinatable { } static func makeChild() -> TabChild { - @Default(.Customization.Home.homeSections) - var homeSections - var activeSections: [AnyKeyPath] - - // Re-Add Home back to the Main Tabs if removed - if homeSections.contains(MainTabTypes.home) { - activeSections = homeSections.compactMap(\.keyPath) - } else { - activeSections = homeSections.compactMap(\.keyPath) + [\MainTabCoordinator.home] - } - return TabChild(startingItems: activeSections) + + TabChild( + startingItems: [ + \MainTabCoordinator.home, + \MainTabCoordinator.search, + \MainTabCoordinator.media, + ] + ) } } diff --git a/Shared/Coordinators/MainCoordinator/tvOSMainCoordinator.swift b/Shared/Coordinators/MainCoordinator/tvOSMainCoordinator.swift index 2e93413d3..ec4869d06 100644 --- a/Shared/Coordinators/MainCoordinator/tvOSMainCoordinator.swift +++ b/Shared/Coordinators/MainCoordinator/tvOSMainCoordinator.swift @@ -16,7 +16,7 @@ import SwiftUI // - move some things to App // TODO: server check flow -final class MainCoordinator: NavigationCoordinatable { +final class MainCoordinator: NavigationCoordinatable, Observable { @Injected(\.logService) private var logger @@ -30,8 +30,13 @@ final class MainCoordinator: NavigationCoordinatable { @Root var selectUser = makeSelectUser - init() { + @Published + var mainTabCoordinator: MainTabCoordinator + @Published + var updateMainTab: Bool = false + init() { + self.mainTabCoordinator = MainTabCoordinator() stack = NavigationStack(initial: \.loading) Task { @@ -90,10 +95,18 @@ final class MainCoordinator: NavigationCoordinatable { } func makeMainTab() -> MainTabCoordinator { - MainTabCoordinator() + mainTabCoordinator } func makeSelectUser() -> NavigationViewCoordinator { NavigationViewCoordinator(SelectUserCoordinator()) } + + func refreshMainTab() { + if updateMainTab { + mainTabCoordinator.refresh() + self.objectWillChange.send() + updateMainTab = false + } + } } diff --git a/Shared/Coordinators/MainCoordinator/tvOSMainTabCoordinator.swift b/Shared/Coordinators/MainCoordinator/tvOSMainTabCoordinator.swift index 395605432..2af59f78a 100644 --- a/Shared/Coordinators/MainCoordinator/tvOSMainTabCoordinator.swift +++ b/Shared/Coordinators/MainCoordinator/tvOSMainTabCoordinator.swift @@ -43,7 +43,10 @@ final class MainTabCoordinator: TabCoordinatable { @ViewBuilder func makeHomeTab(isActive: Bool) -> some View { - makeTab(image: MainTabTypes.home.displayIcon, title: MainTabTypes.home.displayTitle) + makeTab( + image: MainTabTypes.home.displayIcon, + title: MainTabTypes.home.displayTitle + ) } func makeBoxSets() -> NavigationViewCoordinator> { @@ -53,7 +56,10 @@ final class MainTabCoordinator: TabCoordinatable { @ViewBuilder func makeBoxSetsTab(isActive: Bool) -> some View { - makeTab(image: MainTabTypes.boxSets.displayIcon, title: MainTabTypes.boxSets.displayTitle) + makeTab( + image: MainTabTypes.boxSets.displayIcon, + title: MainTabTypes.boxSets.displayTitle + ) } func makeTVShows() -> NavigationViewCoordinator> { @@ -63,7 +69,10 @@ final class MainTabCoordinator: TabCoordinatable { @ViewBuilder func makeTvTab(isActive: Bool) -> some View { - makeTab(image: MainTabTypes.tvShows.displayIcon, title: MainTabTypes.tvShows.displayTitle) + makeTab( + image: MainTabTypes.tvShows.displayIcon, + title: MainTabTypes.tvShows.displayTitle + ) } func makeMovies() -> NavigationViewCoordinator> { @@ -73,7 +82,10 @@ final class MainTabCoordinator: TabCoordinatable { @ViewBuilder func makeMoviesTab(isActive: Bool) -> some View { - makeTab(image: MainTabTypes.movies.displayIcon, title: MainTabTypes.movies.displayTitle) + makeTab( + image: MainTabTypes.movies.displayIcon, + title: MainTabTypes.movies.displayTitle + ) } func makeSearch() -> VideoPlayerWrapperCoordinator { @@ -85,7 +97,10 @@ final class MainTabCoordinator: TabCoordinatable { @ViewBuilder func makeSearchTab(isActive: Bool) -> some View { - makeTab(image: MainTabTypes.search.displayIcon, title: MainTabTypes.search.displayTitle) + makeTab( + image: MainTabTypes.search.displayIcon, + title: MainTabTypes.search.displayTitle + ) } func makeMedia() -> NavigationViewCoordinator { @@ -94,7 +109,10 @@ final class MainTabCoordinator: TabCoordinatable { @ViewBuilder func makeMediaTab(isActive: Bool) -> some View { - makeTab(image: MainTabTypes.media.displayIcon, title: MainTabTypes.media.displayTitle) + makeTab( + image: MainTabTypes.media.displayIcon, + title: MainTabTypes.media.displayTitle + ) } func makeSettings() -> NavigationViewCoordinator { @@ -103,7 +121,11 @@ final class MainTabCoordinator: TabCoordinatable { @ViewBuilder func makeSettingsTab(isActive: Bool) -> some View { - makeTab(image: MainTabTypes.settings.displayIcon, title: MainTabTypes.settings.displayTitle, useTitle: false) + makeTab( + image: Image(systemName: "gearshape.fill"), + title: L10n.settings, + useTitle: false + ) } func makeTab(image tabIcon: Image, title tabLabel: String, useTitle tabTitle: Bool = true) -> some View { @@ -119,14 +141,12 @@ final class MainTabCoordinator: TabCoordinatable { static func makeChild() -> TabChild { @Default(.Customization.Home.homeSections) var homeSections - var activeSections: [AnyKeyPath] + var activeSections: [AnyKeyPath] = homeSections.compactMap(\.keyPath) + [\MainTabCoordinator.settings] - // Re-Add Settings back to the Main Tabs if removed - if homeSections.contains(MainTabTypes.settings) { - activeSections = homeSections.compactMap(\.keyPath) - } else { - activeSections = homeSections.compactMap(\.keyPath) + [\MainTabCoordinator.settings] - } return TabChild(startingItems: activeSections) } + + func refresh() { + self.child = MainTabCoordinator.makeChild() + } } diff --git a/Shared/Coordinators/SettingsCoordinator.swift b/Shared/Coordinators/SettingsCoordinator.swift index b5abf37f1..063b14154 100644 --- a/Shared/Coordinators/SettingsCoordinator.swift +++ b/Shared/Coordinators/SettingsCoordinator.swift @@ -40,8 +40,6 @@ final class SettingsCoordinator: NavigationCoordinatable { @Route(.push) var experimentalSettings = makeExperimentalSettings @Route(.push) - var homeSectionsSelector = makeHomeSectionsSelector - @Route(.push) var itemFilterDrawerSelector = makeItemFilterDrawerSelector @Route(.push) var indicatorSettings = makeIndicatorSettings @@ -136,10 +134,6 @@ final class SettingsCoordinator: NavigationCoordinatable { OrderedSectionSelectorView(selection: selection, sources: ItemFilterType.allCases) } - func makeHomeSectionsSelector(selection: Binding<[MainTabTypes]>) -> some View { - OrderedSectionSelectorView(selection: selection, sources: MainTabTypes.allCases) - } - #if DEBUG @ViewBuilder func makeDebugSettings() -> some View { diff --git a/Shared/Services/SwiftfinDefaults.swift b/Shared/Services/SwiftfinDefaults.swift index 32ffe57fb..ae7debab5 100644 --- a/Shared/Services/SwiftfinDefaults.swift +++ b/Shared/Services/SwiftfinDefaults.swift @@ -163,15 +163,10 @@ extension Defaults.Keys { enum Home { static let homeLabels: Key = UserKey("homeLabels", default: true) - #if os(iOS) + #if os(tvOS) static let homeSections: Key<[MainTabTypes]> = UserKey( "homeSections", - default: [.home, .search, .media] - ) - #elseif os(tvOS) - static let homeSections: Key<[MainTabTypes]> = UserKey( - "homeSections", - default: [.home, .tvShows, .movies, .search, .media, .settings] + default: [.home, .tvShows, .movies, .search, .media] ) #endif } diff --git a/Swiftfin tvOS/App/SwiftfinApp.swift b/Swiftfin tvOS/App/SwiftfinApp.swift index bd26cb7f2..bf5bb6220 100644 --- a/Swiftfin tvOS/App/SwiftfinApp.swift +++ b/Swiftfin tvOS/App/SwiftfinApp.swift @@ -18,6 +18,9 @@ import SwiftUI @main struct SwiftfinApp: App { + @StateObject + var mainCoordinator = MainCoordinator() + init() { // CoreStore @@ -56,8 +59,9 @@ struct SwiftfinApp: App { var body: some Scene { WindowGroup { - MainCoordinator() + mainCoordinator .view() + .environmentObject(mainCoordinator) .onNotification(UIApplication.didEnterBackgroundNotification) { _ in Defaults[.backgroundTimeStamp] = Date.now } @@ -71,6 +75,9 @@ struct SwiftfinApp: App { Notifications[.didSignOut].post() } } + .onAppear { + mainCoordinator.refreshMainTab() + } } } } diff --git a/Swiftfin tvOS/Views/SettingsView/CustomizeViewsSettings.swift b/Swiftfin tvOS/Views/SettingsView/CustomizeViewsSettings.swift index efd23108f..747709601 100644 --- a/Swiftfin tvOS/Views/SettingsView/CustomizeViewsSettings.swift +++ b/Swiftfin tvOS/Views/SettingsView/CustomizeViewsSettings.swift @@ -56,6 +56,8 @@ struct CustomizeViewsSettings: View { @EnvironmentObject private var router: SettingsCoordinator.Router + @EnvironmentObject + private var mainCoordinator: MainCoordinator var body: some View { SplitFormWindowView() @@ -69,17 +71,38 @@ struct CustomizeViewsSettings: View { Section { - Toggle("Show Section Labels", isOn: $homeLabels) + Toggle("Cinematic Background", isOn: $cinematicBackground) - ChevronButton("Sections") + Toggle("Random Image", isOn: $libraryRandomImage) + + Toggle("Show Favorites", isOn: $showFavorites) + + Toggle("Show Recently Added", isOn: $showRecentlyAdded) + + } header: { + L10n.library.text + } + + Section { + + Toggle(L10n.letterPicker, isOn: $letterPickerEnabled) + + if letterPickerEnabled { + InlineEnumToggle(title: L10n.orientation, selection: $letterPickerOrientation) + } + + ChevronButton(L10n.library) .onSelect { - router.route(to: \.homeSectionsSelector, $homeSections) + router.route(to: \.itemFilterDrawerSelector, $libraryEnabledDrawerFilters) + } + + ChevronButton(L10n.search) + .onSelect { + router.route(to: \.itemFilterDrawerSelector, $searchEnabledDrawerFilters) } } header: { - L10n.home.text - } footer: { - Text("An app restart is required to update sections") + L10n.filters.text } Section { @@ -118,38 +141,21 @@ struct CustomizeViewsSettings: View { Section { - Toggle("Cinematic Background", isOn: $cinematicBackground) - - Toggle("Random Image", isOn: $libraryRandomImage) - - Toggle("Show Favorites", isOn: $showFavorites) - - Toggle("Show Recently Added", isOn: $showRecentlyAdded) - - } header: { - L10n.library.text - } - - Section { - - Toggle(L10n.letterPicker, isOn: $letterPickerEnabled) - - if letterPickerEnabled { - InlineEnumToggle(title: L10n.orientation, selection: $letterPickerOrientation) - } - - ChevronButton(L10n.library) - .onSelect { - router.route(to: \.itemFilterDrawerSelector, $libraryEnabledDrawerFilters) + Toggle("Show Section Labels", isOn: $homeLabels) + .onChange(of: homeLabels) { + mainCoordinator.updateMainTab = true } - ChevronButton(L10n.search) + ChevronButton("Sections") .onSelect { - router.route(to: \.itemFilterDrawerSelector, $searchEnabledDrawerFilters) + router.route(to: \.homeSectionsSelector, $homeSections) + } + .onChange(of: homeSections) { + mainCoordinator.updateMainTab = true } } header: { - L10n.filters.text + L10n.home.text } } .withDescriptionTopPadding() diff --git a/Swiftfin.xcodeproj/project.pbxproj b/Swiftfin.xcodeproj/project.pbxproj index 67f394884..92aa2c850 100644 --- a/Swiftfin.xcodeproj/project.pbxproj +++ b/Swiftfin.xcodeproj/project.pbxproj @@ -13,7 +13,6 @@ 4E16FD532C01840C00110147 /* LetterPickerBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E16FD522C01840C00110147 /* LetterPickerBar.swift */; }; 4E16FD572C01A32700110147 /* LetterPickerOrientation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E16FD562C01A32700110147 /* LetterPickerOrientation.swift */; }; 4E16FD582C01A32700110147 /* LetterPickerOrientation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E16FD562C01A32700110147 /* LetterPickerOrientation.swift */; }; - 4E541F942C52FB72002CB4F8 /* MainTabType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E541F932C52FB72002CB4F8 /* MainTabType.swift */; }; 4E541F952C52FB72002CB4F8 /* MainTabType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E541F932C52FB72002CB4F8 /* MainTabType.swift */; }; 4E5E48E52AB59806003F1B48 /* CustomizeViewsSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E5E48E42AB59806003F1B48 /* CustomizeViewsSettings.swift */; }; 4E73E2A62C41CFD3002D2A78 /* PlaybackBitrateTestSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E73E2A52C41CFD3002D2A78 /* PlaybackBitrateTestSize.swift */; }; @@ -4302,7 +4301,6 @@ E18E01DF288747230022598C /* iPadOSMovieItemView.swift in Sources */, E168BD13289A4162001A6922 /* ContinueWatchingView.swift in Sources */, E154966E296CA2EF00C4EF88 /* LogManager.swift in Sources */, - 4E541F942C52FB72002CB4F8 /* MainTabType.swift in Sources */, 62C29EA126D102A500C1D2E7 /* iOSMainTabCoordinator.swift in Sources */, E18E01E8288747230022598C /* SeriesItemContentView.swift in Sources */, E16AA60828A364A6009A983C /* PosterButton.swift in Sources */, diff --git a/Swiftfin/Views/SettingsView/CustomizeViewsSettings.swift b/Swiftfin/Views/SettingsView/CustomizeViewsSettings.swift index 17d3e9cd4..dc358a7fc 100644 --- a/Swiftfin/Views/SettingsView/CustomizeViewsSettings.swift +++ b/Swiftfin/Views/SettingsView/CustomizeViewsSettings.swift @@ -68,11 +68,11 @@ struct CustomizeViewsSettings: View { @Default(.Customization.Home.homeLabels) private var homeLabels - @Default(.Customization.Home.homeSections) - private var homeSections @EnvironmentObject private var router: SettingsCoordinator.Router + @EnvironmentObject + private var mainCoordinator: MainCoordinator var body: some View { List { @@ -168,16 +168,12 @@ struct CustomizeViewsSettings: View { } Section { + Toggle("Show recently added", isOn: $showRecentlyAdded) - Toggle("Section Labels", isOn: $homeLabels) - ChevronButton("Sections") - .onSelect { - router.route(to: \.homeSectionsSelector, $homeSections) - } + Toggle("Show Section Labels", isOn: $homeLabels) + } header: { L10n.home.text - } footer: { - Text("An app restart is required to update sections") } Section {